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, o<>")
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 ;;; ??? This should have alternatives for constants.
4091 ;;; ??? This was originally identical to the movdf_insn pattern.
4092 ;;; ??? The 'i' constraint looks funny, but it should always be replaced by
4093 ;;; thumb_reorg with a memory reference.
4094 (define_insn "*thumb_movdi_insn"
4095 [(set (match_operand:DI 0 "nonimmediate_operand" "=l,l,l,l,>,l, m,*r")
4096 (match_operand:DI 1 "general_operand" "l, I,J,>,l,mi,l,*r"))]
4098 && !(TARGET_HARD_FLOAT && TARGET_MAVERICK)
4099 && ( register_operand (operands[0], DImode)
4100 || register_operand (operands[1], DImode))"
4103 switch (which_alternative)
4107 if (REGNO (operands[1]) == REGNO (operands[0]) + 1)
4108 return \"add\\t%0, %1, #0\;add\\t%H0, %H1, #0\";
4109 return \"add\\t%H0, %H1, #0\;add\\t%0, %1, #0\";
4111 return \"mov\\t%Q0, %1\;mov\\t%R0, #0\";
4113 operands[1] = GEN_INT (- INTVAL (operands[1]));
4114 return \"mov\\t%Q0, %1\;neg\\t%Q0, %Q0\;asr\\t%R0, %Q0, #31\";
4116 return \"ldmia\\t%1, {%0, %H0}\";
4118 return \"stmia\\t%0, {%1, %H1}\";
4120 return thumb_load_double_from_address (operands);
4122 operands[2] = gen_rtx_MEM (SImode,
4123 plus_constant (XEXP (operands[0], 0), 4));
4124 output_asm_insn (\"str\\t%1, %0\;str\\t%H1, %2\", operands);
4127 if (REGNO (operands[1]) == REGNO (operands[0]) + 1)
4128 return \"mov\\t%0, %1\;mov\\t%H0, %H1\";
4129 return \"mov\\t%H0, %H1\;mov\\t%0, %1\";
4132 [(set_attr "length" "4,4,6,2,2,6,4,4")
4133 (set_attr "type" "*,*,*,load2,store2,load2,store2,*")
4134 (set_attr "pool_range" "*,*,*,*,*,1020,*,*")]
4137 (define_expand "movsi"
4138 [(set (match_operand:SI 0 "general_operand" "")
4139 (match_operand:SI 1 "general_operand" ""))]
4144 /* Everything except mem = const or mem = mem can be done easily. */
4145 if (GET_CODE (operands[0]) == MEM)
4146 operands[1] = force_reg (SImode, operands[1]);
4147 if (arm_general_register_operand (operands[0], SImode)
4148 && GET_CODE (operands[1]) == CONST_INT
4149 && !(const_ok_for_arm (INTVAL (operands[1]))
4150 || const_ok_for_arm (~INTVAL (operands[1]))))
4152 arm_split_constant (SET, SImode, NULL_RTX,
4153 INTVAL (operands[1]), operands[0], NULL_RTX,
4155 : preserve_subexpressions_p ()));
4159 else /* TARGET_THUMB.... */
4161 if (!no_new_pseudos)
4163 if (GET_CODE (operands[0]) != REG)
4164 operands[1] = force_reg (SImode, operands[1]);
4169 && (CONSTANT_P (operands[1])
4170 || symbol_mentioned_p (operands[1])
4171 || label_mentioned_p (operands[1])))
4172 operands[1] = legitimize_pic_address (operands[1], SImode,
4173 (no_new_pseudos ? operands[0] : 0));
4177 (define_insn "*arm_movsi_insn"
4178 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r, m")
4179 (match_operand:SI 1 "general_operand" "rI,K,mi,r"))]
4180 "TARGET_ARM && ! TARGET_IWMMXT
4181 && !(TARGET_HARD_FLOAT && TARGET_VFP)
4182 && ( register_operand (operands[0], SImode)
4183 || register_operand (operands[1], SImode))"
4189 [(set_attr "type" "*,*,load1,store1")
4190 (set_attr "predicable" "yes")
4191 (set_attr "pool_range" "*,*,4096,*")
4192 (set_attr "neg_pool_range" "*,*,4084,*")]
4196 [(set (match_operand:SI 0 "arm_general_register_operand" "")
4197 (match_operand:SI 1 "const_int_operand" ""))]
4199 && (!(const_ok_for_arm (INTVAL (operands[1]))
4200 || const_ok_for_arm (~INTVAL (operands[1]))))"
4201 [(clobber (const_int 0))]
4203 arm_split_constant (SET, SImode, NULL_RTX,
4204 INTVAL (operands[1]), operands[0], NULL_RTX, 0);
4209 (define_insn "*thumb_movsi_insn"
4210 [(set (match_operand:SI 0 "nonimmediate_operand" "=l,l,l,l,l,>,l, m,*lh")
4211 (match_operand:SI 1 "general_operand" "l, I,J,K,>,l,mi,l,*lh"))]
4213 && ( register_operand (operands[0], SImode)
4214 || register_operand (operands[1], SImode))"
4225 [(set_attr "length" "2,2,4,4,2,2,2,2,2")
4226 (set_attr "type" "*,*,*,*,load1,store1,load1,store1,*")
4227 (set_attr "pool_range" "*,*,*,*,*,*,1020,*,*")]
4231 [(set (match_operand:SI 0 "register_operand" "")
4232 (match_operand:SI 1 "const_int_operand" ""))]
4233 "TARGET_THUMB && CONST_OK_FOR_THUMB_LETTER (INTVAL (operands[1]), 'J')"
4234 [(set (match_dup 0) (match_dup 1))
4235 (set (match_dup 0) (neg:SI (match_dup 0)))]
4236 "operands[1] = GEN_INT (- INTVAL (operands[1]));"
4240 [(set (match_operand:SI 0 "register_operand" "")
4241 (match_operand:SI 1 "const_int_operand" ""))]
4242 "TARGET_THUMB && CONST_OK_FOR_THUMB_LETTER (INTVAL (operands[1]), 'K')"
4243 [(set (match_dup 0) (match_dup 1))
4244 (set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))]
4247 unsigned HOST_WIDE_INT val = INTVAL (operands[1]);
4248 unsigned HOST_WIDE_INT mask = 0xff;
4251 for (i = 0; i < 25; i++)
4252 if ((val & (mask << i)) == val)
4255 /* Shouldn't happen, but we don't want to split if the shift is zero. */
4259 operands[1] = GEN_INT (val >> i);
4260 operands[2] = GEN_INT (i);
4264 ;; When generating pic, we need to load the symbol offset into a register.
4265 ;; So that the optimizer does not confuse this with a normal symbol load
4266 ;; we use an unspec. The offset will be loaded from a constant pool entry,
4267 ;; since that is the only type of relocation we can use.
4269 ;; The rather odd constraints on the following are to force reload to leave
4270 ;; the insn alone, and to force the minipool generation pass to then move
4271 ;; the GOT symbol to memory.
4273 (define_insn "pic_load_addr_arm"
4274 [(set (match_operand:SI 0 "s_register_operand" "=r")
4275 (unspec:SI [(match_operand:SI 1 "" "mX")] UNSPEC_PIC_SYM))]
4276 "TARGET_ARM && flag_pic"
4278 [(set_attr "type" "load1")
4279 (set (attr "pool_range") (const_int 4096))
4280 (set (attr "neg_pool_range") (const_int 4084))]
4283 (define_insn "pic_load_addr_thumb"
4284 [(set (match_operand:SI 0 "s_register_operand" "=l")
4285 (unspec:SI [(match_operand:SI 1 "" "mX")] UNSPEC_PIC_SYM))]
4286 "TARGET_THUMB && flag_pic"
4288 [(set_attr "type" "load1")
4289 (set (attr "pool_range") (const_int 1024))]
4292 ;; This variant is used for AOF assembly, since it needs to mention the
4293 ;; pic register in the rtl.
4294 (define_expand "pic_load_addr_based"
4295 [(set (match_operand:SI 0 "s_register_operand" "")
4296 (unspec:SI [(match_operand 1 "" "") (match_dup 2)] UNSPEC_PIC_SYM))]
4297 "TARGET_ARM && flag_pic"
4298 "operands[2] = pic_offset_table_rtx;"
4301 (define_insn "*pic_load_addr_based_insn"
4302 [(set (match_operand:SI 0 "s_register_operand" "=r")
4303 (unspec:SI [(match_operand 1 "" "")
4304 (match_operand 2 "s_register_operand" "r")]
4306 "TARGET_EITHER && flag_pic && operands[2] == pic_offset_table_rtx"
4308 #ifdef AOF_ASSEMBLER
4309 operands[1] = aof_pic_entry (operands[1]);
4311 output_asm_insn (\"ldr%?\\t%0, %a1\", operands);
4314 [(set_attr "type" "load1")
4315 (set (attr "pool_range")
4316 (if_then_else (eq_attr "is_thumb" "yes")
4319 (set (attr "neg_pool_range")
4320 (if_then_else (eq_attr "is_thumb" "yes")
4325 (define_insn "pic_add_dot_plus_four"
4326 [(set (match_operand:SI 0 "register_operand" "+r")
4327 (unspec:SI [(plus:SI (match_dup 0)
4328 (const (plus:SI (pc) (const_int 4))))]
4330 (use (label_ref (match_operand 1 "" "")))]
4331 "TARGET_THUMB && flag_pic"
4333 (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
4334 CODE_LABEL_NUMBER (operands[1]));
4335 return \"add\\t%0, %|pc\";
4337 [(set_attr "length" "2")]
4340 (define_insn "pic_add_dot_plus_eight"
4341 [(set (match_operand:SI 0 "register_operand" "+r")
4342 (unspec:SI [(plus:SI (match_dup 0)
4343 (const (plus:SI (pc) (const_int 8))))]
4345 (use (label_ref (match_operand 1 "" "")))]
4346 "TARGET_ARM && flag_pic"
4348 (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
4349 CODE_LABEL_NUMBER (operands[1]));
4350 return \"add%?\\t%0, %|pc, %0\";
4352 [(set_attr "predicable" "yes")]
4355 (define_expand "builtin_setjmp_receiver"
4356 [(label_ref (match_operand 0 "" ""))]
4360 arm_finalize_pic (0);
4364 ;; If copying one reg to another we can set the condition codes according to
4365 ;; its value. Such a move is common after a return from subroutine and the
4366 ;; result is being tested against zero.
4368 (define_insn "*movsi_compare0"
4369 [(set (reg:CC CC_REGNUM)
4370 (compare:CC (match_operand:SI 1 "s_register_operand" "0,r")
4372 (set (match_operand:SI 0 "s_register_operand" "=r,r")
4377 sub%?s\\t%0, %1, #0"
4378 [(set_attr "conds" "set")]
4381 ;; Subroutine to store a half word from a register into memory.
4382 ;; Operand 0 is the source register (HImode)
4383 ;; Operand 1 is the destination address in a register (SImode)
4385 ;; In both this routine and the next, we must be careful not to spill
4386 ;; a memory address of reg+large_const into a separate PLUS insn, since this
4387 ;; can generate unrecognizable rtl.
4389 (define_expand "storehi"
4390 [;; store the low byte
4391 (set (match_operand 1 "" "") (match_dup 3))
4392 ;; extract the high byte
4394 (ashiftrt:SI (match_operand 0 "" "") (const_int 8)))
4395 ;; store the high byte
4396 (set (match_dup 4) (match_dup 5))]
4400 rtx op1 = operands[1];
4401 rtx addr = XEXP (op1, 0);
4402 enum rtx_code code = GET_CODE (addr);
4404 if ((code == PLUS && GET_CODE (XEXP (addr, 1)) != CONST_INT)
4406 op1 = replace_equiv_address (operands[1], force_reg (SImode, addr));
4408 operands[4] = adjust_address (op1, QImode, 1);
4409 operands[1] = adjust_address (operands[1], QImode, 0);
4410 operands[3] = gen_lowpart (QImode, operands[0]);
4411 operands[0] = gen_lowpart (SImode, operands[0]);
4412 operands[2] = gen_reg_rtx (SImode);
4413 operands[5] = gen_lowpart (QImode, operands[2]);
4417 (define_expand "storehi_bigend"
4418 [(set (match_dup 4) (match_dup 3))
4420 (ashiftrt:SI (match_operand 0 "" "") (const_int 8)))
4421 (set (match_operand 1 "" "") (match_dup 5))]
4425 rtx op1 = operands[1];
4426 rtx addr = XEXP (op1, 0);
4427 enum rtx_code code = GET_CODE (addr);
4429 if ((code == PLUS && GET_CODE (XEXP (addr, 1)) != CONST_INT)
4431 op1 = replace_equiv_address (op1, force_reg (SImode, addr));
4433 operands[4] = adjust_address (op1, QImode, 1);
4434 operands[1] = adjust_address (operands[1], QImode, 0);
4435 operands[3] = gen_lowpart (QImode, operands[0]);
4436 operands[0] = gen_lowpart (SImode, operands[0]);
4437 operands[2] = gen_reg_rtx (SImode);
4438 operands[5] = gen_lowpart (QImode, operands[2]);
4442 ;; Subroutine to store a half word integer constant into memory.
4443 (define_expand "storeinthi"
4444 [(set (match_operand 0 "" "")
4445 (match_operand 1 "" ""))
4446 (set (match_dup 3) (match_dup 2))]
4450 HOST_WIDE_INT value = INTVAL (operands[1]);
4451 rtx addr = XEXP (operands[0], 0);
4452 rtx op0 = operands[0];
4453 enum rtx_code code = GET_CODE (addr);
4455 if ((code == PLUS && GET_CODE (XEXP (addr, 1)) != CONST_INT)
4457 op0 = replace_equiv_address (op0, force_reg (SImode, addr));
4459 operands[1] = gen_reg_rtx (SImode);
4460 if (BYTES_BIG_ENDIAN)
4462 emit_insn (gen_movsi (operands[1], GEN_INT ((value >> 8) & 255)));
4463 if ((value & 255) == ((value >> 8) & 255))
4464 operands[2] = operands[1];
4467 operands[2] = gen_reg_rtx (SImode);
4468 emit_insn (gen_movsi (operands[2], GEN_INT (value & 255)));
4473 emit_insn (gen_movsi (operands[1], GEN_INT (value & 255)));
4474 if ((value & 255) == ((value >> 8) & 255))
4475 operands[2] = operands[1];
4478 operands[2] = gen_reg_rtx (SImode);
4479 emit_insn (gen_movsi (operands[2], GEN_INT ((value >> 8) & 255)));
4483 operands[3] = adjust_address (op0, QImode, 1);
4484 operands[0] = adjust_address (operands[0], QImode, 0);
4485 operands[2] = gen_lowpart (QImode, operands[2]);
4486 operands[1] = gen_lowpart (QImode, operands[1]);
4490 (define_expand "storehi_single_op"
4491 [(set (match_operand:HI 0 "memory_operand" "")
4492 (match_operand:HI 1 "general_operand" ""))]
4493 "TARGET_ARM && arm_arch4"
4495 if (!s_register_operand (operands[1], HImode))
4496 operands[1] = copy_to_mode_reg (HImode, operands[1]);
4500 (define_expand "movhi"
4501 [(set (match_operand:HI 0 "general_operand" "")
4502 (match_operand:HI 1 "general_operand" ""))]
4507 if (!no_new_pseudos)
4509 if (GET_CODE (operands[0]) == MEM)
4513 emit_insn (gen_storehi_single_op (operands[0], operands[1]));
4516 if (GET_CODE (operands[1]) == CONST_INT)
4517 emit_insn (gen_storeinthi (operands[0], operands[1]));
4520 if (GET_CODE (operands[1]) == MEM)
4521 operands[1] = force_reg (HImode, operands[1]);
4522 if (BYTES_BIG_ENDIAN)
4523 emit_insn (gen_storehi_bigend (operands[1], operands[0]));
4525 emit_insn (gen_storehi (operands[1], operands[0]));
4529 /* Sign extend a constant, and keep it in an SImode reg. */
4530 else if (GET_CODE (operands[1]) == CONST_INT)
4532 rtx reg = gen_reg_rtx (SImode);
4533 HOST_WIDE_INT val = INTVAL (operands[1]) & 0xffff;
4535 /* If the constant is already valid, leave it alone. */
4536 if (!const_ok_for_arm (val))
4538 /* If setting all the top bits will make the constant
4539 loadable in a single instruction, then set them.
4540 Otherwise, sign extend the number. */
4542 if (const_ok_for_arm (~(val | ~0xffff)))
4544 else if (val & 0x8000)
4548 emit_insn (gen_movsi (reg, GEN_INT (val)));
4549 operands[1] = gen_lowpart (HImode, reg);
4551 else if (arm_arch4 && !no_new_pseudos && optimize > 0
4552 && GET_CODE (operands[1]) == MEM)
4554 rtx reg = gen_reg_rtx (SImode);
4556 emit_insn (gen_zero_extendhisi2 (reg, operands[1]));
4557 operands[1] = gen_lowpart (HImode, reg);
4559 else if (!arm_arch4)
4561 /* Note: We do not have to worry about TARGET_MMU_TRAPS
4562 for v4 and up architectures because LDRH instructions will
4563 be used to access the HI values, and these cannot generate
4564 unaligned word access faults in the MMU. */
4565 if (GET_CODE (operands[1]) == MEM)
4567 if (TARGET_MMU_TRAPS)
4570 rtx offset = const0_rtx;
4571 rtx reg = gen_reg_rtx (SImode);
4573 if ((GET_CODE (base = XEXP (operands[1], 0)) == REG
4574 || (GET_CODE (base) == PLUS
4575 && (GET_CODE (offset = XEXP (base, 1))
4577 && ((INTVAL(offset) & 1) != 1)
4578 && GET_CODE (base = XEXP (base, 0)) == REG))
4579 && REGNO_POINTER_ALIGN (REGNO (base)) >= 32)
4581 HOST_WIDE_INT new_offset = INTVAL (offset) & ~3;
4584 new = gen_rtx_MEM (SImode,
4585 plus_constant (base, new_offset));
4586 MEM_COPY_ATTRIBUTES (new, operands[1]);
4587 emit_insn (gen_movsi (reg, new));
4588 if (((INTVAL (offset) & 2) != 0)
4589 ^ (BYTES_BIG_ENDIAN ? 1 : 0))
4591 rtx reg2 = gen_reg_rtx (SImode);
4593 emit_insn (gen_lshrsi3 (reg2, reg,
4599 emit_insn (gen_movhi_bytes (reg, operands[1]));
4601 operands[1] = gen_lowpart (HImode, reg);
4603 else if (BYTES_BIG_ENDIAN)
4606 rtx offset = const0_rtx;
4608 if ((GET_CODE (base = XEXP (operands[1], 0)) == REG
4609 || (GET_CODE (base) == PLUS
4610 && (GET_CODE (offset = XEXP (base, 1))
4612 && GET_CODE (base = XEXP (base, 0)) == REG))
4613 && REGNO_POINTER_ALIGN (REGNO (base)) >= 32)
4615 rtx reg = gen_reg_rtx (SImode);
4618 if ((INTVAL (offset) & 2) == 2)
4620 HOST_WIDE_INT new_offset = INTVAL (offset) ^ 2;
4621 new = gen_rtx_MEM (SImode,
4622 plus_constant (base,
4624 MEM_COPY_ATTRIBUTES (new, operands[1]);
4625 emit_insn (gen_movsi (reg, new));
4629 new = gen_rtx_MEM (SImode,
4630 XEXP (operands[1], 0));
4631 MEM_COPY_ATTRIBUTES (new, operands[1]);
4632 emit_insn (gen_rotated_loadsi (reg, new));
4635 operands[1] = gen_lowpart (HImode, reg);
4639 emit_insn (gen_movhi_bigend (operands[0],
4647 /* Handle loading a large integer during reload. */
4648 else if (GET_CODE (operands[1]) == CONST_INT
4649 && !const_ok_for_arm (INTVAL (operands[1]))
4650 && !const_ok_for_arm (~INTVAL (operands[1])))
4652 /* Writing a constant to memory needs a scratch, which should
4653 be handled with SECONDARY_RELOADs. */
4654 if (GET_CODE (operands[0]) != REG)
4657 operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
4658 emit_insn (gen_movsi (operands[0], operands[1]));
4662 else /* TARGET_THUMB */
4664 if (!no_new_pseudos)
4666 if (GET_CODE (operands[0]) != REG)
4667 operands[1] = force_reg (HImode, operands[1]);
4669 /* ??? We shouldn't really get invalid addresses here, but this can
4670 happen if we are passed a SP (never OK for HImode/QImode) or
4671 virtual register (rejected by GO_IF_LEGITIMATE_ADDRESS for
4672 HImode/QImode) relative address. */
4673 /* ??? This should perhaps be fixed elsewhere, for instance, in
4674 fixup_stack_1, by checking for other kinds of invalid addresses,
4675 e.g. a bare reference to a virtual register. This may confuse the
4676 alpha though, which must handle this case differently. */
4677 if (GET_CODE (operands[0]) == MEM
4678 && !memory_address_p (GET_MODE (operands[0]),
4679 XEXP (operands[0], 0)))
4681 = replace_equiv_address (operands[0],
4682 copy_to_reg (XEXP (operands[0], 0)));
4684 if (GET_CODE (operands[1]) == MEM
4685 && !memory_address_p (GET_MODE (operands[1]),
4686 XEXP (operands[1], 0)))
4688 = replace_equiv_address (operands[1],
4689 copy_to_reg (XEXP (operands[1], 0)));
4691 /* Handle loading a large integer during reload. */
4692 else if (GET_CODE (operands[1]) == CONST_INT
4693 && !CONST_OK_FOR_THUMB_LETTER (INTVAL (operands[1]), 'I'))
4695 /* Writing a constant to memory needs a scratch, which should
4696 be handled with SECONDARY_RELOADs. */
4697 if (GET_CODE (operands[0]) != REG)
4700 operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
4701 emit_insn (gen_movsi (operands[0], operands[1]));
4708 (define_insn "*thumb_movhi_insn"
4709 [(set (match_operand:HI 0 "nonimmediate_operand" "=l,l,m,*r,*h,l")
4710 (match_operand:HI 1 "general_operand" "l,m,l,*h,*r,I"))]
4712 && ( register_operand (operands[0], HImode)
4713 || register_operand (operands[1], HImode))"
4715 switch (which_alternative)
4717 case 0: return \"add %0, %1, #0\";
4718 case 2: return \"strh %1, %0\";
4719 case 3: return \"mov %0, %1\";
4720 case 4: return \"mov %0, %1\";
4721 case 5: return \"mov %0, %1\";
4724 /* The stack pointer can end up being taken as an index register.
4725 Catch this case here and deal with it. */
4726 if (GET_CODE (XEXP (operands[1], 0)) == PLUS
4727 && GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == REG
4728 && REGNO (XEXP (XEXP (operands[1], 0), 0)) == SP_REGNUM)
4731 ops[0] = operands[0];
4732 ops[1] = XEXP (XEXP (operands[1], 0), 0);
4734 output_asm_insn (\"mov %0, %1\", ops);
4736 XEXP (XEXP (operands[1], 0), 0) = operands[0];
4739 return \"ldrh %0, %1\";
4741 [(set_attr "length" "2,4,2,2,2,2")
4742 (set_attr "type" "*,load1,store1,*,*,*")]
4746 (define_insn "rotated_loadsi"
4747 [(set (match_operand:SI 0 "s_register_operand" "=r")
4748 (rotate:SI (match_operand:SI 1 "offsettable_memory_operand" "o")
4750 "TARGET_ARM && (!TARGET_MMU_TRAPS)"
4755 ops[0] = operands[0];
4756 ops[1] = gen_rtx_MEM (SImode, plus_constant (XEXP (operands[1], 0), 2));
4757 output_asm_insn (\"ldr%?\\t%0, %1\\t%@ load-rotate\", ops);
4760 [(set_attr "type" "load1")
4761 (set_attr "predicable" "yes")]
4764 (define_expand "movhi_bytes"
4765 [(set (match_dup 2) (zero_extend:SI (match_operand:HI 1 "" "")))
4767 (zero_extend:SI (match_dup 6)))
4768 (set (match_operand:SI 0 "" "")
4769 (ior:SI (ashift:SI (match_dup 4) (const_int 8)) (match_dup 5)))]
4774 rtx addr = copy_to_mode_reg (SImode, XEXP (operands[1], 0));
4776 mem1 = gen_rtx_MEM (QImode, addr);
4777 MEM_COPY_ATTRIBUTES (mem1, operands[1]);
4778 mem2 = gen_rtx_MEM (QImode, plus_constant (addr, 1));
4779 MEM_COPY_ATTRIBUTES (mem2, operands[1]);
4780 operands[0] = gen_lowpart (SImode, operands[0]);
4782 operands[2] = gen_reg_rtx (SImode);
4783 operands[3] = gen_reg_rtx (SImode);
4786 if (BYTES_BIG_ENDIAN)
4788 operands[4] = operands[2];
4789 operands[5] = operands[3];
4793 operands[4] = operands[3];
4794 operands[5] = operands[2];
4799 (define_expand "movhi_bigend"
4801 (rotate:SI (subreg:SI (match_operand:HI 1 "memory_operand" "") 0)
4804 (ashiftrt:SI (match_dup 2) (const_int 16)))
4805 (set (match_operand:HI 0 "s_register_operand" "")
4809 operands[2] = gen_reg_rtx (SImode);
4810 operands[3] = gen_reg_rtx (SImode);
4811 operands[4] = gen_lowpart (HImode, operands[3]);
4815 ;; Pattern to recognize insn generated default case above
4816 (define_insn "*movhi_insn_arch4"
4817 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,m,r")
4818 (match_operand:HI 1 "general_operand" "rI,K,r,m"))]
4821 && (GET_CODE (operands[1]) != CONST_INT
4822 || const_ok_for_arm (INTVAL (operands[1]))
4823 || const_ok_for_arm (~INTVAL (operands[1])))"
4825 mov%?\\t%0, %1\\t%@ movhi
4826 mvn%?\\t%0, #%B1\\t%@ movhi
4827 str%?h\\t%1, %0\\t%@ movhi
4828 ldr%?h\\t%0, %1\\t%@ movhi"
4829 [(set_attr "type" "*,*,store1,load1")
4830 (set_attr "predicable" "yes")
4831 (set_attr "pool_range" "*,*,*,256")
4832 (set_attr "neg_pool_range" "*,*,*,244")]
4835 (define_insn "*movhi_insn_littleend"
4836 [(set (match_operand:HI 0 "s_register_operand" "=r,r,r")
4837 (match_operand:HI 1 "general_operand" "rI,K,m"))]
4840 && !BYTES_BIG_ENDIAN
4841 && !TARGET_MMU_TRAPS
4842 && (GET_CODE (operands[1]) != CONST_INT
4843 || const_ok_for_arm (INTVAL (operands[1]))
4844 || const_ok_for_arm (~INTVAL (operands[1])))"
4846 mov%?\\t%0, %1\\t%@ movhi
4847 mvn%?\\t%0, #%B1\\t%@ movhi
4848 ldr%?\\t%0, %1\\t%@ movhi"
4849 [(set_attr "type" "*,*,load1")
4850 (set_attr "predicable" "yes")
4851 (set_attr "pool_range" "4096")
4852 (set_attr "neg_pool_range" "4084")]
4855 (define_insn "*movhi_insn_bigend"
4856 [(set (match_operand:HI 0 "s_register_operand" "=r,r,r")
4857 (match_operand:HI 1 "general_operand" "rI,K,m"))]
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_bigend\;mov%?\\t%0, %0, asr #16"
4869 [(set_attr "type" "*,*,load1")
4870 (set_attr "predicable" "yes")
4871 (set_attr "length" "4,4,8")
4872 (set_attr "pool_range" "*,*,4092")
4873 (set_attr "neg_pool_range" "*,*,4084")]
4876 (define_insn "*loadhi_si_bigend"
4877 [(set (match_operand:SI 0 "s_register_operand" "=r")
4878 (rotate:SI (subreg:SI (match_operand:HI 1 "memory_operand" "m") 0)
4882 && !TARGET_MMU_TRAPS"
4883 "ldr%?\\t%0, %1\\t%@ movhi_bigend"
4884 [(set_attr "type" "load1")
4885 (set_attr "predicable" "yes")
4886 (set_attr "pool_range" "4096")
4887 (set_attr "neg_pool_range" "4084")]
4890 (define_insn "*movhi_bytes"
4891 [(set (match_operand:HI 0 "s_register_operand" "=r,r")
4892 (match_operand:HI 1 "arm_rhs_operand" "rI,K"))]
4893 "TARGET_ARM && TARGET_MMU_TRAPS"
4895 mov%?\\t%0, %1\\t%@ movhi
4896 mvn%?\\t%0, #%B1\\t%@ movhi"
4897 [(set_attr "predicable" "yes")]
4900 (define_insn "thumb_movhi_clobber"
4901 [(set (match_operand:HI 0 "memory_operand" "=m")
4902 (match_operand:HI 1 "register_operand" "l"))
4903 (clobber (match_operand:SI 2 "register_operand" "=&l"))]
4909 ;; We use a DImode scratch because we may occasionally need an additional
4910 ;; temporary if the address isn't offsettable -- push_reload doesn't seem
4911 ;; to take any notice of the "o" constraints on reload_memory_operand operand.
4912 (define_expand "reload_outhi"
4913 [(parallel [(match_operand:HI 0 "arm_reload_memory_operand" "=o")
4914 (match_operand:HI 1 "s_register_operand" "r")
4915 (match_operand:DI 2 "s_register_operand" "=&l")])]
4918 arm_reload_out_hi (operands);
4920 thumb_reload_out_hi (operands);
4925 (define_expand "reload_inhi"
4926 [(parallel [(match_operand:HI 0 "s_register_operand" "=r")
4927 (match_operand:HI 1 "arm_reload_memory_operand" "o")
4928 (match_operand:DI 2 "s_register_operand" "=&r")])]
4929 "TARGET_THUMB || (TARGET_ARM && TARGET_MMU_TRAPS)"
4932 arm_reload_in_hi (operands);
4934 thumb_reload_out_hi (operands);
4938 (define_expand "movqi"
4939 [(set (match_operand:QI 0 "general_operand" "")
4940 (match_operand:QI 1 "general_operand" ""))]
4945 /* Everything except mem = const or mem = mem can be done easily */
4947 if (!no_new_pseudos)
4949 if (GET_CODE (operands[1]) == CONST_INT)
4951 rtx reg = gen_reg_rtx (SImode);
4953 emit_insn (gen_movsi (reg, operands[1]));
4954 operands[1] = gen_lowpart (QImode, reg);
4956 if (GET_CODE (operands[1]) == MEM && optimize > 0)
4958 rtx reg = gen_reg_rtx (SImode);
4960 emit_insn (gen_zero_extendqisi2 (reg, operands[1]));
4961 operands[1] = gen_lowpart (QImode, reg);
4963 if (GET_CODE (operands[0]) == MEM)
4964 operands[1] = force_reg (QImode, operands[1]);
4967 else /* TARGET_THUMB */
4969 if (!no_new_pseudos)
4971 if (GET_CODE (operands[0]) != REG)
4972 operands[1] = force_reg (QImode, operands[1]);
4974 /* ??? We shouldn't really get invalid addresses here, but this can
4975 happen if we are passed a SP (never OK for HImode/QImode) or
4976 virtual register (rejected by GO_IF_LEGITIMATE_ADDRESS for
4977 HImode/QImode) relative address. */
4978 /* ??? This should perhaps be fixed elsewhere, for instance, in
4979 fixup_stack_1, by checking for other kinds of invalid addresses,
4980 e.g. a bare reference to a virtual register. This may confuse the
4981 alpha though, which must handle this case differently. */
4982 if (GET_CODE (operands[0]) == MEM
4983 && !memory_address_p (GET_MODE (operands[0]),
4984 XEXP (operands[0], 0)))
4986 = replace_equiv_address (operands[0],
4987 copy_to_reg (XEXP (operands[0], 0)));
4988 if (GET_CODE (operands[1]) == MEM
4989 && !memory_address_p (GET_MODE (operands[1]),
4990 XEXP (operands[1], 0)))
4992 = replace_equiv_address (operands[1],
4993 copy_to_reg (XEXP (operands[1], 0)));
4995 /* Handle loading a large integer during reload. */
4996 else if (GET_CODE (operands[1]) == CONST_INT
4997 && !CONST_OK_FOR_LETTER_P (INTVAL (operands[1]), 'I'))
4999 /* Writing a constant to memory needs a scratch, which should
5000 be handled with SECONDARY_RELOADs. */
5001 if (GET_CODE (operands[0]) != REG)
5004 operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
5005 emit_insn (gen_movsi (operands[0], operands[1]));
5013 (define_insn "*arm_movqi_insn"
5014 [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,r,m")
5015 (match_operand:QI 1 "general_operand" "rI,K,m,r"))]
5017 && ( register_operand (operands[0], QImode)
5018 || register_operand (operands[1], QImode))"
5024 [(set_attr "type" "*,*,load1,store1")
5025 (set_attr "predicable" "yes")]
5028 (define_insn "*thumb_movqi_insn"
5029 [(set (match_operand:QI 0 "nonimmediate_operand" "=l,l,m,*r,*h,l")
5030 (match_operand:QI 1 "general_operand" "l, m,l,*h,*r,I"))]
5032 && ( register_operand (operands[0], QImode)
5033 || register_operand (operands[1], QImode))"
5041 [(set_attr "length" "2")
5042 (set_attr "type" "*,load1,store1,*,*,*")
5043 (set_attr "pool_range" "*,32,*,*,*,*")]
5046 (define_expand "movsf"
5047 [(set (match_operand:SF 0 "general_operand" "")
5048 (match_operand:SF 1 "general_operand" ""))]
5053 if (GET_CODE (operands[0]) == MEM)
5054 operands[1] = force_reg (SFmode, operands[1]);
5056 else /* TARGET_THUMB */
5058 if (!no_new_pseudos)
5060 if (GET_CODE (operands[0]) != REG)
5061 operands[1] = force_reg (SFmode, operands[1]);
5068 [(set (match_operand:SF 0 "nonimmediate_operand" "")
5069 (match_operand:SF 1 "immediate_operand" ""))]
5071 && !(TARGET_HARD_FLOAT && TARGET_FPA)
5073 && GET_CODE (operands[1]) == CONST_DOUBLE"
5074 [(set (match_dup 2) (match_dup 3))]
5076 operands[2] = gen_lowpart (SImode, operands[0]);
5077 operands[3] = gen_lowpart (SImode, operands[1]);
5078 if (operands[2] == 0 || operands[3] == 0)
5083 (define_insn "*arm_movsf_soft_insn"
5084 [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,m")
5085 (match_operand:SF 1 "general_operand" "r,mE,r"))]
5087 && TARGET_SOFT_FLOAT
5088 && (GET_CODE (operands[0]) != MEM
5089 || register_operand (operands[1], SFmode))"
5092 ldr%?\\t%0, %1\\t%@ float
5093 str%?\\t%1, %0\\t%@ float"
5094 [(set_attr "length" "4,4,4")
5095 (set_attr "predicable" "yes")
5096 (set_attr "type" "*,load1,store1")
5097 (set_attr "pool_range" "*,4096,*")
5098 (set_attr "neg_pool_range" "*,4084,*")]
5101 ;;; ??? This should have alternatives for constants.
5102 (define_insn "*thumb_movsf_insn"
5103 [(set (match_operand:SF 0 "nonimmediate_operand" "=l,l,>,l, m,*r,*h")
5104 (match_operand:SF 1 "general_operand" "l, >,l,mF,l,*h,*r"))]
5106 && ( register_operand (operands[0], SFmode)
5107 || register_operand (operands[1], SFmode))"
5116 [(set_attr "length" "2")
5117 (set_attr "type" "*,load1,store1,load1,store1,*,*")
5118 (set_attr "pool_range" "*,*,*,1020,*,*,*")]
5121 (define_expand "movdf"
5122 [(set (match_operand:DF 0 "general_operand" "")
5123 (match_operand:DF 1 "general_operand" ""))]
5128 if (GET_CODE (operands[0]) == MEM)
5129 operands[1] = force_reg (DFmode, operands[1]);
5131 else /* TARGET_THUMB */
5133 if (!no_new_pseudos)
5135 if (GET_CODE (operands[0]) != REG)
5136 operands[1] = force_reg (DFmode, operands[1]);
5142 ;; Reloading a df mode value stored in integer regs to memory can require a
5144 (define_expand "reload_outdf"
5145 [(match_operand:DF 0 "arm_reload_memory_operand" "=o")
5146 (match_operand:DF 1 "s_register_operand" "r")
5147 (match_operand:SI 2 "s_register_operand" "=&r")]
5151 enum rtx_code code = GET_CODE (XEXP (operands[0], 0));
5154 operands[2] = XEXP (operands[0], 0);
5155 else if (code == POST_INC || code == PRE_DEC)
5157 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
5158 operands[1] = gen_rtx_SUBREG (DImode, operands[1], 0);
5159 emit_insn (gen_movdi (operands[0], operands[1]));
5162 else if (code == PRE_INC)
5164 rtx reg = XEXP (XEXP (operands[0], 0), 0);
5166 emit_insn (gen_addsi3 (reg, reg, GEN_INT (8)));
5169 else if (code == POST_DEC)
5170 operands[2] = XEXP (XEXP (operands[0], 0), 0);
5172 emit_insn (gen_addsi3 (operands[2], XEXP (XEXP (operands[0], 0), 0),
5173 XEXP (XEXP (operands[0], 0), 1)));
5175 emit_insn (gen_rtx_SET (VOIDmode, gen_rtx_MEM (DFmode, operands[2]),
5178 if (code == POST_DEC)
5179 emit_insn (gen_addsi3 (operands[2], operands[2], GEN_INT (-8)));
5185 (define_insn "*movdf_soft_insn"
5186 [(set (match_operand:DF 0 "nonimmediate_soft_df_operand" "=r,r,m")
5187 (match_operand:DF 1 "soft_df_operand" "r,mF,r"))]
5188 "TARGET_ARM && TARGET_SOFT_FLOAT
5190 "* return output_move_double (operands);"
5191 [(set_attr "length" "8,8,8")
5192 (set_attr "type" "*,load2,store2")
5193 (set_attr "pool_range" "1020")
5194 (set_attr "neg_pool_range" "1008")]
5197 ;;; ??? This should have alternatives for constants.
5198 ;;; ??? This was originally identical to the movdi_insn pattern.
5199 ;;; ??? The 'F' constraint looks funny, but it should always be replaced by
5200 ;;; thumb_reorg with a memory reference.
5201 (define_insn "*thumb_movdf_insn"
5202 [(set (match_operand:DF 0 "nonimmediate_operand" "=l,l,>,l, m,*r")
5203 (match_operand:DF 1 "general_operand" "l, >,l,mF,l,*r"))]
5205 && ( register_operand (operands[0], DFmode)
5206 || register_operand (operands[1], DFmode))"
5208 switch (which_alternative)
5212 if (REGNO (operands[1]) == REGNO (operands[0]) + 1)
5213 return \"add\\t%0, %1, #0\;add\\t%H0, %H1, #0\";
5214 return \"add\\t%H0, %H1, #0\;add\\t%0, %1, #0\";
5216 return \"ldmia\\t%1, {%0, %H0}\";
5218 return \"stmia\\t%0, {%1, %H1}\";
5220 return thumb_load_double_from_address (operands);
5222 operands[2] = gen_rtx_MEM (SImode,
5223 plus_constant (XEXP (operands[0], 0), 4));
5224 output_asm_insn (\"str\\t%1, %0\;str\\t%H1, %2\", operands);
5227 if (REGNO (operands[1]) == REGNO (operands[0]) + 1)
5228 return \"mov\\t%0, %1\;mov\\t%H0, %H1\";
5229 return \"mov\\t%H0, %H1\;mov\\t%0, %1\";
5232 [(set_attr "length" "4,2,2,6,4,4")
5233 (set_attr "type" "*,load2,store2,load2,store2,*")
5234 (set_attr "pool_range" "*,*,*,1020,*,*")]
5238 (define_expand "movv2si"
5239 [(set (match_operand:V2SI 0 "nonimmediate_operand" "")
5240 (match_operand:V2SI 1 "general_operand" ""))]
5241 "TARGET_REALLY_IWMMXT"
5245 (define_expand "movv4hi"
5246 [(set (match_operand:V4HI 0 "nonimmediate_operand" "")
5247 (match_operand:V4HI 1 "general_operand" ""))]
5248 "TARGET_REALLY_IWMMXT"
5252 (define_expand "movv8qi"
5253 [(set (match_operand:V8QI 0 "nonimmediate_operand" "")
5254 (match_operand:V8QI 1 "general_operand" ""))]
5255 "TARGET_REALLY_IWMMXT"
5260 ;; load- and store-multiple insns
5261 ;; The arm can load/store any set of registers, provided that they are in
5262 ;; ascending order; but that is beyond GCC so stick with what it knows.
5264 (define_expand "load_multiple"
5265 [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
5266 (match_operand:SI 1 "" ""))
5267 (use (match_operand:SI 2 "" ""))])]
5270 /* Support only fixed point registers. */
5271 if (GET_CODE (operands[2]) != CONST_INT
5272 || INTVAL (operands[2]) > 14
5273 || INTVAL (operands[2]) < 2
5274 || GET_CODE (operands[1]) != MEM
5275 || GET_CODE (operands[0]) != REG
5276 || REGNO (operands[0]) > (LAST_ARM_REGNUM - 1)
5277 || REGNO (operands[0]) + INTVAL (operands[2]) > LAST_ARM_REGNUM)
5281 = arm_gen_load_multiple (REGNO (operands[0]), INTVAL (operands[2]),
5282 force_reg (SImode, XEXP (operands[1], 0)),
5283 TRUE, FALSE, RTX_UNCHANGING_P(operands[1]),
5284 MEM_IN_STRUCT_P(operands[1]),
5285 MEM_SCALAR_P (operands[1]));
5289 ;; Load multiple with write-back
5291 (define_insn "*ldmsi_postinc4"
5292 [(match_parallel 0 "load_multiple_operation"
5293 [(set (match_operand:SI 1 "s_register_operand" "=r")
5294 (plus:SI (match_operand:SI 2 "s_register_operand" "1")
5296 (set (match_operand:SI 3 "arm_hard_register_operand" "")
5297 (mem:SI (match_dup 2)))
5298 (set (match_operand:SI 4 "arm_hard_register_operand" "")
5299 (mem:SI (plus:SI (match_dup 2) (const_int 4))))
5300 (set (match_operand:SI 5 "arm_hard_register_operand" "")
5301 (mem:SI (plus:SI (match_dup 2) (const_int 8))))
5302 (set (match_operand:SI 6 "arm_hard_register_operand" "")
5303 (mem:SI (plus:SI (match_dup 2) (const_int 12))))])]
5304 "TARGET_ARM && XVECLEN (operands[0], 0) == 5"
5305 "ldm%?ia\\t%1!, {%3, %4, %5, %6}"
5306 [(set_attr "type" "load4")
5307 (set_attr "predicable" "yes")]
5310 (define_insn "*ldmsi_postinc3"
5311 [(match_parallel 0 "load_multiple_operation"
5312 [(set (match_operand:SI 1 "s_register_operand" "=r")
5313 (plus:SI (match_operand:SI 2 "s_register_operand" "1")
5315 (set (match_operand:SI 3 "arm_hard_register_operand" "")
5316 (mem:SI (match_dup 2)))
5317 (set (match_operand:SI 4 "arm_hard_register_operand" "")
5318 (mem:SI (plus:SI (match_dup 2) (const_int 4))))
5319 (set (match_operand:SI 5 "arm_hard_register_operand" "")
5320 (mem:SI (plus:SI (match_dup 2) (const_int 8))))])]
5321 "TARGET_ARM && XVECLEN (operands[0], 0) == 4"
5322 "ldm%?ia\\t%1!, {%3, %4, %5}"
5323 [(set_attr "type" "load3")
5324 (set_attr "predicable" "yes")]
5327 (define_insn "*ldmsi_postinc2"
5328 [(match_parallel 0 "load_multiple_operation"
5329 [(set (match_operand:SI 1 "s_register_operand" "=r")
5330 (plus:SI (match_operand:SI 2 "s_register_operand" "1")
5332 (set (match_operand:SI 3 "arm_hard_register_operand" "")
5333 (mem:SI (match_dup 2)))
5334 (set (match_operand:SI 4 "arm_hard_register_operand" "")
5335 (mem:SI (plus:SI (match_dup 2) (const_int 4))))])]
5336 "TARGET_ARM && XVECLEN (operands[0], 0) == 3"
5337 "ldm%?ia\\t%1!, {%3, %4}"
5338 [(set_attr "type" "load2")
5339 (set_attr "predicable" "yes")]
5342 ;; Ordinary load multiple
5344 (define_insn "*ldmsi4"
5345 [(match_parallel 0 "load_multiple_operation"
5346 [(set (match_operand:SI 2 "arm_hard_register_operand" "")
5347 (mem:SI (match_operand:SI 1 "s_register_operand" "r")))
5348 (set (match_operand:SI 3 "arm_hard_register_operand" "")
5349 (mem:SI (plus:SI (match_dup 1) (const_int 4))))
5350 (set (match_operand:SI 4 "arm_hard_register_operand" "")
5351 (mem:SI (plus:SI (match_dup 1) (const_int 8))))
5352 (set (match_operand:SI 5 "arm_hard_register_operand" "")
5353 (mem:SI (plus:SI (match_dup 1) (const_int 12))))])]
5354 "TARGET_ARM && XVECLEN (operands[0], 0) == 4"
5355 "ldm%?ia\\t%1, {%2, %3, %4, %5}"
5356 [(set_attr "type" "load4")
5357 (set_attr "predicable" "yes")]
5360 (define_insn "*ldmsi3"
5361 [(match_parallel 0 "load_multiple_operation"
5362 [(set (match_operand:SI 2 "arm_hard_register_operand" "")
5363 (mem:SI (match_operand:SI 1 "s_register_operand" "r")))
5364 (set (match_operand:SI 3 "arm_hard_register_operand" "")
5365 (mem:SI (plus:SI (match_dup 1) (const_int 4))))
5366 (set (match_operand:SI 4 "arm_hard_register_operand" "")
5367 (mem:SI (plus:SI (match_dup 1) (const_int 8))))])]
5368 "TARGET_ARM && XVECLEN (operands[0], 0) == 3"
5369 "ldm%?ia\\t%1, {%2, %3, %4}"
5370 [(set_attr "type" "load3")
5371 (set_attr "predicable" "yes")]
5374 (define_insn "*ldmsi2"
5375 [(match_parallel 0 "load_multiple_operation"
5376 [(set (match_operand:SI 2 "arm_hard_register_operand" "")
5377 (mem:SI (match_operand:SI 1 "s_register_operand" "r")))
5378 (set (match_operand:SI 3 "arm_hard_register_operand" "")
5379 (mem:SI (plus:SI (match_dup 1) (const_int 4))))])]
5380 "TARGET_ARM && XVECLEN (operands[0], 0) == 2"
5381 "ldm%?ia\\t%1, {%2, %3}"
5382 [(set_attr "type" "load2")
5383 (set_attr "predicable" "yes")]
5386 (define_expand "store_multiple"
5387 [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
5388 (match_operand:SI 1 "" ""))
5389 (use (match_operand:SI 2 "" ""))])]
5392 /* Support only fixed point registers. */
5393 if (GET_CODE (operands[2]) != CONST_INT
5394 || INTVAL (operands[2]) > 14
5395 || INTVAL (operands[2]) < 2
5396 || GET_CODE (operands[1]) != REG
5397 || GET_CODE (operands[0]) != MEM
5398 || REGNO (operands[1]) > (LAST_ARM_REGNUM - 1)
5399 || REGNO (operands[1]) + INTVAL (operands[2]) > LAST_ARM_REGNUM)
5403 = arm_gen_store_multiple (REGNO (operands[1]), INTVAL (operands[2]),
5404 force_reg (SImode, XEXP (operands[0], 0)),
5405 TRUE, FALSE, RTX_UNCHANGING_P (operands[0]),
5406 MEM_IN_STRUCT_P(operands[0]),
5407 MEM_SCALAR_P (operands[0]));
5411 ;; Store multiple with write-back
5413 (define_insn "*stmsi_postinc4"
5414 [(match_parallel 0 "store_multiple_operation"
5415 [(set (match_operand:SI 1 "s_register_operand" "=r")
5416 (plus:SI (match_operand:SI 2 "s_register_operand" "1")
5418 (set (mem:SI (match_dup 2))
5419 (match_operand:SI 3 "arm_hard_register_operand" ""))
5420 (set (mem:SI (plus:SI (match_dup 2) (const_int 4)))
5421 (match_operand:SI 4 "arm_hard_register_operand" ""))
5422 (set (mem:SI (plus:SI (match_dup 2) (const_int 8)))
5423 (match_operand:SI 5 "arm_hard_register_operand" ""))
5424 (set (mem:SI (plus:SI (match_dup 2) (const_int 12)))
5425 (match_operand:SI 6 "arm_hard_register_operand" ""))])]
5426 "TARGET_ARM && XVECLEN (operands[0], 0) == 5"
5427 "stm%?ia\\t%1!, {%3, %4, %5, %6}"
5428 [(set_attr "predicable" "yes")
5429 (set_attr "type" "store4")]
5432 (define_insn "*stmsi_postinc3"
5433 [(match_parallel 0 "store_multiple_operation"
5434 [(set (match_operand:SI 1 "s_register_operand" "=r")
5435 (plus:SI (match_operand:SI 2 "s_register_operand" "1")
5437 (set (mem:SI (match_dup 2))
5438 (match_operand:SI 3 "arm_hard_register_operand" ""))
5439 (set (mem:SI (plus:SI (match_dup 2) (const_int 4)))
5440 (match_operand:SI 4 "arm_hard_register_operand" ""))
5441 (set (mem:SI (plus:SI (match_dup 2) (const_int 8)))
5442 (match_operand:SI 5 "arm_hard_register_operand" ""))])]
5443 "TARGET_ARM && XVECLEN (operands[0], 0) == 4"
5444 "stm%?ia\\t%1!, {%3, %4, %5}"
5445 [(set_attr "predicable" "yes")
5446 (set_attr "type" "store3")]
5449 (define_insn "*stmsi_postinc2"
5450 [(match_parallel 0 "store_multiple_operation"
5451 [(set (match_operand:SI 1 "s_register_operand" "=r")
5452 (plus:SI (match_operand:SI 2 "s_register_operand" "1")
5454 (set (mem:SI (match_dup 2))
5455 (match_operand:SI 3 "arm_hard_register_operand" ""))
5456 (set (mem:SI (plus:SI (match_dup 2) (const_int 4)))
5457 (match_operand:SI 4 "arm_hard_register_operand" ""))])]
5458 "TARGET_ARM && XVECLEN (operands[0], 0) == 3"
5459 "stm%?ia\\t%1!, {%3, %4}"
5460 [(set_attr "predicable" "yes")
5461 (set_attr "type" "store2")]
5464 ;; Ordinary store multiple
5466 (define_insn "*stmsi4"
5467 [(match_parallel 0 "store_multiple_operation"
5468 [(set (mem:SI (match_operand:SI 1 "s_register_operand" "r"))
5469 (match_operand:SI 2 "arm_hard_register_operand" ""))
5470 (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
5471 (match_operand:SI 3 "arm_hard_register_operand" ""))
5472 (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
5473 (match_operand:SI 4 "arm_hard_register_operand" ""))
5474 (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
5475 (match_operand:SI 5 "arm_hard_register_operand" ""))])]
5476 "TARGET_ARM && XVECLEN (operands[0], 0) == 4"
5477 "stm%?ia\\t%1, {%2, %3, %4, %5}"
5478 [(set_attr "predicable" "yes")
5479 (set_attr "type" "store4")]
5482 (define_insn "*stmsi3"
5483 [(match_parallel 0 "store_multiple_operation"
5484 [(set (mem:SI (match_operand:SI 1 "s_register_operand" "r"))
5485 (match_operand:SI 2 "arm_hard_register_operand" ""))
5486 (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
5487 (match_operand:SI 3 "arm_hard_register_operand" ""))
5488 (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
5489 (match_operand:SI 4 "arm_hard_register_operand" ""))])]
5490 "TARGET_ARM && XVECLEN (operands[0], 0) == 3"
5491 "stm%?ia\\t%1, {%2, %3, %4}"
5492 [(set_attr "predicable" "yes")
5493 (set_attr "type" "store3")]
5496 (define_insn "*stmsi2"
5497 [(match_parallel 0 "store_multiple_operation"
5498 [(set (mem:SI (match_operand:SI 1 "s_register_operand" "r"))
5499 (match_operand:SI 2 "arm_hard_register_operand" ""))
5500 (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
5501 (match_operand:SI 3 "arm_hard_register_operand" ""))])]
5502 "TARGET_ARM && XVECLEN (operands[0], 0) == 2"
5503 "stm%?ia\\t%1, {%2, %3}"
5504 [(set_attr "predicable" "yes")
5505 (set_attr "type" "store2")]
5508 ;; Move a block of memory if it is word aligned and MORE than 2 words long.
5509 ;; We could let this apply for blocks of less than this, but it clobbers so
5510 ;; many registers that there is then probably a better way.
5512 (define_expand "movstrqi"
5513 [(match_operand:BLK 0 "general_operand" "")
5514 (match_operand:BLK 1 "general_operand" "")
5515 (match_operand:SI 2 "const_int_operand" "")
5516 (match_operand:SI 3 "const_int_operand" "")]
5521 if (arm_gen_movstrqi (operands))
5525 else /* TARGET_THUMB */
5527 if ( INTVAL (operands[3]) != 4
5528 || INTVAL (operands[2]) > 48)
5531 thumb_expand_movstrqi (operands);
5537 ;; Thumb block-move insns
5539 (define_insn "movmem12b"
5540 [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
5541 (mem:SI (match_operand:SI 3 "register_operand" "1")))
5542 (set (mem:SI (plus:SI (match_dup 2) (const_int 4)))
5543 (mem:SI (plus:SI (match_dup 3) (const_int 4))))
5544 (set (mem:SI (plus:SI (match_dup 2) (const_int 8)))
5545 (mem:SI (plus:SI (match_dup 3) (const_int 8))))
5546 (set (match_operand:SI 0 "register_operand" "=l")
5547 (plus:SI (match_dup 2) (const_int 12)))
5548 (set (match_operand:SI 1 "register_operand" "=l")
5549 (plus:SI (match_dup 3) (const_int 12)))
5550 (clobber (match_scratch:SI 4 "=&l"))
5551 (clobber (match_scratch:SI 5 "=&l"))
5552 (clobber (match_scratch:SI 6 "=&l"))]
5554 "* return thumb_output_move_mem_multiple (3, operands);"
5555 [(set_attr "length" "4")
5556 ; This isn't entirely accurate... It loads as well, but in terms of
5557 ; scheduling the following insn it is better to consider it as a store
5558 (set_attr "type" "store3")]
5561 (define_insn "movmem8b"
5562 [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
5563 (mem:SI (match_operand:SI 3 "register_operand" "1")))
5564 (set (mem:SI (plus:SI (match_dup 2) (const_int 4)))
5565 (mem:SI (plus:SI (match_dup 3) (const_int 4))))
5566 (set (match_operand:SI 0 "register_operand" "=l")
5567 (plus:SI (match_dup 2) (const_int 8)))
5568 (set (match_operand:SI 1 "register_operand" "=l")
5569 (plus:SI (match_dup 3) (const_int 8)))
5570 (clobber (match_scratch:SI 4 "=&l"))
5571 (clobber (match_scratch:SI 5 "=&l"))]
5573 "* return thumb_output_move_mem_multiple (2, operands);"
5574 [(set_attr "length" "4")
5575 ; This isn't entirely accurate... It loads as well, but in terms of
5576 ; scheduling the following insn it is better to consider it as a store
5577 (set_attr "type" "store2")]
5582 ;; Compare & branch insns
5583 ;; The range calculations are based as follows:
5584 ;; For forward branches, the address calculation returns the address of
5585 ;; the next instruction. This is 2 beyond the branch instruction.
5586 ;; For backward branches, the address calculation returns the address of
5587 ;; the first instruction in this pattern (cmp). This is 2 before the branch
5588 ;; instruction for the shortest sequence, and 4 before the branch instruction
5589 ;; if we have to jump around an unconditional branch.
5590 ;; To the basic branch range the PC offset must be added (this is +4).
5591 ;; So for forward branches we have
5592 ;; (pos_range - pos_base_offs + pc_offs) = (pos_range - 2 + 4).
5593 ;; And for backward branches we have
5594 ;; (neg_range - neg_base_offs + pc_offs) = (neg_range - (-2 or -4) + 4).
5596 ;; For a 'b' pos_range = 2046, neg_range = -2048 giving (-2040->2048).
5597 ;; For a 'b<cond>' pos_range = 254, neg_range = -256 giving (-250 ->256).
5599 (define_expand "cbranchsi4"
5600 [(set (pc) (if_then_else
5601 (match_operator 0 "arm_comparison_operator"
5602 [(match_operand:SI 1 "s_register_operand" "")
5603 (match_operand:SI 2 "nonmemory_operand" "")])
5604 (label_ref (match_operand 3 "" ""))
5608 if (thumb_cmpneg_operand (operands[2], SImode))
5610 emit_jump_insn (gen_cbranchsi4_scratch (NULL, operands[1], operands[2],
5611 operands[3], operands[0]));
5614 if (!thumb_cmp_operand (operands[2], SImode))
5615 operands[2] = force_reg (SImode, operands[2]);
5618 (define_insn "*cbranchsi4_insn"
5619 [(set (pc) (if_then_else
5620 (match_operator 0 "arm_comparison_operator"
5621 [(match_operand:SI 1 "s_register_operand" "l,*h")
5622 (match_operand:SI 2 "thumb_cmp_operand" "lI*h,*r")])
5623 (label_ref (match_operand 3 "" ""))
5627 output_asm_insn (\"cmp\\t%1, %2\", operands);
5629 switch (get_attr_length (insn))
5631 case 4: return \"b%d0\\t%l3\";
5632 case 6: return \"b%D0\\t.LCB%=\;b\\t%l3\\t%@long jump\\n.LCB%=:\";
5633 default: return \"b%D0\\t.LCB%=\;bl\\t%l3\\t%@far jump\\n.LCB%=:\";
5636 [(set (attr "far_jump")
5638 (eq_attr "length" "8")
5639 (const_string "yes")
5640 (const_string "no")))
5641 (set (attr "length")
5643 (and (ge (minus (match_dup 3) (pc)) (const_int -250))
5644 (le (minus (match_dup 3) (pc)) (const_int 256)))
5647 (and (ge (minus (match_dup 3) (pc)) (const_int -2040))
5648 (le (minus (match_dup 3) (pc)) (const_int 2048)))
5653 (define_insn "cbranchsi4_scratch"
5654 [(set (pc) (if_then_else
5655 (match_operator 4 "arm_comparison_operator"
5656 [(match_operand:SI 1 "s_register_operand" "l,0")
5657 (match_operand:SI 2 "thumb_cmpneg_operand" "L,J")])
5658 (label_ref (match_operand 3 "" ""))
5660 (clobber (match_scratch:SI 0 "=l,l"))]
5663 output_asm_insn (\"add\\t%0, %1, #%n2\", operands);
5665 switch (get_attr_length (insn))
5667 case 4: return \"b%d4\\t%l3\";
5668 case 6: return \"b%D4\\t.LCB%=\;b\\t%l3\\t%@long jump\\n.LCB%=:\";
5669 default: return \"b%D4\\t.LCB%=\;bl\\t%l3\\t%@far jump\\n.LCB%=:\";
5672 [(set (attr "far_jump")
5674 (eq_attr "length" "8")
5675 (const_string "yes")
5676 (const_string "no")))
5677 (set (attr "length")
5679 (and (ge (minus (match_dup 3) (pc)) (const_int -250))
5680 (le (minus (match_dup 3) (pc)) (const_int 256)))
5683 (and (ge (minus (match_dup 3) (pc)) (const_int -2040))
5684 (le (minus (match_dup 3) (pc)) (const_int 2048)))
5688 (define_insn "*movsi_cbranchsi4"
5691 (match_operator 3 "arm_comparison_operator"
5692 [(match_operand:SI 1 "s_register_operand" "0,l,l,l")
5694 (label_ref (match_operand 2 "" ""))
5696 (set (match_operand:SI 0 "thumb_cbrch_target_operand" "=l,l,*h,*m")
5700 if (which_alternative == 0)
5701 output_asm_insn (\"cmp\t%0, #0\", operands);
5702 else if (which_alternative == 1)
5703 output_asm_insn (\"sub\t%0, %1, #0\", operands);
5706 output_asm_insn (\"cmp\t%1, #0\", operands);
5707 if (which_alternative == 2)
5708 output_asm_insn (\"mov\t%0, %1\", operands);
5710 output_asm_insn (\"str\t%1, %0\", operands);
5712 switch (get_attr_length (insn) - ((which_alternative > 1) ? 2 : 0))
5714 case 4: return \"b%d3\\t%l2\";
5715 case 6: return \"b%D3\\t.LCB%=\;b\\t%l2\\t%@long jump\\n.LCB%=:\";
5716 default: return \"b%D3\\t.LCB%=\;bl\\t%l2\\t%@far jump\\n.LCB%=:\";
5719 [(set (attr "far_jump")
5721 (ior (and (gt (symbol_ref ("which_alternative"))
5723 (eq_attr "length" "8"))
5724 (eq_attr "length" "10"))
5725 (const_string "yes")
5726 (const_string "no")))
5727 (set (attr "length")
5729 (le (symbol_ref ("which_alternative"))
5732 (and (ge (minus (match_dup 2) (pc)) (const_int -250))
5733 (le (minus (match_dup 2) (pc)) (const_int 256)))
5736 (and (ge (minus (match_dup 2) (pc)) (const_int -2040))
5737 (le (minus (match_dup 2) (pc)) (const_int 2048)))
5741 (and (ge (minus (match_dup 2) (pc)) (const_int -248))
5742 (le (minus (match_dup 2) (pc)) (const_int 256)))
5745 (and (ge (minus (match_dup 2) (pc)) (const_int -2038))
5746 (le (minus (match_dup 2) (pc)) (const_int 2048)))
5751 (define_insn "*negated_cbranchsi4"
5754 (match_operator 0 "arm_comparison_operator"
5755 [(match_operand:SI 1 "s_register_operand" "l")
5756 (neg:SI (match_operand:SI 2 "s_register_operand" "l"))])
5757 (label_ref (match_operand 3 "" ""))
5761 output_asm_insn (\"cmn\\t%1, %2\", operands);
5762 switch (get_attr_length (insn))
5764 case 4: return \"b%d0\\t%l3\";
5765 case 6: return \"b%D0\\t.LCB%=\;b\\t%l3\\t%@long jump\\n.LCB%=:\";
5766 default: return \"b%D0\\t.LCB%=\;bl\\t%l3\\t%@far jump\\n.LCB%=:\";
5769 [(set (attr "far_jump")
5771 (eq_attr "length" "8")
5772 (const_string "yes")
5773 (const_string "no")))
5774 (set (attr "length")
5776 (and (ge (minus (match_dup 3) (pc)) (const_int -250))
5777 (le (minus (match_dup 3) (pc)) (const_int 256)))
5780 (and (ge (minus (match_dup 3) (pc)) (const_int -2040))
5781 (le (minus (match_dup 3) (pc)) (const_int 2048)))
5786 (define_insn "*tbit_cbranch"
5789 (match_operator 0 "equality_operator"
5790 [(zero_extract:SI (match_operand:SI 1 "s_register_operand" "l")
5792 (match_operand:SI 2 "const_int_operand" "i"))
5794 (label_ref (match_operand 3 "" ""))
5796 (clobber (match_scratch:SI 4 "=l"))]
5801 op[0] = operands[4];
5802 op[1] = operands[1];
5803 op[2] = GEN_INT (32 - 1 - INTVAL (operands[2]));
5805 output_asm_insn (\"lsl\\t%0, %1, %2\", op);
5806 switch (get_attr_length (insn))
5808 case 4: return \"b%d0\\t%l3\";
5809 case 6: return \"b%D0\\t.LCB%=\;b\\t%l3\\t%@long jump\\n.LCB%=:\";
5810 default: return \"b%D0\\t.LCB%=\;bl\\t%l3\\t%@far jump\\n.LCB%=:\";
5813 [(set (attr "far_jump")
5815 (eq_attr "length" "8")
5816 (const_string "yes")
5817 (const_string "no")))
5818 (set (attr "length")
5820 (and (ge (minus (match_dup 3) (pc)) (const_int -250))
5821 (le (minus (match_dup 3) (pc)) (const_int 256)))
5824 (and (ge (minus (match_dup 3) (pc)) (const_int -2040))
5825 (le (minus (match_dup 3) (pc)) (const_int 2048)))
5830 (define_insn "*tstsi3_cbranch"
5833 (match_operator 3 "equality_operator"
5834 [(and:SI (match_operand:SI 0 "s_register_operand" "%l")
5835 (match_operand:SI 1 "s_register_operand" "l"))
5837 (label_ref (match_operand 2 "" ""))
5842 output_asm_insn (\"tst\\t%0, %1\", operands);
5843 switch (get_attr_length (insn))
5845 case 4: return \"b%d3\\t%l2\";
5846 case 6: return \"b%D3\\t.LCB%=\;b\\t%l2\\t%@long jump\\n.LCB%=:\";
5847 default: return \"b%D3\\t.LCB%=\;bl\\t%l2\\t%@far jump\\n.LCB%=:\";
5850 [(set (attr "far_jump")
5852 (eq_attr "length" "8")
5853 (const_string "yes")
5854 (const_string "no")))
5855 (set (attr "length")
5857 (and (ge (minus (match_dup 2) (pc)) (const_int -250))
5858 (le (minus (match_dup 2) (pc)) (const_int 256)))
5861 (and (ge (minus (match_dup 2) (pc)) (const_int -2040))
5862 (le (minus (match_dup 2) (pc)) (const_int 2048)))
5867 (define_insn "*andsi3_cbranch"
5870 (match_operator 5 "equality_operator"
5871 [(and:SI (match_operand:SI 2 "s_register_operand" "%0,1,1,1")
5872 (match_operand:SI 3 "s_register_operand" "l,l,l,l"))
5874 (label_ref (match_operand 4 "" ""))
5876 (set (match_operand:SI 0 "thumb_cbrch_target_operand" "=l,*?h,*?m,*?m")
5877 (and:SI (match_dup 2) (match_dup 3)))
5878 (clobber (match_scratch:SI 1 "=X,l,&l,&l"))]
5882 if (which_alternative == 0)
5883 output_asm_insn (\"and\\t%0, %3\", operands);
5884 else if (which_alternative == 1)
5886 output_asm_insn (\"and\\t%1, %3\", operands);
5887 output_asm_insn (\"mov\\t%0, %1\", operands);
5891 output_asm_insn (\"and\\t%1, %3\", operands);
5892 output_asm_insn (\"str\\t%1, %0\", operands);
5895 switch (get_attr_length (insn) - (which_alternative ? 2 : 0))
5897 case 4: return \"b%d5\\t%l4\";
5898 case 6: return \"b%D5\\t.LCB%=\;b\\t%l4\\t%@long jump\\n.LCB%=:\";
5899 default: return \"b%D5\\t.LCB%=\;bl\\t%l4\\t%@far jump\\n.LCB%=:\";
5902 [(set (attr "far_jump")
5904 (ior (and (eq (symbol_ref ("which_alternative"))
5906 (eq_attr "length" "8"))
5907 (eq_attr "length" "10"))
5908 (const_string "yes")
5909 (const_string "no")))
5910 (set (attr "length")
5912 (eq (symbol_ref ("which_alternative"))
5915 (and (ge (minus (match_dup 4) (pc)) (const_int -250))
5916 (le (minus (match_dup 4) (pc)) (const_int 256)))
5919 (and (ge (minus (match_dup 4) (pc)) (const_int -2040))
5920 (le (minus (match_dup 4) (pc)) (const_int 2048)))
5924 (and (ge (minus (match_dup 4) (pc)) (const_int -248))
5925 (le (minus (match_dup 4) (pc)) (const_int 256)))
5928 (and (ge (minus (match_dup 4) (pc)) (const_int -2038))
5929 (le (minus (match_dup 4) (pc)) (const_int 2048)))
5934 (define_insn "*orrsi3_cbranch_scratch"
5937 (match_operator 4 "equality_operator"
5938 [(ior:SI (match_operand:SI 1 "s_register_operand" "%0")
5939 (match_operand:SI 2 "s_register_operand" "l"))
5941 (label_ref (match_operand 3 "" ""))
5943 (clobber (match_scratch:SI 0 "=l"))]
5947 output_asm_insn (\"orr\\t%0, %2\", operands);
5948 switch (get_attr_length (insn))
5950 case 4: return \"b%d4\\t%l3\";
5951 case 6: return \"b%D4\\t.LCB%=\;b\\t%l3\\t%@long jump\\n.LCB%=:\";
5952 default: return \"b%D4\\t.LCB%=\;bl\\t%l3\\t%@far jump\\n.LCB%=:\";
5955 [(set (attr "far_jump")
5957 (eq_attr "length" "8")
5958 (const_string "yes")
5959 (const_string "no")))
5960 (set (attr "length")
5962 (and (ge (minus (match_dup 3) (pc)) (const_int -250))
5963 (le (minus (match_dup 3) (pc)) (const_int 256)))
5966 (and (ge (minus (match_dup 3) (pc)) (const_int -2040))
5967 (le (minus (match_dup 3) (pc)) (const_int 2048)))
5972 (define_insn "*orrsi3_cbranch"
5975 (match_operator 5 "equality_operator"
5976 [(ior:SI (match_operand:SI 2 "s_register_operand" "%0,1,1,1")
5977 (match_operand:SI 3 "s_register_operand" "l,l,l,l"))
5979 (label_ref (match_operand 4 "" ""))
5981 (set (match_operand:SI 0 "thumb_cbrch_target_operand" "=l,*?h,*?m,*?m")
5982 (ior:SI (match_dup 2) (match_dup 3)))
5983 (clobber (match_scratch:SI 1 "=X,l,&l,&l"))]
5987 if (which_alternative == 0)
5988 output_asm_insn (\"orr\\t%0, %3\", operands);
5989 else if (which_alternative == 1)
5991 output_asm_insn (\"orr\\t%1, %3\", operands);
5992 output_asm_insn (\"mov\\t%0, %1\", operands);
5996 output_asm_insn (\"orr\\t%1, %3\", operands);
5997 output_asm_insn (\"str\\t%1, %0\", operands);
6000 switch (get_attr_length (insn) - (which_alternative ? 2 : 0))
6002 case 4: return \"b%d5\\t%l4\";
6003 case 6: return \"b%D5\\t.LCB%=\;b\\t%l4\\t%@long jump\\n.LCB%=:\";
6004 default: return \"b%D5\\t.LCB%=\;bl\\t%l4\\t%@far jump\\n.LCB%=:\";
6007 [(set (attr "far_jump")
6009 (ior (and (eq (symbol_ref ("which_alternative"))
6011 (eq_attr "length" "8"))
6012 (eq_attr "length" "10"))
6013 (const_string "yes")
6014 (const_string "no")))
6015 (set (attr "length")
6017 (eq (symbol_ref ("which_alternative"))
6020 (and (ge (minus (match_dup 4) (pc)) (const_int -250))
6021 (le (minus (match_dup 4) (pc)) (const_int 256)))
6024 (and (ge (minus (match_dup 4) (pc)) (const_int -2040))
6025 (le (minus (match_dup 4) (pc)) (const_int 2048)))
6029 (and (ge (minus (match_dup 4) (pc)) (const_int -248))
6030 (le (minus (match_dup 4) (pc)) (const_int 256)))
6033 (and (ge (minus (match_dup 4) (pc)) (const_int -2038))
6034 (le (minus (match_dup 4) (pc)) (const_int 2048)))
6039 (define_insn "*xorsi3_cbranch_scratch"
6042 (match_operator 4 "equality_operator"
6043 [(xor:SI (match_operand:SI 1 "s_register_operand" "%0")
6044 (match_operand:SI 2 "s_register_operand" "l"))
6046 (label_ref (match_operand 3 "" ""))
6048 (clobber (match_scratch:SI 0 "=l"))]
6052 output_asm_insn (\"eor\\t%0, %2\", operands);
6053 switch (get_attr_length (insn))
6055 case 4: return \"b%d4\\t%l3\";
6056 case 6: return \"b%D4\\t.LCB%=\;b\\t%l3\\t%@long jump\\n.LCB%=:\";
6057 default: return \"b%D4\\t.LCB%=\;bl\\t%l3\\t%@far jump\\n.LCB%=:\";
6060 [(set (attr "far_jump")
6062 (eq_attr "length" "8")
6063 (const_string "yes")
6064 (const_string "no")))
6065 (set (attr "length")
6067 (and (ge (minus (match_dup 3) (pc)) (const_int -250))
6068 (le (minus (match_dup 3) (pc)) (const_int 256)))
6071 (and (ge (minus (match_dup 3) (pc)) (const_int -2040))
6072 (le (minus (match_dup 3) (pc)) (const_int 2048)))
6077 (define_insn "*xorsi3_cbranch"
6080 (match_operator 5 "equality_operator"
6081 [(xor:SI (match_operand:SI 2 "s_register_operand" "%0,1,1,1")
6082 (match_operand:SI 3 "s_register_operand" "l,l,l,l"))
6084 (label_ref (match_operand 4 "" ""))
6086 (set (match_operand:SI 0 "thumb_cbrch_target_operand" "=l,*?h,*?m,*?m")
6087 (xor:SI (match_dup 2) (match_dup 3)))
6088 (clobber (match_scratch:SI 1 "=X,l,&l,&l"))]
6092 if (which_alternative == 0)
6093 output_asm_insn (\"eor\\t%0, %3\", operands);
6094 else if (which_alternative == 1)
6096 output_asm_insn (\"eor\\t%1, %3\", operands);
6097 output_asm_insn (\"mov\\t%0, %1\", operands);
6101 output_asm_insn (\"eor\\t%1, %3\", operands);
6102 output_asm_insn (\"str\\t%1, %0\", operands);
6105 switch (get_attr_length (insn) - (which_alternative ? 2 : 0))
6107 case 4: return \"b%d5\\t%l4\";
6108 case 6: return \"b%D5\\t.LCB%=\;b\\t%l4\\t%@long jump\\n.LCB%=:\";
6109 default: return \"b%D5\\t.LCB%=\;bl\\t%l4\\t%@far jump\\n.LCB%=:\";
6112 [(set (attr "far_jump")
6114 (ior (and (eq (symbol_ref ("which_alternative"))
6116 (eq_attr "length" "8"))
6117 (eq_attr "length" "10"))
6118 (const_string "yes")
6119 (const_string "no")))
6120 (set (attr "length")
6122 (eq (symbol_ref ("which_alternative"))
6125 (and (ge (minus (match_dup 4) (pc)) (const_int -250))
6126 (le (minus (match_dup 4) (pc)) (const_int 256)))
6129 (and (ge (minus (match_dup 4) (pc)) (const_int -2040))
6130 (le (minus (match_dup 4) (pc)) (const_int 2048)))
6134 (and (ge (minus (match_dup 4) (pc)) (const_int -248))
6135 (le (minus (match_dup 4) (pc)) (const_int 256)))
6138 (and (ge (minus (match_dup 4) (pc)) (const_int -2038))
6139 (le (minus (match_dup 4) (pc)) (const_int 2048)))
6144 (define_insn "*bicsi3_cbranch_scratch"
6147 (match_operator 4 "equality_operator"
6148 [(and:SI (not:SI (match_operand:SI 2 "s_register_operand" "l"))
6149 (match_operand:SI 1 "s_register_operand" "0"))
6151 (label_ref (match_operand 3 "" ""))
6153 (clobber (match_scratch:SI 0 "=l"))]
6157 output_asm_insn (\"bic\\t%0, %2\", operands);
6158 switch (get_attr_length (insn))
6160 case 4: return \"b%d4\\t%l3\";
6161 case 6: return \"b%D4\\t.LCB%=\;b\\t%l3\\t%@long jump\\n.LCB%=:\";
6162 default: return \"b%D4\\t.LCB%=\;bl\\t%l3\\t%@far jump\\n.LCB%=:\";
6165 [(set (attr "far_jump")
6167 (eq_attr "length" "8")
6168 (const_string "yes")
6169 (const_string "no")))
6170 (set (attr "length")
6172 (and (ge (minus (match_dup 3) (pc)) (const_int -250))
6173 (le (minus (match_dup 3) (pc)) (const_int 256)))
6176 (and (ge (minus (match_dup 3) (pc)) (const_int -2040))
6177 (le (minus (match_dup 3) (pc)) (const_int 2048)))
6182 (define_insn "*bicsi3_cbranch"
6185 (match_operator 5 "equality_operator"
6186 [(and:SI (not:SI (match_operand:SI 3 "s_register_operand" "l,l,l,l"))
6187 (match_operand:SI 2 "s_register_operand" "0,1,1,1"))
6189 (label_ref (match_operand 4 "" ""))
6191 (set (match_operand:SI 0 "thumb_cbrch_target_operand" "=l,*?h,*?m,*?m")
6192 (and:SI (not:SI (match_dup 3)) (match_dup 2)))
6193 (clobber (match_scratch:SI 1 "=X,l,&l,&l"))]
6197 if (which_alternative == 0)
6198 output_asm_insn (\"bic\\t%0, %3\", operands);
6199 else if (which_alternative == 1)
6201 output_asm_insn (\"bic\\t%1, %3\", operands);
6202 output_asm_insn (\"mov\\t%0, %1\", operands);
6206 output_asm_insn (\"bic\\t%1, %3\", operands);
6207 output_asm_insn (\"str\\t%1, %0\", operands);
6210 switch (get_attr_length (insn) - (which_alternative ? 2 : 0))
6212 case 4: return \"b%d5\\t%l4\";
6213 case 6: return \"b%D5\\t.LCB%=\;b\\t%l4\\t%@long jump\\n.LCB%=:\";
6214 default: return \"b%D5\\t.LCB%=\;bl\\t%l4\\t%@far jump\\n.LCB%=:\";
6217 [(set (attr "far_jump")
6219 (ior (and (eq (symbol_ref ("which_alternative"))
6221 (eq_attr "length" "8"))
6222 (eq_attr "length" "10"))
6223 (const_string "yes")
6224 (const_string "no")))
6225 (set (attr "length")
6227 (eq (symbol_ref ("which_alternative"))
6230 (and (ge (minus (match_dup 4) (pc)) (const_int -250))
6231 (le (minus (match_dup 4) (pc)) (const_int 256)))
6234 (and (ge (minus (match_dup 4) (pc)) (const_int -2040))
6235 (le (minus (match_dup 4) (pc)) (const_int 2048)))
6239 (and (ge (minus (match_dup 4) (pc)) (const_int -248))
6240 (le (minus (match_dup 4) (pc)) (const_int 256)))
6243 (and (ge (minus (match_dup 4) (pc)) (const_int -2038))
6244 (le (minus (match_dup 4) (pc)) (const_int 2048)))
6249 (define_insn "*cbranchne_decr1"
6251 (if_then_else (match_operator 3 "equality_operator"
6252 [(match_operand:SI 2 "s_register_operand" "l,l,1,l")
6254 (label_ref (match_operand 4 "" ""))
6256 (set (match_operand:SI 0 "thumb_cbrch_target_operand" "=l,*?h,*?m,*?m")
6257 (plus:SI (match_dup 2) (const_int -1)))
6258 (clobber (match_scratch:SI 1 "=X,l,&l,&l"))]
6263 cond[0] = gen_rtx_fmt_ee ((GET_CODE (operands[3]) == NE
6265 VOIDmode, operands[2], const1_rtx);
6266 cond[1] = operands[4];
6268 if (which_alternative == 0)
6269 output_asm_insn (\"sub\\t%0, %2, #1\", operands);
6270 else if (which_alternative == 1)
6272 /* We must provide an alternative for a hi reg because reload
6273 cannot handle output reloads on a jump instruction, but we
6274 can't subtract into that. Fortunately a mov from lo to hi
6275 does not clobber the condition codes. */
6276 output_asm_insn (\"sub\\t%1, %2, #1\", operands);
6277 output_asm_insn (\"mov\\t%0, %1\", operands);
6281 /* Similarly, but the target is memory. */
6282 output_asm_insn (\"sub\\t%1, %2, #1\", operands);
6283 output_asm_insn (\"str\\t%1, %0\", operands);
6286 switch (get_attr_length (insn) - (which_alternative ? 2 : 0))
6289 output_asm_insn (\"b%d0\\t%l1\", cond);
6292 output_asm_insn (\"b%D0\\t.LCB%=\", cond);
6293 return \"b\\t%l4\\t%@long jump\\n.LCB%=:\";
6295 output_asm_insn (\"b%D0\\t.LCB%=\", cond);
6296 return \"bl\\t%l4\\t%@far jump\\n.LCB%=:\";
6300 [(set (attr "far_jump")
6302 (ior (and (eq (symbol_ref ("which_alternative"))
6304 (eq_attr "length" "8"))
6305 (eq_attr "length" "10"))
6306 (const_string "yes")
6307 (const_string "no")))
6308 (set_attr_alternative "length"
6312 (and (ge (minus (match_dup 4) (pc)) (const_int -250))
6313 (le (minus (match_dup 4) (pc)) (const_int 256)))
6316 (and (ge (minus (match_dup 4) (pc)) (const_int -2040))
6317 (le (minus (match_dup 4) (pc)) (const_int 2048)))
6322 (and (ge (minus (match_dup 4) (pc)) (const_int -248))
6323 (le (minus (match_dup 4) (pc)) (const_int 256)))
6326 (and (ge (minus (match_dup 4) (pc)) (const_int -2038))
6327 (le (minus (match_dup 4) (pc)) (const_int 2048)))
6332 (and (ge (minus (match_dup 4) (pc)) (const_int -248))
6333 (le (minus (match_dup 4) (pc)) (const_int 256)))
6336 (and (ge (minus (match_dup 4) (pc)) (const_int -2038))
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 (define_insn "*addsi3_cbranch"
6355 (match_operator 4 "comparison_operator"
6357 (match_operand:SI 2 "s_register_operand" "%l,0,*0,1,1,1")
6358 (match_operand:SI 3 "reg_or_int_operand" "lL,IJ,*r,lIJ,lIJ,lIJ"))
6360 (label_ref (match_operand 5 "" ""))
6363 (match_operand:SI 0 "thumb_cbrch_target_operand" "=l,l,*!h,*?h,*?m,*?m")
6364 (plus:SI (match_dup 2) (match_dup 3)))
6365 (clobber (match_scratch:SI 1 "=X,X,X,l,&l,&l"))]
6367 && (GET_CODE (operands[4]) == EQ
6368 || GET_CODE (operands[4]) == NE
6369 || GET_CODE (operands[4]) == GE
6370 || GET_CODE (operands[4]) == LT)"
6376 cond[0] = (which_alternative < 3) ? operands[0] : operands[1];
6377 cond[1] = operands[2];
6378 cond[2] = operands[3];
6380 if (GET_CODE (cond[2]) == CONST_INT && INTVAL (cond[2]) < 0)
6381 output_asm_insn (\"sub\\t%0, %1, #%n2\", cond);
6383 output_asm_insn (\"add\\t%0, %1, %2\", cond);
6385 if (which_alternative >= 3
6386 && which_alternative < 4)
6387 output_asm_insn (\"mov\\t%0, %1\", operands);
6388 else if (which_alternative >= 4)
6389 output_asm_insn (\"str\\t%1, %0\", operands);
6391 switch (get_attr_length (insn) - ((which_alternative >= 3) ? 2 : 0))
6394 return \"b%d4\\t%l5\";
6396 return \"b%D4\\t.LCB%=\;b\\t%l5\\t%@long jump\\n.LCB%=:\";
6398 return \"b%D4\\t.LCB%=\;bl\\t%l5\\t%@far jump\\n.LCB%=:\";
6402 [(set (attr "far_jump")
6404 (ior (and (lt (symbol_ref ("which_alternative"))
6406 (eq_attr "length" "8"))
6407 (eq_attr "length" "10"))
6408 (const_string "yes")
6409 (const_string "no")))
6410 (set (attr "length")
6412 (lt (symbol_ref ("which_alternative"))
6415 (and (ge (minus (match_dup 5) (pc)) (const_int -250))
6416 (le (minus (match_dup 5) (pc)) (const_int 256)))
6419 (and (ge (minus (match_dup 5) (pc)) (const_int -2040))
6420 (le (minus (match_dup 5) (pc)) (const_int 2048)))
6424 (and (ge (minus (match_dup 5) (pc)) (const_int -248))
6425 (le (minus (match_dup 5) (pc)) (const_int 256)))
6428 (and (ge (minus (match_dup 5) (pc)) (const_int -2038))
6429 (le (minus (match_dup 5) (pc)) (const_int 2048)))
6434 (define_insn "*addsi3_cbranch_scratch"
6437 (match_operator 3 "comparison_operator"
6439 (match_operand:SI 1 "s_register_operand" "%l,l,l,0")
6440 (match_operand:SI 2 "reg_or_int_operand" "J,l,I,L"))
6442 (label_ref (match_operand 4 "" ""))
6444 (clobber (match_scratch:SI 0 "=X,X,l,l"))]
6446 && (GET_CODE (operands[3]) == EQ
6447 || GET_CODE (operands[3]) == NE
6448 || GET_CODE (operands[3]) == GE
6449 || GET_CODE (operands[3]) == LT)"
6452 switch (which_alternative)
6455 output_asm_insn (\"cmp\t%1, #%n2\", operands);
6458 output_asm_insn (\"cmn\t%1, %2\", operands);
6461 output_asm_insn (\"add\t%0, %1, %2\", operands);
6464 output_asm_insn (\"add\t%0, %0, %2\", operands);
6468 switch (get_attr_length (insn))
6471 return \"b%d3\\t%l4\";
6473 return \"b%D3\\t.LCB%=\;b\\t%l4\\t%@long jump\\n.LCB%=:\";
6475 return \"b%D3\\t.LCB%=\;bl\\t%l4\\t%@far jump\\n.LCB%=:\";
6479 [(set (attr "far_jump")
6481 (eq_attr "length" "8")
6482 (const_string "yes")
6483 (const_string "no")))
6484 (set (attr "length")
6486 (and (ge (minus (match_dup 4) (pc)) (const_int -250))
6487 (le (minus (match_dup 4) (pc)) (const_int 256)))
6490 (and (ge (minus (match_dup 4) (pc)) (const_int -2040))
6491 (le (minus (match_dup 4) (pc)) (const_int 2048)))
6496 (define_insn "*subsi3_cbranch"
6499 (match_operator 4 "comparison_operator"
6501 (match_operand:SI 2 "s_register_operand" "l,l,1,l")
6502 (match_operand:SI 3 "s_register_operand" "l,l,l,l"))
6504 (label_ref (match_operand 5 "" ""))
6506 (set (match_operand:SI 0 "thumb_cbrch_target_operand" "=l,*?h,*?m,*?m")
6507 (minus:SI (match_dup 2) (match_dup 3)))
6508 (clobber (match_scratch:SI 1 "=X,l,&l,&l"))]
6510 && (GET_CODE (operands[4]) == EQ
6511 || GET_CODE (operands[4]) == NE
6512 || GET_CODE (operands[4]) == GE
6513 || GET_CODE (operands[4]) == LT)"
6516 if (which_alternative == 0)
6517 output_asm_insn (\"sub\\t%0, %2, %3\", operands);
6518 else if (which_alternative == 1)
6520 /* We must provide an alternative for a hi reg because reload
6521 cannot handle output reloads on a jump instruction, but we
6522 can't subtract into that. Fortunately a mov from lo to hi
6523 does not clobber the condition codes. */
6524 output_asm_insn (\"sub\\t%1, %2, %3\", operands);
6525 output_asm_insn (\"mov\\t%0, %1\", operands);
6529 /* Similarly, but the target is memory. */
6530 output_asm_insn (\"sub\\t%1, %2, %3\", operands);
6531 output_asm_insn (\"str\\t%1, %0\", operands);
6534 switch (get_attr_length (insn) - ((which_alternative != 0) ? 2 : 0))
6537 return \"b%d4\\t%l5\";
6539 return \"b%D4\\t.LCB%=\;b\\t%l5\\t%@long jump\\n.LCB%=:\";
6541 return \"b%D4\\t.LCB%=\;bl\\t%l5\\t%@far jump\\n.LCB%=:\";
6545 [(set (attr "far_jump")
6547 (ior (and (eq (symbol_ref ("which_alternative"))
6549 (eq_attr "length" "8"))
6550 (eq_attr "length" "10"))
6551 (const_string "yes")
6552 (const_string "no")))
6553 (set (attr "length")
6555 (eq (symbol_ref ("which_alternative"))
6558 (and (ge (minus (match_dup 5) (pc)) (const_int -250))
6559 (le (minus (match_dup 5) (pc)) (const_int 256)))
6562 (and (ge (minus (match_dup 5) (pc)) (const_int -2040))
6563 (le (minus (match_dup 5) (pc)) (const_int 2048)))
6567 (and (ge (minus (match_dup 5) (pc)) (const_int -248))
6568 (le (minus (match_dup 5) (pc)) (const_int 256)))
6571 (and (ge (minus (match_dup 5) (pc)) (const_int -2038))
6572 (le (minus (match_dup 5) (pc)) (const_int 2048)))
6577 (define_insn "*subsi3_cbranch_scratch"
6580 (match_operator 0 "arm_comparison_operator"
6581 [(minus:SI (match_operand:SI 1 "register_operand" "l")
6582 (match_operand:SI 2 "nonmemory_operand" "l"))
6584 (label_ref (match_operand 3 "" ""))
6587 && (GET_CODE (operands[0]) == EQ
6588 || GET_CODE (operands[0]) == NE
6589 || GET_CODE (operands[0]) == GE
6590 || GET_CODE (operands[0]) == LT)"
6592 output_asm_insn (\"cmp\\t%1, %2\", operands);
6593 switch (get_attr_length (insn))
6595 case 4: return \"b%d0\\t%l3\";
6596 case 6: return \"b%D0\\t.LCB%=\;b\\t%l3\\t%@long jump\\n.LCB%=:\";
6597 default: return \"b%D0\\t.LCB%=\;bl\\t%l3\\t%@far jump\\n.LCB%=:\";
6600 [(set (attr "far_jump")
6602 (eq_attr "length" "8")
6603 (const_string "yes")
6604 (const_string "no")))
6605 (set (attr "length")
6607 (and (ge (minus (match_dup 3) (pc)) (const_int -250))
6608 (le (minus (match_dup 3) (pc)) (const_int 256)))
6611 (and (ge (minus (match_dup 3) (pc)) (const_int -2040))
6612 (le (minus (match_dup 3) (pc)) (const_int 2048)))
6617 ;; Comparison and test insns
6619 (define_expand "cmpsi"
6620 [(match_operand:SI 0 "s_register_operand" "")
6621 (match_operand:SI 1 "arm_add_operand" "")]
6624 arm_compare_op0 = operands[0];
6625 arm_compare_op1 = operands[1];
6630 (define_expand "cmpsf"
6631 [(match_operand:SF 0 "s_register_operand" "")
6632 (match_operand:SF 1 "arm_float_compare_operand" "")]
6633 "TARGET_ARM && TARGET_HARD_FLOAT"
6635 arm_compare_op0 = operands[0];
6636 arm_compare_op1 = operands[1];
6641 (define_expand "cmpdf"
6642 [(match_operand:DF 0 "s_register_operand" "")
6643 (match_operand:DF 1 "arm_float_compare_operand" "")]
6644 "TARGET_ARM && TARGET_HARD_FLOAT"
6646 arm_compare_op0 = operands[0];
6647 arm_compare_op1 = operands[1];
6652 (define_insn "*arm_cmpsi_insn"
6653 [(set (reg:CC CC_REGNUM)
6654 (compare:CC (match_operand:SI 0 "s_register_operand" "r,r")
6655 (match_operand:SI 1 "arm_add_operand" "rI,L")))]
6660 [(set_attr "conds" "set")]
6663 (define_insn "*cmpsi_shiftsi"
6664 [(set (reg:CC CC_REGNUM)
6665 (compare:CC (match_operand:SI 0 "s_register_operand" "r")
6666 (match_operator:SI 3 "shift_operator"
6667 [(match_operand:SI 1 "s_register_operand" "r")
6668 (match_operand:SI 2 "arm_rhs_operand" "rM")])))]
6671 [(set_attr "conds" "set")
6672 (set_attr "shift" "1")
6673 (set (attr "type") (if_then_else (match_operand 2 "const_int_operand" "")
6674 (const_string "alu_shift")
6675 (const_string "alu_shift_reg")))]
6678 (define_insn "*cmpsi_shiftsi_swp"
6679 [(set (reg:CC_SWP CC_REGNUM)
6680 (compare:CC_SWP (match_operator:SI 3 "shift_operator"
6681 [(match_operand:SI 1 "s_register_operand" "r")
6682 (match_operand:SI 2 "reg_or_int_operand" "rM")])
6683 (match_operand:SI 0 "s_register_operand" "r")))]
6686 [(set_attr "conds" "set")
6687 (set_attr "shift" "1")
6688 (set (attr "type") (if_then_else (match_operand 2 "const_int_operand" "")
6689 (const_string "alu_shift")
6690 (const_string "alu_shift_reg")))]
6693 (define_insn "*cmpsi_neg_shiftsi"
6694 [(set (reg:CC CC_REGNUM)
6695 (compare:CC (match_operand:SI 0 "s_register_operand" "r")
6696 (neg:SI (match_operator:SI 3 "shift_operator"
6697 [(match_operand:SI 1 "s_register_operand" "r")
6698 (match_operand:SI 2 "arm_rhs_operand" "rM")]))))]
6701 [(set_attr "conds" "set")
6702 (set_attr "shift" "1")
6703 (set (attr "type") (if_then_else (match_operand 2 "const_int_operand" "")
6704 (const_string "alu_shift")
6705 (const_string "alu_shift_reg")))]
6708 ;; Cirrus SF compare instruction
6709 (define_insn "*cirrus_cmpsf"
6710 [(set (reg:CCFP CC_REGNUM)
6711 (compare:CCFP (match_operand:SF 0 "cirrus_fp_register" "v")
6712 (match_operand:SF 1 "cirrus_fp_register" "v")))]
6713 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_MAVERICK"
6714 "cfcmps%?\\tr15, %V0, %V1"
6715 [(set_attr "type" "mav_farith")
6716 (set_attr "cirrus" "compare")]
6719 ;; Cirrus DF compare instruction
6720 (define_insn "*cirrus_cmpdf"
6721 [(set (reg:CCFP CC_REGNUM)
6722 (compare:CCFP (match_operand:DF 0 "cirrus_fp_register" "v")
6723 (match_operand:DF 1 "cirrus_fp_register" "v")))]
6724 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_MAVERICK"
6725 "cfcmpd%?\\tr15, %V0, %V1"
6726 [(set_attr "type" "mav_farith")
6727 (set_attr "cirrus" "compare")]
6730 ;; Cirrus DI compare instruction
6731 (define_expand "cmpdi"
6732 [(match_operand:DI 0 "cirrus_fp_register" "")
6733 (match_operand:DI 1 "cirrus_fp_register" "")]
6734 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_MAVERICK"
6736 arm_compare_op0 = operands[0];
6737 arm_compare_op1 = operands[1];
6741 (define_insn "*cirrus_cmpdi"
6742 [(set (reg:CC CC_REGNUM)
6743 (compare:CC (match_operand:DI 0 "cirrus_fp_register" "v")
6744 (match_operand:DI 1 "cirrus_fp_register" "v")))]
6745 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_MAVERICK"
6746 "cfcmp64%?\\tr15, %V0, %V1"
6747 [(set_attr "type" "mav_farith")
6748 (set_attr "cirrus" "compare")]
6751 ; This insn allows redundant compares to be removed by cse, nothing should
6752 ; ever appear in the output file since (set (reg x) (reg x)) is a no-op that
6753 ; is deleted later on. The match_dup will match the mode here, so that
6754 ; mode changes of the condition codes aren't lost by this even though we don't
6755 ; specify what they are.
6757 (define_insn "*deleted_compare"
6758 [(set (match_operand 0 "cc_register" "") (match_dup 0))]
6760 "\\t%@ deleted compare"
6761 [(set_attr "conds" "set")
6762 (set_attr "length" "0")]
6766 ;; Conditional branch insns
6768 (define_expand "beq"
6770 (if_then_else (eq (match_dup 1) (const_int 0))
6771 (label_ref (match_operand 0 "" ""))
6774 "operands[1] = arm_gen_compare_reg (EQ, arm_compare_op0, arm_compare_op1);"
6777 (define_expand "bne"
6779 (if_then_else (ne (match_dup 1) (const_int 0))
6780 (label_ref (match_operand 0 "" ""))
6783 "operands[1] = arm_gen_compare_reg (NE, arm_compare_op0, arm_compare_op1);"
6786 (define_expand "bgt"
6788 (if_then_else (gt (match_dup 1) (const_int 0))
6789 (label_ref (match_operand 0 "" ""))
6792 "operands[1] = arm_gen_compare_reg (GT, arm_compare_op0, arm_compare_op1);"
6795 (define_expand "ble"
6797 (if_then_else (le (match_dup 1) (const_int 0))
6798 (label_ref (match_operand 0 "" ""))
6801 "operands[1] = arm_gen_compare_reg (LE, arm_compare_op0, arm_compare_op1);"
6804 (define_expand "bge"
6806 (if_then_else (ge (match_dup 1) (const_int 0))
6807 (label_ref (match_operand 0 "" ""))
6810 "operands[1] = arm_gen_compare_reg (GE, arm_compare_op0, arm_compare_op1);"
6813 (define_expand "blt"
6815 (if_then_else (lt (match_dup 1) (const_int 0))
6816 (label_ref (match_operand 0 "" ""))
6819 "operands[1] = arm_gen_compare_reg (LT, arm_compare_op0, arm_compare_op1);"
6822 (define_expand "bgtu"
6824 (if_then_else (gtu (match_dup 1) (const_int 0))
6825 (label_ref (match_operand 0 "" ""))
6828 "operands[1] = arm_gen_compare_reg (GTU, arm_compare_op0, arm_compare_op1);"
6831 (define_expand "bleu"
6833 (if_then_else (leu (match_dup 1) (const_int 0))
6834 (label_ref (match_operand 0 "" ""))
6837 "operands[1] = arm_gen_compare_reg (LEU, arm_compare_op0, arm_compare_op1);"
6840 (define_expand "bgeu"
6842 (if_then_else (geu (match_dup 1) (const_int 0))
6843 (label_ref (match_operand 0 "" ""))
6846 "operands[1] = arm_gen_compare_reg (GEU, arm_compare_op0, arm_compare_op1);"
6849 (define_expand "bltu"
6851 (if_then_else (ltu (match_dup 1) (const_int 0))
6852 (label_ref (match_operand 0 "" ""))
6855 "operands[1] = arm_gen_compare_reg (LTU, arm_compare_op0, arm_compare_op1);"
6858 (define_expand "bunordered"
6860 (if_then_else (unordered (match_dup 1) (const_int 0))
6861 (label_ref (match_operand 0 "" ""))
6863 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
6864 "operands[1] = arm_gen_compare_reg (UNORDERED, arm_compare_op0,
6868 (define_expand "bordered"
6870 (if_then_else (ordered (match_dup 1) (const_int 0))
6871 (label_ref (match_operand 0 "" ""))
6873 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
6874 "operands[1] = arm_gen_compare_reg (ORDERED, arm_compare_op0,
6878 (define_expand "bungt"
6880 (if_then_else (ungt (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 (UNGT, arm_compare_op0, arm_compare_op1);"
6887 (define_expand "bunlt"
6889 (if_then_else (unlt (match_dup 1) (const_int 0))
6890 (label_ref (match_operand 0 "" ""))
6892 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
6893 "operands[1] = arm_gen_compare_reg (UNLT, arm_compare_op0, arm_compare_op1);"
6896 (define_expand "bunge"
6898 (if_then_else (unge (match_dup 1) (const_int 0))
6899 (label_ref (match_operand 0 "" ""))
6901 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
6902 "operands[1] = arm_gen_compare_reg (UNGE, arm_compare_op0, arm_compare_op1);"
6905 (define_expand "bunle"
6907 (if_then_else (unle (match_dup 1) (const_int 0))
6908 (label_ref (match_operand 0 "" ""))
6910 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
6911 "operands[1] = arm_gen_compare_reg (UNLE, arm_compare_op0, arm_compare_op1);"
6914 ;; The following two patterns need two branch instructions, since there is
6915 ;; no single instruction that will handle all cases.
6916 (define_expand "buneq"
6918 (if_then_else (uneq (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 (UNEQ, arm_compare_op0, arm_compare_op1);"
6925 (define_expand "bltgt"
6927 (if_then_else (ltgt (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 (LTGT, arm_compare_op0, arm_compare_op1);"
6935 ;; Patterns to match conditional branch insns.
6938 ; Special pattern to match UNEQ.
6939 (define_insn "*arm_buneq"
6941 (if_then_else (uneq (match_operand 1 "cc_register" "") (const_int 0))
6942 (label_ref (match_operand 0 "" ""))
6944 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
6946 if (arm_ccfsm_state != 0)
6949 return \"bvs\\t%l0\;beq\\t%l0\";
6951 [(set_attr "conds" "jump_clob")
6952 (set_attr "length" "8")]
6955 ; Special pattern to match LTGT.
6956 (define_insn "*arm_bltgt"
6958 (if_then_else (ltgt (match_operand 1 "cc_register" "") (const_int 0))
6959 (label_ref (match_operand 0 "" ""))
6961 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
6963 if (arm_ccfsm_state != 0)
6966 return \"bmi\\t%l0\;bgt\\t%l0\";
6968 [(set_attr "conds" "jump_clob")
6969 (set_attr "length" "8")]
6972 (define_insn "*arm_cond_branch"
6974 (if_then_else (match_operator 1 "arm_comparison_operator"
6975 [(match_operand 2 "cc_register" "") (const_int 0)])
6976 (label_ref (match_operand 0 "" ""))
6980 if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
6982 arm_ccfsm_state += 2;
6985 return \"b%d1\\t%l0\";
6987 [(set_attr "conds" "use")
6988 (set_attr "type" "branch")]
6991 ; Special pattern to match reversed UNEQ.
6992 (define_insn "*arm_buneq_reversed"
6994 (if_then_else (uneq (match_operand 1 "cc_register" "") (const_int 0))
6996 (label_ref (match_operand 0 "" ""))))]
6997 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
6999 if (arm_ccfsm_state != 0)
7002 return \"bmi\\t%l0\;bgt\\t%l0\";
7004 [(set_attr "conds" "jump_clob")
7005 (set_attr "length" "8")]
7008 ; Special pattern to match reversed LTGT.
7009 (define_insn "*arm_bltgt_reversed"
7011 (if_then_else (ltgt (match_operand 1 "cc_register" "") (const_int 0))
7013 (label_ref (match_operand 0 "" ""))))]
7014 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
7016 if (arm_ccfsm_state != 0)
7019 return \"bvs\\t%l0\;beq\\t%l0\";
7021 [(set_attr "conds" "jump_clob")
7022 (set_attr "length" "8")]
7025 (define_insn "*arm_cond_branch_reversed"
7027 (if_then_else (match_operator 1 "arm_comparison_operator"
7028 [(match_operand 2 "cc_register" "") (const_int 0)])
7030 (label_ref (match_operand 0 "" ""))))]
7033 if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
7035 arm_ccfsm_state += 2;
7038 return \"b%D1\\t%l0\";
7040 [(set_attr "conds" "use")
7041 (set_attr "type" "branch")]
7048 (define_expand "seq"
7049 [(set (match_operand:SI 0 "s_register_operand" "")
7050 (eq:SI (match_dup 1) (const_int 0)))]
7052 "operands[1] = arm_gen_compare_reg (EQ, arm_compare_op0, arm_compare_op1);"
7055 (define_expand "sne"
7056 [(set (match_operand:SI 0 "s_register_operand" "")
7057 (ne:SI (match_dup 1) (const_int 0)))]
7059 "operands[1] = arm_gen_compare_reg (NE, arm_compare_op0, arm_compare_op1);"
7062 (define_expand "sgt"
7063 [(set (match_operand:SI 0 "s_register_operand" "")
7064 (gt:SI (match_dup 1) (const_int 0)))]
7066 "operands[1] = arm_gen_compare_reg (GT, arm_compare_op0, arm_compare_op1);"
7069 (define_expand "sle"
7070 [(set (match_operand:SI 0 "s_register_operand" "")
7071 (le:SI (match_dup 1) (const_int 0)))]
7073 "operands[1] = arm_gen_compare_reg (LE, arm_compare_op0, arm_compare_op1);"
7076 (define_expand "sge"
7077 [(set (match_operand:SI 0 "s_register_operand" "")
7078 (ge:SI (match_dup 1) (const_int 0)))]
7080 "operands[1] = arm_gen_compare_reg (GE, arm_compare_op0, arm_compare_op1);"
7083 (define_expand "slt"
7084 [(set (match_operand:SI 0 "s_register_operand" "")
7085 (lt:SI (match_dup 1) (const_int 0)))]
7087 "operands[1] = arm_gen_compare_reg (LT, arm_compare_op0, arm_compare_op1);"
7090 (define_expand "sgtu"
7091 [(set (match_operand:SI 0 "s_register_operand" "")
7092 (gtu:SI (match_dup 1) (const_int 0)))]
7094 "operands[1] = arm_gen_compare_reg (GTU, arm_compare_op0, arm_compare_op1);"
7097 (define_expand "sleu"
7098 [(set (match_operand:SI 0 "s_register_operand" "")
7099 (leu:SI (match_dup 1) (const_int 0)))]
7101 "operands[1] = arm_gen_compare_reg (LEU, arm_compare_op0, arm_compare_op1);"
7104 (define_expand "sgeu"
7105 [(set (match_operand:SI 0 "s_register_operand" "")
7106 (geu:SI (match_dup 1) (const_int 0)))]
7108 "operands[1] = arm_gen_compare_reg (GEU, arm_compare_op0, arm_compare_op1);"
7111 (define_expand "sltu"
7112 [(set (match_operand:SI 0 "s_register_operand" "")
7113 (ltu:SI (match_dup 1) (const_int 0)))]
7115 "operands[1] = arm_gen_compare_reg (LTU, arm_compare_op0, arm_compare_op1);"
7118 (define_expand "sunordered"
7119 [(set (match_operand:SI 0 "s_register_operand" "")
7120 (unordered:SI (match_dup 1) (const_int 0)))]
7121 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
7122 "operands[1] = arm_gen_compare_reg (UNORDERED, arm_compare_op0,
7126 (define_expand "sordered"
7127 [(set (match_operand:SI 0 "s_register_operand" "")
7128 (ordered:SI (match_dup 1) (const_int 0)))]
7129 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
7130 "operands[1] = arm_gen_compare_reg (ORDERED, arm_compare_op0,
7134 (define_expand "sungt"
7135 [(set (match_operand:SI 0 "s_register_operand" "")
7136 (ungt:SI (match_dup 1) (const_int 0)))]
7137 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
7138 "operands[1] = arm_gen_compare_reg (UNGT, arm_compare_op0,
7142 (define_expand "sunge"
7143 [(set (match_operand:SI 0 "s_register_operand" "")
7144 (unge:SI (match_dup 1) (const_int 0)))]
7145 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
7146 "operands[1] = arm_gen_compare_reg (UNGE, arm_compare_op0,
7150 (define_expand "sunlt"
7151 [(set (match_operand:SI 0 "s_register_operand" "")
7152 (unlt:SI (match_dup 1) (const_int 0)))]
7153 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
7154 "operands[1] = arm_gen_compare_reg (UNLT, arm_compare_op0,
7158 (define_expand "sunle"
7159 [(set (match_operand:SI 0 "s_register_operand" "")
7160 (unle:SI (match_dup 1) (const_int 0)))]
7161 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
7162 "operands[1] = arm_gen_compare_reg (UNLE, arm_compare_op0,
7166 ;;; DO NOT add patterns for SUNEQ or SLTGT, these can't be represented with
7167 ;;; simple ARM instructions.
7169 ; (define_expand "suneq"
7170 ; [(set (match_operand:SI 0 "s_register_operand" "")
7171 ; (uneq:SI (match_dup 1) (const_int 0)))]
7172 ; "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
7176 ; (define_expand "sltgt"
7177 ; [(set (match_operand:SI 0 "s_register_operand" "")
7178 ; (ltgt:SI (match_dup 1) (const_int 0)))]
7179 ; "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
7183 (define_insn "*mov_scc"
7184 [(set (match_operand:SI 0 "s_register_operand" "=r")
7185 (match_operator:SI 1 "arm_comparison_operator"
7186 [(match_operand 2 "cc_register" "") (const_int 0)]))]
7188 "mov%D1\\t%0, #0\;mov%d1\\t%0, #1"
7189 [(set_attr "conds" "use")
7190 (set_attr "length" "8")]
7193 (define_insn "*mov_negscc"
7194 [(set (match_operand:SI 0 "s_register_operand" "=r")
7195 (neg:SI (match_operator:SI 1 "arm_comparison_operator"
7196 [(match_operand 2 "cc_register" "") (const_int 0)])))]
7198 "mov%D1\\t%0, #0\;mvn%d1\\t%0, #0"
7199 [(set_attr "conds" "use")
7200 (set_attr "length" "8")]
7203 (define_insn "*mov_notscc"
7204 [(set (match_operand:SI 0 "s_register_operand" "=r")
7205 (not:SI (match_operator:SI 1 "arm_comparison_operator"
7206 [(match_operand 2 "cc_register" "") (const_int 0)])))]
7208 "mov%D1\\t%0, #0\;mvn%d1\\t%0, #1"
7209 [(set_attr "conds" "use")
7210 (set_attr "length" "8")]
7214 ;; Conditional move insns
7216 (define_expand "movsicc"
7217 [(set (match_operand:SI 0 "s_register_operand" "")
7218 (if_then_else:SI (match_operand 1 "arm_comparison_operator" "")
7219 (match_operand:SI 2 "arm_not_operand" "")
7220 (match_operand:SI 3 "arm_not_operand" "")))]
7224 enum rtx_code code = GET_CODE (operands[1]);
7227 if (code == UNEQ || code == LTGT)
7230 ccreg = arm_gen_compare_reg (code, arm_compare_op0, arm_compare_op1);
7231 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
7235 (define_expand "movsfcc"
7236 [(set (match_operand:SF 0 "s_register_operand" "")
7237 (if_then_else:SF (match_operand 1 "arm_comparison_operator" "")
7238 (match_operand:SF 2 "s_register_operand" "")
7239 (match_operand:SF 3 "nonmemory_operand" "")))]
7243 enum rtx_code code = GET_CODE (operands[1]);
7246 if (code == UNEQ || code == LTGT)
7249 /* When compiling for SOFT_FLOAT, ensure both arms are in registers.
7250 Otherwise, ensure it is a valid FP add operand */
7251 if ((!(TARGET_HARD_FLOAT && TARGET_FPA))
7252 || (!arm_float_add_operand (operands[3], SFmode)))
7253 operands[3] = force_reg (SFmode, operands[3]);
7255 ccreg = arm_gen_compare_reg (code, arm_compare_op0, arm_compare_op1);
7256 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
7260 (define_expand "movdfcc"
7261 [(set (match_operand:DF 0 "s_register_operand" "")
7262 (if_then_else:DF (match_operand 1 "arm_comparison_operator" "")
7263 (match_operand:DF 2 "s_register_operand" "")
7264 (match_operand:DF 3 "arm_float_add_operand" "")))]
7265 "TARGET_ARM && TARGET_HARD_FLOAT && (TARGET_FPA || TARGET_VFP)"
7268 enum rtx_code code = GET_CODE (operands[1]);
7271 if (code == UNEQ || code == LTGT)
7274 ccreg = arm_gen_compare_reg (code, arm_compare_op0, arm_compare_op1);
7275 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
7279 (define_insn "*movsicc_insn"
7280 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r,r,r,r,r")
7282 (match_operator 3 "arm_comparison_operator"
7283 [(match_operand 4 "cc_register" "") (const_int 0)])
7284 (match_operand:SI 1 "arm_not_operand" "0,0,rI,K,rI,rI,K,K")
7285 (match_operand:SI 2 "arm_not_operand" "rI,K,0,0,rI,K,rI,K")))]
7292 mov%d3\\t%0, %1\;mov%D3\\t%0, %2
7293 mov%d3\\t%0, %1\;mvn%D3\\t%0, #%B2
7294 mvn%d3\\t%0, #%B1\;mov%D3\\t%0, %2
7295 mvn%d3\\t%0, #%B1\;mvn%D3\\t%0, #%B2"
7296 [(set_attr "length" "4,4,4,4,8,8,8,8")
7297 (set_attr "conds" "use")]
7300 (define_insn "*movsfcc_soft_insn"
7301 [(set (match_operand:SF 0 "s_register_operand" "=r,r")
7302 (if_then_else:SF (match_operator 3 "arm_comparison_operator"
7303 [(match_operand 4 "cc_register" "") (const_int 0)])
7304 (match_operand:SF 1 "s_register_operand" "0,r")
7305 (match_operand:SF 2 "s_register_operand" "r,0")))]
7306 "TARGET_ARM && TARGET_SOFT_FLOAT"
7310 [(set_attr "conds" "use")]
7314 ;; Jump and linkage insns
7316 (define_expand "jump"
7318 (label_ref (match_operand 0 "" "")))]
7323 (define_insn "*arm_jump"
7325 (label_ref (match_operand 0 "" "")))]
7329 if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
7331 arm_ccfsm_state += 2;
7334 return \"b%?\\t%l0\";
7337 [(set_attr "predicable" "yes")]
7340 (define_insn "*thumb_jump"
7342 (label_ref (match_operand 0 "" "")))]
7345 if (get_attr_length (insn) == 2)
7347 return \"bl\\t%l0\\t%@ far jump\";
7349 [(set (attr "far_jump")
7351 (eq_attr "length" "4")
7352 (const_string "yes")
7353 (const_string "no")))
7354 (set (attr "length")
7356 (and (ge (minus (match_dup 0) (pc)) (const_int -2044))
7357 (le (minus (match_dup 0) (pc)) (const_int 2048)))
7362 (define_expand "call"
7363 [(parallel [(call (match_operand 0 "memory_operand" "")
7364 (match_operand 1 "general_operand" ""))
7365 (use (match_operand 2 "" ""))
7366 (clobber (reg:SI LR_REGNUM))])]
7372 /* In an untyped call, we can get NULL for operand 2. */
7373 if (operands[2] == NULL_RTX)
7374 operands[2] = const0_rtx;
7376 /* This is to decide if we should generate indirect calls by loading the
7377 32 bit address of the callee into a register before performing the
7378 branch and link. operand[2] encodes the long_call/short_call
7379 attribute of the function being called. This attribute is set whenever
7380 __attribute__((long_call/short_call)) or #pragma long_call/no_long_call
7381 is used, and the short_call attribute can also be set if function is
7382 declared as static or if it has already been defined in the current
7383 compilation unit. See arm.c and arm.h for info about this. The third
7384 parameter to arm_is_longcall_p is used to tell it which pattern
7386 callee = XEXP (operands[0], 0);
7388 if (GET_CODE (callee) != REG
7389 && arm_is_longcall_p (operands[0], INTVAL (operands[2]), 0))
7390 XEXP (operands[0], 0) = force_reg (Pmode, callee);
7394 (define_insn "*call_reg"
7395 [(call (mem:SI (match_operand:SI 0 "s_register_operand" "r"))
7396 (match_operand 1 "" ""))
7397 (use (match_operand 2 "" ""))
7398 (clobber (reg:SI LR_REGNUM))]
7401 return output_call (operands);
7403 ;; length is worst case, normally it is only two
7404 [(set_attr "length" "12")
7405 (set_attr "type" "call")]
7408 (define_insn "*call_mem"
7409 [(call (mem:SI (match_operand:SI 0 "memory_operand" "m"))
7410 (match_operand 1 "" ""))
7411 (use (match_operand 2 "" ""))
7412 (clobber (reg:SI LR_REGNUM))]
7415 return output_call_mem (operands);
7417 [(set_attr "length" "12")
7418 (set_attr "type" "call")]
7421 (define_insn "*call_indirect"
7422 [(call (mem:SI (match_operand:SI 0 "register_operand" "l*r"))
7423 (match_operand 1 "" ""))
7424 (use (match_operand 2 "" ""))
7425 (clobber (reg:SI LR_REGNUM))]
7429 if (TARGET_CALLER_INTERWORKING)
7430 return \"bl\\t%__interwork_call_via_%0\";
7432 return \"bl\\t%__call_via_%0\";
7434 [(set_attr "type" "call")]
7437 (define_insn "*call_value_indirect"
7438 [(set (match_operand 0 "" "")
7439 (call (mem:SI (match_operand:SI 1 "register_operand" "l*r"))
7440 (match_operand 2 "" "")))
7441 (use (match_operand 3 "" ""))
7442 (clobber (reg:SI LR_REGNUM))]
7446 if (TARGET_CALLER_INTERWORKING)
7447 return \"bl\\t%__interwork_call_via_%1\";
7449 return \"bl\\t%__call_via_%1\";
7451 [(set_attr "type" "call")]
7454 (define_expand "call_value"
7455 [(parallel [(set (match_operand 0 "" "")
7456 (call (match_operand 1 "memory_operand" "")
7457 (match_operand 2 "general_operand" "")))
7458 (use (match_operand 3 "" ""))
7459 (clobber (reg:SI LR_REGNUM))])]
7463 rtx callee = XEXP (operands[1], 0);
7465 /* In an untyped call, we can get NULL for operand 2. */
7466 if (operands[3] == 0)
7467 operands[3] = const0_rtx;
7469 /* See the comment in define_expand \"call\". */
7470 if (GET_CODE (callee) != REG
7471 && arm_is_longcall_p (operands[1], INTVAL (operands[3]), 0))
7472 XEXP (operands[1], 0) = force_reg (Pmode, callee);
7476 (define_insn "*call_value_reg"
7477 [(set (match_operand 0 "" "")
7478 (call (mem:SI (match_operand:SI 1 "s_register_operand" "r"))
7479 (match_operand 2 "" "")))
7480 (use (match_operand 3 "" ""))
7481 (clobber (reg:SI LR_REGNUM))]
7484 return output_call (&operands[1]);
7486 [(set_attr "length" "12")
7487 (set_attr "type" "call")]
7490 (define_insn "*call_value_mem"
7491 [(set (match_operand 0 "" "")
7492 (call (mem:SI (match_operand:SI 1 "memory_operand" "m"))
7493 (match_operand 2 "" "")))
7494 (use (match_operand 3 "" ""))
7495 (clobber (reg:SI LR_REGNUM))]
7496 "TARGET_ARM && (!CONSTANT_ADDRESS_P (XEXP (operands[1], 0)))"
7498 return output_call_mem (&operands[1]);
7500 [(set_attr "length" "12")
7501 (set_attr "type" "call")]
7504 ;; Allow calls to SYMBOL_REFs specially as they are not valid general addresses
7505 ;; The 'a' causes the operand to be treated as an address, i.e. no '#' output.
7507 (define_insn "*call_symbol"
7508 [(call (mem:SI (match_operand:SI 0 "" ""))
7509 (match_operand 1 "" ""))
7510 (use (match_operand 2 "" ""))
7511 (clobber (reg:SI LR_REGNUM))]
7513 && (GET_CODE (operands[0]) == SYMBOL_REF)
7514 && !arm_is_longcall_p (operands[0], INTVAL (operands[2]), 1)"
7517 return NEED_PLT_RELOC ? \"bl%?\\t%a0(PLT)\" : \"bl%?\\t%a0\";
7519 [(set_attr "type" "call")]
7522 (define_insn "*call_value_symbol"
7523 [(set (match_operand 0 "s_register_operand" "")
7524 (call (mem:SI (match_operand:SI 1 "" ""))
7525 (match_operand:SI 2 "" "")))
7526 (use (match_operand 3 "" ""))
7527 (clobber (reg:SI LR_REGNUM))]
7529 && (GET_CODE (operands[1]) == SYMBOL_REF)
7530 && !arm_is_longcall_p (operands[1], INTVAL (operands[3]), 1)"
7533 return NEED_PLT_RELOC ? \"bl%?\\t%a1(PLT)\" : \"bl%?\\t%a1\";
7535 [(set_attr "type" "call")]
7538 (define_insn "*call_insn"
7539 [(call (mem:SI (match_operand:SI 0 "" ""))
7540 (match_operand:SI 1 "" ""))
7541 (use (match_operand 2 "" ""))
7542 (clobber (reg:SI LR_REGNUM))]
7544 && GET_CODE (operands[0]) == SYMBOL_REF
7545 && !arm_is_longcall_p (operands[0], INTVAL (operands[2]), 1)"
7547 [(set_attr "length" "4")
7548 (set_attr "type" "call")]
7551 (define_insn "*call_value_insn"
7552 [(set (match_operand 0 "register_operand" "")
7553 (call (mem:SI (match_operand 1 "" ""))
7554 (match_operand 2 "" "")))
7555 (use (match_operand 3 "" ""))
7556 (clobber (reg:SI LR_REGNUM))]
7558 && GET_CODE (operands[1]) == SYMBOL_REF
7559 && !arm_is_longcall_p (operands[1], INTVAL (operands[3]), 1)"
7561 [(set_attr "length" "4")
7562 (set_attr "type" "call")]
7565 ;; We may also be able to do sibcalls for Thumb, but it's much harder...
7566 (define_expand "sibcall"
7567 [(parallel [(call (match_operand 0 "memory_operand" "")
7568 (match_operand 1 "general_operand" ""))
7570 (use (match_operand 2 "" ""))])]
7574 if (operands[2] == NULL_RTX)
7575 operands[2] = const0_rtx;
7579 (define_expand "sibcall_value"
7580 [(parallel [(set (match_operand 0 "register_operand" "")
7581 (call (match_operand 1 "memory_operand" "")
7582 (match_operand 2 "general_operand" "")))
7584 (use (match_operand 3 "" ""))])]
7588 if (operands[3] == NULL_RTX)
7589 operands[3] = const0_rtx;
7593 (define_insn "*sibcall_insn"
7594 [(call (mem:SI (match_operand:SI 0 "" "X"))
7595 (match_operand 1 "" ""))
7597 (use (match_operand 2 "" ""))]
7598 "TARGET_ARM && GET_CODE (operands[0]) == SYMBOL_REF"
7600 return NEED_PLT_RELOC ? \"b%?\\t%a0(PLT)\" : \"b%?\\t%a0\";
7602 [(set_attr "type" "call")]
7605 (define_insn "*sibcall_value_insn"
7606 [(set (match_operand 0 "s_register_operand" "")
7607 (call (mem:SI (match_operand:SI 1 "" "X"))
7608 (match_operand 2 "" "")))
7610 (use (match_operand 3 "" ""))]
7611 "TARGET_ARM && GET_CODE (operands[1]) == SYMBOL_REF"
7613 return NEED_PLT_RELOC ? \"b%?\\t%a1(PLT)\" : \"b%?\\t%a1\";
7615 [(set_attr "type" "call")]
7618 ;; Often the return insn will be the same as loading from memory, so set attr
7619 (define_insn "return"
7621 "TARGET_ARM && USE_RETURN_INSN (FALSE)"
7624 if (arm_ccfsm_state == 2)
7626 arm_ccfsm_state += 2;
7629 return output_return_instruction (const_true_rtx, TRUE, FALSE);
7631 [(set_attr "type" "load1")
7632 (set_attr "length" "12")
7633 (set_attr "predicable" "yes")]
7636 (define_insn "*cond_return"
7638 (if_then_else (match_operator 0 "arm_comparison_operator"
7639 [(match_operand 1 "cc_register" "") (const_int 0)])
7642 "TARGET_ARM && USE_RETURN_INSN (TRUE)"
7645 if (arm_ccfsm_state == 2)
7647 arm_ccfsm_state += 2;
7650 return output_return_instruction (operands[0], TRUE, FALSE);
7652 [(set_attr "conds" "use")
7653 (set_attr "length" "12")
7654 (set_attr "type" "load1")]
7657 (define_insn "*cond_return_inverted"
7659 (if_then_else (match_operator 0 "arm_comparison_operator"
7660 [(match_operand 1 "cc_register" "") (const_int 0)])
7663 "TARGET_ARM && USE_RETURN_INSN (TRUE)"
7666 if (arm_ccfsm_state == 2)
7668 arm_ccfsm_state += 2;
7671 return output_return_instruction (operands[0], TRUE, TRUE);
7673 [(set_attr "conds" "use")
7674 (set_attr "type" "load1")]
7677 ;; Generate a sequence of instructions to determine if the processor is
7678 ;; in 26-bit or 32-bit mode, and return the appropriate return address
7681 (define_expand "return_addr_mask"
7683 (compare:CC_NOOV (unspec [(const_int 0)] UNSPEC_CHECK_ARCH)
7685 (set (match_operand:SI 0 "s_register_operand" "")
7686 (if_then_else:SI (eq (match_dup 1) (const_int 0))
7688 (const_int 67108860)))] ; 0x03fffffc
7691 operands[1] = gen_rtx_REG (CC_NOOVmode, CC_REGNUM);
7694 (define_insn "*check_arch2"
7695 [(set (match_operand:CC_NOOV 0 "cc_register" "")
7696 (compare:CC_NOOV (unspec [(const_int 0)] UNSPEC_CHECK_ARCH)
7699 "teq\\t%|r0, %|r0\;teq\\t%|pc, %|pc"
7700 [(set_attr "length" "8")
7701 (set_attr "conds" "set")]
7704 ;; Call subroutine returning any type.
7706 (define_expand "untyped_call"
7707 [(parallel [(call (match_operand 0 "" "")
7709 (match_operand 1 "" "")
7710 (match_operand 2 "" "")])]
7716 emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, const0_rtx));
7718 for (i = 0; i < XVECLEN (operands[2], 0); i++)
7720 rtx set = XVECEXP (operands[2], 0, i);
7722 emit_move_insn (SET_DEST (set), SET_SRC (set));
7725 /* The optimizer does not know that the call sets the function value
7726 registers we stored in the result block. We avoid problems by
7727 claiming that all hard registers are used and clobbered at this
7729 emit_insn (gen_blockage ());
7735 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
7736 ;; all of memory. This blocks insns from being moved across this point.
7738 (define_insn "blockage"
7739 [(unspec_volatile [(const_int 0)] VUNSPEC_BLOCKAGE)]
7742 [(set_attr "length" "0")
7743 (set_attr "type" "block")]
7746 (define_expand "casesi"
7747 [(match_operand:SI 0 "s_register_operand" "") ; index to jump on
7748 (match_operand:SI 1 "const_int_operand" "") ; lower bound
7749 (match_operand:SI 2 "const_int_operand" "") ; total range
7750 (match_operand:SI 3 "" "") ; table label
7751 (match_operand:SI 4 "" "")] ; Out of range label
7756 if (operands[1] != const0_rtx)
7758 reg = gen_reg_rtx (SImode);
7760 emit_insn (gen_addsi3 (reg, operands[0],
7761 GEN_INT (-INTVAL (operands[1]))));
7765 if (!const_ok_for_arm (INTVAL (operands[2])))
7766 operands[2] = force_reg (SImode, operands[2]);
7768 emit_jump_insn (gen_casesi_internal (operands[0], operands[2], operands[3],
7774 ;; The USE in this pattern is needed to tell flow analysis that this is
7775 ;; a CASESI insn. It has no other purpose.
7776 (define_insn "casesi_internal"
7777 [(parallel [(set (pc)
7779 (leu (match_operand:SI 0 "s_register_operand" "r")
7780 (match_operand:SI 1 "arm_rhs_operand" "rI"))
7781 (mem:SI (plus:SI (mult:SI (match_dup 0) (const_int 4))
7782 (label_ref (match_operand 2 "" ""))))
7783 (label_ref (match_operand 3 "" ""))))
7784 (clobber (reg:CC CC_REGNUM))
7785 (use (label_ref (match_dup 2)))])]
7789 return \"cmp\\t%0, %1\;addls\\t%|pc, %|pc, %0, asl #2\;b\\t%l3\";
7790 return \"cmp\\t%0, %1\;ldrls\\t%|pc, [%|pc, %0, asl #2]\;b\\t%l3\";
7792 [(set_attr "conds" "clob")
7793 (set_attr "length" "12")]
7796 (define_expand "indirect_jump"
7798 (match_operand:SI 0 "s_register_operand" ""))]
7803 (define_insn "*arm_indirect_jump"
7805 (match_operand:SI 0 "s_register_operand" "r"))]
7807 "mov%?\\t%|pc, %0\\t%@ indirect register jump"
7808 [(set_attr "predicable" "yes")]
7811 ;; Although not supported by the define_expand above,
7812 ;; cse/combine may generate this form.
7813 (define_insn "*load_indirect_jump"
7815 (match_operand:SI 0 "memory_operand" "m"))]
7817 "ldr%?\\t%|pc, %0\\t%@ indirect memory jump"
7818 [(set_attr "type" "load1")
7819 (set_attr "pool_range" "4096")
7820 (set_attr "neg_pool_range" "4084")
7821 (set_attr "predicable" "yes")]
7824 (define_insn "*thumb_indirect_jump"
7826 (match_operand:SI 0 "register_operand" "l*r"))]
7829 [(set_attr "conds" "clob")
7830 (set_attr "length" "2")]
7841 return \"mov%?\\t%|r0, %|r0\\t%@ nop\";
7842 return \"mov\\tr8, r8\";
7844 [(set (attr "length")
7845 (if_then_else (eq_attr "is_thumb" "yes")
7851 ;; Patterns to allow combination of arithmetic, cond code and shifts
7853 (define_insn "*arith_shiftsi"
7854 [(set (match_operand:SI 0 "s_register_operand" "=r")
7855 (match_operator:SI 1 "shiftable_operator"
7856 [(match_operator:SI 3 "shift_operator"
7857 [(match_operand:SI 4 "s_register_operand" "r")
7858 (match_operand:SI 5 "reg_or_int_operand" "rI")])
7859 (match_operand:SI 2 "s_register_operand" "r")]))]
7861 "%i1%?\\t%0, %2, %4%S3"
7862 [(set_attr "predicable" "yes")
7863 (set_attr "shift" "4")
7864 (set (attr "type") (if_then_else (match_operand 5 "const_int_operand" "")
7865 (const_string "alu_shift")
7866 (const_string "alu_shift_reg")))]
7870 [(set (match_operand:SI 0 "s_register_operand" "")
7871 (match_operator:SI 1 "shiftable_operator"
7872 [(match_operator:SI 2 "shiftable_operator"
7873 [(match_operator:SI 3 "shift_operator"
7874 [(match_operand:SI 4 "s_register_operand" "")
7875 (match_operand:SI 5 "reg_or_int_operand" "")])
7876 (match_operand:SI 6 "s_register_operand" "")])
7877 (match_operand:SI 7 "arm_rhs_operand" "")]))
7878 (clobber (match_operand:SI 8 "s_register_operand" ""))]
7881 (match_op_dup 2 [(match_op_dup 3 [(match_dup 4) (match_dup 5)])
7884 (match_op_dup 1 [(match_dup 8) (match_dup 7)]))]
7887 (define_insn "*arith_shiftsi_compare0"
7888 [(set (reg:CC_NOOV CC_REGNUM)
7889 (compare:CC_NOOV (match_operator:SI 1 "shiftable_operator"
7890 [(match_operator:SI 3 "shift_operator"
7891 [(match_operand:SI 4 "s_register_operand" "r")
7892 (match_operand:SI 5 "reg_or_int_operand" "rI")])
7893 (match_operand:SI 2 "s_register_operand" "r")])
7895 (set (match_operand:SI 0 "s_register_operand" "=r")
7896 (match_op_dup 1 [(match_op_dup 3 [(match_dup 4) (match_dup 5)])
7899 "%i1%?s\\t%0, %2, %4%S3"
7900 [(set_attr "conds" "set")
7901 (set_attr "shift" "4")
7902 (set (attr "type") (if_then_else (match_operand 5 "const_int_operand" "")
7903 (const_string "alu_shift")
7904 (const_string "alu_shift_reg")))]
7907 (define_insn "*arith_shiftsi_compare0_scratch"
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 (clobber (match_scratch:SI 0 "=r"))]
7917 "%i1%?s\\t%0, %2, %4%S3"
7918 [(set_attr "conds" "set")
7919 (set_attr "shift" "4")
7920 (set (attr "type") (if_then_else (match_operand 5 "const_int_operand" "")
7921 (const_string "alu_shift")
7922 (const_string "alu_shift_reg")))]
7925 (define_insn "*sub_shiftsi"
7926 [(set (match_operand:SI 0 "s_register_operand" "=r")
7927 (minus:SI (match_operand:SI 1 "s_register_operand" "r")
7928 (match_operator:SI 2 "shift_operator"
7929 [(match_operand:SI 3 "s_register_operand" "r")
7930 (match_operand:SI 4 "reg_or_int_operand" "rM")])))]
7932 "sub%?\\t%0, %1, %3%S2"
7933 [(set_attr "predicable" "yes")
7934 (set_attr "shift" "3")
7935 (set (attr "type") (if_then_else (match_operand 4 "const_int_operand" "")
7936 (const_string "alu_shift")
7937 (const_string "alu_shift_reg")))]
7940 (define_insn "*sub_shiftsi_compare0"
7941 [(set (reg:CC_NOOV CC_REGNUM)
7943 (minus:SI (match_operand:SI 1 "s_register_operand" "r")
7944 (match_operator:SI 2 "shift_operator"
7945 [(match_operand:SI 3 "s_register_operand" "r")
7946 (match_operand:SI 4 "reg_or_int_operand" "rM")]))
7948 (set (match_operand:SI 0 "s_register_operand" "=r")
7949 (minus:SI (match_dup 1) (match_op_dup 2 [(match_dup 3)
7952 "sub%?s\\t%0, %1, %3%S2"
7953 [(set_attr "conds" "set")
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_scratch"
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 (clobber (match_scratch:SI 0 "=r"))]
7970 "sub%?s\\t%0, %1, %3%S2"
7971 [(set_attr "conds" "set")
7972 (set_attr "shift" "3")
7973 (set (attr "type") (if_then_else (match_operand 4 "const_int_operand" "")
7974 (const_string "alu_shift")
7975 (const_string "alu_shift_reg")))]
7980 (define_insn "*and_scc"
7981 [(set (match_operand:SI 0 "s_register_operand" "=r")
7982 (and:SI (match_operator:SI 1 "arm_comparison_operator"
7983 [(match_operand 3 "cc_register" "") (const_int 0)])
7984 (match_operand:SI 2 "s_register_operand" "r")))]
7986 "mov%D1\\t%0, #0\;and%d1\\t%0, %2, #1"
7987 [(set_attr "conds" "use")
7988 (set_attr "length" "8")]
7991 (define_insn "*ior_scc"
7992 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
7993 (ior:SI (match_operator:SI 2 "arm_comparison_operator"
7994 [(match_operand 3 "cc_register" "") (const_int 0)])
7995 (match_operand:SI 1 "s_register_operand" "0,?r")))]
7999 mov%D2\\t%0, %1\;orr%d2\\t%0, %1, #1"
8000 [(set_attr "conds" "use")
8001 (set_attr "length" "4,8")]
8004 (define_insn "*compare_scc"
8005 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8006 (match_operator:SI 1 "arm_comparison_operator"
8007 [(match_operand:SI 2 "s_register_operand" "r,r")
8008 (match_operand:SI 3 "arm_add_operand" "rI,L")]))
8009 (clobber (reg:CC CC_REGNUM))]
8012 if (operands[3] == const0_rtx)
8014 if (GET_CODE (operands[1]) == LT)
8015 return \"mov\\t%0, %2, lsr #31\";
8017 if (GET_CODE (operands[1]) == GE)
8018 return \"mvn\\t%0, %2\;mov\\t%0, %0, lsr #31\";
8020 if (GET_CODE (operands[1]) == EQ)
8021 return \"rsbs\\t%0, %2, #1\;movcc\\t%0, #0\";
8024 if (GET_CODE (operands[1]) == NE)
8026 if (which_alternative == 1)
8027 return \"adds\\t%0, %2, #%n3\;movne\\t%0, #1\";
8028 return \"subs\\t%0, %2, %3\;movne\\t%0, #1\";
8030 if (which_alternative == 1)
8031 output_asm_insn (\"cmn\\t%2, #%n3\", operands);
8033 output_asm_insn (\"cmp\\t%2, %3\", operands);
8034 return \"mov%D1\\t%0, #0\;mov%d1\\t%0, #1\";
8036 [(set_attr "conds" "clob")
8037 (set_attr "length" "12")]
8040 (define_insn "*cond_move"
8041 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
8042 (if_then_else:SI (match_operator 3 "equality_operator"
8043 [(match_operator 4 "arm_comparison_operator"
8044 [(match_operand 5 "cc_register" "") (const_int 0)])
8046 (match_operand:SI 1 "arm_rhs_operand" "0,rI,?rI")
8047 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))]
8050 if (GET_CODE (operands[3]) == NE)
8052 if (which_alternative != 1)
8053 output_asm_insn (\"mov%D4\\t%0, %2\", operands);
8054 if (which_alternative != 0)
8055 output_asm_insn (\"mov%d4\\t%0, %1\", operands);
8058 if (which_alternative != 0)
8059 output_asm_insn (\"mov%D4\\t%0, %1\", operands);
8060 if (which_alternative != 1)
8061 output_asm_insn (\"mov%d4\\t%0, %2\", operands);
8064 [(set_attr "conds" "use")
8065 (set_attr "length" "4,4,8")]
8068 (define_insn "*cond_arith"
8069 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8070 (match_operator:SI 5 "shiftable_operator"
8071 [(match_operator:SI 4 "arm_comparison_operator"
8072 [(match_operand:SI 2 "s_register_operand" "r,r")
8073 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
8074 (match_operand:SI 1 "s_register_operand" "0,?r")]))
8075 (clobber (reg:CC CC_REGNUM))]
8078 if (GET_CODE (operands[4]) == LT && operands[3] == const0_rtx)
8079 return \"%i5\\t%0, %1, %2, lsr #31\";
8081 output_asm_insn (\"cmp\\t%2, %3\", operands);
8082 if (GET_CODE (operands[5]) == AND)
8083 output_asm_insn (\"mov%D4\\t%0, #0\", operands);
8084 else if (GET_CODE (operands[5]) == MINUS)
8085 output_asm_insn (\"rsb%D4\\t%0, %1, #0\", operands);
8086 else if (which_alternative != 0)
8087 output_asm_insn (\"mov%D4\\t%0, %1\", operands);
8088 return \"%i5%d4\\t%0, %1, #1\";
8090 [(set_attr "conds" "clob")
8091 (set_attr "length" "12")]
8094 (define_insn "*cond_sub"
8095 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8096 (minus:SI (match_operand:SI 1 "s_register_operand" "0,?r")
8097 (match_operator:SI 4 "arm_comparison_operator"
8098 [(match_operand:SI 2 "s_register_operand" "r,r")
8099 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))
8100 (clobber (reg:CC CC_REGNUM))]
8103 output_asm_insn (\"cmp\\t%2, %3\", operands);
8104 if (which_alternative != 0)
8105 output_asm_insn (\"mov%D4\\t%0, %1\", operands);
8106 return \"sub%d4\\t%0, %1, #1\";
8108 [(set_attr "conds" "clob")
8109 (set_attr "length" "8,12")]
8112 (define_insn "*cmp_ite0"
8113 [(set (match_operand 6 "dominant_cc_register" "")
8116 (match_operator 4 "arm_comparison_operator"
8117 [(match_operand:SI 0 "s_register_operand" "r,r,r,r")
8118 (match_operand:SI 1 "arm_add_operand" "rI,L,rI,L")])
8119 (match_operator:SI 5 "arm_comparison_operator"
8120 [(match_operand:SI 2 "s_register_operand" "r,r,r,r")
8121 (match_operand:SI 3 "arm_add_operand" "rI,rI,L,L")])
8127 static const char * const opcodes[4][2] =
8129 {\"cmp\\t%2, %3\;cmp%d5\\t%0, %1\",
8130 \"cmp\\t%0, %1\;cmp%d4\\t%2, %3\"},
8131 {\"cmp\\t%2, %3\;cmn%d5\\t%0, #%n1\",
8132 \"cmn\\t%0, #%n1\;cmp%d4\\t%2, %3\"},
8133 {\"cmn\\t%2, #%n3\;cmp%d5\\t%0, %1\",
8134 \"cmp\\t%0, %1\;cmn%d4\\t%2, #%n3\"},
8135 {\"cmn\\t%2, #%n3\;cmn%d5\\t%0, #%n1\",
8136 \"cmn\\t%0, #%n1\;cmn%d4\\t%2, #%n3\"}
8139 comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4]));
8141 return opcodes[which_alternative][swap];
8143 [(set_attr "conds" "set")
8144 (set_attr "length" "8")]
8147 (define_insn "*cmp_ite1"
8148 [(set (match_operand 6 "dominant_cc_register" "")
8151 (match_operator 4 "arm_comparison_operator"
8152 [(match_operand:SI 0 "s_register_operand" "r,r,r,r")
8153 (match_operand:SI 1 "arm_add_operand" "rI,L,rI,L")])
8154 (match_operator:SI 5 "arm_comparison_operator"
8155 [(match_operand:SI 2 "s_register_operand" "r,r,r,r")
8156 (match_operand:SI 3 "arm_add_operand" "rI,rI,L,L")])
8162 static const char * const opcodes[4][2] =
8164 {\"cmp\\t%0, %1\;cmp%d4\\t%2, %3\",
8165 \"cmp\\t%2, %3\;cmp%D5\\t%0, %1\"},
8166 {\"cmn\\t%0, #%n1\;cmp%d4\\t%2, %3\",
8167 \"cmp\\t%2, %3\;cmn%D5\\t%0, #%n1\"},
8168 {\"cmp\\t%0, %1\;cmn%d4\\t%2, #%n3\",
8169 \"cmn\\t%2, #%n3\;cmp%D5\\t%0, %1\"},
8170 {\"cmn\\t%0, #%n1\;cmn%d4\\t%2, #%n3\",
8171 \"cmn\\t%2, #%n3\;cmn%D5\\t%0, #%n1\"}
8174 comparison_dominates_p (GET_CODE (operands[5]),
8175 reverse_condition (GET_CODE (operands[4])));
8177 return opcodes[which_alternative][swap];
8179 [(set_attr "conds" "set")
8180 (set_attr "length" "8")]
8183 (define_insn "*cmp_and"
8184 [(set (match_operand 6 "dominant_cc_register" "")
8187 (match_operator 4 "arm_comparison_operator"
8188 [(match_operand:SI 0 "s_register_operand" "r,r,r,r")
8189 (match_operand:SI 1 "arm_add_operand" "rI,L,rI,L")])
8190 (match_operator:SI 5 "arm_comparison_operator"
8191 [(match_operand:SI 2 "s_register_operand" "r,r,r,r")
8192 (match_operand:SI 3 "arm_add_operand" "rI,rI,L,L")]))
8197 static const char *const opcodes[4][2] =
8199 {\"cmp\\t%2, %3\;cmp%d5\\t%0, %1\",
8200 \"cmp\\t%0, %1\;cmp%d4\\t%2, %3\"},
8201 {\"cmp\\t%2, %3\;cmn%d5\\t%0, #%n1\",
8202 \"cmn\\t%0, #%n1\;cmp%d4\\t%2, %3\"},
8203 {\"cmn\\t%2, #%n3\;cmp%d5\\t%0, %1\",
8204 \"cmp\\t%0, %1\;cmn%d4\\t%2, #%n3\"},
8205 {\"cmn\\t%2, #%n3\;cmn%d5\\t%0, #%n1\",
8206 \"cmn\\t%0, #%n1\;cmn%d4\\t%2, #%n3\"}
8209 comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4]));
8211 return opcodes[which_alternative][swap];
8213 [(set_attr "conds" "set")
8214 (set_attr "predicable" "no")
8215 (set_attr "length" "8")]
8218 (define_insn "*cmp_ior"
8219 [(set (match_operand 6 "dominant_cc_register" "")
8222 (match_operator 4 "arm_comparison_operator"
8223 [(match_operand:SI 0 "s_register_operand" "r,r,r,r")
8224 (match_operand:SI 1 "arm_add_operand" "rI,L,rI,L")])
8225 (match_operator:SI 5 "arm_comparison_operator"
8226 [(match_operand:SI 2 "s_register_operand" "r,r,r,r")
8227 (match_operand:SI 3 "arm_add_operand" "rI,rI,L,L")]))
8232 static const char *const opcodes[4][2] =
8234 {\"cmp\\t%0, %1\;cmp%D4\\t%2, %3\",
8235 \"cmp\\t%2, %3\;cmp%D5\\t%0, %1\"},
8236 {\"cmn\\t%0, #%n1\;cmp%D4\\t%2, %3\",
8237 \"cmp\\t%2, %3\;cmn%D5\\t%0, #%n1\"},
8238 {\"cmp\\t%0, %1\;cmn%D4\\t%2, #%n3\",
8239 \"cmn\\t%2, #%n3\;cmp%D5\\t%0, %1\"},
8240 {\"cmn\\t%0, #%n1\;cmn%D4\\t%2, #%n3\",
8241 \"cmn\\t%2, #%n3\;cmn%D5\\t%0, #%n1\"}
8244 comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4]));
8246 return opcodes[which_alternative][swap];
8249 [(set_attr "conds" "set")
8250 (set_attr "length" "8")]
8253 (define_insn_and_split "*ior_scc_scc"
8254 [(set (match_operand:SI 0 "s_register_operand" "=r")
8255 (ior:SI (match_operator:SI 3 "arm_comparison_operator"
8256 [(match_operand:SI 1 "s_register_operand" "r")
8257 (match_operand:SI 2 "arm_add_operand" "rIL")])
8258 (match_operator:SI 6 "arm_comparison_operator"
8259 [(match_operand:SI 4 "s_register_operand" "r")
8260 (match_operand:SI 5 "arm_add_operand" "rIL")])))
8261 (clobber (reg:CC CC_REGNUM))]
8263 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_OR_Y)
8266 "TARGET_ARM && reload_completed"
8270 (match_op_dup 3 [(match_dup 1) (match_dup 2)])
8271 (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
8273 (set (match_dup 0) (ne:SI (match_dup 7) (const_int 0)))]
8275 = gen_rtx_REG (arm_select_dominance_cc_mode (operands[3], operands[6],
8278 [(set_attr "conds" "clob")
8279 (set_attr "length" "16")])
8281 ; If the above pattern is followed by a CMP insn, then the compare is
8282 ; redundant, since we can rework the conditional instruction that follows.
8283 (define_insn_and_split "*ior_scc_scc_cmp"
8284 [(set (match_operand 0 "dominant_cc_register" "")
8285 (compare (ior:SI (match_operator:SI 3 "arm_comparison_operator"
8286 [(match_operand:SI 1 "s_register_operand" "r")
8287 (match_operand:SI 2 "arm_add_operand" "rIL")])
8288 (match_operator:SI 6 "arm_comparison_operator"
8289 [(match_operand:SI 4 "s_register_operand" "r")
8290 (match_operand:SI 5 "arm_add_operand" "rIL")]))
8292 (set (match_operand:SI 7 "s_register_operand" "=r")
8293 (ior:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)])
8294 (match_op_dup 6 [(match_dup 4) (match_dup 5)])))]
8297 "TARGET_ARM && reload_completed"
8301 (match_op_dup 3 [(match_dup 1) (match_dup 2)])
8302 (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
8304 (set (match_dup 7) (ne:SI (match_dup 0) (const_int 0)))]
8306 [(set_attr "conds" "set")
8307 (set_attr "length" "16")])
8309 (define_insn_and_split "*and_scc_scc"
8310 [(set (match_operand:SI 0 "s_register_operand" "=r")
8311 (and:SI (match_operator:SI 3 "arm_comparison_operator"
8312 [(match_operand:SI 1 "s_register_operand" "r")
8313 (match_operand:SI 2 "arm_add_operand" "rIL")])
8314 (match_operator:SI 6 "arm_comparison_operator"
8315 [(match_operand:SI 4 "s_register_operand" "r")
8316 (match_operand:SI 5 "arm_add_operand" "rIL")])))
8317 (clobber (reg:CC CC_REGNUM))]
8319 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y)
8322 "TARGET_ARM && reload_completed
8323 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y)
8328 (match_op_dup 3 [(match_dup 1) (match_dup 2)])
8329 (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
8331 (set (match_dup 0) (ne:SI (match_dup 7) (const_int 0)))]
8333 = gen_rtx_REG (arm_select_dominance_cc_mode (operands[3], operands[6],
8336 [(set_attr "conds" "clob")
8337 (set_attr "length" "16")])
8339 ; If the above pattern is followed by a CMP insn, then the compare is
8340 ; redundant, since we can rework the conditional instruction that follows.
8341 (define_insn_and_split "*and_scc_scc_cmp"
8342 [(set (match_operand 0 "dominant_cc_register" "")
8343 (compare (and:SI (match_operator:SI 3 "arm_comparison_operator"
8344 [(match_operand:SI 1 "s_register_operand" "r")
8345 (match_operand:SI 2 "arm_add_operand" "rIL")])
8346 (match_operator:SI 6 "arm_comparison_operator"
8347 [(match_operand:SI 4 "s_register_operand" "r")
8348 (match_operand:SI 5 "arm_add_operand" "rIL")]))
8350 (set (match_operand:SI 7 "s_register_operand" "=r")
8351 (and:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)])
8352 (match_op_dup 6 [(match_dup 4) (match_dup 5)])))]
8355 "TARGET_ARM && reload_completed"
8359 (match_op_dup 3 [(match_dup 1) (match_dup 2)])
8360 (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
8362 (set (match_dup 7) (ne:SI (match_dup 0) (const_int 0)))]
8364 [(set_attr "conds" "set")
8365 (set_attr "length" "16")])
8367 ;; If there is no dominance in the comparison, then we can still save an
8368 ;; instruction in the AND case, since we can know that the second compare
8369 ;; need only zero the value if false (if true, then the value is already
8371 (define_insn_and_split "*and_scc_scc_nodom"
8372 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r")
8373 (and:SI (match_operator:SI 3 "arm_comparison_operator"
8374 [(match_operand:SI 1 "s_register_operand" "r,r,0")
8375 (match_operand:SI 2 "arm_add_operand" "rIL,0,rIL")])
8376 (match_operator:SI 6 "arm_comparison_operator"
8377 [(match_operand:SI 4 "s_register_operand" "r,r,r")
8378 (match_operand:SI 5 "arm_add_operand" "rIL,rIL,rIL")])))
8379 (clobber (reg:CC CC_REGNUM))]
8381 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y)
8384 "TARGET_ARM && reload_completed"
8385 [(parallel [(set (match_dup 0)
8386 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
8387 (clobber (reg:CC CC_REGNUM))])
8388 (set (match_dup 7) (match_op_dup 8 [(match_dup 4) (match_dup 5)]))
8390 (if_then_else:SI (match_op_dup 6 [(match_dup 7) (const_int 0)])
8393 "operands[7] = gen_rtx_REG (SELECT_CC_MODE (GET_CODE (operands[6]),
8394 operands[4], operands[5]),
8396 operands[8] = gen_rtx_COMPARE (GET_MODE (operands[7]), operands[4],
8398 [(set_attr "conds" "clob")
8399 (set_attr "length" "20")])
8402 [(set (reg:CC_NOOV CC_REGNUM)
8403 (compare:CC_NOOV (ior:SI
8404 (and:SI (match_operand:SI 0 "s_register_operand" "")
8406 (match_operator:SI 1 "comparison_operator"
8407 [(match_operand:SI 2 "s_register_operand" "")
8408 (match_operand:SI 3 "arm_add_operand" "")]))
8410 (clobber (match_operand:SI 4 "s_register_operand" ""))]
8413 (ior:SI (match_op_dup 1 [(match_dup 2) (match_dup 3)])
8415 (set (reg:CC_NOOV CC_REGNUM)
8416 (compare:CC_NOOV (and:SI (match_dup 4) (const_int 1))
8421 [(set (reg:CC_NOOV CC_REGNUM)
8422 (compare:CC_NOOV (ior:SI
8423 (match_operator:SI 1 "comparison_operator"
8424 [(match_operand:SI 2 "s_register_operand" "")
8425 (match_operand:SI 3 "arm_add_operand" "")])
8426 (and:SI (match_operand:SI 0 "s_register_operand" "")
8429 (clobber (match_operand:SI 4 "s_register_operand" ""))]
8432 (ior:SI (match_op_dup 1 [(match_dup 2) (match_dup 3)])
8434 (set (reg:CC_NOOV CC_REGNUM)
8435 (compare:CC_NOOV (and:SI (match_dup 4) (const_int 1))
8439 (define_insn "*negscc"
8440 [(set (match_operand:SI 0 "s_register_operand" "=r")
8441 (neg:SI (match_operator 3 "arm_comparison_operator"
8442 [(match_operand:SI 1 "s_register_operand" "r")
8443 (match_operand:SI 2 "arm_rhs_operand" "rI")])))
8444 (clobber (reg:CC CC_REGNUM))]
8447 if (GET_CODE (operands[3]) == LT && operands[3] == const0_rtx)
8448 return \"mov\\t%0, %1, asr #31\";
8450 if (GET_CODE (operands[3]) == NE)
8451 return \"subs\\t%0, %1, %2\;mvnne\\t%0, #0\";
8453 if (GET_CODE (operands[3]) == GT)
8454 return \"subs\\t%0, %1, %2\;mvnne\\t%0, %0, asr #31\";
8456 output_asm_insn (\"cmp\\t%1, %2\", operands);
8457 output_asm_insn (\"mov%D3\\t%0, #0\", operands);
8458 return \"mvn%d3\\t%0, #0\";
8460 [(set_attr "conds" "clob")
8461 (set_attr "length" "12")]
8464 (define_insn "movcond"
8465 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
8467 (match_operator 5 "arm_comparison_operator"
8468 [(match_operand:SI 3 "s_register_operand" "r,r,r")
8469 (match_operand:SI 4 "arm_add_operand" "rIL,rIL,rIL")])
8470 (match_operand:SI 1 "arm_rhs_operand" "0,rI,?rI")
8471 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
8472 (clobber (reg:CC CC_REGNUM))]
8475 if (GET_CODE (operands[5]) == LT
8476 && (operands[4] == const0_rtx))
8478 if (which_alternative != 1 && GET_CODE (operands[1]) == REG)
8480 if (operands[2] == const0_rtx)
8481 return \"and\\t%0, %1, %3, asr #31\";
8482 return \"ands\\t%0, %1, %3, asr #32\;movcc\\t%0, %2\";
8484 else if (which_alternative != 0 && GET_CODE (operands[2]) == REG)
8486 if (operands[1] == const0_rtx)
8487 return \"bic\\t%0, %2, %3, asr #31\";
8488 return \"bics\\t%0, %2, %3, asr #32\;movcs\\t%0, %1\";
8490 /* The only case that falls through to here is when both ops 1 & 2
8494 if (GET_CODE (operands[5]) == GE
8495 && (operands[4] == const0_rtx))
8497 if (which_alternative != 1 && GET_CODE (operands[1]) == REG)
8499 if (operands[2] == const0_rtx)
8500 return \"bic\\t%0, %1, %3, asr #31\";
8501 return \"bics\\t%0, %1, %3, asr #32\;movcs\\t%0, %2\";
8503 else if (which_alternative != 0 && GET_CODE (operands[2]) == REG)
8505 if (operands[1] == const0_rtx)
8506 return \"and\\t%0, %2, %3, asr #31\";
8507 return \"ands\\t%0, %2, %3, asr #32\;movcc\\t%0, %1\";
8509 /* The only case that falls through to here is when both ops 1 & 2
8512 if (GET_CODE (operands[4]) == CONST_INT
8513 && !const_ok_for_arm (INTVAL (operands[4])))
8514 output_asm_insn (\"cmn\\t%3, #%n4\", operands);
8516 output_asm_insn (\"cmp\\t%3, %4\", operands);
8517 if (which_alternative != 0)
8518 output_asm_insn (\"mov%d5\\t%0, %1\", operands);
8519 if (which_alternative != 1)
8520 output_asm_insn (\"mov%D5\\t%0, %2\", operands);
8523 [(set_attr "conds" "clob")
8524 (set_attr "length" "8,8,12")]
8527 (define_insn "*ifcompare_plus_move"
8528 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8529 (if_then_else:SI (match_operator 6 "arm_comparison_operator"
8530 [(match_operand:SI 4 "s_register_operand" "r,r")
8531 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
8533 (match_operand:SI 2 "s_register_operand" "r,r")
8534 (match_operand:SI 3 "arm_add_operand" "rIL,rIL"))
8535 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))
8536 (clobber (reg:CC CC_REGNUM))]
8539 [(set_attr "conds" "clob")
8540 (set_attr "length" "8,12")]
8543 (define_insn "*if_plus_move"
8544 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r")
8546 (match_operator 4 "arm_comparison_operator"
8547 [(match_operand 5 "cc_register" "") (const_int 0)])
8549 (match_operand:SI 2 "s_register_operand" "r,r,r,r")
8550 (match_operand:SI 3 "arm_add_operand" "rI,L,rI,L"))
8551 (match_operand:SI 1 "arm_rhs_operand" "0,0,?rI,?rI")))]
8555 sub%d4\\t%0, %2, #%n3
8556 add%d4\\t%0, %2, %3\;mov%D4\\t%0, %1
8557 sub%d4\\t%0, %2, #%n3\;mov%D4\\t%0, %1"
8558 [(set_attr "conds" "use")
8559 (set_attr "length" "4,4,8,8")
8560 (set_attr "type" "*,*,*,*")]
8563 (define_insn "*ifcompare_move_plus"
8564 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8565 (if_then_else:SI (match_operator 6 "arm_comparison_operator"
8566 [(match_operand:SI 4 "s_register_operand" "r,r")
8567 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
8568 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
8570 (match_operand:SI 2 "s_register_operand" "r,r")
8571 (match_operand:SI 3 "arm_add_operand" "rIL,rIL"))))
8572 (clobber (reg:CC CC_REGNUM))]
8575 [(set_attr "conds" "clob")
8576 (set_attr "length" "8,12")]
8579 (define_insn "*if_move_plus"
8580 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r")
8582 (match_operator 4 "arm_comparison_operator"
8583 [(match_operand 5 "cc_register" "") (const_int 0)])
8584 (match_operand:SI 1 "arm_rhs_operand" "0,0,?rI,?rI")
8586 (match_operand:SI 2 "s_register_operand" "r,r,r,r")
8587 (match_operand:SI 3 "arm_add_operand" "rI,L,rI,L"))))]
8591 sub%D4\\t%0, %2, #%n3
8592 add%D4\\t%0, %2, %3\;mov%d4\\t%0, %1
8593 sub%D4\\t%0, %2, #%n3\;mov%d4\\t%0, %1"
8594 [(set_attr "conds" "use")
8595 (set_attr "length" "4,4,8,8")
8596 (set_attr "type" "*,*,*,*")]
8599 (define_insn "*ifcompare_arith_arith"
8600 [(set (match_operand:SI 0 "s_register_operand" "=r")
8601 (if_then_else:SI (match_operator 9 "arm_comparison_operator"
8602 [(match_operand:SI 5 "s_register_operand" "r")
8603 (match_operand:SI 6 "arm_add_operand" "rIL")])
8604 (match_operator:SI 8 "shiftable_operator"
8605 [(match_operand:SI 1 "s_register_operand" "r")
8606 (match_operand:SI 2 "arm_rhs_operand" "rI")])
8607 (match_operator:SI 7 "shiftable_operator"
8608 [(match_operand:SI 3 "s_register_operand" "r")
8609 (match_operand:SI 4 "arm_rhs_operand" "rI")])))
8610 (clobber (reg:CC CC_REGNUM))]
8613 [(set_attr "conds" "clob")
8614 (set_attr "length" "12")]
8617 (define_insn "*if_arith_arith"
8618 [(set (match_operand:SI 0 "s_register_operand" "=r")
8619 (if_then_else:SI (match_operator 5 "arm_comparison_operator"
8620 [(match_operand 8 "cc_register" "") (const_int 0)])
8621 (match_operator:SI 6 "shiftable_operator"
8622 [(match_operand:SI 1 "s_register_operand" "r")
8623 (match_operand:SI 2 "arm_rhs_operand" "rI")])
8624 (match_operator:SI 7 "shiftable_operator"
8625 [(match_operand:SI 3 "s_register_operand" "r")
8626 (match_operand:SI 4 "arm_rhs_operand" "rI")])))]
8628 "%I6%d5\\t%0, %1, %2\;%I7%D5\\t%0, %3, %4"
8629 [(set_attr "conds" "use")
8630 (set_attr "length" "8")]
8633 (define_insn "*ifcompare_arith_move"
8634 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8635 (if_then_else:SI (match_operator 6 "arm_comparison_operator"
8636 [(match_operand:SI 2 "s_register_operand" "r,r")
8637 (match_operand:SI 3 "arm_add_operand" "rIL,rIL")])
8638 (match_operator:SI 7 "shiftable_operator"
8639 [(match_operand:SI 4 "s_register_operand" "r,r")
8640 (match_operand:SI 5 "arm_rhs_operand" "rI,rI")])
8641 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))
8642 (clobber (reg:CC CC_REGNUM))]
8645 /* If we have an operation where (op x 0) is the identity operation and
8646 the conditional operator is LT or GE and we are comparing against zero and
8647 everything is in registers then we can do this in two instructions. */
8648 if (operands[3] == const0_rtx
8649 && GET_CODE (operands[7]) != AND
8650 && GET_CODE (operands[5]) == REG
8651 && GET_CODE (operands[1]) == REG
8652 && REGNO (operands[1]) == REGNO (operands[4])
8653 && REGNO (operands[4]) != REGNO (operands[0]))
8655 if (GET_CODE (operands[6]) == LT)
8656 return \"and\\t%0, %5, %2, asr #31\;%I7\\t%0, %4, %0\";
8657 else if (GET_CODE (operands[6]) == GE)
8658 return \"bic\\t%0, %5, %2, asr #31\;%I7\\t%0, %4, %0\";
8660 if (GET_CODE (operands[3]) == CONST_INT
8661 && !const_ok_for_arm (INTVAL (operands[3])))
8662 output_asm_insn (\"cmn\\t%2, #%n3\", operands);
8664 output_asm_insn (\"cmp\\t%2, %3\", operands);
8665 output_asm_insn (\"%I7%d6\\t%0, %4, %5\", operands);
8666 if (which_alternative != 0)
8667 return \"mov%D6\\t%0, %1\";
8670 [(set_attr "conds" "clob")
8671 (set_attr "length" "8,12")]
8674 (define_insn "*if_arith_move"
8675 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8676 (if_then_else:SI (match_operator 4 "arm_comparison_operator"
8677 [(match_operand 6 "cc_register" "") (const_int 0)])
8678 (match_operator:SI 5 "shiftable_operator"
8679 [(match_operand:SI 2 "s_register_operand" "r,r")
8680 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
8681 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))]
8685 %I5%d4\\t%0, %2, %3\;mov%D4\\t%0, %1"
8686 [(set_attr "conds" "use")
8687 (set_attr "length" "4,8")
8688 (set_attr "type" "*,*")]
8691 (define_insn "*ifcompare_move_arith"
8692 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8693 (if_then_else:SI (match_operator 6 "arm_comparison_operator"
8694 [(match_operand:SI 4 "s_register_operand" "r,r")
8695 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
8696 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
8697 (match_operator:SI 7 "shiftable_operator"
8698 [(match_operand:SI 2 "s_register_operand" "r,r")
8699 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))
8700 (clobber (reg:CC CC_REGNUM))]
8703 /* If we have an operation where (op x 0) is the identity operation and
8704 the conditional operator is LT or GE and we are comparing against zero and
8705 everything is in registers then we can do this in two instructions */
8706 if (operands[5] == const0_rtx
8707 && GET_CODE (operands[7]) != AND
8708 && GET_CODE (operands[3]) == REG
8709 && GET_CODE (operands[1]) == REG
8710 && REGNO (operands[1]) == REGNO (operands[2])
8711 && REGNO (operands[2]) != REGNO (operands[0]))
8713 if (GET_CODE (operands[6]) == GE)
8714 return \"and\\t%0, %3, %4, asr #31\;%I7\\t%0, %2, %0\";
8715 else if (GET_CODE (operands[6]) == LT)
8716 return \"bic\\t%0, %3, %4, asr #31\;%I7\\t%0, %2, %0\";
8719 if (GET_CODE (operands[5]) == CONST_INT
8720 && !const_ok_for_arm (INTVAL (operands[5])))
8721 output_asm_insn (\"cmn\\t%4, #%n5\", operands);
8723 output_asm_insn (\"cmp\\t%4, %5\", operands);
8725 if (which_alternative != 0)
8726 output_asm_insn (\"mov%d6\\t%0, %1\", operands);
8727 return \"%I7%D6\\t%0, %2, %3\";
8729 [(set_attr "conds" "clob")
8730 (set_attr "length" "8,12")]
8733 (define_insn "*if_move_arith"
8734 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8736 (match_operator 4 "arm_comparison_operator"
8737 [(match_operand 6 "cc_register" "") (const_int 0)])
8738 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
8739 (match_operator:SI 5 "shiftable_operator"
8740 [(match_operand:SI 2 "s_register_operand" "r,r")
8741 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))]
8745 %I5%D4\\t%0, %2, %3\;mov%d4\\t%0, %1"
8746 [(set_attr "conds" "use")
8747 (set_attr "length" "4,8")
8748 (set_attr "type" "*,*")]
8751 (define_insn "*ifcompare_move_not"
8752 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8754 (match_operator 5 "arm_comparison_operator"
8755 [(match_operand:SI 3 "s_register_operand" "r,r")
8756 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
8757 (match_operand:SI 1 "arm_not_operand" "0,?rIK")
8759 (match_operand:SI 2 "s_register_operand" "r,r"))))
8760 (clobber (reg:CC CC_REGNUM))]
8763 [(set_attr "conds" "clob")
8764 (set_attr "length" "8,12")]
8767 (define_insn "*if_move_not"
8768 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
8770 (match_operator 4 "arm_comparison_operator"
8771 [(match_operand 3 "cc_register" "") (const_int 0)])
8772 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")
8773 (not:SI (match_operand:SI 2 "s_register_operand" "r,r,r"))))]
8777 mov%d4\\t%0, %1\;mvn%D4\\t%0, %2
8778 mvn%d4\\t%0, #%B1\;mvn%D4\\t%0, %2"
8779 [(set_attr "conds" "use")
8780 (set_attr "length" "4,8,8")]
8783 (define_insn "*ifcompare_not_move"
8784 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8786 (match_operator 5 "arm_comparison_operator"
8787 [(match_operand:SI 3 "s_register_operand" "r,r")
8788 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
8790 (match_operand:SI 2 "s_register_operand" "r,r"))
8791 (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
8792 (clobber (reg:CC CC_REGNUM))]
8795 [(set_attr "conds" "clob")
8796 (set_attr "length" "8,12")]
8799 (define_insn "*if_not_move"
8800 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
8802 (match_operator 4 "arm_comparison_operator"
8803 [(match_operand 3 "cc_register" "") (const_int 0)])
8804 (not:SI (match_operand:SI 2 "s_register_operand" "r,r,r"))
8805 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")))]
8809 mov%D4\\t%0, %1\;mvn%d4\\t%0, %2
8810 mvn%D4\\t%0, #%B1\;mvn%d4\\t%0, %2"
8811 [(set_attr "conds" "use")
8812 (set_attr "length" "4,8,8")]
8815 (define_insn "*ifcompare_shift_move"
8816 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8818 (match_operator 6 "arm_comparison_operator"
8819 [(match_operand:SI 4 "s_register_operand" "r,r")
8820 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
8821 (match_operator:SI 7 "shift_operator"
8822 [(match_operand:SI 2 "s_register_operand" "r,r")
8823 (match_operand:SI 3 "arm_rhs_operand" "rM,rM")])
8824 (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
8825 (clobber (reg:CC CC_REGNUM))]
8828 [(set_attr "conds" "clob")
8829 (set_attr "length" "8,12")]
8832 (define_insn "*if_shift_move"
8833 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
8835 (match_operator 5 "arm_comparison_operator"
8836 [(match_operand 6 "cc_register" "") (const_int 0)])
8837 (match_operator:SI 4 "shift_operator"
8838 [(match_operand:SI 2 "s_register_operand" "r,r,r")
8839 (match_operand:SI 3 "arm_rhs_operand" "rM,rM,rM")])
8840 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")))]
8844 mov%D5\\t%0, %1\;mov%d5\\t%0, %2%S4
8845 mvn%D5\\t%0, #%B1\;mov%d5\\t%0, %2%S4"
8846 [(set_attr "conds" "use")
8847 (set_attr "shift" "2")
8848 (set_attr "length" "4,8,8")
8849 (set (attr "type") (if_then_else (match_operand 3 "const_int_operand" "")
8850 (const_string "alu_shift")
8851 (const_string "alu_shift_reg")))]
8854 (define_insn "*ifcompare_move_shift"
8855 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8857 (match_operator 6 "arm_comparison_operator"
8858 [(match_operand:SI 4 "s_register_operand" "r,r")
8859 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
8860 (match_operand:SI 1 "arm_not_operand" "0,?rIK")
8861 (match_operator:SI 7 "shift_operator"
8862 [(match_operand:SI 2 "s_register_operand" "r,r")
8863 (match_operand:SI 3 "arm_rhs_operand" "rM,rM")])))
8864 (clobber (reg:CC CC_REGNUM))]
8867 [(set_attr "conds" "clob")
8868 (set_attr "length" "8,12")]
8871 (define_insn "*if_move_shift"
8872 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
8874 (match_operator 5 "arm_comparison_operator"
8875 [(match_operand 6 "cc_register" "") (const_int 0)])
8876 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")
8877 (match_operator:SI 4 "shift_operator"
8878 [(match_operand:SI 2 "s_register_operand" "r,r,r")
8879 (match_operand:SI 3 "arm_rhs_operand" "rM,rM,rM")])))]
8883 mov%d5\\t%0, %1\;mov%D5\\t%0, %2%S4
8884 mvn%d5\\t%0, #%B1\;mov%D5\\t%0, %2%S4"
8885 [(set_attr "conds" "use")
8886 (set_attr "shift" "2")
8887 (set_attr "length" "4,8,8")
8888 (set (attr "type") (if_then_else (match_operand 3 "const_int_operand" "")
8889 (const_string "alu_shift")
8890 (const_string "alu_shift_reg")))]
8893 (define_insn "*ifcompare_shift_shift"
8894 [(set (match_operand:SI 0 "s_register_operand" "=r")
8896 (match_operator 7 "arm_comparison_operator"
8897 [(match_operand:SI 5 "s_register_operand" "r")
8898 (match_operand:SI 6 "arm_add_operand" "rIL")])
8899 (match_operator:SI 8 "shift_operator"
8900 [(match_operand:SI 1 "s_register_operand" "r")
8901 (match_operand:SI 2 "arm_rhs_operand" "rM")])
8902 (match_operator:SI 9 "shift_operator"
8903 [(match_operand:SI 3 "s_register_operand" "r")
8904 (match_operand:SI 4 "arm_rhs_operand" "rM")])))
8905 (clobber (reg:CC CC_REGNUM))]
8908 [(set_attr "conds" "clob")
8909 (set_attr "length" "12")]
8912 (define_insn "*if_shift_shift"
8913 [(set (match_operand:SI 0 "s_register_operand" "=r")
8915 (match_operator 5 "arm_comparison_operator"
8916 [(match_operand 8 "cc_register" "") (const_int 0)])
8917 (match_operator:SI 6 "shift_operator"
8918 [(match_operand:SI 1 "s_register_operand" "r")
8919 (match_operand:SI 2 "arm_rhs_operand" "rM")])
8920 (match_operator:SI 7 "shift_operator"
8921 [(match_operand:SI 3 "s_register_operand" "r")
8922 (match_operand:SI 4 "arm_rhs_operand" "rM")])))]
8924 "mov%d5\\t%0, %1%S6\;mov%D5\\t%0, %3%S7"
8925 [(set_attr "conds" "use")
8926 (set_attr "shift" "1")
8927 (set_attr "length" "8")
8928 (set (attr "type") (if_then_else
8929 (and (match_operand 2 "const_int_operand" "")
8930 (match_operand 4 "const_int_operand" ""))
8931 (const_string "alu_shift")
8932 (const_string "alu_shift_reg")))]
8935 (define_insn "*ifcompare_not_arith"
8936 [(set (match_operand:SI 0 "s_register_operand" "=r")
8938 (match_operator 6 "arm_comparison_operator"
8939 [(match_operand:SI 4 "s_register_operand" "r")
8940 (match_operand:SI 5 "arm_add_operand" "rIL")])
8941 (not:SI (match_operand:SI 1 "s_register_operand" "r"))
8942 (match_operator:SI 7 "shiftable_operator"
8943 [(match_operand:SI 2 "s_register_operand" "r")
8944 (match_operand:SI 3 "arm_rhs_operand" "rI")])))
8945 (clobber (reg:CC CC_REGNUM))]
8948 [(set_attr "conds" "clob")
8949 (set_attr "length" "12")]
8952 (define_insn "*if_not_arith"
8953 [(set (match_operand:SI 0 "s_register_operand" "=r")
8955 (match_operator 5 "arm_comparison_operator"
8956 [(match_operand 4 "cc_register" "") (const_int 0)])
8957 (not:SI (match_operand:SI 1 "s_register_operand" "r"))
8958 (match_operator:SI 6 "shiftable_operator"
8959 [(match_operand:SI 2 "s_register_operand" "r")
8960 (match_operand:SI 3 "arm_rhs_operand" "rI")])))]
8962 "mvn%d5\\t%0, %1\;%I6%D5\\t%0, %2, %3"
8963 [(set_attr "conds" "use")
8964 (set_attr "length" "8")]
8967 (define_insn "*ifcompare_arith_not"
8968 [(set (match_operand:SI 0 "s_register_operand" "=r")
8970 (match_operator 6 "arm_comparison_operator"
8971 [(match_operand:SI 4 "s_register_operand" "r")
8972 (match_operand:SI 5 "arm_add_operand" "rIL")])
8973 (match_operator:SI 7 "shiftable_operator"
8974 [(match_operand:SI 2 "s_register_operand" "r")
8975 (match_operand:SI 3 "arm_rhs_operand" "rI")])
8976 (not:SI (match_operand:SI 1 "s_register_operand" "r"))))
8977 (clobber (reg:CC CC_REGNUM))]
8980 [(set_attr "conds" "clob")
8981 (set_attr "length" "12")]
8984 (define_insn "*if_arith_not"
8985 [(set (match_operand:SI 0 "s_register_operand" "=r")
8987 (match_operator 5 "arm_comparison_operator"
8988 [(match_operand 4 "cc_register" "") (const_int 0)])
8989 (match_operator:SI 6 "shiftable_operator"
8990 [(match_operand:SI 2 "s_register_operand" "r")
8991 (match_operand:SI 3 "arm_rhs_operand" "rI")])
8992 (not:SI (match_operand:SI 1 "s_register_operand" "r"))))]
8994 "mvn%D5\\t%0, %1\;%I6%d5\\t%0, %2, %3"
8995 [(set_attr "conds" "use")
8996 (set_attr "length" "8")]
8999 (define_insn "*ifcompare_neg_move"
9000 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9002 (match_operator 5 "arm_comparison_operator"
9003 [(match_operand:SI 3 "s_register_operand" "r,r")
9004 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
9005 (neg:SI (match_operand:SI 2 "s_register_operand" "r,r"))
9006 (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
9007 (clobber (reg:CC CC_REGNUM))]
9010 [(set_attr "conds" "clob")
9011 (set_attr "length" "8,12")]
9014 (define_insn "*if_neg_move"
9015 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9017 (match_operator 4 "arm_comparison_operator"
9018 [(match_operand 3 "cc_register" "") (const_int 0)])
9019 (neg:SI (match_operand:SI 2 "s_register_operand" "r,r,r"))
9020 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")))]
9024 mov%D4\\t%0, %1\;rsb%d4\\t%0, %2, #0
9025 mvn%D4\\t%0, #%B1\;rsb%d4\\t%0, %2, #0"
9026 [(set_attr "conds" "use")
9027 (set_attr "length" "4,8,8")]
9030 (define_insn "*ifcompare_move_neg"
9031 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9033 (match_operator 5 "arm_comparison_operator"
9034 [(match_operand:SI 3 "s_register_operand" "r,r")
9035 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
9036 (match_operand:SI 1 "arm_not_operand" "0,?rIK")
9037 (neg:SI (match_operand:SI 2 "s_register_operand" "r,r"))))
9038 (clobber (reg:CC CC_REGNUM))]
9041 [(set_attr "conds" "clob")
9042 (set_attr "length" "8,12")]
9045 (define_insn "*if_move_neg"
9046 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9048 (match_operator 4 "arm_comparison_operator"
9049 [(match_operand 3 "cc_register" "") (const_int 0)])
9050 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")
9051 (neg:SI (match_operand:SI 2 "s_register_operand" "r,r,r"))))]
9055 mov%d4\\t%0, %1\;rsb%D4\\t%0, %2, #0
9056 mvn%d4\\t%0, #%B1\;rsb%D4\\t%0, %2, #0"
9057 [(set_attr "conds" "use")
9058 (set_attr "length" "4,8,8")]
9061 (define_insn "*arith_adjacentmem"
9062 [(set (match_operand:SI 0 "s_register_operand" "=r")
9063 (match_operator:SI 1 "shiftable_operator"
9064 [(match_operand:SI 2 "memory_operand" "m")
9065 (match_operand:SI 3 "memory_operand" "m")]))
9066 (clobber (match_scratch:SI 4 "=r"))]
9067 "TARGET_ARM && adjacent_mem_locations (operands[2], operands[3])"
9072 int val1 = 0, val2 = 0;
9074 if (REGNO (operands[0]) > REGNO (operands[4]))
9076 ldm[1] = operands[4];
9077 ldm[2] = operands[0];
9081 ldm[1] = operands[0];
9082 ldm[2] = operands[4];
9084 if (GET_CODE (XEXP (operands[2], 0)) != REG)
9085 val1 = INTVAL (XEXP (XEXP (operands[2], 0), 1));
9086 if (GET_CODE (XEXP (operands[3], 0)) != REG)
9087 val2 = INTVAL (XEXP (XEXP (operands[3], 0), 1));
9088 arith[0] = operands[0];
9089 arith[3] = operands[1];
9103 ldm[0] = ops[0] = operands[4];
9104 ops[1] = XEXP (XEXP (operands[2], 0), 0);
9105 ops[2] = XEXP (XEXP (operands[2], 0), 1);
9106 output_add_immediate (ops);
9108 output_asm_insn (\"ldm%?ia\\t%0, {%1, %2}\", ldm);
9110 output_asm_insn (\"ldm%?da\\t%0, {%1, %2}\", ldm);
9114 ldm[0] = XEXP (operands[3], 0);
9116 output_asm_insn (\"ldm%?da\\t%0, {%1, %2}\", ldm);
9118 output_asm_insn (\"ldm%?ia\\t%0, {%1, %2}\", ldm);
9122 ldm[0] = XEXP (operands[2], 0);
9124 output_asm_insn (\"ldm%?ia\\t%0, {%1, %2}\", ldm);
9126 output_asm_insn (\"ldm%?da\\t%0, {%1, %2}\", ldm);
9128 output_asm_insn (\"%I3%?\\t%0, %1, %2\", arith);
9131 [(set_attr "length" "12")
9132 (set_attr "predicable" "yes")
9133 (set_attr "type" "load1")]
9136 ;; the arm can support extended pre-inc instructions
9138 ;; In all these cases, we use operands 0 and 1 for the register being
9139 ;; incremented because those are the operands that local-alloc will
9140 ;; tie and these are the pair most likely to be tieable (and the ones
9141 ;; that will benefit the most).
9143 ;; We reject the frame pointer if it occurs anywhere in these patterns since
9144 ;; elimination will cause too many headaches.
9146 (define_insn "*strqi_preinc"
9147 [(set (mem:QI (plus:SI (match_operand:SI 1 "s_register_operand" "%0")
9148 (match_operand:SI 2 "index_operand" "rJ")))
9149 (match_operand:QI 3 "s_register_operand" "r"))
9150 (set (match_operand:SI 0 "s_register_operand" "=r")
9151 (plus:SI (match_dup 1) (match_dup 2)))]
9153 && REGNO (operands[0]) != FRAME_POINTER_REGNUM
9154 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
9155 && (GET_CODE (operands[2]) != REG
9156 || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
9157 "str%?b\\t%3, [%0, %2]!"
9158 [(set_attr "type" "store1")
9159 (set_attr "predicable" "yes")]
9162 (define_insn "*strqi_predec"
9163 [(set (mem:QI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
9164 (match_operand:SI 2 "s_register_operand" "r")))
9165 (match_operand:QI 3 "s_register_operand" "r"))
9166 (set (match_operand:SI 0 "s_register_operand" "=r")
9167 (minus:SI (match_dup 1) (match_dup 2)))]
9169 && REGNO (operands[0]) != FRAME_POINTER_REGNUM
9170 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
9171 && (GET_CODE (operands[2]) != REG
9172 || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
9173 "str%?b\\t%3, [%0, -%2]!"
9174 [(set_attr "type" "store1")
9175 (set_attr "predicable" "yes")]
9178 (define_insn "*loadqi_preinc"
9179 [(set (match_operand:QI 3 "s_register_operand" "=r")
9180 (mem:QI (plus:SI (match_operand:SI 1 "s_register_operand" "%0")
9181 (match_operand:SI 2 "index_operand" "rJ"))))
9182 (set (match_operand:SI 0 "s_register_operand" "=r")
9183 (plus:SI (match_dup 1) (match_dup 2)))]
9185 && REGNO (operands[0]) != FRAME_POINTER_REGNUM
9186 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
9187 && (GET_CODE (operands[2]) != REG
9188 || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
9189 "ldr%?b\\t%3, [%0, %2]!"
9190 [(set_attr "type" "load_byte")
9191 (set_attr "predicable" "yes")]
9194 (define_insn "*loadqi_predec"
9195 [(set (match_operand:QI 3 "s_register_operand" "=r")
9196 (mem:QI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
9197 (match_operand:SI 2 "s_register_operand" "r"))))
9198 (set (match_operand:SI 0 "s_register_operand" "=r")
9199 (minus:SI (match_dup 1) (match_dup 2)))]
9201 && REGNO (operands[0]) != FRAME_POINTER_REGNUM
9202 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
9203 && (GET_CODE (operands[2]) != REG
9204 || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
9205 "ldr%?b\\t%3, [%0, -%2]!"
9206 [(set_attr "type" "load_byte")
9207 (set_attr "predicable" "yes")]
9210 (define_insn "*loadqisi_preinc"
9211 [(set (match_operand:SI 3 "s_register_operand" "=r")
9213 (mem:QI (plus:SI (match_operand:SI 1 "s_register_operand" "%0")
9214 (match_operand:SI 2 "index_operand" "rJ")))))
9215 (set (match_operand:SI 0 "s_register_operand" "=r")
9216 (plus:SI (match_dup 1) (match_dup 2)))]
9218 && REGNO (operands[0]) != FRAME_POINTER_REGNUM
9219 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
9220 && (GET_CODE (operands[2]) != REG
9221 || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
9222 "ldr%?b\\t%3, [%0, %2]!\\t%@ z_extendqisi"
9223 [(set_attr "type" "load_byte")
9224 (set_attr "predicable" "yes")]
9227 (define_insn "*loadqisi_predec"
9228 [(set (match_operand:SI 3 "s_register_operand" "=r")
9230 (mem:QI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
9231 (match_operand:SI 2 "s_register_operand" "r")))))
9232 (set (match_operand:SI 0 "s_register_operand" "=r")
9233 (minus:SI (match_dup 1) (match_dup 2)))]
9235 && REGNO (operands[0]) != FRAME_POINTER_REGNUM
9236 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
9237 && (GET_CODE (operands[2]) != REG
9238 || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
9239 "ldr%?b\\t%3, [%0, -%2]!\\t%@ z_extendqisi"
9240 [(set_attr "type" "load_byte")
9241 (set_attr "predicable" "yes")]
9244 (define_insn "*strsi_preinc"
9245 [(set (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "%0")
9246 (match_operand:SI 2 "index_operand" "rJ")))
9247 (match_operand:SI 3 "s_register_operand" "r"))
9248 (set (match_operand:SI 0 "s_register_operand" "=r")
9249 (plus:SI (match_dup 1) (match_dup 2)))]
9251 && REGNO (operands[0]) != FRAME_POINTER_REGNUM
9252 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
9253 && (GET_CODE (operands[2]) != REG
9254 || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
9255 "str%?\\t%3, [%0, %2]!"
9256 [(set_attr "type" "store1")
9257 (set_attr "predicable" "yes")]
9260 (define_insn "*strsi_predec"
9261 [(set (mem:SI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
9262 (match_operand:SI 2 "s_register_operand" "r")))
9263 (match_operand:SI 3 "s_register_operand" "r"))
9264 (set (match_operand:SI 0 "s_register_operand" "=r")
9265 (minus:SI (match_dup 1) (match_dup 2)))]
9267 && REGNO (operands[0]) != FRAME_POINTER_REGNUM
9268 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
9269 && (GET_CODE (operands[2]) != REG
9270 || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
9271 "str%?\\t%3, [%0, -%2]!"
9272 [(set_attr "type" "store1")
9273 (set_attr "predicable" "yes")]
9276 (define_insn "*loadsi_preinc"
9277 [(set (match_operand:SI 3 "s_register_operand" "=r")
9278 (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "%0")
9279 (match_operand:SI 2 "index_operand" "rJ"))))
9280 (set (match_operand:SI 0 "s_register_operand" "=r")
9281 (plus:SI (match_dup 1) (match_dup 2)))]
9283 && REGNO (operands[0]) != FRAME_POINTER_REGNUM
9284 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
9285 && (GET_CODE (operands[2]) != REG
9286 || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
9287 "ldr%?\\t%3, [%0, %2]!"
9288 [(set_attr "type" "load1")
9289 (set_attr "predicable" "yes")]
9292 (define_insn "*loadsi_predec"
9293 [(set (match_operand:SI 3 "s_register_operand" "=r")
9294 (mem:SI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
9295 (match_operand:SI 2 "s_register_operand" "r"))))
9296 (set (match_operand:SI 0 "s_register_operand" "=r")
9297 (minus:SI (match_dup 1) (match_dup 2)))]
9299 && REGNO (operands[0]) != FRAME_POINTER_REGNUM
9300 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
9301 && (GET_CODE (operands[2]) != REG
9302 || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
9303 "ldr%?\\t%3, [%0, -%2]!"
9304 [(set_attr "type" "load1")
9305 (set_attr "predicable" "yes")]
9308 (define_insn "*loadhi_preinc"
9309 [(set (match_operand:HI 3 "s_register_operand" "=r")
9310 (mem:HI (plus:SI (match_operand:SI 1 "s_register_operand" "%0")
9311 (match_operand:SI 2 "index_operand" "rJ"))))
9312 (set (match_operand:SI 0 "s_register_operand" "=r")
9313 (plus:SI (match_dup 1) (match_dup 2)))]
9315 && !BYTES_BIG_ENDIAN
9316 && !TARGET_MMU_TRAPS
9318 && REGNO (operands[0]) != FRAME_POINTER_REGNUM
9319 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
9320 && (GET_CODE (operands[2]) != REG
9321 || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
9322 "ldr%?\\t%3, [%0, %2]!\\t%@ loadhi"
9323 [(set_attr "type" "load_byte")
9324 (set_attr "predicable" "yes")]
9327 (define_insn "*loadhi_predec"
9328 [(set (match_operand:HI 3 "s_register_operand" "=r")
9329 (mem:HI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
9330 (match_operand:SI 2 "s_register_operand" "r"))))
9331 (set (match_operand:SI 0 "s_register_operand" "=r")
9332 (minus:SI (match_dup 1) (match_dup 2)))]
9334 && !BYTES_BIG_ENDIAN
9335 && !TARGET_MMU_TRAPS
9337 && REGNO (operands[0]) != FRAME_POINTER_REGNUM
9338 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
9339 && (GET_CODE (operands[2]) != REG
9340 || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
9341 "ldr%?\\t%3, [%0, -%2]!\\t%@ loadhi"
9342 [(set_attr "type" "load_byte")
9343 (set_attr "predicable" "yes")]
9346 (define_insn "*strqi_shiftpreinc"
9347 [(set (mem:QI (plus:SI (match_operator:SI 2 "shift_operator"
9348 [(match_operand:SI 3 "s_register_operand" "r")
9349 (match_operand:SI 4 "const_shift_operand" "n")])
9350 (match_operand:SI 1 "s_register_operand" "0")))
9351 (match_operand:QI 5 "s_register_operand" "r"))
9352 (set (match_operand:SI 0 "s_register_operand" "=r")
9353 (plus:SI (match_op_dup 2 [(match_dup 3) (match_dup 4)])
9356 && REGNO (operands[0]) != FRAME_POINTER_REGNUM
9357 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
9358 && REGNO (operands[3]) != FRAME_POINTER_REGNUM"
9359 "str%?b\\t%5, [%0, %3%S2]!"
9360 [(set_attr "type" "store1")
9361 (set_attr "predicable" "yes")]
9364 (define_insn "*strqi_shiftpredec"
9365 [(set (mem:QI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
9366 (match_operator:SI 2 "shift_operator"
9367 [(match_operand:SI 3 "s_register_operand" "r")
9368 (match_operand:SI 4 "const_shift_operand" "n")])))
9369 (match_operand:QI 5 "s_register_operand" "r"))
9370 (set (match_operand:SI 0 "s_register_operand" "=r")
9371 (minus:SI (match_dup 1) (match_op_dup 2 [(match_dup 3)
9374 && REGNO (operands[0]) != FRAME_POINTER_REGNUM
9375 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
9376 && REGNO (operands[3]) != FRAME_POINTER_REGNUM"
9377 "str%?b\\t%5, [%0, -%3%S2]!"
9378 [(set_attr "type" "store1")
9379 (set_attr "predicable" "yes")]
9382 (define_insn "*loadqi_shiftpreinc"
9383 [(set (match_operand:QI 5 "s_register_operand" "=r")
9384 (mem:QI (plus:SI (match_operator:SI 2 "shift_operator"
9385 [(match_operand:SI 3 "s_register_operand" "r")
9386 (match_operand:SI 4 "const_shift_operand" "n")])
9387 (match_operand:SI 1 "s_register_operand" "0"))))
9388 (set (match_operand:SI 0 "s_register_operand" "=r")
9389 (plus:SI (match_op_dup 2 [(match_dup 3) (match_dup 4)])
9392 && REGNO (operands[0]) != FRAME_POINTER_REGNUM
9393 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
9394 && REGNO (operands[3]) != FRAME_POINTER_REGNUM"
9395 "ldr%?b\\t%5, [%0, %3%S2]!"
9396 [(set_attr "type" "load_byte")
9397 (set_attr "predicable" "yes")]
9400 (define_insn "*loadqi_shiftpredec"
9401 [(set (match_operand:QI 5 "s_register_operand" "=r")
9402 (mem:QI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
9403 (match_operator:SI 2 "shift_operator"
9404 [(match_operand:SI 3 "s_register_operand" "r")
9405 (match_operand:SI 4 "const_shift_operand" "n")]))))
9406 (set (match_operand:SI 0 "s_register_operand" "=r")
9407 (minus:SI (match_dup 1) (match_op_dup 2 [(match_dup 3)
9410 && REGNO (operands[0]) != FRAME_POINTER_REGNUM
9411 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
9412 && REGNO (operands[3]) != FRAME_POINTER_REGNUM"
9413 "ldr%?b\\t%5, [%0, -%3%S2]!"
9414 [(set_attr "type" "load_byte")
9415 (set_attr "predicable" "yes")]
9418 (define_insn "*strsi_shiftpreinc"
9419 [(set (mem:SI (plus:SI (match_operator:SI 2 "shift_operator"
9420 [(match_operand:SI 3 "s_register_operand" "r")
9421 (match_operand:SI 4 "const_shift_operand" "n")])
9422 (match_operand:SI 1 "s_register_operand" "0")))
9423 (match_operand:SI 5 "s_register_operand" "r"))
9424 (set (match_operand:SI 0 "s_register_operand" "=r")
9425 (plus:SI (match_op_dup 2 [(match_dup 3) (match_dup 4)])
9428 && REGNO (operands[0]) != FRAME_POINTER_REGNUM
9429 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
9430 && REGNO (operands[3]) != FRAME_POINTER_REGNUM"
9431 "str%?\\t%5, [%0, %3%S2]!"
9432 [(set_attr "type" "store1")
9433 (set_attr "predicable" "yes")]
9436 (define_insn "*strsi_shiftpredec"
9437 [(set (mem:SI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
9438 (match_operator:SI 2 "shift_operator"
9439 [(match_operand:SI 3 "s_register_operand" "r")
9440 (match_operand:SI 4 "const_shift_operand" "n")])))
9441 (match_operand:SI 5 "s_register_operand" "r"))
9442 (set (match_operand:SI 0 "s_register_operand" "=r")
9443 (minus:SI (match_dup 1) (match_op_dup 2 [(match_dup 3)
9446 && REGNO (operands[0]) != FRAME_POINTER_REGNUM
9447 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
9448 && REGNO (operands[3]) != FRAME_POINTER_REGNUM"
9449 "str%?\\t%5, [%0, -%3%S2]!"
9450 [(set_attr "type" "store1")
9451 (set_attr "predicable" "yes")]
9454 (define_insn "*loadsi_shiftpreinc"
9455 [(set (match_operand:SI 5 "s_register_operand" "=r")
9456 (mem:SI (plus:SI (match_operator:SI 2 "shift_operator"
9457 [(match_operand:SI 3 "s_register_operand" "r")
9458 (match_operand:SI 4 "const_shift_operand" "n")])
9459 (match_operand:SI 1 "s_register_operand" "0"))))
9460 (set (match_operand:SI 0 "s_register_operand" "=r")
9461 (plus:SI (match_op_dup 2 [(match_dup 3) (match_dup 4)])
9464 && REGNO (operands[0]) != FRAME_POINTER_REGNUM
9465 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
9466 && REGNO (operands[3]) != FRAME_POINTER_REGNUM"
9467 "ldr%?\\t%5, [%0, %3%S2]!"
9468 [(set_attr "type" "load1")
9469 (set_attr "predicable" "yes")]
9472 (define_insn "*loadsi_shiftpredec"
9473 [(set (match_operand:SI 5 "s_register_operand" "=r")
9474 (mem:SI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
9475 (match_operator:SI 2 "shift_operator"
9476 [(match_operand:SI 3 "s_register_operand" "r")
9477 (match_operand:SI 4 "const_shift_operand" "n")]))))
9478 (set (match_operand:SI 0 "s_register_operand" "=r")
9479 (minus:SI (match_dup 1) (match_op_dup 2 [(match_dup 3)
9482 && REGNO (operands[0]) != FRAME_POINTER_REGNUM
9483 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
9484 && REGNO (operands[3]) != FRAME_POINTER_REGNUM"
9485 "ldr%?\\t%5, [%0, -%3%S2]!"
9486 [(set_attr "type" "load1")
9487 (set_attr "predicable" "yes")])
9489 (define_insn "*loadhi_shiftpreinc"
9490 [(set (match_operand:HI 5 "s_register_operand" "=r")
9491 (mem:HI (plus:SI (match_operator:SI 2 "shift_operator"
9492 [(match_operand:SI 3 "s_register_operand" "r")
9493 (match_operand:SI 4 "const_shift_operand" "n")])
9494 (match_operand:SI 1 "s_register_operand" "0"))))
9495 (set (match_operand:SI 0 "s_register_operand" "=r")
9496 (plus:SI (match_op_dup 2 [(match_dup 3) (match_dup 4)])
9499 && !BYTES_BIG_ENDIAN
9500 && !TARGET_MMU_TRAPS
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]!\\t%@ loadhi"
9506 [(set_attr "type" "load_byte")
9507 (set_attr "predicable" "yes")]
9510 (define_insn "*loadhi_shiftpredec"
9511 [(set (match_operand:HI 5 "s_register_operand" "=r")
9512 (mem:HI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
9513 (match_operator:SI 2 "shift_operator"
9514 [(match_operand:SI 3 "s_register_operand" "r")
9515 (match_operand:SI 4 "const_shift_operand" "n")]))))
9516 (set (match_operand:SI 0 "s_register_operand" "=r")
9517 (minus:SI (match_dup 1) (match_op_dup 2 [(match_dup 3)
9520 && !BYTES_BIG_ENDIAN
9521 && !TARGET_MMU_TRAPS
9523 && REGNO (operands[0]) != FRAME_POINTER_REGNUM
9524 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
9525 && REGNO (operands[3]) != FRAME_POINTER_REGNUM"
9526 "ldr%?\\t%5, [%0, -%3%S2]!\\t%@ loadhi"
9527 [(set_attr "type" "load_byte")
9528 (set_attr "predicable" "yes")]
9531 ; It can also support extended post-inc expressions, but combine doesn't
9533 ; It doesn't seem worth adding peepholes for anything but the most common
9534 ; cases since, unlike combine, the increment must immediately follow the load
9535 ; for this pattern to match.
9536 ; We must watch to see that the source/destination register isn't also the
9537 ; same as the base address register, and that if the index is a register,
9538 ; that it is not the same as the base address register. In such cases the
9539 ; instruction that we would generate would have UNPREDICTABLE behavior so
9543 [(set (mem:QI (match_operand:SI 0 "s_register_operand" "+r"))
9544 (match_operand:QI 2 "s_register_operand" "r"))
9546 (plus:SI (match_dup 0) (match_operand:SI 1 "index_operand" "rJ")))]
9548 && (REGNO (operands[2]) != REGNO (operands[0]))
9549 && (GET_CODE (operands[1]) != REG
9550 || (REGNO (operands[1]) != REGNO (operands[0])))"
9551 "str%?b\\t%2, [%0], %1"
9555 [(set (match_operand:QI 0 "s_register_operand" "=r")
9556 (mem:QI (match_operand:SI 1 "s_register_operand" "+r")))
9558 (plus:SI (match_dup 1) (match_operand:SI 2 "index_operand" "rJ")))]
9560 && REGNO (operands[0]) != REGNO(operands[1])
9561 && (GET_CODE (operands[2]) != REG
9562 || REGNO(operands[0]) != REGNO (operands[2]))"
9563 "ldr%?b\\t%0, [%1], %2"
9567 [(set (mem:SI (match_operand:SI 0 "s_register_operand" "+r"))
9568 (match_operand:SI 2 "s_register_operand" "r"))
9570 (plus:SI (match_dup 0) (match_operand:SI 1 "index_operand" "rJ")))]
9572 && (REGNO (operands[2]) != REGNO (operands[0]))
9573 && (GET_CODE (operands[1]) != REG
9574 || (REGNO (operands[1]) != REGNO (operands[0])))"
9575 "str%?\\t%2, [%0], %1"
9579 [(set (match_operand:HI 0 "s_register_operand" "=r")
9580 (mem:HI (match_operand:SI 1 "s_register_operand" "+r")))
9582 (plus:SI (match_dup 1) (match_operand:SI 2 "index_operand" "rJ")))]
9584 && !BYTES_BIG_ENDIAN
9585 && !TARGET_MMU_TRAPS
9587 && REGNO (operands[0]) != REGNO(operands[1])
9588 && (GET_CODE (operands[2]) != REG
9589 || REGNO(operands[0]) != REGNO (operands[2]))"
9590 "ldr%?\\t%0, [%1], %2\\t%@ loadhi"
9594 [(set (match_operand:SI 0 "s_register_operand" "=r")
9595 (mem:SI (match_operand:SI 1 "s_register_operand" "+r")))
9597 (plus:SI (match_dup 1) (match_operand:SI 2 "index_operand" "rJ")))]
9599 && REGNO (operands[0]) != REGNO(operands[1])
9600 && (GET_CODE (operands[2]) != REG
9601 || REGNO(operands[0]) != REGNO (operands[2]))"
9602 "ldr%?\\t%0, [%1], %2"
9606 [(set (mem:QI (plus:SI (match_operand:SI 0 "s_register_operand" "+r")
9607 (match_operand:SI 1 "index_operand" "rJ")))
9608 (match_operand:QI 2 "s_register_operand" "r"))
9609 (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))]
9611 && (REGNO (operands[2]) != REGNO (operands[0]))
9612 && (GET_CODE (operands[1]) != REG
9613 || (REGNO (operands[1]) != REGNO (operands[0])))"
9614 "str%?b\\t%2, [%0, %1]!"
9618 [(set (mem:QI (plus:SI (match_operator:SI 4 "shift_operator"
9619 [(match_operand:SI 0 "s_register_operand" "r")
9620 (match_operand:SI 1 "const_int_operand" "n")])
9621 (match_operand:SI 2 "s_register_operand" "+r")))
9622 (match_operand:QI 3 "s_register_operand" "r"))
9623 (set (match_dup 2) (plus:SI (match_op_dup 4 [(match_dup 0) (match_dup 1)])
9626 && (REGNO (operands[3]) != REGNO (operands[2]))
9627 && (REGNO (operands[0]) != REGNO (operands[2]))"
9628 "str%?b\\t%3, [%2, %0%S4]!"
9631 ; This pattern is never tried by combine, so do it as a peephole
9634 [(set (match_operand:SI 0 "s_register_operand" "")
9635 (match_operand:SI 1 "s_register_operand" ""))
9636 (set (reg:CC CC_REGNUM)
9637 (compare:CC (match_dup 1) (const_int 0)))]
9639 && (!(TARGET_HARD_FLOAT && TARGET_MAVERICK)
9640 || (!cirrus_fp_register (operands[0], SImode)
9641 && !cirrus_fp_register (operands[1], SImode)))
9643 [(parallel [(set (reg:CC CC_REGNUM) (compare:CC (match_dup 1) (const_int 0)))
9644 (set (match_dup 0) (match_dup 1))])]
9648 ; Peepholes to spot possible load- and store-multiples, if the ordering is
9649 ; reversed, check that the memory references aren't volatile.
9652 [(set (match_operand:SI 0 "s_register_operand" "=r")
9653 (match_operand:SI 4 "memory_operand" "m"))
9654 (set (match_operand:SI 1 "s_register_operand" "=r")
9655 (match_operand:SI 5 "memory_operand" "m"))
9656 (set (match_operand:SI 2 "s_register_operand" "=r")
9657 (match_operand:SI 6 "memory_operand" "m"))
9658 (set (match_operand:SI 3 "s_register_operand" "=r")
9659 (match_operand:SI 7 "memory_operand" "m"))]
9660 "TARGET_ARM && load_multiple_sequence (operands, 4, NULL, NULL, NULL)"
9662 return emit_ldm_seq (operands, 4);
9667 [(set (match_operand:SI 0 "s_register_operand" "=r")
9668 (match_operand:SI 3 "memory_operand" "m"))
9669 (set (match_operand:SI 1 "s_register_operand" "=r")
9670 (match_operand:SI 4 "memory_operand" "m"))
9671 (set (match_operand:SI 2 "s_register_operand" "=r")
9672 (match_operand:SI 5 "memory_operand" "m"))]
9673 "TARGET_ARM && load_multiple_sequence (operands, 3, NULL, NULL, NULL)"
9675 return emit_ldm_seq (operands, 3);
9680 [(set (match_operand:SI 0 "s_register_operand" "=r")
9681 (match_operand:SI 2 "memory_operand" "m"))
9682 (set (match_operand:SI 1 "s_register_operand" "=r")
9683 (match_operand:SI 3 "memory_operand" "m"))]
9684 "TARGET_ARM && load_multiple_sequence (operands, 2, NULL, NULL, NULL)"
9686 return emit_ldm_seq (operands, 2);
9691 [(set (match_operand:SI 4 "memory_operand" "=m")
9692 (match_operand:SI 0 "s_register_operand" "r"))
9693 (set (match_operand:SI 5 "memory_operand" "=m")
9694 (match_operand:SI 1 "s_register_operand" "r"))
9695 (set (match_operand:SI 6 "memory_operand" "=m")
9696 (match_operand:SI 2 "s_register_operand" "r"))
9697 (set (match_operand:SI 7 "memory_operand" "=m")
9698 (match_operand:SI 3 "s_register_operand" "r"))]
9699 "TARGET_ARM && store_multiple_sequence (operands, 4, NULL, NULL, NULL)"
9701 return emit_stm_seq (operands, 4);
9706 [(set (match_operand:SI 3 "memory_operand" "=m")
9707 (match_operand:SI 0 "s_register_operand" "r"))
9708 (set (match_operand:SI 4 "memory_operand" "=m")
9709 (match_operand:SI 1 "s_register_operand" "r"))
9710 (set (match_operand:SI 5 "memory_operand" "=m")
9711 (match_operand:SI 2 "s_register_operand" "r"))]
9712 "TARGET_ARM && store_multiple_sequence (operands, 3, NULL, NULL, NULL)"
9714 return emit_stm_seq (operands, 3);
9719 [(set (match_operand:SI 2 "memory_operand" "=m")
9720 (match_operand:SI 0 "s_register_operand" "r"))
9721 (set (match_operand:SI 3 "memory_operand" "=m")
9722 (match_operand:SI 1 "s_register_operand" "r"))]
9723 "TARGET_ARM && store_multiple_sequence (operands, 2, NULL, NULL, NULL)"
9725 return emit_stm_seq (operands, 2);
9730 [(set (match_operand:SI 0 "s_register_operand" "")
9731 (and:SI (ge:SI (match_operand:SI 1 "s_register_operand" "")
9733 (neg:SI (match_operator:SI 2 "arm_comparison_operator"
9734 [(match_operand:SI 3 "s_register_operand" "")
9735 (match_operand:SI 4 "arm_rhs_operand" "")]))))
9736 (clobber (match_operand:SI 5 "s_register_operand" ""))]
9738 [(set (match_dup 5) (not:SI (ashiftrt:SI (match_dup 1) (const_int 31))))
9739 (set (match_dup 0) (and:SI (match_op_dup 2 [(match_dup 3) (match_dup 4)])
9744 ;; This split can be used because CC_Z mode implies that the following
9745 ;; branch will be an equality, or an unsigned inequality, so the sign
9746 ;; extension is not needed.
9749 [(set (reg:CC_Z CC_REGNUM)
9751 (ashift:SI (subreg:SI (match_operand:QI 0 "memory_operand" "") 0)
9753 (match_operand 1 "const_int_operand" "")))
9754 (clobber (match_scratch:SI 2 ""))]
9756 && (((unsigned HOST_WIDE_INT) INTVAL (operands[1]))
9757 == (((unsigned HOST_WIDE_INT) INTVAL (operands[1])) >> 24) << 24)"
9758 [(set (match_dup 2) (zero_extend:SI (match_dup 0)))
9759 (set (reg:CC CC_REGNUM) (compare:CC (match_dup 2) (match_dup 1)))]
9761 operands[1] = GEN_INT (((unsigned long) INTVAL (operands[1])) >> 24);
9765 (define_expand "prologue"
9766 [(clobber (const_int 0))]
9769 arm_expand_prologue ();
9771 thumb_expand_prologue ();
9776 (define_expand "epilogue"
9777 [(unspec_volatile [(return)] VUNSPEC_EPILOGUE)]
9781 thumb_expand_epilogue ();
9782 else if (USE_RETURN_INSN (FALSE))
9784 emit_jump_insn (gen_return ());
9787 emit_jump_insn (gen_rtx_UNSPEC_VOLATILE (VOIDmode,
9789 gen_rtx_RETURN (VOIDmode)),
9795 ;; Note - although unspec_volatile's USE all hard registers,
9796 ;; USEs are ignored after relaod has completed. Thus we need
9797 ;; to add an unspec of the link register to ensure that flow
9798 ;; does not think that it is unused by the sibcall branch that
9799 ;; will replace the standard function epilogue.
9800 (define_insn "sibcall_epilogue"
9801 [(parallel [(unspec:SI [(reg:SI LR_REGNUM)] UNSPEC_PROLOGUE_USE)
9802 (unspec_volatile [(return)] VUNSPEC_EPILOGUE)])]
9805 if (use_return_insn (FALSE, next_nonnote_insn (insn)))
9806 return output_return_instruction (const_true_rtx, FALSE, FALSE);
9807 return arm_output_epilogue (next_nonnote_insn (insn));
9809 ;; Length is absolute worst case
9810 [(set_attr "length" "44")
9811 (set_attr "type" "block")
9812 ;; We don't clobber the conditions, but the potential length of this
9813 ;; operation is sufficient to make conditionalizing the sequence
9814 ;; unlikely to be profitable.
9815 (set_attr "conds" "clob")]
9818 (define_insn "*epilogue_insns"
9819 [(unspec_volatile [(return)] VUNSPEC_EPILOGUE)]
9823 return arm_output_epilogue (NULL);
9824 else /* TARGET_THUMB */
9825 return thumb_unexpanded_epilogue ();
9827 ; Length is absolute worst case
9828 [(set_attr "length" "44")
9829 (set_attr "type" "block")
9830 ;; We don't clobber the conditions, but the potential length of this
9831 ;; operation is sufficient to make conditionalizing the sequence
9832 ;; unlikely to be profitable.
9833 (set_attr "conds" "clob")]
9836 (define_expand "eh_epilogue"
9837 [(use (match_operand:SI 0 "register_operand" ""))
9838 (use (match_operand:SI 1 "register_operand" ""))
9839 (use (match_operand:SI 2 "register_operand" ""))]
9843 cfun->machine->eh_epilogue_sp_ofs = operands[1];
9844 if (GET_CODE (operands[2]) != REG || REGNO (operands[2]) != 2)
9846 rtx ra = gen_rtx_REG (Pmode, 2);
9848 emit_move_insn (ra, operands[2]);
9851 /* This is a hack -- we may have crystalized the function type too
9853 cfun->machine->func_type = 0;
9857 ;; This split is only used during output to reduce the number of patterns
9858 ;; that need assembler instructions adding to them. We allowed the setting
9859 ;; of the conditions to be implicit during rtl generation so that
9860 ;; the conditional compare patterns would work. However this conflicts to
9861 ;; some extent with the conditional data operations, so we have to split them
9865 [(set (match_operand:SI 0 "s_register_operand" "")
9866 (if_then_else:SI (match_operator 1 "arm_comparison_operator"
9867 [(match_operand 2 "" "") (match_operand 3 "" "")])
9869 (match_operand 4 "" "")))
9870 (clobber (reg:CC CC_REGNUM))]
9871 "TARGET_ARM && reload_completed"
9872 [(set (match_dup 5) (match_dup 6))
9873 (cond_exec (match_dup 7)
9874 (set (match_dup 0) (match_dup 4)))]
9877 enum machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
9878 operands[2], operands[3]);
9879 enum rtx_code rc = GET_CODE (operands[1]);
9881 operands[5] = gen_rtx_REG (mode, CC_REGNUM);
9882 operands[6] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
9883 if (mode == CCFPmode || mode == CCFPEmode)
9884 rc = reverse_condition_maybe_unordered (rc);
9886 rc = reverse_condition (rc);
9888 operands[7] = gen_rtx_fmt_ee (rc, VOIDmode, operands[5], const0_rtx);
9893 [(set (match_operand:SI 0 "s_register_operand" "")
9894 (if_then_else:SI (match_operator 1 "arm_comparison_operator"
9895 [(match_operand 2 "" "") (match_operand 3 "" "")])
9896 (match_operand 4 "" "")
9898 (clobber (reg:CC CC_REGNUM))]
9899 "TARGET_ARM && reload_completed"
9900 [(set (match_dup 5) (match_dup 6))
9901 (cond_exec (match_op_dup 1 [(match_dup 5) (const_int 0)])
9902 (set (match_dup 0) (match_dup 4)))]
9905 enum machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
9906 operands[2], operands[3]);
9908 operands[5] = gen_rtx_REG (mode, CC_REGNUM);
9909 operands[6] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
9914 [(set (match_operand:SI 0 "s_register_operand" "")
9915 (if_then_else:SI (match_operator 1 "arm_comparison_operator"
9916 [(match_operand 2 "" "") (match_operand 3 "" "")])
9917 (match_operand 4 "" "")
9918 (match_operand 5 "" "")))
9919 (clobber (reg:CC CC_REGNUM))]
9920 "TARGET_ARM && reload_completed"
9921 [(set (match_dup 6) (match_dup 7))
9922 (cond_exec (match_op_dup 1 [(match_dup 6) (const_int 0)])
9923 (set (match_dup 0) (match_dup 4)))
9924 (cond_exec (match_dup 8)
9925 (set (match_dup 0) (match_dup 5)))]
9928 enum machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
9929 operands[2], operands[3]);
9930 enum rtx_code rc = GET_CODE (operands[1]);
9932 operands[6] = gen_rtx_REG (mode, CC_REGNUM);
9933 operands[7] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
9934 if (mode == CCFPmode || mode == CCFPEmode)
9935 rc = reverse_condition_maybe_unordered (rc);
9937 rc = reverse_condition (rc);
9939 operands[8] = gen_rtx_fmt_ee (rc, VOIDmode, operands[6], const0_rtx);
9944 [(set (match_operand:SI 0 "s_register_operand" "")
9945 (if_then_else:SI (match_operator 1 "arm_comparison_operator"
9946 [(match_operand:SI 2 "s_register_operand" "")
9947 (match_operand:SI 3 "arm_add_operand" "")])
9948 (match_operand:SI 4 "arm_rhs_operand" "")
9950 (match_operand:SI 5 "s_register_operand" ""))))
9951 (clobber (reg:CC CC_REGNUM))]
9952 "TARGET_ARM && reload_completed"
9953 [(set (match_dup 6) (match_dup 7))
9954 (cond_exec (match_op_dup 1 [(match_dup 6) (const_int 0)])
9955 (set (match_dup 0) (match_dup 4)))
9956 (cond_exec (match_dup 8)
9957 (set (match_dup 0) (not:SI (match_dup 5))))]
9960 enum machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
9961 operands[2], operands[3]);
9962 enum rtx_code rc = GET_CODE (operands[1]);
9964 operands[6] = gen_rtx_REG (mode, CC_REGNUM);
9965 operands[7] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
9966 if (mode == CCFPmode || mode == CCFPEmode)
9967 rc = reverse_condition_maybe_unordered (rc);
9969 rc = reverse_condition (rc);
9971 operands[8] = gen_rtx_fmt_ee (rc, VOIDmode, operands[6], const0_rtx);
9975 (define_insn "*cond_move_not"
9976 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9977 (if_then_else:SI (match_operator 4 "arm_comparison_operator"
9978 [(match_operand 3 "cc_register" "") (const_int 0)])
9979 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
9981 (match_operand:SI 2 "s_register_operand" "r,r"))))]
9985 mov%d4\\t%0, %1\;mvn%D4\\t%0, %2"
9986 [(set_attr "conds" "use")
9987 (set_attr "length" "4,8")]
9990 ;; The next two patterns occur when an AND operation is followed by a
9991 ;; scc insn sequence
9993 (define_insn "*sign_extract_onebit"
9994 [(set (match_operand:SI 0 "s_register_operand" "=r")
9995 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
9997 (match_operand:SI 2 "const_int_operand" "n")))
9998 (clobber (reg:CC CC_REGNUM))]
10001 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
10002 output_asm_insn (\"ands\\t%0, %1, %2\", operands);
10003 return \"mvnne\\t%0, #0\";
10005 [(set_attr "conds" "clob")
10006 (set_attr "length" "8")]
10009 (define_insn "*not_signextract_onebit"
10010 [(set (match_operand:SI 0 "s_register_operand" "=r")
10012 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
10014 (match_operand:SI 2 "const_int_operand" "n"))))
10015 (clobber (reg:CC CC_REGNUM))]
10018 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
10019 output_asm_insn (\"tst\\t%1, %2\", operands);
10020 output_asm_insn (\"mvneq\\t%0, #0\", operands);
10021 return \"movne\\t%0, #0\";
10023 [(set_attr "conds" "clob")
10024 (set_attr "length" "12")]
10027 ;; Push multiple registers to the stack. Registers are in parallel (use ...)
10028 ;; expressions. For simplicity, the first register is also in the unspec
10030 (define_insn "*push_multi"
10031 [(match_parallel 2 "multi_register_push"
10032 [(set (match_operand:BLK 0 "memory_operand" "=m")
10033 (unspec:BLK [(match_operand:SI 1 "s_register_operand" "r")]
10034 UNSPEC_PUSH_MULT))])]
10038 int num_saves = XVECLEN (operands[2], 0);
10040 /* For the StrongARM at least it is faster to
10041 use STR to store only a single register. */
10042 if (num_saves == 1)
10043 output_asm_insn (\"str\\t%1, [%m0, #-4]!\", operands);
10049 strcpy (pattern, \"stmfd\\t%m0!, {%1\");
10051 for (i = 1; i < num_saves; i++)
10053 strcat (pattern, \", %|\");
10055 reg_names[REGNO (XEXP (XVECEXP (operands[2], 0, i), 0))]);
10058 strcat (pattern, \"}\");
10059 output_asm_insn (pattern, operands);
10064 [(set_attr "type" "store4")]
10067 (define_insn "stack_tie"
10068 [(set (mem:BLK (scratch))
10069 (unspec:BLK [(match_operand:SI 0 "s_register_operand" "r")
10070 (match_operand:SI 1 "s_register_operand" "r")]
10074 [(set_attr "length" "0")]
10077 ;; Similarly for the floating point registers
10078 (define_insn "*push_fp_multi"
10079 [(match_parallel 2 "multi_register_push"
10080 [(set (match_operand:BLK 0 "memory_operand" "=m")
10081 (unspec:BLK [(match_operand:XF 1 "f_register_operand" "f")]
10082 UNSPEC_PUSH_MULT))])]
10083 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
10088 sprintf (pattern, \"sfmfd\\t%%1, %d, [%%m0]!\", XVECLEN (operands[2], 0));
10089 output_asm_insn (pattern, operands);
10092 [(set_attr "type" "f_store")]
10095 ;; Special patterns for dealing with the constant pool
10097 (define_insn "align_4"
10098 [(unspec_volatile [(const_int 0)] VUNSPEC_ALIGN)]
10101 assemble_align (32);
10106 (define_insn "align_8"
10107 [(unspec_volatile [(const_int 0)] VUNSPEC_ALIGN8)]
10110 assemble_align (64);
10115 (define_insn "consttable_end"
10116 [(unspec_volatile [(const_int 0)] VUNSPEC_POOL_END)]
10119 making_const_table = FALSE;
10124 (define_insn "consttable_1"
10125 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_1)]
10128 making_const_table = TRUE;
10129 assemble_integer (operands[0], 1, BITS_PER_WORD, 1);
10130 assemble_zeros (3);
10133 [(set_attr "length" "4")]
10136 (define_insn "consttable_2"
10137 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_2)]
10140 making_const_table = TRUE;
10141 assemble_integer (operands[0], 2, BITS_PER_WORD, 1);
10142 assemble_zeros (2);
10145 [(set_attr "length" "4")]
10148 (define_insn "consttable_4"
10149 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_4)]
10153 making_const_table = TRUE;
10154 switch (GET_MODE_CLASS (GET_MODE (operands[0])))
10159 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[0]);
10160 assemble_real (r, GET_MODE (operands[0]), BITS_PER_WORD);
10164 assemble_integer (operands[0], 4, BITS_PER_WORD, 1);
10169 [(set_attr "length" "4")]
10172 (define_insn "consttable_8"
10173 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_8)]
10177 making_const_table = TRUE;
10178 switch (GET_MODE_CLASS (GET_MODE (operands[0])))
10183 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[0]);
10184 assemble_real (r, GET_MODE (operands[0]), BITS_PER_WORD);
10188 assemble_integer (operands[0], 8, BITS_PER_WORD, 1);
10193 [(set_attr "length" "8")]
10196 ;; Miscellaneous Thumb patterns
10198 (define_expand "tablejump"
10199 [(parallel [(set (pc) (match_operand:SI 0 "register_operand" ""))
10200 (use (label_ref (match_operand 1 "" "")))])]
10205 /* Hopefully, CSE will eliminate this copy. */
10206 rtx reg1 = copy_addr_to_reg (gen_rtx_LABEL_REF (Pmode, operands[1]));
10207 rtx reg2 = gen_reg_rtx (SImode);
10209 emit_insn (gen_addsi3 (reg2, operands[0], reg1));
10210 operands[0] = reg2;
10215 (define_insn "*thumb_tablejump"
10216 [(set (pc) (match_operand:SI 0 "register_operand" "l*r"))
10217 (use (label_ref (match_operand 1 "" "")))]
10220 [(set_attr "length" "2")]
10223 ;; V5 Instructions,
10225 (define_insn "clzsi2"
10226 [(set (match_operand:SI 0 "s_register_operand" "=r")
10227 (clz:SI (match_operand:SI 1 "s_register_operand" "r")))]
10228 "TARGET_ARM && arm_arch5"
10230 [(set_attr "predicable" "yes")])
10232 (define_expand "ffssi2"
10233 [(set (match_operand:SI 0 "s_register_operand" "")
10234 (ffs:SI (match_operand:SI 1 "s_register_operand" "")))]
10235 "TARGET_ARM && arm_arch5"
10240 t1 = gen_reg_rtx (SImode);
10241 t2 = gen_reg_rtx (SImode);
10242 t3 = gen_reg_rtx (SImode);
10244 emit_insn (gen_negsi2 (t1, operands[1]));
10245 emit_insn (gen_andsi3 (t2, operands[1], t1));
10246 emit_insn (gen_clzsi2 (t3, t2));
10247 emit_insn (gen_subsi3 (operands[0], GEN_INT (32), t3));
10252 (define_expand "ctzsi2"
10253 [(set (match_operand:SI 0 "s_register_operand" "")
10254 (ctz: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 (31), t3));
10272 ;; V5E instructions.
10274 (define_insn "prefetch"
10275 [(prefetch (match_operand:SI 0 "address_operand" "p")
10276 (match_operand:SI 1 "" "")
10277 (match_operand:SI 2 "" ""))]
10278 "TARGET_ARM && arm_arch5e"
10281 ;; General predication pattern
10284 [(match_operator 0 "arm_comparison_operator"
10285 [(match_operand 1 "cc_register" "")
10291 (define_insn "prologue_use"
10292 [(unspec:SI [(match_operand:SI 0 "register_operand" "")] UNSPEC_PROLOGUE_USE)]
10294 "%@ %0 needed for prologue"
10297 ;; Load the FPA co-processor patterns
10299 ;; Load the Maverick co-processor patterns
10300 (include "cirrus.md")
10301 ;; Load the Intel Wireless Multimedia Extension patterns
10302 (include "iwmmxt.md")
10303 ;; Load the VFP co-processor patterns