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, INTVAL (operands[2]), operands[0],
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, INTVAL (operands[2]), operands[0],
500 [(set_attr "length" "4,4,16")
501 (set_attr "predicable" "yes")]
504 ;; Register group 'k' is a single register group containing only the stack
505 ;; register. Trying to reload it will always fail catastrophically,
506 ;; so never allow those alternatives to match if reloading is needed.
508 (define_insn "*thumb_addsi3"
509 [(set (match_operand:SI 0 "register_operand" "=l,l,l,*r,*h,l,!k")
510 (plus:SI (match_operand:SI 1 "register_operand" "%0,0,l,*0,*0,!k,!k")
511 (match_operand:SI 2 "nonmemory_operand" "I,J,lL,*h,*r,!M,!O")))]
514 static const char * const asms[] =
516 \"add\\t%0, %0, %2\",
517 \"sub\\t%0, %0, #%n2\",
518 \"add\\t%0, %1, %2\",
519 \"add\\t%0, %0, %2\",
520 \"add\\t%0, %0, %2\",
521 \"add\\t%0, %1, %2\",
524 if ((which_alternative == 2 || which_alternative == 6)
525 && GET_CODE (operands[2]) == CONST_INT
526 && INTVAL (operands[2]) < 0)
527 return \"sub\\t%0, %1, #%n2\";
528 return asms[which_alternative];
530 [(set_attr "length" "2")]
533 ;; Reloading and elimination of the frame pointer can
534 ;; sometimes cause this optimization to be missed.
536 [(set (match_operand:SI 0 "register_operand" "")
537 (match_operand:SI 1 "const_int_operand" ""))
539 (plus:SI (match_dup 0) (match_operand:SI 2 "register_operand" "")))]
541 && REGNO (operands[2]) == STACK_POINTER_REGNUM
542 && (unsigned HOST_WIDE_INT) (INTVAL (operands[1])) < 1024
543 && (INTVAL (operands[1]) & 3) == 0"
544 [(set (match_dup 0) (plus:SI (match_dup 2) (match_dup 1)))]
548 (define_insn "*addsi3_compare0"
549 [(set (reg:CC_NOOV CC_REGNUM)
551 (plus:SI (match_operand:SI 1 "s_register_operand" "r, r")
552 (match_operand:SI 2 "arm_add_operand" "rI,L"))
554 (set (match_operand:SI 0 "s_register_operand" "=r,r")
555 (plus:SI (match_dup 1) (match_dup 2)))]
559 sub%?s\\t%0, %1, #%n2"
560 [(set_attr "conds" "set")]
563 (define_insn "*addsi3_compare0_scratch"
564 [(set (reg:CC_NOOV CC_REGNUM)
566 (plus:SI (match_operand:SI 0 "s_register_operand" "r, r")
567 (match_operand:SI 1 "arm_add_operand" "rI,L"))
573 [(set_attr "conds" "set")]
576 ;; These patterns are the same ones as the two regular addsi3_compare0
577 ;; patterns, except we write them slightly different - the combiner
578 ;; tends to generate them this way.
579 (define_insn "*addsi3_compare0_for_combiner"
580 [(set (reg:CC CC_REGNUM)
582 (match_operand:SI 1 "s_register_operand" "r,r")
583 (neg:SI (match_operand:SI 2 "arm_add_operand" "rI,L"))))
584 (set (match_operand:SI 0 "s_register_operand" "=r,r")
585 (plus:SI (match_dup 1) (match_dup 2)))]
589 sub%?s\\t%0, %1, #%n2"
590 [(set_attr "conds" "set")]
593 (define_insn "*addsi3_compare0_scratch_for_combiner"
594 [(set (reg:CC CC_REGNUM)
596 (match_operand:SI 0 "s_register_operand" "r,r")
597 (neg:SI (match_operand:SI 1 "arm_add_operand" "rI,L"))))]
602 [(set_attr "conds" "set")]
605 ;; This is the canonicalization of addsi3_compare0_for_combiner when the
606 ;; addend is a constant.
607 (define_insn "*cmpsi2_addneg"
608 [(set (reg:CC CC_REGNUM)
610 (match_operand:SI 1 "s_register_operand" "r,r")
611 (match_operand:SI 2 "arm_addimm_operand" "I,L")))
612 (set (match_operand:SI 0 "s_register_operand" "=r,r")
613 (plus:SI (match_dup 1)
614 (match_operand:SI 3 "arm_addimm_operand" "L,I")))]
615 "TARGET_ARM && INTVAL (operands[2]) == -INTVAL (operands[3])"
618 add%?s\\t%0, %1, #%n2"
619 [(set_attr "conds" "set")]
622 ;; Convert the sequence
624 ;; cmn rd, #1 (equivalent to cmp rd, #-1)
628 ;; bcs dest ((unsigned)rn >= 1)
629 ;; similarly for the beq variant using bcc.
630 ;; This is a common looping idiom (while (n--))
632 [(set (match_operand:SI 0 "s_register_operand" "")
633 (plus:SI (match_operand:SI 1 "s_register_operand" "")
635 (set (match_operand 2 "cc_register" "")
636 (compare (match_dup 0) (const_int -1)))
638 (if_then_else (match_operator 3 "equality_operator"
639 [(match_dup 2) (const_int 0)])
640 (match_operand 4 "" "")
641 (match_operand 5 "" "")))]
642 "TARGET_ARM && peep2_reg_dead_p (3, operands[2])"
646 (match_dup 1) (const_int 1)))
647 (set (match_dup 0) (plus:SI (match_dup 1) (const_int -1)))])
649 (if_then_else (match_op_dup 3 [(match_dup 2) (const_int 0)])
652 "operands[2] = gen_rtx_REG (CCmode, CC_REGNUM);
653 operands[3] = gen_rtx_fmt_ee ((GET_CODE (operands[3]) == NE
656 operands[2], const0_rtx);"
659 ;; The next four insns work because they compare the result with one of
660 ;; the operands, and we know that the use of the condition code is
661 ;; either GEU or LTU, so we can use the carry flag from the addition
662 ;; instead of doing the compare a second time.
663 (define_insn "*addsi3_compare_op1"
664 [(set (reg:CC_C CC_REGNUM)
666 (plus:SI (match_operand:SI 1 "s_register_operand" "r,r")
667 (match_operand:SI 2 "arm_add_operand" "rI,L"))
669 (set (match_operand:SI 0 "s_register_operand" "=r,r")
670 (plus:SI (match_dup 1) (match_dup 2)))]
674 sub%?s\\t%0, %1, #%n2"
675 [(set_attr "conds" "set")]
678 (define_insn "*addsi3_compare_op2"
679 [(set (reg:CC_C CC_REGNUM)
681 (plus:SI (match_operand:SI 1 "s_register_operand" "r,r")
682 (match_operand:SI 2 "arm_add_operand" "rI,L"))
684 (set (match_operand:SI 0 "s_register_operand" "=r,r")
685 (plus:SI (match_dup 1) (match_dup 2)))]
689 sub%?s\\t%0, %1, #%n2"
690 [(set_attr "conds" "set")]
693 (define_insn "*compare_addsi2_op0"
694 [(set (reg:CC_C CC_REGNUM)
696 (plus:SI (match_operand:SI 0 "s_register_operand" "r,r")
697 (match_operand:SI 1 "arm_add_operand" "rI,L"))
703 [(set_attr "conds" "set")]
706 (define_insn "*compare_addsi2_op1"
707 [(set (reg:CC_C CC_REGNUM)
709 (plus:SI (match_operand:SI 0 "s_register_operand" "r,r")
710 (match_operand:SI 1 "arm_add_operand" "rI,L"))
716 [(set_attr "conds" "set")]
719 (define_insn "*addsi3_carryin"
720 [(set (match_operand:SI 0 "s_register_operand" "=r")
721 (plus:SI (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))
722 (plus:SI (match_operand:SI 1 "s_register_operand" "r")
723 (match_operand:SI 2 "arm_rhs_operand" "rI"))))]
726 [(set_attr "conds" "use")]
729 (define_insn "*addsi3_carryin_shift"
730 [(set (match_operand:SI 0 "s_register_operand" "=r")
731 (plus:SI (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))
733 (match_operator:SI 2 "shift_operator"
734 [(match_operand:SI 3 "s_register_operand" "r")
735 (match_operand:SI 4 "reg_or_int_operand" "rM")])
736 (match_operand:SI 1 "s_register_operand" "r"))))]
738 "adc%?\\t%0, %1, %3%S2"
739 [(set_attr "conds" "use")
740 (set (attr "type") (if_then_else (match_operand 4 "const_int_operand" "")
741 (const_string "alu_shift")
742 (const_string "alu_shift_reg")))]
745 (define_insn "*addsi3_carryin_alt1"
746 [(set (match_operand:SI 0 "s_register_operand" "=r")
747 (plus:SI (plus:SI (match_operand:SI 1 "s_register_operand" "r")
748 (match_operand:SI 2 "arm_rhs_operand" "rI"))
749 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
752 [(set_attr "conds" "use")]
755 (define_insn "*addsi3_carryin_alt2"
756 [(set (match_operand:SI 0 "s_register_operand" "=r")
757 (plus:SI (plus:SI (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))
758 (match_operand:SI 1 "s_register_operand" "r"))
759 (match_operand:SI 2 "arm_rhs_operand" "rI")))]
762 [(set_attr "conds" "use")]
765 (define_insn "*addsi3_carryin_alt3"
766 [(set (match_operand:SI 0 "s_register_operand" "=r")
767 (plus:SI (plus:SI (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))
768 (match_operand:SI 2 "arm_rhs_operand" "rI"))
769 (match_operand:SI 1 "s_register_operand" "r")))]
772 [(set_attr "conds" "use")]
775 (define_insn "incscc"
776 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
777 (plus:SI (match_operator:SI 2 "arm_comparison_operator"
778 [(match_operand:CC 3 "cc_register" "") (const_int 0)])
779 (match_operand:SI 1 "s_register_operand" "0,?r")))]
783 mov%D2\\t%0, %1\;add%d2\\t%0, %1, #1"
784 [(set_attr "conds" "use")
785 (set_attr "length" "4,8")]
788 ; transform ((x << y) - 1) to ~(~(x-1) << y) Where X is a constant.
790 [(set (match_operand:SI 0 "s_register_operand" "")
791 (plus:SI (ashift:SI (match_operand:SI 1 "const_int_operand" "")
792 (match_operand:SI 2 "s_register_operand" ""))
794 (clobber (match_operand:SI 3 "s_register_operand" ""))]
796 [(set (match_dup 3) (match_dup 1))
797 (set (match_dup 0) (not:SI (ashift:SI (match_dup 3) (match_dup 2))))]
799 operands[1] = GEN_INT (~(INTVAL (operands[1]) - 1));
802 (define_expand "addsf3"
803 [(set (match_operand:SF 0 "s_register_operand" "")
804 (plus:SF (match_operand:SF 1 "s_register_operand" "")
805 (match_operand:SF 2 "arm_float_add_operand" "")))]
806 "TARGET_ARM && TARGET_HARD_FLOAT"
809 && !cirrus_fp_register (operands[2], SFmode))
810 operands[2] = force_reg (SFmode, operands[2]);
813 (define_expand "adddf3"
814 [(set (match_operand:DF 0 "s_register_operand" "")
815 (plus:DF (match_operand:DF 1 "s_register_operand" "")
816 (match_operand:DF 2 "arm_float_add_operand" "")))]
817 "TARGET_ARM && TARGET_HARD_FLOAT"
820 && !cirrus_fp_register (operands[2], DFmode))
821 operands[2] = force_reg (DFmode, operands[2]);
824 (define_expand "subdi3"
826 [(set (match_operand:DI 0 "s_register_operand" "")
827 (minus:DI (match_operand:DI 1 "s_register_operand" "")
828 (match_operand:DI 2 "s_register_operand" "")))
829 (clobber (reg:CC CC_REGNUM))])]
832 if (TARGET_HARD_FLOAT && TARGET_MAVERICK
834 && cirrus_fp_register (operands[0], DImode)
835 && cirrus_fp_register (operands[1], DImode))
837 emit_insn (gen_cirrus_subdi3 (operands[0], operands[1], operands[2]));
843 if (GET_CODE (operands[1]) != REG)
844 operands[1] = force_reg (SImode, operands[1]);
845 if (GET_CODE (operands[2]) != REG)
846 operands[2] = force_reg (SImode, operands[2]);
851 (define_insn "*arm_subdi3"
852 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r,&r")
853 (minus:DI (match_operand:DI 1 "s_register_operand" "0,r,0")
854 (match_operand:DI 2 "s_register_operand" "r,0,0")))
855 (clobber (reg:CC CC_REGNUM))]
857 "subs\\t%Q0, %Q1, %Q2\;sbc\\t%R0, %R1, %R2"
858 [(set_attr "conds" "clob")
859 (set_attr "length" "8")]
862 (define_insn "*thumb_subdi3"
863 [(set (match_operand:DI 0 "register_operand" "=l")
864 (minus:DI (match_operand:DI 1 "register_operand" "0")
865 (match_operand:DI 2 "register_operand" "l")))
866 (clobber (reg:CC CC_REGNUM))]
868 "sub\\t%Q0, %Q0, %Q2\;sbc\\t%R0, %R0, %R2"
869 [(set_attr "length" "4")]
872 (define_insn "*subdi_di_zesidi"
873 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
874 (minus:DI (match_operand:DI 1 "s_register_operand" "?r,0")
876 (match_operand:SI 2 "s_register_operand" "r,r"))))
877 (clobber (reg:CC CC_REGNUM))]
879 "subs\\t%Q0, %Q1, %2\;sbc\\t%R0, %R1, #0"
880 [(set_attr "conds" "clob")
881 (set_attr "length" "8")]
884 (define_insn "*subdi_di_sesidi"
885 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
886 (minus:DI (match_operand:DI 1 "s_register_operand" "r,0")
888 (match_operand:SI 2 "s_register_operand" "r,r"))))
889 (clobber (reg:CC CC_REGNUM))]
891 "subs\\t%Q0, %Q1, %2\;sbc\\t%R0, %R1, %2, asr #31"
892 [(set_attr "conds" "clob")
893 (set_attr "length" "8")]
896 (define_insn "*subdi_zesidi_di"
897 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
898 (minus:DI (zero_extend:DI
899 (match_operand:SI 2 "s_register_operand" "r,r"))
900 (match_operand:DI 1 "s_register_operand" "?r,0")))
901 (clobber (reg:CC CC_REGNUM))]
903 "rsbs\\t%Q0, %Q1, %2\;rsc\\t%R0, %R1, #0"
904 [(set_attr "conds" "clob")
905 (set_attr "length" "8")]
908 (define_insn "*subdi_sesidi_di"
909 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
910 (minus:DI (sign_extend:DI
911 (match_operand:SI 2 "s_register_operand" "r,r"))
912 (match_operand:DI 1 "s_register_operand" "?r,0")))
913 (clobber (reg:CC CC_REGNUM))]
915 "rsbs\\t%Q0, %Q1, %2\;rsc\\t%R0, %R1, %2, asr #31"
916 [(set_attr "conds" "clob")
917 (set_attr "length" "8")]
920 (define_insn "*subdi_zesidi_zesidi"
921 [(set (match_operand:DI 0 "s_register_operand" "=r")
922 (minus:DI (zero_extend:DI
923 (match_operand:SI 1 "s_register_operand" "r"))
925 (match_operand:SI 2 "s_register_operand" "r"))))
926 (clobber (reg:CC CC_REGNUM))]
928 "subs\\t%Q0, %1, %2\;rsc\\t%R0, %1, %1"
929 [(set_attr "conds" "clob")
930 (set_attr "length" "8")]
933 (define_expand "subsi3"
934 [(set (match_operand:SI 0 "s_register_operand" "")
935 (minus:SI (match_operand:SI 1 "reg_or_int_operand" "")
936 (match_operand:SI 2 "s_register_operand" "")))]
939 if (GET_CODE (operands[1]) == CONST_INT)
943 arm_split_constant (MINUS, SImode, INTVAL (operands[1]), operands[0],
946 : preserve_subexpressions_p ()));
949 else /* TARGET_THUMB */
950 operands[1] = force_reg (SImode, operands[1]);
955 (define_insn "*thumb_subsi3_insn"
956 [(set (match_operand:SI 0 "register_operand" "=l")
957 (minus:SI (match_operand:SI 1 "register_operand" "l")
958 (match_operand:SI 2 "register_operand" "l")))]
961 [(set_attr "length" "2")]
964 (define_insn_and_split "*arm_subsi3_insn"
965 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
966 (minus:SI (match_operand:SI 1 "reg_or_int_operand" "rI,?n")
967 (match_operand:SI 2 "s_register_operand" "r,r")))]
973 && GET_CODE (operands[1]) == CONST_INT
974 && !const_ok_for_arm (INTVAL (operands[1]))"
975 [(clobber (const_int 0))]
977 arm_split_constant (MINUS, SImode, INTVAL (operands[1]), operands[0],
981 [(set_attr "length" "4,16")
982 (set_attr "predicable" "yes")]
986 [(match_scratch:SI 3 "r")
987 (set (match_operand:SI 0 "s_register_operand" "")
988 (minus:SI (match_operand:SI 1 "const_int_operand" "")
989 (match_operand:SI 2 "s_register_operand" "")))]
991 && !const_ok_for_arm (INTVAL (operands[1]))
992 && const_ok_for_arm (~INTVAL (operands[1]))"
993 [(set (match_dup 3) (match_dup 1))
994 (set (match_dup 0) (minus:SI (match_dup 3) (match_dup 2)))]
998 (define_insn "*subsi3_compare0"
999 [(set (reg:CC_NOOV CC_REGNUM)
1001 (minus:SI (match_operand:SI 1 "arm_rhs_operand" "r,I")
1002 (match_operand:SI 2 "arm_rhs_operand" "rI,r"))
1004 (set (match_operand:SI 0 "s_register_operand" "=r,r")
1005 (minus:SI (match_dup 1) (match_dup 2)))]
1009 rsb%?s\\t%0, %2, %1"
1010 [(set_attr "conds" "set")]
1013 (define_insn "decscc"
1014 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
1015 (minus:SI (match_operand:SI 1 "s_register_operand" "0,?r")
1016 (match_operator:SI 2 "arm_comparison_operator"
1017 [(match_operand 3 "cc_register" "") (const_int 0)])))]
1021 mov%D2\\t%0, %1\;sub%d2\\t%0, %1, #1"
1022 [(set_attr "conds" "use")
1023 (set_attr "length" "*,8")]
1026 (define_expand "subsf3"
1027 [(set (match_operand:SF 0 "s_register_operand" "")
1028 (minus:SF (match_operand:SF 1 "arm_float_rhs_operand" "")
1029 (match_operand:SF 2 "arm_float_rhs_operand" "")))]
1030 "TARGET_ARM && TARGET_HARD_FLOAT"
1032 if (TARGET_MAVERICK)
1034 if (!cirrus_fp_register (operands[1], SFmode))
1035 operands[1] = force_reg (SFmode, operands[1]);
1036 if (!cirrus_fp_register (operands[2], SFmode))
1037 operands[2] = force_reg (SFmode, operands[2]);
1041 (define_expand "subdf3"
1042 [(set (match_operand:DF 0 "s_register_operand" "")
1043 (minus:DF (match_operand:DF 1 "arm_float_rhs_operand" "")
1044 (match_operand:DF 2 "arm_float_rhs_operand" "")))]
1045 "TARGET_ARM && TARGET_HARD_FLOAT"
1047 if (TARGET_MAVERICK)
1049 if (!cirrus_fp_register (operands[1], DFmode))
1050 operands[1] = force_reg (DFmode, operands[1]);
1051 if (!cirrus_fp_register (operands[2], DFmode))
1052 operands[2] = force_reg (DFmode, operands[2]);
1057 ;; Multiplication insns
1059 (define_expand "mulsi3"
1060 [(set (match_operand:SI 0 "s_register_operand" "")
1061 (mult:SI (match_operand:SI 2 "s_register_operand" "")
1062 (match_operand:SI 1 "s_register_operand" "")))]
1067 ;; Use `&' and then `0' to prevent the operands 0 and 1 being the same
1068 (define_insn "*arm_mulsi3"
1069 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r")
1070 (mult:SI (match_operand:SI 2 "s_register_operand" "r,r")
1071 (match_operand:SI 1 "s_register_operand" "%?r,0")))]
1073 "mul%?\\t%0, %2, %1"
1074 [(set_attr "insn" "mul")
1075 (set_attr "predicable" "yes")]
1078 ; Unfortunately with the Thumb the '&'/'0' trick can fails when operands
1079 ; 1 and 2; are the same, because reload will make operand 0 match
1080 ; operand 1 without realizing that this conflicts with operand 2. We fix
1081 ; this by adding another alternative to match this case, and then `reload'
1082 ; it ourselves. This alternative must come first.
1083 (define_insn "*thumb_mulsi3"
1084 [(set (match_operand:SI 0 "register_operand" "=&l,&l,&l")
1085 (mult:SI (match_operand:SI 1 "register_operand" "%l,*h,0")
1086 (match_operand:SI 2 "register_operand" "l,l,l")))]
1089 if (which_alternative < 2)
1090 return \"mov\\t%0, %1\;mul\\t%0, %0, %2\";
1092 return \"mul\\t%0, %0, %2\";
1094 [(set_attr "length" "4,4,2")
1095 (set_attr "insn" "mul")]
1098 (define_insn "*mulsi3_compare0"
1099 [(set (reg:CC_NOOV CC_REGNUM)
1100 (compare:CC_NOOV (mult:SI
1101 (match_operand:SI 2 "s_register_operand" "r,r")
1102 (match_operand:SI 1 "s_register_operand" "%?r,0"))
1104 (set (match_operand:SI 0 "s_register_operand" "=&r,&r")
1105 (mult:SI (match_dup 2) (match_dup 1)))]
1106 "TARGET_ARM && !arm_arch_xscale"
1107 "mul%?s\\t%0, %2, %1"
1108 [(set_attr "conds" "set")
1109 (set_attr "insn" "muls")]
1112 (define_insn "*mulsi_compare0_scratch"
1113 [(set (reg:CC_NOOV CC_REGNUM)
1114 (compare:CC_NOOV (mult:SI
1115 (match_operand:SI 2 "s_register_operand" "r,r")
1116 (match_operand:SI 1 "s_register_operand" "%?r,0"))
1118 (clobber (match_scratch:SI 0 "=&r,&r"))]
1119 "TARGET_ARM && !arm_arch_xscale"
1120 "mul%?s\\t%0, %2, %1"
1121 [(set_attr "conds" "set")
1122 (set_attr "insn" "muls")]
1125 ;; Unnamed templates to match MLA instruction.
1127 (define_insn "*mulsi3addsi"
1128 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r,&r")
1130 (mult:SI (match_operand:SI 2 "s_register_operand" "r,r,r,r")
1131 (match_operand:SI 1 "s_register_operand" "%r,0,r,0"))
1132 (match_operand:SI 3 "s_register_operand" "?r,r,0,0")))]
1134 "mla%?\\t%0, %2, %1, %3"
1135 [(set_attr "insn" "mla")
1136 (set_attr "predicable" "yes")]
1139 (define_insn "*mulsi3addsi_compare0"
1140 [(set (reg:CC_NOOV CC_REGNUM)
1143 (match_operand:SI 2 "s_register_operand" "r,r,r,r")
1144 (match_operand:SI 1 "s_register_operand" "%r,0,r,0"))
1145 (match_operand:SI 3 "s_register_operand" "?r,r,0,0"))
1147 (set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r,&r")
1148 (plus:SI (mult:SI (match_dup 2) (match_dup 1))
1150 "TARGET_ARM && !arm_arch_xscale"
1151 "mla%?s\\t%0, %2, %1, %3"
1152 [(set_attr "conds" "set")
1153 (set_attr "insn" "mlas")]
1156 (define_insn "*mulsi3addsi_compare0_scratch"
1157 [(set (reg:CC_NOOV CC_REGNUM)
1160 (match_operand:SI 2 "s_register_operand" "r,r,r,r")
1161 (match_operand:SI 1 "s_register_operand" "%r,0,r,0"))
1162 (match_operand:SI 3 "s_register_operand" "?r,r,0,0"))
1164 (clobber (match_scratch:SI 0 "=&r,&r,&r,&r"))]
1165 "TARGET_ARM && !arm_arch_xscale"
1166 "mla%?s\\t%0, %2, %1, %3"
1167 [(set_attr "conds" "set")
1168 (set_attr "insn" "mlas")]
1171 ;; Unnamed template to match long long multiply-accumulate (smlal)
1173 (define_insn "*mulsidi3adddi"
1174 [(set (match_operand:DI 0 "s_register_operand" "=&r")
1177 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "%r"))
1178 (sign_extend:DI (match_operand:SI 3 "s_register_operand" "r")))
1179 (match_operand:DI 1 "s_register_operand" "0")))]
1180 "TARGET_ARM && arm_arch3m"
1181 "smlal%?\\t%Q0, %R0, %3, %2"
1182 [(set_attr "insn" "smlal")
1183 (set_attr "predicable" "yes")]
1186 (define_insn "mulsidi3"
1187 [(set (match_operand:DI 0 "s_register_operand" "=&r")
1189 (sign_extend:DI (match_operand:SI 1 "s_register_operand" "%r"))
1190 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))]
1191 "TARGET_ARM && arm_arch3m"
1192 "smull%?\\t%Q0, %R0, %1, %2"
1193 [(set_attr "insn" "smull")
1194 (set_attr "predicable" "yes")]
1197 (define_insn "umulsidi3"
1198 [(set (match_operand:DI 0 "s_register_operand" "=&r")
1200 (zero_extend:DI (match_operand:SI 1 "s_register_operand" "%r"))
1201 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))]
1202 "TARGET_ARM && arm_arch3m"
1203 "umull%?\\t%Q0, %R0, %1, %2"
1204 [(set_attr "insn" "umull")
1205 (set_attr "predicable" "yes")]
1208 ;; Unnamed template to match long long unsigned multiply-accumulate (umlal)
1210 (define_insn "*umulsidi3adddi"
1211 [(set (match_operand:DI 0 "s_register_operand" "=&r")
1214 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "%r"))
1215 (zero_extend:DI (match_operand:SI 3 "s_register_operand" "r")))
1216 (match_operand:DI 1 "s_register_operand" "0")))]
1217 "TARGET_ARM && arm_arch3m"
1218 "umlal%?\\t%Q0, %R0, %3, %2"
1219 [(set_attr "insn" "umlal")
1220 (set_attr "predicable" "yes")]
1223 (define_insn "smulsi3_highpart"
1224 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r")
1228 (sign_extend:DI (match_operand:SI 1 "s_register_operand" "%r,0"))
1229 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r,r")))
1231 (clobber (match_scratch:SI 3 "=&r,&r"))]
1232 "TARGET_ARM && arm_arch3m"
1233 "smull%?\\t%3, %0, %2, %1"
1234 [(set_attr "insn" "smull")
1235 (set_attr "predicable" "yes")]
1238 (define_insn "umulsi3_highpart"
1239 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r")
1243 (zero_extend:DI (match_operand:SI 1 "s_register_operand" "%r,0"))
1244 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r,r")))
1246 (clobber (match_scratch:SI 3 "=&r,&r"))]
1247 "TARGET_ARM && arm_arch3m"
1248 "umull%?\\t%3, %0, %2, %1"
1249 [(set_attr "insn" "umull")
1250 (set_attr "predicable" "yes")]
1253 (define_insn "mulhisi3"
1254 [(set (match_operand:SI 0 "s_register_operand" "=r")
1255 (mult:SI (sign_extend:SI
1256 (match_operand:HI 1 "s_register_operand" "%r"))
1258 (match_operand:HI 2 "s_register_operand" "r"))))]
1259 "TARGET_ARM && arm_arch5e"
1260 "smulbb%?\\t%0, %1, %2"
1261 [(set_attr "insn" "smulxy")
1262 (set_attr "predicable" "yes")]
1265 (define_insn "*mulhisi3tb"
1266 [(set (match_operand:SI 0 "s_register_operand" "=r")
1267 (mult:SI (ashiftrt:SI
1268 (match_operand:SI 1 "s_register_operand" "r")
1271 (match_operand:HI 2 "s_register_operand" "r"))))]
1272 "TARGET_ARM && arm_arch5e"
1273 "smultb%?\\t%0, %1, %2"
1274 [(set_attr "insn" "smulxy")
1275 (set_attr "predicable" "yes")]
1278 (define_insn "*mulhisi3bt"
1279 [(set (match_operand:SI 0 "s_register_operand" "=r")
1280 (mult:SI (sign_extend:SI
1281 (match_operand:HI 1 "s_register_operand" "r"))
1283 (match_operand:SI 2 "s_register_operand" "r")
1285 "TARGET_ARM && arm_arch5e"
1286 "smulbt%?\\t%0, %1, %2"
1287 [(set_attr "insn" "smulxy")
1288 (set_attr "predicable" "yes")]
1291 (define_insn "*mulhisi3tt"
1292 [(set (match_operand:SI 0 "s_register_operand" "=r")
1293 (mult:SI (ashiftrt:SI
1294 (match_operand:SI 1 "s_register_operand" "r")
1297 (match_operand:SI 2 "s_register_operand" "r")
1299 "TARGET_ARM && arm_arch5e"
1300 "smultt%?\\t%0, %1, %2"
1301 [(set_attr "insn" "smulxy")
1302 (set_attr "predicable" "yes")]
1305 (define_insn "*mulhisi3addsi"
1306 [(set (match_operand:SI 0 "s_register_operand" "=r")
1307 (plus:SI (match_operand:SI 1 "s_register_operand" "r")
1308 (mult:SI (sign_extend:SI
1309 (match_operand:HI 2 "s_register_operand" "%r"))
1311 (match_operand:HI 3 "s_register_operand" "r")))))]
1312 "TARGET_ARM && arm_arch5e"
1313 "smlabb%?\\t%0, %2, %3, %1"
1314 [(set_attr "insn" "smlaxy")
1315 (set_attr "predicable" "yes")]
1318 (define_insn "*mulhidi3adddi"
1319 [(set (match_operand:DI 0 "s_register_operand" "=r")
1321 (match_operand:DI 1 "s_register_operand" "0")
1322 (mult:DI (sign_extend:DI
1323 (match_operand:HI 2 "s_register_operand" "%r"))
1325 (match_operand:HI 3 "s_register_operand" "r")))))]
1326 "TARGET_ARM && arm_arch5e"
1327 "smlalbb%?\\t%Q0, %R0, %2, %3"
1328 [(set_attr "insn" "smlalxy")
1329 (set_attr "predicable" "yes")])
1331 (define_expand "mulsf3"
1332 [(set (match_operand:SF 0 "s_register_operand" "")
1333 (mult:SF (match_operand:SF 1 "s_register_operand" "")
1334 (match_operand:SF 2 "arm_float_rhs_operand" "")))]
1335 "TARGET_ARM && TARGET_HARD_FLOAT"
1338 && !cirrus_fp_register (operands[2], SFmode))
1339 operands[2] = force_reg (SFmode, operands[2]);
1342 (define_expand "muldf3"
1343 [(set (match_operand:DF 0 "s_register_operand" "")
1344 (mult:DF (match_operand:DF 1 "s_register_operand" "")
1345 (match_operand:DF 2 "arm_float_rhs_operand" "")))]
1346 "TARGET_ARM && TARGET_HARD_FLOAT"
1349 && !cirrus_fp_register (operands[2], DFmode))
1350 operands[2] = force_reg (DFmode, operands[2]);
1355 (define_expand "divsf3"
1356 [(set (match_operand:SF 0 "s_register_operand" "")
1357 (div:SF (match_operand:SF 1 "arm_float_rhs_operand" "")
1358 (match_operand:SF 2 "arm_float_rhs_operand" "")))]
1359 "TARGET_ARM && TARGET_HARD_FLOAT && (TARGET_FPA || TARGET_VFP)"
1362 (define_expand "divdf3"
1363 [(set (match_operand:DF 0 "s_register_operand" "")
1364 (div:DF (match_operand:DF 1 "arm_float_rhs_operand" "")
1365 (match_operand:DF 2 "arm_float_rhs_operand" "")))]
1366 "TARGET_ARM && TARGET_HARD_FLOAT && (TARGET_FPA || TARGET_VFP)"
1371 (define_expand "modsf3"
1372 [(set (match_operand:SF 0 "s_register_operand" "")
1373 (mod:SF (match_operand:SF 1 "s_register_operand" "")
1374 (match_operand:SF 2 "arm_float_rhs_operand" "")))]
1375 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
1378 (define_expand "moddf3"
1379 [(set (match_operand:DF 0 "s_register_operand" "")
1380 (mod:DF (match_operand:DF 1 "s_register_operand" "")
1381 (match_operand:DF 2 "arm_float_rhs_operand" "")))]
1382 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
1385 ;; Boolean and,ior,xor insns
1387 ;; Split up double word logical operations
1389 ;; Split up simple DImode logical operations. Simply perform the logical
1390 ;; operation on the upper and lower halves of the registers.
1392 [(set (match_operand:DI 0 "s_register_operand" "")
1393 (match_operator:DI 6 "logical_binary_operator"
1394 [(match_operand:DI 1 "s_register_operand" "")
1395 (match_operand:DI 2 "s_register_operand" "")]))]
1396 "TARGET_ARM && reload_completed && ! IS_IWMMXT_REGNUM (REGNO (operands[0]))"
1397 [(set (match_dup 0) (match_op_dup:SI 6 [(match_dup 1) (match_dup 2)]))
1398 (set (match_dup 3) (match_op_dup:SI 6 [(match_dup 4) (match_dup 5)]))]
1401 operands[3] = gen_highpart (SImode, operands[0]);
1402 operands[0] = gen_lowpart (SImode, operands[0]);
1403 operands[4] = gen_highpart (SImode, operands[1]);
1404 operands[1] = gen_lowpart (SImode, operands[1]);
1405 operands[5] = gen_highpart (SImode, operands[2]);
1406 operands[2] = gen_lowpart (SImode, operands[2]);
1411 [(set (match_operand:DI 0 "s_register_operand" "")
1412 (match_operator:DI 6 "logical_binary_operator"
1413 [(sign_extend:DI (match_operand:SI 2 "s_register_operand" ""))
1414 (match_operand:DI 1 "s_register_operand" "")]))]
1415 "TARGET_ARM && reload_completed"
1416 [(set (match_dup 0) (match_op_dup:SI 6 [(match_dup 1) (match_dup 2)]))
1417 (set (match_dup 3) (match_op_dup:SI 6
1418 [(ashiftrt:SI (match_dup 2) (const_int 31))
1422 operands[3] = gen_highpart (SImode, operands[0]);
1423 operands[0] = gen_lowpart (SImode, operands[0]);
1424 operands[4] = gen_highpart (SImode, operands[1]);
1425 operands[1] = gen_lowpart (SImode, operands[1]);
1426 operands[5] = gen_highpart (SImode, operands[2]);
1427 operands[2] = gen_lowpart (SImode, operands[2]);
1431 ;; The zero extend of operand 2 means we can just copy the high part of
1432 ;; operand1 into operand0.
1434 [(set (match_operand:DI 0 "s_register_operand" "")
1436 (zero_extend:DI (match_operand:SI 2 "s_register_operand" ""))
1437 (match_operand:DI 1 "s_register_operand" "")))]
1438 "TARGET_ARM && operands[0] != operands[1] && reload_completed"
1439 [(set (match_dup 0) (ior:SI (match_dup 1) (match_dup 2)))
1440 (set (match_dup 3) (match_dup 4))]
1443 operands[4] = gen_highpart (SImode, operands[1]);
1444 operands[3] = gen_highpart (SImode, operands[0]);
1445 operands[0] = gen_lowpart (SImode, operands[0]);
1446 operands[1] = gen_lowpart (SImode, operands[1]);
1450 ;; The zero extend of operand 2 means we can just copy the high part of
1451 ;; operand1 into operand0.
1453 [(set (match_operand:DI 0 "s_register_operand" "")
1455 (zero_extend:DI (match_operand:SI 2 "s_register_operand" ""))
1456 (match_operand:DI 1 "s_register_operand" "")))]
1457 "TARGET_ARM && operands[0] != operands[1] && reload_completed"
1458 [(set (match_dup 0) (xor:SI (match_dup 1) (match_dup 2)))
1459 (set (match_dup 3) (match_dup 4))]
1462 operands[4] = gen_highpart (SImode, operands[1]);
1463 operands[3] = gen_highpart (SImode, operands[0]);
1464 operands[0] = gen_lowpart (SImode, operands[0]);
1465 operands[1] = gen_lowpart (SImode, operands[1]);
1469 (define_insn "anddi3"
1470 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1471 (and:DI (match_operand:DI 1 "s_register_operand" "%0,r")
1472 (match_operand:DI 2 "s_register_operand" "r,r")))]
1473 "TARGET_ARM && ! TARGET_IWMMXT"
1475 [(set_attr "length" "8")]
1478 (define_insn_and_split "*anddi_zesidi_di"
1479 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1480 (and:DI (zero_extend:DI
1481 (match_operand:SI 2 "s_register_operand" "r,r"))
1482 (match_operand:DI 1 "s_register_operand" "?r,0")))]
1485 "TARGET_ARM && reload_completed"
1486 ; The zero extend of operand 2 clears the high word of the output
1488 [(set (match_dup 0) (and:SI (match_dup 1) (match_dup 2)))
1489 (set (match_dup 3) (const_int 0))]
1492 operands[3] = gen_highpart (SImode, operands[0]);
1493 operands[0] = gen_lowpart (SImode, operands[0]);
1494 operands[1] = gen_lowpart (SImode, operands[1]);
1496 [(set_attr "length" "8")]
1499 (define_insn "*anddi_sesdi_di"
1500 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1501 (and:DI (sign_extend:DI
1502 (match_operand:SI 2 "s_register_operand" "r,r"))
1503 (match_operand:DI 1 "s_register_operand" "?r,0")))]
1506 [(set_attr "length" "8")]
1509 (define_expand "andsi3"
1510 [(set (match_operand:SI 0 "s_register_operand" "")
1511 (and:SI (match_operand:SI 1 "s_register_operand" "")
1512 (match_operand:SI 2 "reg_or_int_operand" "")))]
1517 if (GET_CODE (operands[2]) == CONST_INT)
1519 arm_split_constant (AND, SImode, INTVAL (operands[2]), operands[0],
1522 ? 0 : preserve_subexpressions_p ()));
1526 else /* TARGET_THUMB */
1528 if (GET_CODE (operands[2]) != CONST_INT)
1529 operands[2] = force_reg (SImode, operands[2]);
1534 if (((unsigned HOST_WIDE_INT) ~INTVAL (operands[2])) < 256)
1536 operands[2] = force_reg (SImode,
1537 GEN_INT (~INTVAL (operands[2])));
1539 emit_insn (gen_bicsi3 (operands[0], operands[2], operands[1]));
1544 for (i = 9; i <= 31; i++)
1546 if ((((HOST_WIDE_INT) 1) << i) - 1 == INTVAL (operands[2]))
1548 emit_insn (gen_extzv (operands[0], operands[1], GEN_INT (i),
1552 else if ((((HOST_WIDE_INT) 1) << i) - 1
1553 == ~INTVAL (operands[2]))
1555 rtx shift = GEN_INT (i);
1556 rtx reg = gen_reg_rtx (SImode);
1558 emit_insn (gen_lshrsi3 (reg, operands[1], shift));
1559 emit_insn (gen_ashlsi3 (operands[0], reg, shift));
1565 operands[2] = force_reg (SImode, operands[2]);
1571 (define_insn_and_split "*arm_andsi3_insn"
1572 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
1573 (and:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
1574 (match_operand:SI 2 "reg_or_int_operand" "rI,K,?n")))]
1578 bic%?\\t%0, %1, #%B2
1581 && GET_CODE (operands[2]) == CONST_INT
1582 && !(const_ok_for_arm (INTVAL (operands[2]))
1583 || const_ok_for_arm (~INTVAL (operands[2])))"
1584 [(clobber (const_int 0))]
1586 arm_split_constant (AND, SImode, INTVAL (operands[2]), operands[0],
1590 [(set_attr "length" "4,4,16")
1591 (set_attr "predicable" "yes")]
1594 (define_insn "*thumb_andsi3_insn"
1595 [(set (match_operand:SI 0 "register_operand" "=l")
1596 (and:SI (match_operand:SI 1 "register_operand" "%0")
1597 (match_operand:SI 2 "register_operand" "l")))]
1600 [(set_attr "length" "2")]
1603 (define_insn "*andsi3_compare0"
1604 [(set (reg:CC_NOOV CC_REGNUM)
1606 (and:SI (match_operand:SI 1 "s_register_operand" "r,r")
1607 (match_operand:SI 2 "arm_not_operand" "rI,K"))
1609 (set (match_operand:SI 0 "s_register_operand" "=r,r")
1610 (and:SI (match_dup 1) (match_dup 2)))]
1614 bic%?s\\t%0, %1, #%B2"
1615 [(set_attr "conds" "set")]
1618 (define_insn "*andsi3_compare0_scratch"
1619 [(set (reg:CC_NOOV CC_REGNUM)
1621 (and:SI (match_operand:SI 0 "s_register_operand" "r,r")
1622 (match_operand:SI 1 "arm_not_operand" "rI,K"))
1624 (clobber (match_scratch:SI 2 "=X,r"))]
1628 bic%?s\\t%2, %0, #%B1"
1629 [(set_attr "conds" "set")]
1632 (define_insn "*zeroextractsi_compare0_scratch"
1633 [(set (reg:CC_NOOV CC_REGNUM)
1634 (compare:CC_NOOV (zero_extract:SI
1635 (match_operand:SI 0 "s_register_operand" "r")
1636 (match_operand 1 "const_int_operand" "n")
1637 (match_operand 2 "const_int_operand" "n"))
1640 && (INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) < 32
1641 && INTVAL (operands[1]) > 0
1642 && INTVAL (operands[1]) + (INTVAL (operands[2]) & 1) <= 8
1643 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32)"
1645 operands[1] = GEN_INT (((1 << INTVAL (operands[1])) - 1)
1646 << INTVAL (operands[2]));
1647 output_asm_insn (\"tst%?\\t%0, %1\", operands);
1650 [(set_attr "conds" "set")]
1653 (define_insn "*ne_zeroextractsi"
1654 [(set (match_operand:SI 0 "s_register_operand" "=r")
1655 (ne:SI (zero_extract:SI
1656 (match_operand:SI 1 "s_register_operand" "r")
1657 (match_operand:SI 2 "const_int_operand" "n")
1658 (match_operand:SI 3 "const_int_operand" "n"))
1660 (clobber (reg:CC CC_REGNUM))]
1662 && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
1663 && INTVAL (operands[2]) > 0
1664 && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
1665 && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)"
1667 operands[2] = GEN_INT (((1 << INTVAL (operands[2])) - 1)
1668 << INTVAL (operands[3]));
1669 output_asm_insn (\"ands\\t%0, %1, %2\", operands);
1670 return \"movne\\t%0, #1\";
1672 [(set_attr "conds" "clob")
1673 (set_attr "length" "8")]
1677 [(set (match_operand:SI 0 "s_register_operand" "")
1678 (zero_extract:SI (match_operand:SI 1 "s_register_operand" "")
1679 (match_operand:SI 2 "const_int_operand" "")
1680 (match_operand:SI 3 "const_int_operand" "")))
1681 (clobber (match_operand:SI 4 "s_register_operand" ""))]
1683 [(set (match_dup 4) (ashift:SI (match_dup 1) (match_dup 2)))
1684 (set (match_dup 0) (lshiftrt:SI (match_dup 4) (match_dup 3)))]
1686 HOST_WIDE_INT temp = INTVAL (operands[2]);
1688 operands[2] = GEN_INT (32 - temp - INTVAL (operands[3]));
1689 operands[3] = GEN_INT (32 - temp);
1694 [(set (match_operand:SI 0 "s_register_operand" "")
1695 (match_operator:SI 1 "shiftable_operator"
1696 [(zero_extract:SI (match_operand:SI 2 "s_register_operand" "")
1697 (match_operand:SI 3 "const_int_operand" "")
1698 (match_operand:SI 4 "const_int_operand" ""))
1699 (match_operand:SI 5 "s_register_operand" "")]))
1700 (clobber (match_operand:SI 6 "s_register_operand" ""))]
1702 [(set (match_dup 6) (ashift:SI (match_dup 2) (match_dup 3)))
1705 [(lshiftrt:SI (match_dup 6) (match_dup 4))
1708 HOST_WIDE_INT temp = INTVAL (operands[3]);
1710 operands[3] = GEN_INT (32 - temp - INTVAL (operands[4]));
1711 operands[4] = GEN_INT (32 - temp);
1716 [(set (match_operand:SI 0 "s_register_operand" "")
1717 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "")
1718 (match_operand:SI 2 "const_int_operand" "")
1719 (match_operand:SI 3 "const_int_operand" "")))]
1721 [(set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 2)))
1722 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (match_dup 3)))]
1724 HOST_WIDE_INT temp = INTVAL (operands[2]);
1726 operands[2] = GEN_INT (32 - temp - INTVAL (operands[3]));
1727 operands[3] = GEN_INT (32 - temp);
1732 [(set (match_operand:SI 0 "s_register_operand" "")
1733 (match_operator:SI 1 "shiftable_operator"
1734 [(sign_extract:SI (match_operand:SI 2 "s_register_operand" "")
1735 (match_operand:SI 3 "const_int_operand" "")
1736 (match_operand:SI 4 "const_int_operand" ""))
1737 (match_operand:SI 5 "s_register_operand" "")]))
1738 (clobber (match_operand:SI 6 "s_register_operand" ""))]
1740 [(set (match_dup 6) (ashift:SI (match_dup 2) (match_dup 3)))
1743 [(ashiftrt:SI (match_dup 6) (match_dup 4))
1746 HOST_WIDE_INT temp = INTVAL (operands[3]);
1748 operands[3] = GEN_INT (32 - temp - INTVAL (operands[4]));
1749 operands[4] = GEN_INT (32 - temp);
1753 ;;; ??? This pattern is bogus. If operand3 has bits outside the range
1754 ;;; represented by the bitfield, then this will produce incorrect results.
1755 ;;; Somewhere, the value needs to be truncated. On targets like the m68k,
1756 ;;; which have a real bit-field insert instruction, the truncation happens
1757 ;;; in the bit-field insert instruction itself. Since arm does not have a
1758 ;;; bit-field insert instruction, we would have to emit code here to truncate
1759 ;;; the value before we insert. This loses some of the advantage of having
1760 ;;; this insv pattern, so this pattern needs to be reevalutated.
1762 (define_expand "insv"
1763 [(set (zero_extract:SI (match_operand:SI 0 "s_register_operand" "")
1764 (match_operand:SI 1 "general_operand" "")
1765 (match_operand:SI 2 "general_operand" ""))
1766 (match_operand:SI 3 "reg_or_int_operand" ""))]
1770 int start_bit = INTVAL (operands[2]);
1771 int width = INTVAL (operands[1]);
1772 HOST_WIDE_INT mask = (((HOST_WIDE_INT)1) << width) - 1;
1773 rtx target, subtarget;
1775 target = operands[0];
1776 /* Avoid using a subreg as a subtarget, and avoid writing a paradoxical
1777 subreg as the final target. */
1778 if (GET_CODE (target) == SUBREG)
1780 subtarget = gen_reg_rtx (SImode);
1781 if (GET_MODE_SIZE (GET_MODE (SUBREG_REG (target)))
1782 < GET_MODE_SIZE (SImode))
1783 target = SUBREG_REG (target);
1788 if (GET_CODE (operands[3]) == CONST_INT)
1790 /* Since we are inserting a known constant, we may be able to
1791 reduce the number of bits that we have to clear so that
1792 the mask becomes simple. */
1793 /* ??? This code does not check to see if the new mask is actually
1794 simpler. It may not be. */
1795 rtx op1 = gen_reg_rtx (SImode);
1796 /* ??? Truncate operand3 to fit in the bitfield. See comment before
1797 start of this pattern. */
1798 HOST_WIDE_INT op3_value = mask & INTVAL (operands[3]);
1799 HOST_WIDE_INT mask2 = ((mask & ~op3_value) << start_bit);
1801 emit_insn (gen_andsi3 (op1, operands[0], GEN_INT (~mask2)));
1802 emit_insn (gen_iorsi3 (subtarget, op1,
1803 GEN_INT (op3_value << start_bit)));
1805 else if (start_bit == 0
1806 && !(const_ok_for_arm (mask)
1807 || const_ok_for_arm (~mask)))
1809 /* A Trick, since we are setting the bottom bits in the word,
1810 we can shift operand[3] up, operand[0] down, OR them together
1811 and rotate the result back again. This takes 3 insns, and
1812 the third might be mergeable into another op. */
1813 /* The shift up copes with the possibility that operand[3] is
1814 wider than the bitfield. */
1815 rtx op0 = gen_reg_rtx (SImode);
1816 rtx op1 = gen_reg_rtx (SImode);
1818 emit_insn (gen_ashlsi3 (op0, operands[3], GEN_INT (32 - width)));
1819 emit_insn (gen_lshrsi3 (op1, operands[0], operands[1]));
1820 emit_insn (gen_iorsi3 (op1, op1, op0));
1821 emit_insn (gen_rotlsi3 (subtarget, op1, operands[1]));
1823 else if ((width + start_bit == 32)
1824 && !(const_ok_for_arm (mask)
1825 || const_ok_for_arm (~mask)))
1827 /* Similar trick, but slightly less efficient. */
1829 rtx op0 = gen_reg_rtx (SImode);
1830 rtx op1 = gen_reg_rtx (SImode);
1832 emit_insn (gen_ashlsi3 (op0, operands[3], GEN_INT (32 - width)));
1833 emit_insn (gen_ashlsi3 (op1, operands[0], operands[1]));
1834 emit_insn (gen_lshrsi3 (op1, op1, operands[1]));
1835 emit_insn (gen_iorsi3 (subtarget, op1, op0));
1839 rtx op0 = GEN_INT (mask);
1840 rtx op1 = gen_reg_rtx (SImode);
1841 rtx op2 = gen_reg_rtx (SImode);
1843 if (!(const_ok_for_arm (mask) || const_ok_for_arm (~mask)))
1845 rtx tmp = gen_reg_rtx (SImode);
1847 emit_insn (gen_movsi (tmp, op0));
1851 /* Mask out any bits in operand[3] that are not needed. */
1852 emit_insn (gen_andsi3 (op1, operands[3], op0));
1854 if (GET_CODE (op0) == CONST_INT
1855 && (const_ok_for_arm (mask << start_bit)
1856 || const_ok_for_arm (~(mask << start_bit))))
1858 op0 = GEN_INT (~(mask << start_bit));
1859 emit_insn (gen_andsi3 (op2, operands[0], op0));
1863 if (GET_CODE (op0) == CONST_INT)
1865 rtx tmp = gen_reg_rtx (SImode);
1867 emit_insn (gen_movsi (tmp, op0));
1872 emit_insn (gen_ashlsi3 (op0, op0, operands[2]));
1874 emit_insn (gen_andsi_notsi_si (op2, operands[0], op0));
1878 emit_insn (gen_ashlsi3 (op1, op1, operands[2]));
1880 emit_insn (gen_iorsi3 (subtarget, op1, op2));
1883 if (subtarget != target)
1885 /* If TARGET is still a SUBREG, then it must be wider than a word,
1886 so we must be careful only to set the subword we were asked to. */
1887 if (GET_CODE (target) == SUBREG)
1888 emit_move_insn (target, subtarget);
1890 emit_move_insn (target, gen_lowpart (GET_MODE (target), subtarget));
1897 ; constants for op 2 will never be given to these patterns.
1898 (define_insn_and_split "*anddi_notdi_di"
1899 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1900 (and:DI (not:DI (match_operand:DI 1 "s_register_operand" "r,0"))
1901 (match_operand:DI 2 "s_register_operand" "0,r")))]
1904 "TARGET_ARM && reload_completed && ! IS_IWMMXT_REGNUM (REGNO (operands[0]))"
1905 [(set (match_dup 0) (and:SI (not:SI (match_dup 1)) (match_dup 2)))
1906 (set (match_dup 3) (and:SI (not:SI (match_dup 4)) (match_dup 5)))]
1909 operands[3] = gen_highpart (SImode, operands[0]);
1910 operands[0] = gen_lowpart (SImode, operands[0]);
1911 operands[4] = gen_highpart (SImode, operands[1]);
1912 operands[1] = gen_lowpart (SImode, operands[1]);
1913 operands[5] = gen_highpart (SImode, operands[2]);
1914 operands[2] = gen_lowpart (SImode, operands[2]);
1916 [(set_attr "length" "8")
1917 (set_attr "predicable" "yes")]
1920 (define_insn_and_split "*anddi_notzesidi_di"
1921 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1922 (and:DI (not:DI (zero_extend:DI
1923 (match_operand:SI 2 "s_register_operand" "r,r")))
1924 (match_operand:DI 1 "s_register_operand" "0,?r")))]
1927 bic%?\\t%Q0, %Q1, %2
1929 ; (not (zero_extend ...)) allows us to just copy the high word from
1930 ; operand1 to operand0.
1933 && operands[0] != operands[1]"
1934 [(set (match_dup 0) (and:SI (not:SI (match_dup 2)) (match_dup 1)))
1935 (set (match_dup 3) (match_dup 4))]
1938 operands[3] = gen_highpart (SImode, operands[0]);
1939 operands[0] = gen_lowpart (SImode, operands[0]);
1940 operands[4] = gen_highpart (SImode, operands[1]);
1941 operands[1] = gen_lowpart (SImode, operands[1]);
1943 [(set_attr "length" "4,8")
1944 (set_attr "predicable" "yes")]
1947 (define_insn_and_split "*anddi_notsesidi_di"
1948 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1949 (and:DI (not:DI (sign_extend:DI
1950 (match_operand:SI 2 "s_register_operand" "r,r")))
1951 (match_operand:DI 1 "s_register_operand" "0,r")))]
1954 "TARGET_ARM && reload_completed"
1955 [(set (match_dup 0) (and:SI (not:SI (match_dup 2)) (match_dup 1)))
1956 (set (match_dup 3) (and:SI (not:SI
1957 (ashiftrt:SI (match_dup 2) (const_int 31)))
1961 operands[3] = gen_highpart (SImode, operands[0]);
1962 operands[0] = gen_lowpart (SImode, operands[0]);
1963 operands[4] = gen_highpart (SImode, operands[1]);
1964 operands[1] = gen_lowpart (SImode, operands[1]);
1966 [(set_attr "length" "8")
1967 (set_attr "predicable" "yes")]
1970 (define_insn "andsi_notsi_si"
1971 [(set (match_operand:SI 0 "s_register_operand" "=r")
1972 (and:SI (not:SI (match_operand:SI 2 "s_register_operand" "r"))
1973 (match_operand:SI 1 "s_register_operand" "r")))]
1975 "bic%?\\t%0, %1, %2"
1976 [(set_attr "predicable" "yes")]
1979 (define_insn "bicsi3"
1980 [(set (match_operand:SI 0 "register_operand" "=l")
1981 (and:SI (not:SI (match_operand:SI 1 "register_operand" "l"))
1982 (match_operand:SI 2 "register_operand" "0")))]
1985 [(set_attr "length" "2")]
1988 (define_insn "andsi_not_shiftsi_si"
1989 [(set (match_operand:SI 0 "s_register_operand" "=r")
1990 (and:SI (not:SI (match_operator:SI 4 "shift_operator"
1991 [(match_operand:SI 2 "s_register_operand" "r")
1992 (match_operand:SI 3 "arm_rhs_operand" "rM")]))
1993 (match_operand:SI 1 "s_register_operand" "r")))]
1995 "bic%?\\t%0, %1, %2%S4"
1996 [(set_attr "predicable" "yes")
1997 (set_attr "shift" "2")
1998 (set (attr "type") (if_then_else (match_operand 3 "const_int_operand" "")
1999 (const_string "alu_shift")
2000 (const_string "alu_shift_reg")))]
2003 (define_insn "*andsi_notsi_si_compare0"
2004 [(set (reg:CC_NOOV CC_REGNUM)
2006 (and:SI (not:SI (match_operand:SI 2 "s_register_operand" "r"))
2007 (match_operand:SI 1 "s_register_operand" "r"))
2009 (set (match_operand:SI 0 "s_register_operand" "=r")
2010 (and:SI (not:SI (match_dup 2)) (match_dup 1)))]
2012 "bic%?s\\t%0, %1, %2"
2013 [(set_attr "conds" "set")]
2016 (define_insn "*andsi_notsi_si_compare0_scratch"
2017 [(set (reg:CC_NOOV CC_REGNUM)
2019 (and:SI (not:SI (match_operand:SI 2 "s_register_operand" "r"))
2020 (match_operand:SI 1 "s_register_operand" "r"))
2022 (clobber (match_scratch:SI 0 "=r"))]
2024 "bic%?s\\t%0, %1, %2"
2025 [(set_attr "conds" "set")]
2028 (define_insn "iordi3"
2029 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2030 (ior:DI (match_operand:DI 1 "s_register_operand" "%0,r")
2031 (match_operand:DI 2 "s_register_operand" "r,r")))]
2032 "TARGET_ARM && ! TARGET_IWMMXT"
2034 [(set_attr "length" "8")
2035 (set_attr "predicable" "yes")]
2038 (define_insn "*iordi_zesidi_di"
2039 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2040 (ior:DI (zero_extend:DI
2041 (match_operand:SI 2 "s_register_operand" "r,r"))
2042 (match_operand:DI 1 "s_register_operand" "0,?r")))]
2045 orr%?\\t%Q0, %Q1, %2
2047 [(set_attr "length" "4,8")
2048 (set_attr "predicable" "yes")]
2051 (define_insn "*iordi_sesidi_di"
2052 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2053 (ior:DI (sign_extend:DI
2054 (match_operand:SI 2 "s_register_operand" "r,r"))
2055 (match_operand:DI 1 "s_register_operand" "?r,0")))]
2058 [(set_attr "length" "8")
2059 (set_attr "predicable" "yes")]
2062 (define_expand "iorsi3"
2063 [(set (match_operand:SI 0 "s_register_operand" "")
2064 (ior:SI (match_operand:SI 1 "s_register_operand" "")
2065 (match_operand:SI 2 "reg_or_int_operand" "")))]
2068 if (GET_CODE (operands[2]) == CONST_INT)
2072 arm_split_constant (IOR, SImode, INTVAL (operands[2]), operands[0],
2075 ? 0 : preserve_subexpressions_p ()));
2078 else /* TARGET_THUMB */
2079 operands [2] = force_reg (SImode, operands [2]);
2084 (define_insn_and_split "*arm_iorsi3"
2085 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
2086 (ior:SI (match_operand:SI 1 "s_register_operand" "r,r")
2087 (match_operand:SI 2 "reg_or_int_operand" "rI,?n")))]
2093 && GET_CODE (operands[2]) == CONST_INT
2094 && !const_ok_for_arm (INTVAL (operands[2]))"
2095 [(clobber (const_int 0))]
2097 arm_split_constant (IOR, SImode, INTVAL (operands[2]), operands[0],
2101 [(set_attr "length" "4,16")
2102 (set_attr "predicable" "yes")]
2105 (define_insn "*thumb_iorsi3"
2106 [(set (match_operand:SI 0 "register_operand" "=l")
2107 (ior:SI (match_operand:SI 1 "register_operand" "%0")
2108 (match_operand:SI 2 "register_operand" "l")))]
2111 [(set_attr "length" "2")]
2115 [(match_scratch:SI 3 "r")
2116 (set (match_operand:SI 0 "s_register_operand" "")
2117 (ior:SI (match_operand:SI 1 "s_register_operand" "")
2118 (match_operand:SI 2 "const_int_operand" "")))]
2120 && !const_ok_for_arm (INTVAL (operands[2]))
2121 && const_ok_for_arm (~INTVAL (operands[2]))"
2122 [(set (match_dup 3) (match_dup 2))
2123 (set (match_dup 0) (ior:SI (match_dup 1) (match_dup 3)))]
2127 (define_insn "*iorsi3_compare0"
2128 [(set (reg:CC_NOOV CC_REGNUM)
2129 (compare:CC_NOOV (ior:SI (match_operand:SI 1 "s_register_operand" "%r")
2130 (match_operand:SI 2 "arm_rhs_operand" "rI"))
2132 (set (match_operand:SI 0 "s_register_operand" "=r")
2133 (ior:SI (match_dup 1) (match_dup 2)))]
2135 "orr%?s\\t%0, %1, %2"
2136 [(set_attr "conds" "set")]
2139 (define_insn "*iorsi3_compare0_scratch"
2140 [(set (reg:CC_NOOV CC_REGNUM)
2141 (compare:CC_NOOV (ior:SI (match_operand:SI 1 "s_register_operand" "%r")
2142 (match_operand:SI 2 "arm_rhs_operand" "rI"))
2144 (clobber (match_scratch:SI 0 "=r"))]
2146 "orr%?s\\t%0, %1, %2"
2147 [(set_attr "conds" "set")]
2150 (define_insn "xordi3"
2151 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2152 (xor:DI (match_operand:DI 1 "s_register_operand" "%0,r")
2153 (match_operand:DI 2 "s_register_operand" "r,r")))]
2154 "TARGET_ARM && !TARGET_IWMMXT"
2156 [(set_attr "length" "8")
2157 (set_attr "predicable" "yes")]
2160 (define_insn "*xordi_zesidi_di"
2161 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2162 (xor:DI (zero_extend:DI
2163 (match_operand:SI 2 "s_register_operand" "r,r"))
2164 (match_operand:DI 1 "s_register_operand" "0,?r")))]
2167 eor%?\\t%Q0, %Q1, %2
2169 [(set_attr "length" "4,8")
2170 (set_attr "predicable" "yes")]
2173 (define_insn "*xordi_sesidi_di"
2174 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2175 (xor:DI (sign_extend:DI
2176 (match_operand:SI 2 "s_register_operand" "r,r"))
2177 (match_operand:DI 1 "s_register_operand" "?r,0")))]
2180 [(set_attr "length" "8")
2181 (set_attr "predicable" "yes")]
2184 (define_expand "xorsi3"
2185 [(set (match_operand:SI 0 "s_register_operand" "")
2186 (xor:SI (match_operand:SI 1 "s_register_operand" "")
2187 (match_operand:SI 2 "arm_rhs_operand" "")))]
2190 if (GET_CODE (operands[2]) == CONST_INT)
2191 operands[2] = force_reg (SImode, operands[2]);
2195 (define_insn "*arm_xorsi3"
2196 [(set (match_operand:SI 0 "s_register_operand" "=r")
2197 (xor:SI (match_operand:SI 1 "s_register_operand" "r")
2198 (match_operand:SI 2 "arm_rhs_operand" "rI")))]
2200 "eor%?\\t%0, %1, %2"
2201 [(set_attr "predicable" "yes")]
2204 (define_insn "*thumb_xorsi3"
2205 [(set (match_operand:SI 0 "register_operand" "=l")
2206 (xor:SI (match_operand:SI 1 "register_operand" "%0")
2207 (match_operand:SI 2 "register_operand" "l")))]
2210 [(set_attr "length" "2")]
2213 (define_insn "*xorsi3_compare0"
2214 [(set (reg:CC_NOOV CC_REGNUM)
2215 (compare:CC_NOOV (xor:SI (match_operand:SI 1 "s_register_operand" "r")
2216 (match_operand:SI 2 "arm_rhs_operand" "rI"))
2218 (set (match_operand:SI 0 "s_register_operand" "=r")
2219 (xor:SI (match_dup 1) (match_dup 2)))]
2221 "eor%?s\\t%0, %1, %2"
2222 [(set_attr "conds" "set")]
2225 (define_insn "*xorsi3_compare0_scratch"
2226 [(set (reg:CC_NOOV CC_REGNUM)
2227 (compare:CC_NOOV (xor:SI (match_operand:SI 0 "s_register_operand" "r")
2228 (match_operand:SI 1 "arm_rhs_operand" "rI"))
2232 [(set_attr "conds" "set")]
2235 ; By splitting (IOR (AND (NOT A) (NOT B)) C) as D = AND (IOR A B) (NOT C),
2236 ; (NOT D) we can sometimes merge the final NOT into one of the following
2240 [(set (match_operand:SI 0 "s_register_operand" "")
2241 (ior:SI (and:SI (not:SI (match_operand:SI 1 "s_register_operand" ""))
2242 (not:SI (match_operand:SI 2 "arm_rhs_operand" "")))
2243 (match_operand:SI 3 "arm_rhs_operand" "")))
2244 (clobber (match_operand:SI 4 "s_register_operand" ""))]
2246 [(set (match_dup 4) (and:SI (ior:SI (match_dup 1) (match_dup 2))
2247 (not:SI (match_dup 3))))
2248 (set (match_dup 0) (not:SI (match_dup 4)))]
2252 (define_insn "*andsi_iorsi3_notsi"
2253 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r")
2254 (and:SI (ior:SI (match_operand:SI 1 "s_register_operand" "r,r,0")
2255 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI"))
2256 (not:SI (match_operand:SI 3 "arm_rhs_operand" "rI,rI,rI"))))]
2258 "orr%?\\t%0, %1, %2\;bic%?\\t%0, %0, %3"
2259 [(set_attr "length" "8")
2260 (set_attr "predicable" "yes")]
2264 [(set (match_operand:SI 0 "s_register_operand" "")
2265 (match_operator:SI 1 "logical_binary_operator"
2266 [(zero_extract:SI (match_operand:SI 2 "s_register_operand" "")
2267 (match_operand:SI 3 "const_int_operand" "")
2268 (match_operand:SI 4 "const_int_operand" ""))
2269 (match_operator:SI 9 "logical_binary_operator"
2270 [(lshiftrt:SI (match_operand:SI 5 "s_register_operand" "")
2271 (match_operand:SI 6 "const_int_operand" ""))
2272 (match_operand:SI 7 "s_register_operand" "")])]))
2273 (clobber (match_operand:SI 8 "s_register_operand" ""))]
2275 && GET_CODE (operands[1]) == GET_CODE (operands[9])
2276 && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
2279 [(ashift:SI (match_dup 2) (match_dup 4))
2283 [(lshiftrt:SI (match_dup 8) (match_dup 6))
2286 operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
2290 [(set (match_operand:SI 0 "s_register_operand" "")
2291 (match_operator:SI 1 "logical_binary_operator"
2292 [(match_operator:SI 9 "logical_binary_operator"
2293 [(lshiftrt:SI (match_operand:SI 5 "s_register_operand" "")
2294 (match_operand:SI 6 "const_int_operand" ""))
2295 (match_operand:SI 7 "s_register_operand" "")])
2296 (zero_extract:SI (match_operand:SI 2 "s_register_operand" "")
2297 (match_operand:SI 3 "const_int_operand" "")
2298 (match_operand:SI 4 "const_int_operand" ""))]))
2299 (clobber (match_operand:SI 8 "s_register_operand" ""))]
2301 && GET_CODE (operands[1]) == GET_CODE (operands[9])
2302 && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
2305 [(ashift:SI (match_dup 2) (match_dup 4))
2309 [(lshiftrt:SI (match_dup 8) (match_dup 6))
2312 operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
2316 [(set (match_operand:SI 0 "s_register_operand" "")
2317 (match_operator:SI 1 "logical_binary_operator"
2318 [(sign_extract:SI (match_operand:SI 2 "s_register_operand" "")
2319 (match_operand:SI 3 "const_int_operand" "")
2320 (match_operand:SI 4 "const_int_operand" ""))
2321 (match_operator:SI 9 "logical_binary_operator"
2322 [(ashiftrt:SI (match_operand:SI 5 "s_register_operand" "")
2323 (match_operand:SI 6 "const_int_operand" ""))
2324 (match_operand:SI 7 "s_register_operand" "")])]))
2325 (clobber (match_operand:SI 8 "s_register_operand" ""))]
2327 && GET_CODE (operands[1]) == GET_CODE (operands[9])
2328 && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
2331 [(ashift:SI (match_dup 2) (match_dup 4))
2335 [(ashiftrt:SI (match_dup 8) (match_dup 6))
2338 operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
2342 [(set (match_operand:SI 0 "s_register_operand" "")
2343 (match_operator:SI 1 "logical_binary_operator"
2344 [(match_operator:SI 9 "logical_binary_operator"
2345 [(ashiftrt:SI (match_operand:SI 5 "s_register_operand" "")
2346 (match_operand:SI 6 "const_int_operand" ""))
2347 (match_operand:SI 7 "s_register_operand" "")])
2348 (sign_extract:SI (match_operand:SI 2 "s_register_operand" "")
2349 (match_operand:SI 3 "const_int_operand" "")
2350 (match_operand:SI 4 "const_int_operand" ""))]))
2351 (clobber (match_operand:SI 8 "s_register_operand" ""))]
2353 && GET_CODE (operands[1]) == GET_CODE (operands[9])
2354 && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
2357 [(ashift:SI (match_dup 2) (match_dup 4))
2361 [(ashiftrt:SI (match_dup 8) (match_dup 6))
2364 operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
2368 ;; Minimum and maximum insns
2370 (define_insn "smaxsi3"
2371 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
2372 (smax:SI (match_operand:SI 1 "s_register_operand" "0,r,?r")
2373 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
2374 (clobber (reg:CC CC_REGNUM))]
2377 cmp\\t%1, %2\;movlt\\t%0, %2
2378 cmp\\t%1, %2\;movge\\t%0, %1
2379 cmp\\t%1, %2\;movge\\t%0, %1\;movlt\\t%0, %2"
2380 [(set_attr "conds" "clob")
2381 (set_attr "length" "8,8,12")]
2384 (define_insn "sminsi3"
2385 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
2386 (smin:SI (match_operand:SI 1 "s_register_operand" "0,r,?r")
2387 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
2388 (clobber (reg:CC CC_REGNUM))]
2391 cmp\\t%1, %2\;movge\\t%0, %2
2392 cmp\\t%1, %2\;movlt\\t%0, %1
2393 cmp\\t%1, %2\;movlt\\t%0, %1\;movge\\t%0, %2"
2394 [(set_attr "conds" "clob")
2395 (set_attr "length" "8,8,12")]
2398 (define_insn "umaxsi3"
2399 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
2400 (umax:SI (match_operand:SI 1 "s_register_operand" "0,r,?r")
2401 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
2402 (clobber (reg:CC CC_REGNUM))]
2405 cmp\\t%1, %2\;movcc\\t%0, %2
2406 cmp\\t%1, %2\;movcs\\t%0, %1
2407 cmp\\t%1, %2\;movcs\\t%0, %1\;movcc\\t%0, %2"
2408 [(set_attr "conds" "clob")
2409 (set_attr "length" "8,8,12")]
2412 (define_insn "uminsi3"
2413 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
2414 (umin:SI (match_operand:SI 1 "s_register_operand" "0,r,?r")
2415 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
2416 (clobber (reg:CC CC_REGNUM))]
2419 cmp\\t%1, %2\;movcs\\t%0, %2
2420 cmp\\t%1, %2\;movcc\\t%0, %1
2421 cmp\\t%1, %2\;movcc\\t%0, %1\;movcs\\t%0, %2"
2422 [(set_attr "conds" "clob")
2423 (set_attr "length" "8,8,12")]
2426 (define_insn "*store_minmaxsi"
2427 [(set (match_operand:SI 0 "memory_operand" "=m")
2428 (match_operator:SI 3 "minmax_operator"
2429 [(match_operand:SI 1 "s_register_operand" "r")
2430 (match_operand:SI 2 "s_register_operand" "r")]))
2431 (clobber (reg:CC CC_REGNUM))]
2434 operands[3] = gen_rtx_fmt_ee (minmax_code (operands[3]), SImode,
2435 operands[1], operands[2]);
2436 output_asm_insn (\"cmp\\t%1, %2\", operands);
2437 output_asm_insn (\"str%d3\\t%1, %0\", operands);
2438 output_asm_insn (\"str%D3\\t%2, %0\", operands);
2441 [(set_attr "conds" "clob")
2442 (set_attr "length" "12")
2443 (set_attr "type" "store1")]
2446 ; Reject the frame pointer in operand[1], since reloading this after
2447 ; it has been eliminated can cause carnage.
2448 (define_insn "*minmax_arithsi"
2449 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
2450 (match_operator:SI 4 "shiftable_operator"
2451 [(match_operator:SI 5 "minmax_operator"
2452 [(match_operand:SI 2 "s_register_operand" "r,r")
2453 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
2454 (match_operand:SI 1 "s_register_operand" "0,?r")]))
2455 (clobber (reg:CC CC_REGNUM))]
2457 && (GET_CODE (operands[1]) != REG
2458 || (REGNO(operands[1]) != FRAME_POINTER_REGNUM
2459 && REGNO(operands[1]) != ARG_POINTER_REGNUM))"
2462 enum rtx_code code = GET_CODE (operands[4]);
2464 operands[5] = gen_rtx_fmt_ee (minmax_code (operands[5]), SImode,
2465 operands[2], operands[3]);
2466 output_asm_insn (\"cmp\\t%2, %3\", operands);
2467 output_asm_insn (\"%i4%d5\\t%0, %1, %2\", operands);
2468 if (which_alternative != 0 || operands[3] != const0_rtx
2469 || (code != PLUS && code != MINUS && code != IOR && code != XOR))
2470 output_asm_insn (\"%i4%D5\\t%0, %1, %3\", operands);
2473 [(set_attr "conds" "clob")
2474 (set_attr "length" "12")]
2478 ;; Shift and rotation insns
2480 (define_expand "ashldi3"
2481 [(set (match_operand:DI 0 "s_register_operand" "")
2482 (ashift:DI (match_operand:DI 1 "s_register_operand" "")
2483 (match_operand:SI 2 "reg_or_int_operand" "")))]
2486 if (GET_CODE (operands[2]) == CONST_INT)
2488 if ((HOST_WIDE_INT) INTVAL (operands[2]) == 1)
2490 emit_insn (gen_arm_ashldi3_1bit (operands[0], operands[1]));
2493 /* Ideally we shouldn't fail here if we could know that operands[1]
2494 ends up already living in an iwmmxt register. Otherwise it's
2495 cheaper to have the alternate code being generated than moving
2496 values to iwmmxt regs and back. */
2499 else if (!TARGET_REALLY_IWMMXT && !(TARGET_HARD_FLOAT && TARGET_MAVERICK))
2504 (define_insn "arm_ashldi3_1bit"
2505 [(set (match_operand:DI 0 "s_register_operand" "=&r,r")
2506 (ashift:DI (match_operand:DI 1 "s_register_operand" "?r,0")
2508 (clobber (reg:CC CC_REGNUM))]
2510 "movs\\t%Q0, %Q1, asl #1\;adc\\t%R0, %R1, %R1"
2511 [(set_attr "conds" "clob")
2512 (set_attr "length" "8")]
2515 (define_expand "ashlsi3"
2516 [(set (match_operand:SI 0 "s_register_operand" "")
2517 (ashift:SI (match_operand:SI 1 "s_register_operand" "")
2518 (match_operand:SI 2 "arm_rhs_operand" "")))]
2521 if (GET_CODE (operands[2]) == CONST_INT
2522 && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) > 31)
2524 emit_insn (gen_movsi (operands[0], const0_rtx));
2530 (define_insn "*thumb_ashlsi3"
2531 [(set (match_operand:SI 0 "register_operand" "=l,l")
2532 (ashift:SI (match_operand:SI 1 "register_operand" "l,0")
2533 (match_operand:SI 2 "nonmemory_operand" "N,l")))]
2536 [(set_attr "length" "2")]
2539 (define_expand "ashrdi3"
2540 [(set (match_operand:DI 0 "s_register_operand" "")
2541 (ashiftrt:DI (match_operand:DI 1 "s_register_operand" "")
2542 (match_operand:SI 2 "reg_or_int_operand" "")))]
2545 if (GET_CODE (operands[2]) == CONST_INT)
2547 if ((HOST_WIDE_INT) INTVAL (operands[2]) == 1)
2549 emit_insn (gen_arm_ashrdi3_1bit (operands[0], operands[1]));
2552 /* Ideally we shouldn't fail here if we could know that operands[1]
2553 ends up already living in an iwmmxt register. Otherwise it's
2554 cheaper to have the alternate code being generated than moving
2555 values to iwmmxt regs and back. */
2558 else if (!TARGET_REALLY_IWMMXT)
2563 (define_insn "arm_ashrdi3_1bit"
2564 [(set (match_operand:DI 0 "s_register_operand" "=&r,r")
2565 (ashiftrt:DI (match_operand:DI 1 "s_register_operand" "?r,0")
2567 (clobber (reg:CC CC_REGNUM))]
2569 "movs\\t%R0, %R1, asr #1\;mov\\t%Q0, %Q1, rrx"
2570 [(set_attr "conds" "clob")
2571 (set_attr "length" "8")]
2574 (define_expand "ashrsi3"
2575 [(set (match_operand:SI 0 "s_register_operand" "")
2576 (ashiftrt:SI (match_operand:SI 1 "s_register_operand" "")
2577 (match_operand:SI 2 "arm_rhs_operand" "")))]
2580 if (GET_CODE (operands[2]) == CONST_INT
2581 && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) > 31)
2582 operands[2] = GEN_INT (31);
2586 (define_insn "*thumb_ashrsi3"
2587 [(set (match_operand:SI 0 "register_operand" "=l,l")
2588 (ashiftrt:SI (match_operand:SI 1 "register_operand" "l,0")
2589 (match_operand:SI 2 "nonmemory_operand" "N,l")))]
2592 [(set_attr "length" "2")]
2595 (define_expand "lshrdi3"
2596 [(set (match_operand:DI 0 "s_register_operand" "")
2597 (lshiftrt:DI (match_operand:DI 1 "s_register_operand" "")
2598 (match_operand:SI 2 "reg_or_int_operand" "")))]
2601 if (GET_CODE (operands[2]) == CONST_INT)
2603 if ((HOST_WIDE_INT) INTVAL (operands[2]) == 1)
2605 emit_insn (gen_arm_lshrdi3_1bit (operands[0], operands[1]));
2608 /* Ideally we shouldn't fail here if we could know that operands[1]
2609 ends up already living in an iwmmxt register. Otherwise it's
2610 cheaper to have the alternate code being generated than moving
2611 values to iwmmxt regs and back. */
2614 else if (!TARGET_REALLY_IWMMXT)
2619 (define_insn "arm_lshrdi3_1bit"
2620 [(set (match_operand:DI 0 "s_register_operand" "=&r,r")
2621 (lshiftrt:DI (match_operand:DI 1 "s_register_operand" "?r,0")
2623 (clobber (reg:CC CC_REGNUM))]
2625 "movs\\t%R0, %R1, lsr #1\;mov\\t%Q0, %Q1, rrx"
2626 [(set_attr "conds" "clob")
2627 (set_attr "length" "8")]
2630 (define_expand "lshrsi3"
2631 [(set (match_operand:SI 0 "s_register_operand" "")
2632 (lshiftrt:SI (match_operand:SI 1 "s_register_operand" "")
2633 (match_operand:SI 2 "arm_rhs_operand" "")))]
2636 if (GET_CODE (operands[2]) == CONST_INT
2637 && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) > 31)
2639 emit_insn (gen_movsi (operands[0], const0_rtx));
2645 (define_insn "*thumb_lshrsi3"
2646 [(set (match_operand:SI 0 "register_operand" "=l,l")
2647 (lshiftrt:SI (match_operand:SI 1 "register_operand" "l,0")
2648 (match_operand:SI 2 "nonmemory_operand" "N,l")))]
2651 [(set_attr "length" "2")]
2654 (define_expand "rotlsi3"
2655 [(set (match_operand:SI 0 "s_register_operand" "")
2656 (rotatert:SI (match_operand:SI 1 "s_register_operand" "")
2657 (match_operand:SI 2 "reg_or_int_operand" "")))]
2660 if (GET_CODE (operands[2]) == CONST_INT)
2661 operands[2] = GEN_INT ((32 - INTVAL (operands[2])) % 32);
2664 rtx reg = gen_reg_rtx (SImode);
2665 emit_insn (gen_subsi3 (reg, GEN_INT (32), operands[2]));
2671 (define_expand "rotrsi3"
2672 [(set (match_operand:SI 0 "s_register_operand" "")
2673 (rotatert:SI (match_operand:SI 1 "s_register_operand" "")
2674 (match_operand:SI 2 "arm_rhs_operand" "")))]
2679 if (GET_CODE (operands[2]) == CONST_INT
2680 && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) > 31)
2681 operands[2] = GEN_INT (INTVAL (operands[2]) % 32);
2683 else /* TARGET_THUMB */
2685 if (GET_CODE (operands [2]) == CONST_INT)
2686 operands [2] = force_reg (SImode, operands[2]);
2691 (define_insn "*thumb_rotrsi3"
2692 [(set (match_operand:SI 0 "register_operand" "=l")
2693 (rotatert:SI (match_operand:SI 1 "register_operand" "0")
2694 (match_operand:SI 2 "register_operand" "l")))]
2697 [(set_attr "length" "2")]
2700 (define_insn "*arm_shiftsi3"
2701 [(set (match_operand:SI 0 "s_register_operand" "=r")
2702 (match_operator:SI 3 "shift_operator"
2703 [(match_operand:SI 1 "s_register_operand" "r")
2704 (match_operand:SI 2 "reg_or_int_operand" "rM")]))]
2707 [(set_attr "predicable" "yes")
2708 (set_attr "shift" "1")
2709 (set (attr "type") (if_then_else (match_operand 2 "const_int_operand" "")
2710 (const_string "alu_shift")
2711 (const_string "alu_shift_reg")))]
2714 (define_insn "*shiftsi3_compare0"
2715 [(set (reg:CC_NOOV CC_REGNUM)
2716 (compare:CC_NOOV (match_operator:SI 3 "shift_operator"
2717 [(match_operand:SI 1 "s_register_operand" "r")
2718 (match_operand:SI 2 "arm_rhs_operand" "rM")])
2720 (set (match_operand:SI 0 "s_register_operand" "=r")
2721 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))]
2723 "mov%?s\\t%0, %1%S3"
2724 [(set_attr "conds" "set")
2725 (set_attr "shift" "1")
2726 (set (attr "type") (if_then_else (match_operand 2 "const_int_operand" "")
2727 (const_string "alu_shift")
2728 (const_string "alu_shift_reg")))]
2731 (define_insn "*shiftsi3_compare0_scratch"
2732 [(set (reg:CC_NOOV CC_REGNUM)
2733 (compare:CC_NOOV (match_operator:SI 3 "shift_operator"
2734 [(match_operand:SI 1 "s_register_operand" "r")
2735 (match_operand:SI 2 "arm_rhs_operand" "rM")])
2737 (clobber (match_scratch:SI 0 "=r"))]
2739 "mov%?s\\t%0, %1%S3"
2740 [(set_attr "conds" "set")
2741 (set_attr "shift" "1")]
2744 (define_insn "*notsi_shiftsi"
2745 [(set (match_operand:SI 0 "s_register_operand" "=r")
2746 (not:SI (match_operator:SI 3 "shift_operator"
2747 [(match_operand:SI 1 "s_register_operand" "r")
2748 (match_operand:SI 2 "arm_rhs_operand" "rM")])))]
2751 [(set_attr "predicable" "yes")
2752 (set_attr "shift" "1")
2753 (set (attr "type") (if_then_else (match_operand 2 "const_int_operand" "")
2754 (const_string "alu_shift")
2755 (const_string "alu_shift_reg")))]
2758 (define_insn "*notsi_shiftsi_compare0"
2759 [(set (reg:CC_NOOV CC_REGNUM)
2760 (compare:CC_NOOV (not:SI (match_operator:SI 3 "shift_operator"
2761 [(match_operand:SI 1 "s_register_operand" "r")
2762 (match_operand:SI 2 "arm_rhs_operand" "rM")]))
2764 (set (match_operand:SI 0 "s_register_operand" "=r")
2765 (not:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)])))]
2767 "mvn%?s\\t%0, %1%S3"
2768 [(set_attr "conds" "set")
2769 (set_attr "shift" "1")
2770 (set (attr "type") (if_then_else (match_operand 2 "const_int_operand" "")
2771 (const_string "alu_shift")
2772 (const_string "alu_shift_reg")))]
2775 (define_insn "*not_shiftsi_compare0_scratch"
2776 [(set (reg:CC_NOOV CC_REGNUM)
2777 (compare:CC_NOOV (not:SI (match_operator:SI 3 "shift_operator"
2778 [(match_operand:SI 1 "s_register_operand" "r")
2779 (match_operand:SI 2 "arm_rhs_operand" "rM")]))
2781 (clobber (match_scratch:SI 0 "=r"))]
2783 "mvn%?s\\t%0, %1%S3"
2784 [(set_attr "conds" "set")
2785 (set_attr "shift" "1")
2786 (set (attr "type") (if_then_else (match_operand 2 "const_int_operand" "")
2787 (const_string "alu_shift")
2788 (const_string "alu_shift_reg")))]
2791 ;; We don't really have extzv, but defining this using shifts helps
2792 ;; to reduce register pressure later on.
2794 (define_expand "extzv"
2796 (ashift:SI (match_operand:SI 1 "register_operand" "")
2797 (match_operand:SI 2 "const_int_operand" "")))
2798 (set (match_operand:SI 0 "register_operand" "")
2799 (lshiftrt:SI (match_dup 4)
2800 (match_operand:SI 3 "const_int_operand" "")))]
2804 HOST_WIDE_INT lshift = 32 - INTVAL (operands[2]) - INTVAL (operands[3]);
2805 HOST_WIDE_INT rshift = 32 - INTVAL (operands[2]);
2807 operands[3] = GEN_INT (rshift);
2811 emit_insn (gen_lshrsi3 (operands[0], operands[1], operands[3]));
2815 operands[2] = GEN_INT (lshift);
2816 operands[4] = gen_reg_rtx (SImode);
2821 ;; Unary arithmetic insns
2823 (define_expand "negdi2"
2825 [(set (match_operand:DI 0 "s_register_operand" "")
2826 (neg:DI (match_operand:DI 1 "s_register_operand" "")))
2827 (clobber (reg:CC CC_REGNUM))])]
2832 if (GET_CODE (operands[1]) != REG)
2833 operands[1] = force_reg (SImode, operands[1]);
2838 ;; The constraints here are to prevent a *partial* overlap (where %Q0 == %R1).
2839 ;; The second alternative is to allow the common case of a *full* overlap.
2840 (define_insn "*arm_negdi2"
2841 [(set (match_operand:DI 0 "s_register_operand" "=&r,r")
2842 (neg:DI (match_operand:DI 1 "s_register_operand" "?r,0")))
2843 (clobber (reg:CC CC_REGNUM))]
2845 "rsbs\\t%Q0, %Q1, #0\;rsc\\t%R0, %R1, #0"
2846 [(set_attr "conds" "clob")
2847 (set_attr "length" "8")]
2850 (define_insn "*thumb_negdi2"
2851 [(set (match_operand:DI 0 "register_operand" "=&l")
2852 (neg:DI (match_operand:DI 1 "register_operand" "l")))
2853 (clobber (reg:CC CC_REGNUM))]
2855 "mov\\t%R0, #0\;neg\\t%Q0, %Q1\;sbc\\t%R0, %R1"
2856 [(set_attr "length" "6")]
2859 (define_expand "negsi2"
2860 [(set (match_operand:SI 0 "s_register_operand" "")
2861 (neg:SI (match_operand:SI 1 "s_register_operand" "")))]
2866 (define_insn "*arm_negsi2"
2867 [(set (match_operand:SI 0 "s_register_operand" "=r")
2868 (neg:SI (match_operand:SI 1 "s_register_operand" "r")))]
2870 "rsb%?\\t%0, %1, #0"
2871 [(set_attr "predicable" "yes")]
2874 (define_insn "*thumb_negsi2"
2875 [(set (match_operand:SI 0 "register_operand" "=l")
2876 (neg:SI (match_operand:SI 1 "register_operand" "l")))]
2879 [(set_attr "length" "2")]
2882 (define_expand "negsf2"
2883 [(set (match_operand:SF 0 "s_register_operand" "")
2884 (neg:SF (match_operand:SF 1 "s_register_operand" "")))]
2885 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
2889 (define_expand "negdf2"
2890 [(set (match_operand:DF 0 "s_register_operand" "")
2891 (neg:DF (match_operand:DF 1 "s_register_operand" "")))]
2892 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
2895 ;; abssi2 doesn't really clobber the condition codes if a different register
2896 ;; is being set. To keep things simple, assume during rtl manipulations that
2897 ;; it does, but tell the final scan operator the truth. Similarly for
2900 (define_expand "abssi2"
2902 [(set (match_operand:SI 0 "s_register_operand" "")
2903 (abs:SI (match_operand:SI 1 "s_register_operand" "")))
2904 (clobber (reg:CC CC_REGNUM))])]
2908 (define_insn "*arm_abssi2"
2909 [(set (match_operand:SI 0 "s_register_operand" "=r,&r")
2910 (abs:SI (match_operand:SI 1 "s_register_operand" "0,r")))
2911 (clobber (reg:CC CC_REGNUM))]
2914 cmp\\t%0, #0\;rsblt\\t%0, %0, #0
2915 eor%?\\t%0, %1, %1, asr #31\;sub%?\\t%0, %0, %1, asr #31"
2916 [(set_attr "conds" "clob,*")
2917 (set_attr "shift" "1")
2918 ;; predicable can't be set based on the variant, so left as no
2919 (set_attr "length" "8")]
2922 (define_insn "*neg_abssi2"
2923 [(set (match_operand:SI 0 "s_register_operand" "=r,&r")
2924 (neg:SI (abs:SI (match_operand:SI 1 "s_register_operand" "0,r"))))
2925 (clobber (reg:CC CC_REGNUM))]
2928 cmp\\t%0, #0\;rsbgt\\t%0, %0, #0
2929 eor%?\\t%0, %1, %1, asr #31\;rsb%?\\t%0, %0, %1, asr #31"
2930 [(set_attr "conds" "clob,*")
2931 (set_attr "shift" "1")
2932 ;; predicable can't be set based on the variant, so left as no
2933 (set_attr "length" "8")]
2936 (define_expand "abssf2"
2937 [(set (match_operand:SF 0 "s_register_operand" "")
2938 (abs:SF (match_operand:SF 1 "s_register_operand" "")))]
2939 "TARGET_ARM && TARGET_HARD_FLOAT"
2942 (define_expand "absdf2"
2943 [(set (match_operand:DF 0 "s_register_operand" "")
2944 (abs:DF (match_operand:DF 1 "s_register_operand" "")))]
2945 "TARGET_ARM && TARGET_HARD_FLOAT"
2948 (define_expand "sqrtsf2"
2949 [(set (match_operand:SF 0 "s_register_operand" "")
2950 (sqrt:SF (match_operand:SF 1 "s_register_operand" "")))]
2951 "TARGET_ARM && TARGET_HARD_FLOAT && (TARGET_FPA || TARGET_VFP)"
2954 (define_expand "sqrtdf2"
2955 [(set (match_operand:DF 0 "s_register_operand" "")
2956 (sqrt:DF (match_operand:DF 1 "s_register_operand" "")))]
2957 "TARGET_ARM && TARGET_HARD_FLOAT && (TARGET_FPA || TARGET_VFP)"
2960 (define_insn_and_split "one_cmpldi2"
2961 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2962 (not:DI (match_operand:DI 1 "s_register_operand" "?r,0")))]
2965 "TARGET_ARM && reload_completed"
2966 [(set (match_dup 0) (not:SI (match_dup 1)))
2967 (set (match_dup 2) (not:SI (match_dup 3)))]
2970 operands[2] = gen_highpart (SImode, operands[0]);
2971 operands[0] = gen_lowpart (SImode, operands[0]);
2972 operands[3] = gen_highpart (SImode, operands[1]);
2973 operands[1] = gen_lowpart (SImode, operands[1]);
2975 [(set_attr "length" "8")
2976 (set_attr "predicable" "yes")]
2979 (define_expand "one_cmplsi2"
2980 [(set (match_operand:SI 0 "s_register_operand" "")
2981 (not:SI (match_operand:SI 1 "s_register_operand" "")))]
2986 (define_insn "*arm_one_cmplsi2"
2987 [(set (match_operand:SI 0 "s_register_operand" "=r")
2988 (not:SI (match_operand:SI 1 "s_register_operand" "r")))]
2991 [(set_attr "predicable" "yes")]
2994 (define_insn "*thumb_one_cmplsi2"
2995 [(set (match_operand:SI 0 "register_operand" "=l")
2996 (not:SI (match_operand:SI 1 "register_operand" "l")))]
2999 [(set_attr "length" "2")]
3002 (define_insn "*notsi_compare0"
3003 [(set (reg:CC_NOOV CC_REGNUM)
3004 (compare:CC_NOOV (not:SI (match_operand:SI 1 "s_register_operand" "r"))
3006 (set (match_operand:SI 0 "s_register_operand" "=r")
3007 (not:SI (match_dup 1)))]
3010 [(set_attr "conds" "set")]
3013 (define_insn "*notsi_compare0_scratch"
3014 [(set (reg:CC_NOOV CC_REGNUM)
3015 (compare:CC_NOOV (not:SI (match_operand:SI 1 "s_register_operand" "r"))
3017 (clobber (match_scratch:SI 0 "=r"))]
3020 [(set_attr "conds" "set")]
3023 ;; Fixed <--> Floating conversion insns
3025 (define_expand "floatsisf2"
3026 [(set (match_operand:SF 0 "s_register_operand" "")
3027 (float:SF (match_operand:SI 1 "s_register_operand" "")))]
3028 "TARGET_ARM && TARGET_HARD_FLOAT"
3030 if (TARGET_MAVERICK)
3032 emit_insn (gen_cirrus_floatsisf2 (operands[0], operands[1]));
3037 (define_expand "floatsidf2"
3038 [(set (match_operand:DF 0 "s_register_operand" "")
3039 (float:DF (match_operand:SI 1 "s_register_operand" "")))]
3040 "TARGET_ARM && TARGET_HARD_FLOAT"
3042 if (TARGET_MAVERICK)
3044 emit_insn (gen_cirrus_floatsidf2 (operands[0], operands[1]));
3049 (define_expand "fix_truncsfsi2"
3050 [(set (match_operand:SI 0 "s_register_operand" "")
3051 (fix:SI (fix:SF (match_operand:SF 1 "s_register_operand" ""))))]
3052 "TARGET_ARM && TARGET_HARD_FLOAT"
3054 if (TARGET_MAVERICK)
3056 if (!cirrus_fp_register (operands[0], SImode))
3057 operands[0] = force_reg (SImode, operands[0]);
3058 if (!cirrus_fp_register (operands[1], SFmode))
3059 operands[1] = force_reg (SFmode, operands[0]);
3060 emit_insn (gen_cirrus_truncsfsi2 (operands[0], operands[1]));
3065 (define_expand "fix_truncdfsi2"
3066 [(set (match_operand:SI 0 "s_register_operand" "")
3067 (fix:SI (fix:DF (match_operand:DF 1 "s_register_operand" ""))))]
3068 "TARGET_ARM && TARGET_HARD_FLOAT"
3070 if (TARGET_MAVERICK)
3072 if (!cirrus_fp_register (operands[1], DFmode))
3073 operands[1] = force_reg (DFmode, operands[0]);
3074 emit_insn (gen_cirrus_truncdfsi2 (operands[0], operands[1]));
3081 (define_expand "truncdfsf2"
3082 [(set (match_operand:SF 0 "s_register_operand" "")
3084 (match_operand:DF 1 "s_register_operand" "")))]
3085 "TARGET_ARM && TARGET_HARD_FLOAT"
3089 ;; Zero and sign extension instructions.
3091 (define_insn "zero_extendsidi2"
3092 [(set (match_operand:DI 0 "s_register_operand" "=r")
3093 (zero_extend:DI (match_operand:SI 1 "s_register_operand" "r")))]
3096 if (REGNO (operands[1])
3097 != REGNO (operands[0]) + (WORDS_BIG_ENDIAN ? 1 : 0))
3098 output_asm_insn (\"mov%?\\t%Q0, %1\", operands);
3099 return \"mov%?\\t%R0, #0\";
3101 [(set_attr "length" "8")
3102 (set_attr "predicable" "yes")]
3105 (define_insn "zero_extendqidi2"
3106 [(set (match_operand:DI 0 "s_register_operand" "=r,r")
3107 (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
3110 and%?\\t%Q0, %1, #255\;mov%?\\t%R0, #0
3111 ldr%?b\\t%Q0, %1\;mov%?\\t%R0, #0"
3112 [(set_attr "length" "8")
3113 (set_attr "predicable" "yes")
3114 (set_attr "type" "*,load_byte")
3115 (set_attr "pool_range" "*,4092")
3116 (set_attr "neg_pool_range" "*,4084")]
3119 (define_insn "extendsidi2"
3120 [(set (match_operand:DI 0 "s_register_operand" "=r")
3121 (sign_extend:DI (match_operand:SI 1 "s_register_operand" "r")))]
3124 if (REGNO (operands[1])
3125 != REGNO (operands[0]) + (WORDS_BIG_ENDIAN ? 1 : 0))
3126 output_asm_insn (\"mov%?\\t%Q0, %1\", operands);
3127 return \"mov%?\\t%R0, %Q0, asr #31\";
3129 [(set_attr "length" "8")
3130 (set_attr "shift" "1")
3131 (set_attr "predicable" "yes")]
3134 (define_expand "zero_extendhisi2"
3136 (ashift:SI (match_operand:HI 1 "nonimmediate_operand" "")
3138 (set (match_operand:SI 0 "s_register_operand" "")
3139 (lshiftrt:SI (match_dup 2) (const_int 16)))]
3143 if ((TARGET_THUMB || arm_arch4) && GET_CODE (operands[1]) == MEM)
3145 /* Note: We do not have to worry about TARGET_MMU_TRAPS
3146 here because the insn below will generate an LDRH instruction
3147 rather than an LDR instruction, so we cannot get an unaligned
3149 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
3150 gen_rtx_ZERO_EXTEND (SImode, operands[1])));
3154 if (TARGET_ARM && TARGET_MMU_TRAPS && GET_CODE (operands[1]) == MEM)
3156 emit_insn (gen_movhi_bytes (operands[0], operands[1]));
3160 if (!s_register_operand (operands[1], HImode))
3161 operands[1] = copy_to_mode_reg (HImode, operands[1]);
3165 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
3166 gen_rtx_ZERO_EXTEND (SImode, operands[1])));
3170 operands[1] = gen_lowpart (SImode, operands[1]);
3171 operands[2] = gen_reg_rtx (SImode);
3175 (define_insn "*thumb_zero_extendhisi2"
3176 [(set (match_operand:SI 0 "register_operand" "=l")
3177 (zero_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
3178 "TARGET_THUMB && !arm_arch6"
3180 rtx mem = XEXP (operands[1], 0);
3182 if (GET_CODE (mem) == CONST)
3183 mem = XEXP (mem, 0);
3185 if (GET_CODE (mem) == LABEL_REF)
3186 return \"ldr\\t%0, %1\";
3188 if (GET_CODE (mem) == PLUS)
3190 rtx a = XEXP (mem, 0);
3191 rtx b = XEXP (mem, 1);
3193 /* This can happen due to bugs in reload. */
3194 if (GET_CODE (a) == REG && REGNO (a) == SP_REGNUM)
3197 ops[0] = operands[0];
3200 output_asm_insn (\"mov %0, %1\", ops);
3202 XEXP (mem, 0) = operands[0];
3205 else if ( GET_CODE (a) == LABEL_REF
3206 && GET_CODE (b) == CONST_INT)
3207 return \"ldr\\t%0, %1\";
3210 return \"ldrh\\t%0, %1\";
3212 [(set_attr "length" "4")
3213 (set_attr "type" "load_byte")
3214 (set_attr "pool_range" "60")]
3217 (define_insn "*thumb_zero_extendhisi2_v6"
3218 [(set (match_operand:SI 0 "register_operand" "=l,l")
3219 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "l,m")))]
3220 "TARGET_THUMB && arm_arch6"
3224 if (which_alternative == 0)
3225 return \"uxth\\t%0, %1\";
3227 mem = XEXP (operands[1], 0);
3229 if (GET_CODE (mem) == CONST)
3230 mem = XEXP (mem, 0);
3232 if (GET_CODE (mem) == LABEL_REF)
3233 return \"ldr\\t%0, %1\";
3235 if (GET_CODE (mem) == PLUS)
3237 rtx a = XEXP (mem, 0);
3238 rtx b = XEXP (mem, 1);
3240 /* This can happen due to bugs in reload. */
3241 if (GET_CODE (a) == REG && REGNO (a) == SP_REGNUM)
3244 ops[0] = operands[0];
3247 output_asm_insn (\"mov %0, %1\", ops);
3249 XEXP (mem, 0) = operands[0];
3252 else if ( GET_CODE (a) == LABEL_REF
3253 && GET_CODE (b) == CONST_INT)
3254 return \"ldr\\t%0, %1\";
3257 return \"ldrh\\t%0, %1\";
3259 [(set_attr "length" "2,4")
3260 (set_attr "type" "alu_shift,load_byte")
3261 (set_attr "pool_range" "*,60")]
3264 (define_insn "*arm_zero_extendhisi2"
3265 [(set (match_operand:SI 0 "s_register_operand" "=r")
3266 (zero_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
3267 "TARGET_ARM && arm_arch4 && !arm_arch6"
3269 [(set_attr "type" "load_byte")
3270 (set_attr "predicable" "yes")
3271 (set_attr "pool_range" "256")
3272 (set_attr "neg_pool_range" "244")]
3275 (define_insn "*arm_zero_extendhisi2_v6"
3276 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
3277 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
3278 "TARGET_ARM && arm_arch6"
3282 [(set_attr "type" "alu_shift,load_byte")
3283 (set_attr "predicable" "yes")
3284 (set_attr "pool_range" "*,256")
3285 (set_attr "neg_pool_range" "*,244")]
3288 (define_insn "*arm_zero_extendhisi2addsi"
3289 [(set (match_operand:SI 0 "s_register_operand" "=r")
3290 (plus:SI (zero_extend:SI (match_operand:HI 1 "s_register_operand" "r"))
3291 (match_operand:SI 2 "s_register_operand" "r")))]
3292 "TARGET_ARM && arm_arch6"
3293 "uxtah%?\\t%0, %2, %1"
3294 [(set_attr "type" "alu_shift")
3295 (set_attr "predicable" "yes")]
3299 [(set (match_operand:SI 0 "s_register_operand" "")
3300 (zero_extend:SI (match_operand:HI 1 "alignable_memory_operand" "")))
3301 (clobber (match_operand:SI 2 "s_register_operand" ""))]
3302 "TARGET_ARM && (!arm_arch4)"
3303 [(set (match_dup 2) (match_dup 1))
3304 (set (match_dup 0) (lshiftrt:SI (match_dup 2) (const_int 16)))]
3306 if ((operands[1] = arm_gen_rotated_half_load (operands[1])) == NULL)
3312 [(set (match_operand:SI 0 "s_register_operand" "")
3313 (match_operator:SI 3 "shiftable_operator"
3314 [(zero_extend:SI (match_operand:HI 1 "alignable_memory_operand" ""))
3315 (match_operand:SI 4 "s_register_operand" "")]))
3316 (clobber (match_operand:SI 2 "s_register_operand" ""))]
3317 "TARGET_ARM && (!arm_arch4)"
3318 [(set (match_dup 2) (match_dup 1))
3321 [(lshiftrt:SI (match_dup 2) (const_int 16)) (match_dup 4)]))]
3323 if ((operands[1] = arm_gen_rotated_half_load (operands[1])) == NULL)
3328 (define_expand "zero_extendqisi2"
3329 [(set (match_operand:SI 0 "s_register_operand" "")
3330 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))]
3333 if (!arm_arch6 && GET_CODE (operands[1]) != MEM)
3337 emit_insn (gen_andsi3 (operands[0],
3338 gen_lowpart (SImode, operands[1]),
3341 else /* TARGET_THUMB */
3343 rtx temp = gen_reg_rtx (SImode);
3346 operands[1] = copy_to_mode_reg (QImode, operands[1]);
3347 operands[1] = gen_lowpart (SImode, operands[1]);
3350 ops[1] = operands[1];
3351 ops[2] = GEN_INT (24);
3353 emit_insn (gen_rtx_SET (VOIDmode, ops[0],
3354 gen_rtx_ASHIFT (SImode, ops[1], ops[2])));
3356 ops[0] = operands[0];
3358 ops[2] = GEN_INT (24);
3360 emit_insn (gen_rtx_SET (VOIDmode, ops[0],
3361 gen_rtx_LSHIFTRT (SImode, ops[1], ops[2])));
3368 (define_insn "*thumb_zero_extendqisi2"
3369 [(set (match_operand:SI 0 "register_operand" "=l")
3370 (zero_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
3371 "TARGET_THUMB && !arm_arch6"
3373 [(set_attr "length" "2")
3374 (set_attr "type" "load_byte")
3375 (set_attr "pool_range" "32")]
3378 (define_insn "*thumb_zero_extendqisi2_v6"
3379 [(set (match_operand:SI 0 "register_operand" "=l,l")
3380 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "l,m")))]
3381 "TARGET_THUMB && arm_arch6"
3385 [(set_attr "length" "2,2")
3386 (set_attr "type" "alu_shift,load_byte")
3387 (set_attr "pool_range" "*,32")]
3390 (define_insn "*arm_zero_extendqisi2"
3391 [(set (match_operand:SI 0 "s_register_operand" "=r")
3392 (zero_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
3393 "TARGET_ARM && !arm_arch6"
3394 "ldr%?b\\t%0, %1\\t%@ zero_extendqisi2"
3395 [(set_attr "type" "load_byte")
3396 (set_attr "predicable" "yes")
3397 (set_attr "pool_range" "4096")
3398 (set_attr "neg_pool_range" "4084")]
3401 (define_insn "*arm_zero_extendqisi2_v6"
3402 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
3403 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
3404 "TARGET_ARM && arm_arch6"
3407 ldr%?b\\t%0, %1\\t%@ zero_extendqisi2"
3408 [(set_attr "type" "alu_shift,load_byte")
3409 (set_attr "predicable" "yes")
3410 (set_attr "pool_range" "*,4096")
3411 (set_attr "neg_pool_range" "*,4084")]
3414 (define_insn "*arm_zero_extendqisi2addsi"
3415 [(set (match_operand:SI 0 "s_register_operand" "=r")
3416 (plus:SI (zero_extend:SI (match_operand:QI 1 "s_register_operand" "r"))
3417 (match_operand:SI 2 "s_register_operand" "r")))]
3418 "TARGET_ARM && arm_arch6"
3419 "uxtab%?\\t%0, %2, %1"
3420 [(set_attr "predicable" "yes")
3421 (set_attr "type" "alu_shift")]
3425 [(set (match_operand:SI 0 "s_register_operand" "")
3426 (zero_extend:SI (subreg:QI (match_operand:SI 1 "" "") 0)))
3427 (clobber (match_operand:SI 2 "s_register_operand" ""))]
3428 "TARGET_ARM && (GET_CODE (operands[1]) != MEM) && ! BYTES_BIG_ENDIAN"
3429 [(set (match_dup 2) (match_dup 1))
3430 (set (match_dup 0) (and:SI (match_dup 2) (const_int 255)))]
3434 (define_insn "*compareqi_eq0"
3435 [(set (reg:CC_Z CC_REGNUM)
3436 (compare:CC_Z (match_operand:QI 0 "s_register_operand" "r")
3440 [(set_attr "conds" "set")]
3443 (define_expand "extendhisi2"
3445 (ashift:SI (match_operand:HI 1 "nonimmediate_operand" "")
3447 (set (match_operand:SI 0 "s_register_operand" "")
3448 (ashiftrt:SI (match_dup 2)
3453 if (GET_CODE (operands[1]) == MEM)
3457 emit_insn (gen_thumb_extendhisi2 (operands[0], operands[1]));
3462 /* Note: We do not have to worry about TARGET_MMU_TRAPS
3463 here because the insn below will generate an LDRH instruction
3464 rather than an LDR instruction, so we cannot get an unaligned
3466 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
3467 gen_rtx_SIGN_EXTEND (SImode, operands[1])));
3472 if (TARGET_ARM && TARGET_MMU_TRAPS && GET_CODE (operands[1]) == MEM)
3474 emit_insn (gen_extendhisi2_mem (operands[0], operands[1]));
3478 if (!s_register_operand (operands[1], HImode))
3479 operands[1] = copy_to_mode_reg (HImode, operands[1]);
3484 emit_insn (gen_thumb_extendhisi2 (operands[0], operands[1]));
3486 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
3487 gen_rtx_SIGN_EXTEND (SImode, operands[1])));
3492 operands[1] = gen_lowpart (SImode, operands[1]);
3493 operands[2] = gen_reg_rtx (SImode);
3497 (define_insn "thumb_extendhisi2"
3498 [(set (match_operand:SI 0 "register_operand" "=l")
3499 (sign_extend:SI (match_operand:HI 1 "memory_operand" "m")))
3500 (clobber (match_scratch:SI 2 "=&l"))]
3501 "TARGET_THUMB && !arm_arch6"
3505 rtx mem = XEXP (operands[1], 0);
3507 /* This code used to try to use 'V', and fix the address only if it was
3508 offsettable, but this fails for e.g. REG+48 because 48 is outside the
3509 range of QImode offsets, and offsettable_address_p does a QImode
3512 if (GET_CODE (mem) == CONST)
3513 mem = XEXP (mem, 0);
3515 if (GET_CODE (mem) == LABEL_REF)
3516 return \"ldr\\t%0, %1\";
3518 if (GET_CODE (mem) == PLUS)
3520 rtx a = XEXP (mem, 0);
3521 rtx b = XEXP (mem, 1);
3523 if (GET_CODE (a) == LABEL_REF
3524 && GET_CODE (b) == CONST_INT)
3525 return \"ldr\\t%0, %1\";
3527 if (GET_CODE (b) == REG)
3528 return \"ldrsh\\t%0, %1\";
3536 ops[2] = const0_rtx;
3539 if (GET_CODE (ops[1]) != REG)
3545 ops[0] = operands[0];
3546 ops[3] = operands[2];
3547 output_asm_insn (\"mov\\t%3, %2\;ldrsh\\t%0, [%1, %3]\", ops);
3550 [(set_attr "length" "4")
3551 (set_attr "type" "load_byte")
3552 (set_attr "pool_range" "1020")]
3555 ;; We used to have an early-clobber on the scratch register here.
3556 ;; However, there's a bug somewhere in reload which means that this
3557 ;; can be partially ignored during spill allocation if the memory
3558 ;; address also needs reloading; this causes an abort later on when
3559 ;; we try to verify the operands. Fortunately, we don't really need
3560 ;; the early-clobber: we can always use operand 0 if operand 2
3561 ;; overlaps the address.
3562 (define_insn "*thumb_extendhisi2_insn_v6"
3563 [(set (match_operand:SI 0 "register_operand" "=l,l")
3564 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "l,m")))
3565 (clobber (match_scratch:SI 2 "=X,l"))]
3566 "TARGET_THUMB && arm_arch6"
3572 if (which_alternative == 0)
3573 return \"sxth\\t%0, %1\";
3575 mem = XEXP (operands[1], 0);
3577 /* This code used to try to use 'V', and fix the address only if it was
3578 offsettable, but this fails for e.g. REG+48 because 48 is outside the
3579 range of QImode offsets, and offsettable_address_p does a QImode
3582 if (GET_CODE (mem) == CONST)
3583 mem = XEXP (mem, 0);
3585 if (GET_CODE (mem) == LABEL_REF)
3586 return \"ldr\\t%0, %1\";
3588 if (GET_CODE (mem) == PLUS)
3590 rtx a = XEXP (mem, 0);
3591 rtx b = XEXP (mem, 1);
3593 if (GET_CODE (a) == LABEL_REF
3594 && GET_CODE (b) == CONST_INT)
3595 return \"ldr\\t%0, %1\";
3597 if (GET_CODE (b) == REG)
3598 return \"ldrsh\\t%0, %1\";
3606 ops[2] = const0_rtx;
3609 if (GET_CODE (ops[1]) != REG)
3615 ops[0] = operands[0];
3616 if (reg_mentioned_p (operands[2], ops[1]))
3619 ops[3] = operands[2];
3620 output_asm_insn (\"mov\\t%3, %2\;ldrsh\\t%0, [%1, %3]\", ops);
3623 [(set_attr "length" "2,4")
3624 (set_attr "type" "alu_shift,load_byte")
3625 (set_attr "pool_range" "*,1020")]
3628 (define_expand "extendhisi2_mem"
3629 [(set (match_dup 2) (zero_extend:SI (match_operand:HI 1 "" "")))
3631 (zero_extend:SI (match_dup 7)))
3632 (set (match_dup 6) (ashift:SI (match_dup 4) (const_int 24)))
3633 (set (match_operand:SI 0 "" "")
3634 (ior:SI (ashiftrt:SI (match_dup 6) (const_int 16)) (match_dup 5)))]
3639 rtx addr = copy_to_mode_reg (SImode, XEXP (operands[1], 0));
3641 mem1 = gen_rtx_MEM (QImode, addr);
3642 MEM_COPY_ATTRIBUTES (mem1, operands[1]);
3643 mem2 = gen_rtx_MEM (QImode, plus_constant (addr, 1));
3644 MEM_COPY_ATTRIBUTES (mem2, operands[1]);
3645 operands[0] = gen_lowpart (SImode, operands[0]);
3647 operands[2] = gen_reg_rtx (SImode);
3648 operands[3] = gen_reg_rtx (SImode);
3649 operands[6] = gen_reg_rtx (SImode);
3652 if (BYTES_BIG_ENDIAN)
3654 operands[4] = operands[2];
3655 operands[5] = operands[3];
3659 operands[4] = operands[3];
3660 operands[5] = operands[2];
3665 (define_insn "*arm_extendhisi2"
3666 [(set (match_operand:SI 0 "s_register_operand" "=r")
3667 (sign_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
3668 "TARGET_ARM && arm_arch4 && !arm_arch6"
3670 [(set_attr "type" "load_byte")
3671 (set_attr "predicable" "yes")
3672 (set_attr "pool_range" "256")
3673 (set_attr "neg_pool_range" "244")]
3676 (define_insn "*arm_extendhisi2_v6"
3677 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
3678 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
3679 "TARGET_ARM && arm_arch6"
3683 [(set_attr "type" "alu_shift,load_byte")
3684 (set_attr "predicable" "yes")
3685 (set_attr "pool_range" "*,256")
3686 (set_attr "neg_pool_range" "*,244")]
3689 (define_insn "*arm_extendhisi2addsi"
3690 [(set (match_operand:SI 0 "s_register_operand" "=r")
3691 (plus:SI (sign_extend:SI (match_operand:HI 1 "s_register_operand" "r"))
3692 (match_operand:SI 2 "s_register_operand" "r")))]
3693 "TARGET_ARM && arm_arch6"
3694 "sxtah%?\\t%0, %2, %1"
3698 [(set (match_operand:SI 0 "s_register_operand" "")
3699 (sign_extend:SI (match_operand:HI 1 "alignable_memory_operand" "")))
3700 (clobber (match_operand:SI 2 "s_register_operand" ""))]
3701 "TARGET_ARM && (!arm_arch4)"
3702 [(set (match_dup 2) (match_dup 1))
3703 (set (match_dup 0) (ashiftrt:SI (match_dup 2) (const_int 16)))]
3705 if ((operands[1] = arm_gen_rotated_half_load (operands[1])) == NULL)
3711 [(set (match_operand:SI 0 "s_register_operand" "")
3712 (match_operator:SI 3 "shiftable_operator"
3713 [(sign_extend:SI (match_operand:HI 1 "alignable_memory_operand" ""))
3714 (match_operand:SI 4 "s_register_operand" "")]))
3715 (clobber (match_operand:SI 2 "s_register_operand" ""))]
3716 "TARGET_ARM && (!arm_arch4)"
3717 [(set (match_dup 2) (match_dup 1))
3720 [(ashiftrt:SI (match_dup 2) (const_int 16)) (match_dup 4)]))]
3721 "if ((operands[1] = arm_gen_rotated_half_load (operands[1])) == NULL)
3726 (define_expand "extendqihi2"
3728 (ashift:SI (match_operand:QI 1 "general_operand" "")
3730 (set (match_operand:HI 0 "s_register_operand" "")
3731 (ashiftrt:SI (match_dup 2)
3736 if (arm_arch4 && GET_CODE (operands[1]) == MEM)
3738 emit_insn (gen_rtx_SET (VOIDmode,
3740 gen_rtx_SIGN_EXTEND (HImode, operands[1])));
3743 if (!s_register_operand (operands[1], QImode))
3744 operands[1] = copy_to_mode_reg (QImode, operands[1]);
3745 operands[0] = gen_lowpart (SImode, operands[0]);
3746 operands[1] = gen_lowpart (SImode, operands[1]);
3747 operands[2] = gen_reg_rtx (SImode);
3751 (define_insn "*extendqihi_insn"
3752 [(set (match_operand:HI 0 "s_register_operand" "=r")
3753 (sign_extend:HI (match_operand:QI 1 "memory_operand" "Uq")))]
3754 "TARGET_ARM && arm_arch4"
3756 [(set_attr "type" "load_byte")
3757 (set_attr "predicable" "yes")
3758 (set_attr "pool_range" "256")
3759 (set_attr "neg_pool_range" "244")]
3762 (define_expand "extendqisi2"
3764 (ashift:SI (match_operand:QI 1 "general_operand" "")
3766 (set (match_operand:SI 0 "s_register_operand" "")
3767 (ashiftrt:SI (match_dup 2)
3772 if ((TARGET_THUMB || arm_arch4) && GET_CODE (operands[1]) == MEM)
3774 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
3775 gen_rtx_SIGN_EXTEND (SImode, operands[1])));
3779 if (!s_register_operand (operands[1], QImode))
3780 operands[1] = copy_to_mode_reg (QImode, operands[1]);
3784 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
3785 gen_rtx_SIGN_EXTEND (SImode, operands[1])));
3789 operands[1] = gen_lowpart (SImode, operands[1]);
3790 operands[2] = gen_reg_rtx (SImode);
3794 (define_insn "*arm_extendqisi"
3795 [(set (match_operand:SI 0 "s_register_operand" "=r")
3796 (sign_extend:SI (match_operand:QI 1 "memory_operand" "Uq")))]
3797 "TARGET_ARM && arm_arch4 && !arm_arch6"
3799 [(set_attr "type" "load_byte")
3800 (set_attr "predicable" "yes")
3801 (set_attr "pool_range" "256")
3802 (set_attr "neg_pool_range" "244")]
3805 (define_insn "*arm_extendqisi_v6"
3806 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
3807 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "r,Uq")))]
3808 "TARGET_ARM && arm_arch6"
3812 [(set_attr "type" "alu_shift,load_byte")
3813 (set_attr "predicable" "yes")
3814 (set_attr "pool_range" "*,256")
3815 (set_attr "neg_pool_range" "*,244")]
3818 (define_insn "*arm_extendqisi2addsi"
3819 [(set (match_operand:SI 0 "s_register_operand" "=r")
3820 (plus:SI (sign_extend:SI (match_operand:QI 1 "s_register_operand" "r"))
3821 (match_operand:SI 2 "s_register_operand" "r")))]
3822 "TARGET_ARM && arm_arch6"
3823 "sxtab%?\\t%0, %2, %1"
3824 [(set_attr "type" "alu_shift")
3825 (set_attr "predicable" "yes")]
3828 (define_insn "*thumb_extendqisi2"
3829 [(set (match_operand:SI 0 "register_operand" "=l,l")
3830 (sign_extend:SI (match_operand:QI 1 "memory_operand" "V,m")))]
3831 "TARGET_THUMB && !arm_arch6"
3835 rtx mem = XEXP (operands[1], 0);
3837 if (GET_CODE (mem) == CONST)
3838 mem = XEXP (mem, 0);
3840 if (GET_CODE (mem) == LABEL_REF)
3841 return \"ldr\\t%0, %1\";
3843 if (GET_CODE (mem) == PLUS
3844 && GET_CODE (XEXP (mem, 0)) == LABEL_REF)
3845 return \"ldr\\t%0, %1\";
3847 if (which_alternative == 0)
3848 return \"ldrsb\\t%0, %1\";
3850 ops[0] = operands[0];
3852 if (GET_CODE (mem) == PLUS)
3854 rtx a = XEXP (mem, 0);
3855 rtx b = XEXP (mem, 1);
3860 if (GET_CODE (a) == REG)
3862 if (GET_CODE (b) == REG)
3863 output_asm_insn (\"ldrsb\\t%0, [%1, %2]\", ops);
3864 else if (REGNO (a) == REGNO (ops[0]))
3866 output_asm_insn (\"ldrb\\t%0, [%1, %2]\", ops);
3867 output_asm_insn (\"lsl\\t%0, %0, #24\", ops);
3868 output_asm_insn (\"asr\\t%0, %0, #24\", ops);
3871 output_asm_insn (\"mov\\t%0, %2\;ldrsb\\t%0, [%1, %0]\", ops);
3873 else if (GET_CODE (b) != REG)
3877 if (REGNO (b) == REGNO (ops[0]))
3879 output_asm_insn (\"ldrb\\t%0, [%2, %1]\", ops);
3880 output_asm_insn (\"lsl\\t%0, %0, #24\", ops);
3881 output_asm_insn (\"asr\\t%0, %0, #24\", ops);
3884 output_asm_insn (\"mov\\t%0, %2\;ldrsb\\t%0, [%1, %0]\", ops);
3887 else if (GET_CODE (mem) == REG && REGNO (ops[0]) == REGNO (mem))
3889 output_asm_insn (\"ldrb\\t%0, [%0, #0]\", ops);
3890 output_asm_insn (\"lsl\\t%0, %0, #24\", ops);
3891 output_asm_insn (\"asr\\t%0, %0, #24\", ops);
3896 ops[2] = const0_rtx;
3898 output_asm_insn (\"mov\\t%0, %2\;ldrsb\\t%0, [%1, %0]\", ops);
3902 [(set_attr "length" "2,6")
3903 (set_attr "type" "load_byte,load_byte")
3904 (set_attr "pool_range" "32,32")]
3907 (define_insn "*thumb_extendqisi2_v6"
3908 [(set (match_operand:SI 0 "register_operand" "=l,l,l")
3909 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "l,V,m")))]
3910 "TARGET_THUMB && arm_arch6"
3916 if (which_alternative == 0)
3917 return \"sxtb\\t%0, %1\";
3919 mem = XEXP (operands[1], 0);
3921 if (GET_CODE (mem) == CONST)
3922 mem = XEXP (mem, 0);
3924 if (GET_CODE (mem) == LABEL_REF)
3925 return \"ldr\\t%0, %1\";
3927 if (GET_CODE (mem) == PLUS
3928 && GET_CODE (XEXP (mem, 0)) == LABEL_REF)
3929 return \"ldr\\t%0, %1\";
3931 if (which_alternative == 0)
3932 return \"ldrsb\\t%0, %1\";
3934 ops[0] = operands[0];
3936 if (GET_CODE (mem) == PLUS)
3938 rtx a = XEXP (mem, 0);
3939 rtx b = XEXP (mem, 1);
3944 if (GET_CODE (a) == REG)
3946 if (GET_CODE (b) == REG)
3947 output_asm_insn (\"ldrsb\\t%0, [%1, %2]\", ops);
3948 else if (REGNO (a) == REGNO (ops[0]))
3950 output_asm_insn (\"ldrb\\t%0, [%1, %2]\", ops);
3951 output_asm_insn (\"sxtb\\t%0, %0\", ops);
3954 output_asm_insn (\"mov\\t%0, %2\;ldrsb\\t%0, [%1, %0]\", ops);
3956 else if (GET_CODE (b) != REG)
3960 if (REGNO (b) == REGNO (ops[0]))
3962 output_asm_insn (\"ldrb\\t%0, [%2, %1]\", ops);
3963 output_asm_insn (\"sxtb\\t%0, %0\", ops);
3966 output_asm_insn (\"mov\\t%0, %2\;ldrsb\\t%0, [%1, %0]\", ops);
3969 else if (GET_CODE (mem) == REG && REGNO (ops[0]) == REGNO (mem))
3971 output_asm_insn (\"ldrb\\t%0, [%0, #0]\", ops);
3972 output_asm_insn (\"sxtb\\t%0, %0\", ops);
3977 ops[2] = const0_rtx;
3979 output_asm_insn (\"mov\\t%0, %2\;ldrsb\\t%0, [%1, %0]\", ops);
3983 [(set_attr "length" "2,2,4")
3984 (set_attr "type" "alu_shift,load_byte,load_byte")
3985 (set_attr "pool_range" "*,32,32")]
3988 (define_expand "extendsfdf2"
3989 [(set (match_operand:DF 0 "s_register_operand" "")
3990 (float_extend:DF (match_operand:SF 1 "s_register_operand" "")))]
3991 "TARGET_ARM && TARGET_HARD_FLOAT"
3995 ;; Move insns (including loads and stores)
3997 ;; XXX Just some ideas about movti.
3998 ;; I don't think these are a good idea on the arm, there just aren't enough
4000 ;;(define_expand "loadti"
4001 ;; [(set (match_operand:TI 0 "s_register_operand" "")
4002 ;; (mem:TI (match_operand:SI 1 "address_operand" "")))]
4005 ;;(define_expand "storeti"
4006 ;; [(set (mem:TI (match_operand:TI 0 "address_operand" ""))
4007 ;; (match_operand:TI 1 "s_register_operand" ""))]
4010 ;;(define_expand "movti"
4011 ;; [(set (match_operand:TI 0 "general_operand" "")
4012 ;; (match_operand:TI 1 "general_operand" ""))]
4018 ;; if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
4019 ;; operands[1] = copy_to_reg (operands[1]);
4020 ;; if (GET_CODE (operands[0]) == MEM)
4021 ;; insn = gen_storeti (XEXP (operands[0], 0), operands[1]);
4022 ;; else if (GET_CODE (operands[1]) == MEM)
4023 ;; insn = gen_loadti (operands[0], XEXP (operands[1], 0));
4027 ;; emit_insn (insn);
4031 ;; Recognize garbage generated above.
4034 ;; [(set (match_operand:TI 0 "general_operand" "=r,r,r,<,>,m")
4035 ;; (match_operand:TI 1 "general_operand" "<,>,m,r,r,r"))]
4039 ;; register mem = (which_alternative < 3);
4040 ;; register const char *template;
4042 ;; operands[mem] = XEXP (operands[mem], 0);
4043 ;; switch (which_alternative)
4045 ;; case 0: template = \"ldmdb\\t%1!, %M0\"; break;
4046 ;; case 1: template = \"ldmia\\t%1!, %M0\"; break;
4047 ;; case 2: template = \"ldmia\\t%1, %M0\"; break;
4048 ;; case 3: template = \"stmdb\\t%0!, %M1\"; break;
4049 ;; case 4: template = \"stmia\\t%0!, %M1\"; break;
4050 ;; case 5: template = \"stmia\\t%0, %M1\"; break;
4052 ;; output_asm_insn (template, operands);
4056 (define_expand "movdi"
4057 [(set (match_operand:DI 0 "general_operand" "")
4058 (match_operand:DI 1 "general_operand" ""))]
4063 if (!no_new_pseudos)
4065 if (GET_CODE (operands[0]) != REG)
4066 operands[1] = force_reg (DImode, operands[1]);
4072 (define_insn "*arm_movdi"
4073 [(set (match_operand:DI 0 "nonimmediate_di_operand" "=r, r, o<>")
4074 (match_operand:DI 1 "di_operand" "rIK,mi,r"))]
4076 && !(TARGET_HARD_FLOAT && (TARGET_MAVERICK || TARGET_VFP))
4079 return (output_move_double (operands));
4081 [(set_attr "length" "8")
4082 (set_attr "type" "*,load2,store2")
4083 (set_attr "pool_range" "*,1020,*")
4084 (set_attr "neg_pool_range" "*,1008,*")]
4087 ;;; ??? This should have alternatives for constants.
4088 ;;; ??? This was originally identical to the movdf_insn pattern.
4089 ;;; ??? The 'i' constraint looks funny, but it should always be replaced by
4090 ;;; thumb_reorg with a memory reference.
4091 (define_insn "*thumb_movdi_insn"
4092 [(set (match_operand:DI 0 "nonimmediate_operand" "=l,l,l,l,>,l, m,*r")
4093 (match_operand:DI 1 "general_operand" "l, I,J,>,l,mi,l,*r"))]
4095 && !(TARGET_HARD_FLOAT && TARGET_MAVERICK)
4096 && ( register_operand (operands[0], DImode)
4097 || register_operand (operands[1], DImode))"
4100 switch (which_alternative)
4104 if (REGNO (operands[1]) == REGNO (operands[0]) + 1)
4105 return \"add\\t%0, %1, #0\;add\\t%H0, %H1, #0\";
4106 return \"add\\t%H0, %H1, #0\;add\\t%0, %1, #0\";
4108 return \"mov\\t%Q0, %1\;mov\\t%R0, #0\";
4110 operands[1] = GEN_INT (- INTVAL (operands[1]));
4111 return \"mov\\t%Q0, %1\;neg\\t%Q0, %Q0\;asr\\t%R0, %Q0, #31\";
4113 return \"ldmia\\t%1, {%0, %H0}\";
4115 return \"stmia\\t%0, {%1, %H1}\";
4117 return thumb_load_double_from_address (operands);
4119 operands[2] = gen_rtx_MEM (SImode,
4120 plus_constant (XEXP (operands[0], 0), 4));
4121 output_asm_insn (\"str\\t%1, %0\;str\\t%H1, %2\", operands);
4124 if (REGNO (operands[1]) == REGNO (operands[0]) + 1)
4125 return \"mov\\t%0, %1\;mov\\t%H0, %H1\";
4126 return \"mov\\t%H0, %H1\;mov\\t%0, %1\";
4129 [(set_attr "length" "4,4,6,2,2,6,4,4")
4130 (set_attr "type" "*,*,*,load2,store2,load2,store2,*")
4131 (set_attr "pool_range" "*,*,*,*,*,1020,*,*")]
4134 (define_expand "movsi"
4135 [(set (match_operand:SI 0 "general_operand" "")
4136 (match_operand:SI 1 "general_operand" ""))]
4141 /* Everything except mem = const or mem = mem can be done easily. */
4142 if (GET_CODE (operands[0]) == MEM)
4143 operands[1] = force_reg (SImode, operands[1]);
4144 if (arm_general_register_operand (operands[0], SImode)
4145 && GET_CODE (operands[1]) == CONST_INT
4146 && !(const_ok_for_arm (INTVAL (operands[1]))
4147 || const_ok_for_arm (~INTVAL (operands[1]))))
4149 arm_split_constant (SET, SImode, INTVAL (operands[1]), operands[0],
4152 : preserve_subexpressions_p ()));
4156 else /* TARGET_THUMB.... */
4158 if (!no_new_pseudos)
4160 if (GET_CODE (operands[0]) != REG)
4161 operands[1] = force_reg (SImode, operands[1]);
4166 && (CONSTANT_P (operands[1])
4167 || symbol_mentioned_p (operands[1])
4168 || label_mentioned_p (operands[1])))
4169 operands[1] = legitimize_pic_address (operands[1], SImode,
4170 (no_new_pseudos ? operands[0] : 0));
4174 (define_insn "*arm_movsi_insn"
4175 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r, m")
4176 (match_operand:SI 1 "general_operand" "rI,K,mi,r"))]
4177 "TARGET_ARM && ! TARGET_IWMMXT
4178 && !(TARGET_HARD_FLOAT && TARGET_VFP)
4179 && ( register_operand (operands[0], SImode)
4180 || register_operand (operands[1], SImode))"
4186 [(set_attr "type" "*,*,load1,store1")
4187 (set_attr "predicable" "yes")
4188 (set_attr "pool_range" "*,*,4096,*")
4189 (set_attr "neg_pool_range" "*,*,4084,*")]
4193 [(set (match_operand:SI 0 "arm_general_register_operand" "")
4194 (match_operand:SI 1 "const_int_operand" ""))]
4196 && (!(const_ok_for_arm (INTVAL (operands[1]))
4197 || const_ok_for_arm (~INTVAL (operands[1]))))"
4198 [(clobber (const_int 0))]
4200 arm_split_constant (SET, SImode, INTVAL (operands[1]), operands[0],
4206 (define_insn "*thumb_movsi_insn"
4207 [(set (match_operand:SI 0 "nonimmediate_operand" "=l,l,l,l,l,>,l, m,*lh")
4208 (match_operand:SI 1 "general_operand" "l, I,J,K,>,l,mi,l,*lh"))]
4210 && ( register_operand (operands[0], SImode)
4211 || register_operand (operands[1], SImode))"
4222 [(set_attr "length" "2,2,4,4,2,2,2,2,2")
4223 (set_attr "type" "*,*,*,*,load1,store1,load1,store1,*")
4224 (set_attr "pool_range" "*,*,*,*,*,*,1020,*,*")]
4228 [(set (match_operand:SI 0 "register_operand" "")
4229 (match_operand:SI 1 "const_int_operand" ""))]
4230 "TARGET_THUMB && CONST_OK_FOR_THUMB_LETTER (INTVAL (operands[1]), 'J')"
4231 [(set (match_dup 0) (match_dup 1))
4232 (set (match_dup 0) (neg:SI (match_dup 0)))]
4233 "operands[1] = GEN_INT (- INTVAL (operands[1]));"
4237 [(set (match_operand:SI 0 "register_operand" "")
4238 (match_operand:SI 1 "const_int_operand" ""))]
4239 "TARGET_THUMB && CONST_OK_FOR_THUMB_LETTER (INTVAL (operands[1]), 'K')"
4240 [(set (match_dup 0) (match_dup 1))
4241 (set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))]
4244 unsigned HOST_WIDE_INT val = INTVAL (operands[1]);
4245 unsigned HOST_WIDE_INT mask = 0xff;
4248 for (i = 0; i < 25; i++)
4249 if ((val & (mask << i)) == val)
4252 /* Shouldn't happen, but we don't want to split if the shift is zero. */
4256 operands[1] = GEN_INT (val >> i);
4257 operands[2] = GEN_INT (i);
4261 ;; When generating pic, we need to load the symbol offset into a register.
4262 ;; So that the optimizer does not confuse this with a normal symbol load
4263 ;; we use an unspec. The offset will be loaded from a constant pool entry,
4264 ;; since that is the only type of relocation we can use.
4266 ;; The rather odd constraints on the following are to force reload to leave
4267 ;; the insn alone, and to force the minipool generation pass to then move
4268 ;; the GOT symbol to memory.
4270 (define_insn "pic_load_addr_arm"
4271 [(set (match_operand:SI 0 "s_register_operand" "=r")
4272 (unspec:SI [(match_operand:SI 1 "" "mX")] UNSPEC_PIC_SYM))]
4273 "TARGET_ARM && flag_pic"
4275 [(set_attr "type" "load1")
4276 (set (attr "pool_range") (const_int 4096))
4277 (set (attr "neg_pool_range") (const_int 4084))]
4280 (define_insn "pic_load_addr_thumb"
4281 [(set (match_operand:SI 0 "s_register_operand" "=l")
4282 (unspec:SI [(match_operand:SI 1 "" "mX")] UNSPEC_PIC_SYM))]
4283 "TARGET_THUMB && flag_pic"
4285 [(set_attr "type" "load1")
4286 (set (attr "pool_range") (const_int 1024))]
4289 ;; This variant is used for AOF assembly, since it needs to mention the
4290 ;; pic register in the rtl.
4291 (define_expand "pic_load_addr_based"
4292 [(set (match_operand:SI 0 "s_register_operand" "")
4293 (unspec:SI [(match_operand 1 "" "") (match_dup 2)] UNSPEC_PIC_SYM))]
4294 "TARGET_ARM && flag_pic"
4295 "operands[2] = pic_offset_table_rtx;"
4298 (define_insn "*pic_load_addr_based_insn"
4299 [(set (match_operand:SI 0 "s_register_operand" "=r")
4300 (unspec:SI [(match_operand 1 "" "")
4301 (match_operand 2 "s_register_operand" "r")]
4303 "TARGET_EITHER && flag_pic && operands[2] == pic_offset_table_rtx"
4305 #ifdef AOF_ASSEMBLER
4306 operands[1] = aof_pic_entry (operands[1]);
4308 output_asm_insn (\"ldr%?\\t%0, %a1\", operands);
4311 [(set_attr "type" "load1")
4312 (set (attr "pool_range")
4313 (if_then_else (eq_attr "is_thumb" "yes")
4316 (set (attr "neg_pool_range")
4317 (if_then_else (eq_attr "is_thumb" "yes")
4322 (define_insn "pic_add_dot_plus_four"
4323 [(set (match_operand:SI 0 "register_operand" "+r")
4324 (unspec:SI [(plus:SI (match_dup 0)
4325 (const (plus:SI (pc) (const_int 4))))]
4327 (use (label_ref (match_operand 1 "" "")))]
4328 "TARGET_THUMB && flag_pic"
4330 (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
4331 CODE_LABEL_NUMBER (operands[1]));
4332 return \"add\\t%0, %|pc\";
4334 [(set_attr "length" "2")]
4337 (define_insn "pic_add_dot_plus_eight"
4338 [(set (match_operand:SI 0 "register_operand" "+r")
4339 (unspec:SI [(plus:SI (match_dup 0)
4340 (const (plus:SI (pc) (const_int 8))))]
4342 (use (label_ref (match_operand 1 "" "")))]
4343 "TARGET_ARM && flag_pic"
4345 (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
4346 CODE_LABEL_NUMBER (operands[1]));
4347 return \"add%?\\t%0, %|pc, %0\";
4349 [(set_attr "predicable" "yes")]
4352 (define_expand "builtin_setjmp_receiver"
4353 [(label_ref (match_operand 0 "" ""))]
4357 arm_finalize_pic (0);
4361 ;; If copying one reg to another we can set the condition codes according to
4362 ;; its value. Such a move is common after a return from subroutine and the
4363 ;; result is being tested against zero.
4365 (define_insn "*movsi_compare0"
4366 [(set (reg:CC CC_REGNUM)
4367 (compare:CC (match_operand:SI 1 "s_register_operand" "0,r")
4369 (set (match_operand:SI 0 "s_register_operand" "=r,r")
4374 sub%?s\\t%0, %1, #0"
4375 [(set_attr "conds" "set")]
4378 ;; Subroutine to store a half word from a register into memory.
4379 ;; Operand 0 is the source register (HImode)
4380 ;; Operand 1 is the destination address in a register (SImode)
4382 ;; In both this routine and the next, we must be careful not to spill
4383 ;; a memory address of reg+large_const into a separate PLUS insn, since this
4384 ;; can generate unrecognizable rtl.
4386 (define_expand "storehi"
4387 [;; store the low byte
4388 (set (match_operand 1 "" "") (match_dup 3))
4389 ;; extract the high byte
4391 (ashiftrt:SI (match_operand 0 "" "") (const_int 8)))
4392 ;; store the high byte
4393 (set (match_dup 4) (match_dup 5))]
4397 rtx op1 = operands[1];
4398 rtx addr = XEXP (op1, 0);
4399 enum rtx_code code = GET_CODE (addr);
4401 if ((code == PLUS && GET_CODE (XEXP (addr, 1)) != CONST_INT)
4403 op1 = replace_equiv_address (operands[1], force_reg (SImode, addr));
4405 operands[4] = adjust_address (op1, QImode, 1);
4406 operands[1] = adjust_address (operands[1], QImode, 0);
4407 operands[3] = gen_lowpart (QImode, operands[0]);
4408 operands[0] = gen_lowpart (SImode, operands[0]);
4409 operands[2] = gen_reg_rtx (SImode);
4410 operands[5] = gen_lowpart (QImode, operands[2]);
4414 (define_expand "storehi_bigend"
4415 [(set (match_dup 4) (match_dup 3))
4417 (ashiftrt:SI (match_operand 0 "" "") (const_int 8)))
4418 (set (match_operand 1 "" "") (match_dup 5))]
4422 rtx op1 = operands[1];
4423 rtx addr = XEXP (op1, 0);
4424 enum rtx_code code = GET_CODE (addr);
4426 if ((code == PLUS && GET_CODE (XEXP (addr, 1)) != CONST_INT)
4428 op1 = replace_equiv_address (op1, force_reg (SImode, addr));
4430 operands[4] = adjust_address (op1, QImode, 1);
4431 operands[1] = adjust_address (operands[1], QImode, 0);
4432 operands[3] = gen_lowpart (QImode, operands[0]);
4433 operands[0] = gen_lowpart (SImode, operands[0]);
4434 operands[2] = gen_reg_rtx (SImode);
4435 operands[5] = gen_lowpart (QImode, operands[2]);
4439 ;; Subroutine to store a half word integer constant into memory.
4440 (define_expand "storeinthi"
4441 [(set (match_operand 0 "" "")
4442 (match_operand 1 "" ""))
4443 (set (match_dup 3) (match_dup 2))]
4447 HOST_WIDE_INT value = INTVAL (operands[1]);
4448 rtx addr = XEXP (operands[0], 0);
4449 rtx op0 = operands[0];
4450 enum rtx_code code = GET_CODE (addr);
4452 if ((code == PLUS && GET_CODE (XEXP (addr, 1)) != CONST_INT)
4454 op0 = replace_equiv_address (op0, force_reg (SImode, addr));
4456 operands[1] = gen_reg_rtx (SImode);
4457 if (BYTES_BIG_ENDIAN)
4459 emit_insn (gen_movsi (operands[1], GEN_INT ((value >> 8) & 255)));
4460 if ((value & 255) == ((value >> 8) & 255))
4461 operands[2] = operands[1];
4464 operands[2] = gen_reg_rtx (SImode);
4465 emit_insn (gen_movsi (operands[2], GEN_INT (value & 255)));
4470 emit_insn (gen_movsi (operands[1], GEN_INT (value & 255)));
4471 if ((value & 255) == ((value >> 8) & 255))
4472 operands[2] = operands[1];
4475 operands[2] = gen_reg_rtx (SImode);
4476 emit_insn (gen_movsi (operands[2], GEN_INT ((value >> 8) & 255)));
4480 operands[3] = adjust_address (op0, QImode, 1);
4481 operands[0] = adjust_address (operands[0], QImode, 0);
4482 operands[2] = gen_lowpart (QImode, operands[2]);
4483 operands[1] = gen_lowpart (QImode, operands[1]);
4487 (define_expand "storehi_single_op"
4488 [(set (match_operand:HI 0 "memory_operand" "")
4489 (match_operand:HI 1 "general_operand" ""))]
4490 "TARGET_ARM && arm_arch4"
4492 if (!s_register_operand (operands[1], HImode))
4493 operands[1] = copy_to_mode_reg (HImode, operands[1]);
4497 (define_expand "movhi"
4498 [(set (match_operand:HI 0 "general_operand" "")
4499 (match_operand:HI 1 "general_operand" ""))]
4504 if (!no_new_pseudos)
4506 if (GET_CODE (operands[0]) == MEM)
4510 emit_insn (gen_storehi_single_op (operands[0], operands[1]));
4513 if (GET_CODE (operands[1]) == CONST_INT)
4514 emit_insn (gen_storeinthi (operands[0], operands[1]));
4517 if (GET_CODE (operands[1]) == MEM)
4518 operands[1] = force_reg (HImode, operands[1]);
4519 if (BYTES_BIG_ENDIAN)
4520 emit_insn (gen_storehi_bigend (operands[1], operands[0]));
4522 emit_insn (gen_storehi (operands[1], operands[0]));
4526 /* Sign extend a constant, and keep it in an SImode reg. */
4527 else if (GET_CODE (operands[1]) == CONST_INT)
4529 rtx reg = gen_reg_rtx (SImode);
4530 HOST_WIDE_INT val = INTVAL (operands[1]) & 0xffff;
4532 /* If the constant is already valid, leave it alone. */
4533 if (!const_ok_for_arm (val))
4535 /* If setting all the top bits will make the constant
4536 loadable in a single instruction, then set them.
4537 Otherwise, sign extend the number. */
4539 if (const_ok_for_arm (~(val | ~0xffff)))
4541 else if (val & 0x8000)
4545 emit_insn (gen_movsi (reg, GEN_INT (val)));
4546 operands[1] = gen_lowpart (HImode, reg);
4548 else if (arm_arch4 && !no_new_pseudos && optimize > 0
4549 && GET_CODE (operands[1]) == MEM)
4551 rtx reg = gen_reg_rtx (SImode);
4553 emit_insn (gen_zero_extendhisi2 (reg, operands[1]));
4554 operands[1] = gen_lowpart (HImode, reg);
4556 else if (!arm_arch4)
4558 /* Note: We do not have to worry about TARGET_MMU_TRAPS
4559 for v4 and up architectures because LDRH instructions will
4560 be used to access the HI values, and these cannot generate
4561 unaligned word access faults in the MMU. */
4562 if (GET_CODE (operands[1]) == MEM)
4564 if (TARGET_MMU_TRAPS)
4567 rtx offset = const0_rtx;
4568 rtx reg = gen_reg_rtx (SImode);
4570 if ((GET_CODE (base = XEXP (operands[1], 0)) == REG
4571 || (GET_CODE (base) == PLUS
4572 && (GET_CODE (offset = XEXP (base, 1))
4574 && ((INTVAL(offset) & 1) != 1)
4575 && GET_CODE (base = XEXP (base, 0)) == REG))
4576 && REGNO_POINTER_ALIGN (REGNO (base)) >= 32)
4578 HOST_WIDE_INT new_offset = INTVAL (offset) & ~3;
4581 new = gen_rtx_MEM (SImode,
4582 plus_constant (base, new_offset));
4583 MEM_COPY_ATTRIBUTES (new, operands[1]);
4584 emit_insn (gen_movsi (reg, new));
4585 if (((INTVAL (offset) & 2) != 0)
4586 ^ (BYTES_BIG_ENDIAN ? 1 : 0))
4588 rtx reg2 = gen_reg_rtx (SImode);
4590 emit_insn (gen_lshrsi3 (reg2, reg,
4596 emit_insn (gen_movhi_bytes (reg, operands[1]));
4598 operands[1] = gen_lowpart (HImode, reg);
4600 else if (BYTES_BIG_ENDIAN)
4603 rtx offset = const0_rtx;
4605 if ((GET_CODE (base = XEXP (operands[1], 0)) == REG
4606 || (GET_CODE (base) == PLUS
4607 && (GET_CODE (offset = XEXP (base, 1))
4609 && GET_CODE (base = XEXP (base, 0)) == REG))
4610 && REGNO_POINTER_ALIGN (REGNO (base)) >= 32)
4612 rtx reg = gen_reg_rtx (SImode);
4615 if ((INTVAL (offset) & 2) == 2)
4617 HOST_WIDE_INT new_offset = INTVAL (offset) ^ 2;
4618 new = gen_rtx_MEM (SImode,
4619 plus_constant (base,
4621 MEM_COPY_ATTRIBUTES (new, operands[1]);
4622 emit_insn (gen_movsi (reg, new));
4626 new = gen_rtx_MEM (SImode,
4627 XEXP (operands[1], 0));
4628 MEM_COPY_ATTRIBUTES (new, operands[1]);
4629 emit_insn (gen_rotated_loadsi (reg, new));
4632 operands[1] = gen_lowpart (HImode, reg);
4636 emit_insn (gen_movhi_bigend (operands[0],
4644 /* Handle loading a large integer during reload. */
4645 else if (GET_CODE (operands[1]) == CONST_INT
4646 && !const_ok_for_arm (INTVAL (operands[1]))
4647 && !const_ok_for_arm (~INTVAL (operands[1])))
4649 /* Writing a constant to memory needs a scratch, which should
4650 be handled with SECONDARY_RELOADs. */
4651 if (GET_CODE (operands[0]) != REG)
4654 operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
4655 emit_insn (gen_movsi (operands[0], operands[1]));
4659 else /* TARGET_THUMB */
4661 if (!no_new_pseudos)
4663 if (GET_CODE (operands[0]) != REG)
4664 operands[1] = force_reg (HImode, operands[1]);
4666 /* ??? We shouldn't really get invalid addresses here, but this can
4667 happen if we are passed a SP (never OK for HImode/QImode) or
4668 virtual register (rejected by GO_IF_LEGITIMATE_ADDRESS for
4669 HImode/QImode) relative address. */
4670 /* ??? This should perhaps be fixed elsewhere, for instance, in
4671 fixup_stack_1, by checking for other kinds of invalid addresses,
4672 e.g. a bare reference to a virtual register. This may confuse the
4673 alpha though, which must handle this case differently. */
4674 if (GET_CODE (operands[0]) == MEM
4675 && !memory_address_p (GET_MODE (operands[0]),
4676 XEXP (operands[0], 0)))
4678 = replace_equiv_address (operands[0],
4679 copy_to_reg (XEXP (operands[0], 0)));
4681 if (GET_CODE (operands[1]) == MEM
4682 && !memory_address_p (GET_MODE (operands[1]),
4683 XEXP (operands[1], 0)))
4685 = replace_equiv_address (operands[1],
4686 copy_to_reg (XEXP (operands[1], 0)));
4688 /* Handle loading a large integer during reload. */
4689 else if (GET_CODE (operands[1]) == CONST_INT
4690 && !CONST_OK_FOR_THUMB_LETTER (INTVAL (operands[1]), 'I'))
4692 /* Writing a constant to memory needs a scratch, which should
4693 be handled with SECONDARY_RELOADs. */
4694 if (GET_CODE (operands[0]) != REG)
4697 operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
4698 emit_insn (gen_movsi (operands[0], operands[1]));
4705 (define_insn "*thumb_movhi_insn"
4706 [(set (match_operand:HI 0 "nonimmediate_operand" "=l,l,m,*r,*h,l")
4707 (match_operand:HI 1 "general_operand" "l,m,l,*h,*r,I"))]
4709 && ( register_operand (operands[0], HImode)
4710 || register_operand (operands[1], HImode))"
4712 switch (which_alternative)
4714 case 0: return \"add %0, %1, #0\";
4715 case 2: return \"strh %1, %0\";
4716 case 3: return \"mov %0, %1\";
4717 case 4: return \"mov %0, %1\";
4718 case 5: return \"mov %0, %1\";
4721 /* The stack pointer can end up being taken as an index register.
4722 Catch this case here and deal with it. */
4723 if (GET_CODE (XEXP (operands[1], 0)) == PLUS
4724 && GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == REG
4725 && REGNO (XEXP (XEXP (operands[1], 0), 0)) == SP_REGNUM)
4728 ops[0] = operands[0];
4729 ops[1] = XEXP (XEXP (operands[1], 0), 0);
4731 output_asm_insn (\"mov %0, %1\", ops);
4733 XEXP (XEXP (operands[1], 0), 0) = operands[0];
4736 return \"ldrh %0, %1\";
4738 [(set_attr "length" "2,4,2,2,2,2")
4739 (set_attr "type" "*,load1,store1,*,*,*")]
4743 (define_insn "rotated_loadsi"
4744 [(set (match_operand:SI 0 "s_register_operand" "=r")
4745 (rotate:SI (match_operand:SI 1 "offsettable_memory_operand" "o")
4747 "TARGET_ARM && (!TARGET_MMU_TRAPS)"
4752 ops[0] = operands[0];
4753 ops[1] = gen_rtx_MEM (SImode, plus_constant (XEXP (operands[1], 0), 2));
4754 output_asm_insn (\"ldr%?\\t%0, %1\\t%@ load-rotate\", ops);
4757 [(set_attr "type" "load1")
4758 (set_attr "predicable" "yes")]
4761 (define_expand "movhi_bytes"
4762 [(set (match_dup 2) (zero_extend:SI (match_operand:HI 1 "" "")))
4764 (zero_extend:SI (match_dup 6)))
4765 (set (match_operand:SI 0 "" "")
4766 (ior:SI (ashift:SI (match_dup 4) (const_int 8)) (match_dup 5)))]
4771 rtx addr = copy_to_mode_reg (SImode, XEXP (operands[1], 0));
4773 mem1 = gen_rtx_MEM (QImode, addr);
4774 MEM_COPY_ATTRIBUTES (mem1, operands[1]);
4775 mem2 = gen_rtx_MEM (QImode, plus_constant (addr, 1));
4776 MEM_COPY_ATTRIBUTES (mem2, operands[1]);
4777 operands[0] = gen_lowpart (SImode, operands[0]);
4779 operands[2] = gen_reg_rtx (SImode);
4780 operands[3] = gen_reg_rtx (SImode);
4783 if (BYTES_BIG_ENDIAN)
4785 operands[4] = operands[2];
4786 operands[5] = operands[3];
4790 operands[4] = operands[3];
4791 operands[5] = operands[2];
4796 (define_expand "movhi_bigend"
4798 (rotate:SI (subreg:SI (match_operand:HI 1 "memory_operand" "") 0)
4801 (ashiftrt:SI (match_dup 2) (const_int 16)))
4802 (set (match_operand:HI 0 "s_register_operand" "")
4806 operands[2] = gen_reg_rtx (SImode);
4807 operands[3] = gen_reg_rtx (SImode);
4808 operands[4] = gen_lowpart (HImode, operands[3]);
4812 ;; Pattern to recognize insn generated default case above
4813 (define_insn "*movhi_insn_arch4"
4814 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,m,r")
4815 (match_operand:HI 1 "general_operand" "rI,K,r,m"))]
4818 && (GET_CODE (operands[1]) != CONST_INT
4819 || const_ok_for_arm (INTVAL (operands[1]))
4820 || const_ok_for_arm (~INTVAL (operands[1])))"
4822 mov%?\\t%0, %1\\t%@ movhi
4823 mvn%?\\t%0, #%B1\\t%@ movhi
4824 str%?h\\t%1, %0\\t%@ movhi
4825 ldr%?h\\t%0, %1\\t%@ movhi"
4826 [(set_attr "type" "*,*,store1,load1")
4827 (set_attr "predicable" "yes")
4828 (set_attr "pool_range" "*,*,*,256")
4829 (set_attr "neg_pool_range" "*,*,*,244")]
4832 (define_insn "*movhi_insn_littleend"
4833 [(set (match_operand:HI 0 "s_register_operand" "=r,r,r")
4834 (match_operand:HI 1 "general_operand" "rI,K,m"))]
4837 && !BYTES_BIG_ENDIAN
4838 && !TARGET_MMU_TRAPS
4839 && (GET_CODE (operands[1]) != CONST_INT
4840 || const_ok_for_arm (INTVAL (operands[1]))
4841 || const_ok_for_arm (~INTVAL (operands[1])))"
4843 mov%?\\t%0, %1\\t%@ movhi
4844 mvn%?\\t%0, #%B1\\t%@ movhi
4845 ldr%?\\t%0, %1\\t%@ movhi"
4846 [(set_attr "type" "*,*,load1")
4847 (set_attr "predicable" "yes")
4848 (set_attr "pool_range" "4096")
4849 (set_attr "neg_pool_range" "4084")]
4852 (define_insn "*movhi_insn_bigend"
4853 [(set (match_operand:HI 0 "s_register_operand" "=r,r,r")
4854 (match_operand:HI 1 "general_operand" "rI,K,m"))]
4858 && !TARGET_MMU_TRAPS
4859 && (GET_CODE (operands[1]) != CONST_INT
4860 || const_ok_for_arm (INTVAL (operands[1]))
4861 || const_ok_for_arm (~INTVAL (operands[1])))"
4863 mov%?\\t%0, %1\\t%@ movhi
4864 mvn%?\\t%0, #%B1\\t%@ movhi
4865 ldr%?\\t%0, %1\\t%@ movhi_bigend\;mov%?\\t%0, %0, asr #16"
4866 [(set_attr "type" "*,*,load1")
4867 (set_attr "predicable" "yes")
4868 (set_attr "length" "4,4,8")
4869 (set_attr "pool_range" "*,*,4092")
4870 (set_attr "neg_pool_range" "*,*,4084")]
4873 (define_insn "*loadhi_si_bigend"
4874 [(set (match_operand:SI 0 "s_register_operand" "=r")
4875 (rotate:SI (subreg:SI (match_operand:HI 1 "memory_operand" "m") 0)
4879 && !TARGET_MMU_TRAPS"
4880 "ldr%?\\t%0, %1\\t%@ movhi_bigend"
4881 [(set_attr "type" "load1")
4882 (set_attr "predicable" "yes")
4883 (set_attr "pool_range" "4096")
4884 (set_attr "neg_pool_range" "4084")]
4887 (define_insn "*movhi_bytes"
4888 [(set (match_operand:HI 0 "s_register_operand" "=r,r")
4889 (match_operand:HI 1 "arm_rhs_operand" "rI,K"))]
4890 "TARGET_ARM && TARGET_MMU_TRAPS"
4892 mov%?\\t%0, %1\\t%@ movhi
4893 mvn%?\\t%0, #%B1\\t%@ movhi"
4894 [(set_attr "predicable" "yes")]
4897 (define_insn "thumb_movhi_clobber"
4898 [(set (match_operand:HI 0 "memory_operand" "=m")
4899 (match_operand:HI 1 "register_operand" "l"))
4900 (clobber (match_operand:SI 2 "register_operand" "=&l"))]
4906 ;; We use a DImode scratch because we may occasionally need an additional
4907 ;; temporary if the address isn't offsettable -- push_reload doesn't seem
4908 ;; to take any notice of the "o" constraints on reload_memory_operand operand.
4909 (define_expand "reload_outhi"
4910 [(parallel [(match_operand:HI 0 "arm_reload_memory_operand" "=o")
4911 (match_operand:HI 1 "s_register_operand" "r")
4912 (match_operand:DI 2 "s_register_operand" "=&l")])]
4915 arm_reload_out_hi (operands);
4917 thumb_reload_out_hi (operands);
4922 (define_expand "reload_inhi"
4923 [(parallel [(match_operand:HI 0 "s_register_operand" "=r")
4924 (match_operand:HI 1 "arm_reload_memory_operand" "o")
4925 (match_operand:DI 2 "s_register_operand" "=&r")])]
4926 "TARGET_THUMB || (TARGET_ARM && TARGET_MMU_TRAPS)"
4929 arm_reload_in_hi (operands);
4931 thumb_reload_out_hi (operands);
4935 (define_expand "movqi"
4936 [(set (match_operand:QI 0 "general_operand" "")
4937 (match_operand:QI 1 "general_operand" ""))]
4942 /* Everything except mem = const or mem = mem can be done easily */
4944 if (!no_new_pseudos)
4946 if (GET_CODE (operands[1]) == CONST_INT)
4948 rtx reg = gen_reg_rtx (SImode);
4950 emit_insn (gen_movsi (reg, operands[1]));
4951 operands[1] = gen_lowpart (QImode, reg);
4953 if (GET_CODE (operands[1]) == MEM && optimize > 0)
4955 rtx reg = gen_reg_rtx (SImode);
4957 emit_insn (gen_zero_extendqisi2 (reg, operands[1]));
4958 operands[1] = gen_lowpart (QImode, reg);
4960 if (GET_CODE (operands[0]) == MEM)
4961 operands[1] = force_reg (QImode, operands[1]);
4964 else /* TARGET_THUMB */
4966 if (!no_new_pseudos)
4968 if (GET_CODE (operands[0]) != REG)
4969 operands[1] = force_reg (QImode, operands[1]);
4971 /* ??? We shouldn't really get invalid addresses here, but this can
4972 happen if we are passed a SP (never OK for HImode/QImode) or
4973 virtual register (rejected by GO_IF_LEGITIMATE_ADDRESS for
4974 HImode/QImode) relative address. */
4975 /* ??? This should perhaps be fixed elsewhere, for instance, in
4976 fixup_stack_1, by checking for other kinds of invalid addresses,
4977 e.g. a bare reference to a virtual register. This may confuse the
4978 alpha though, which must handle this case differently. */
4979 if (GET_CODE (operands[0]) == MEM
4980 && !memory_address_p (GET_MODE (operands[0]),
4981 XEXP (operands[0], 0)))
4983 = replace_equiv_address (operands[0],
4984 copy_to_reg (XEXP (operands[0], 0)));
4985 if (GET_CODE (operands[1]) == MEM
4986 && !memory_address_p (GET_MODE (operands[1]),
4987 XEXP (operands[1], 0)))
4989 = replace_equiv_address (operands[1],
4990 copy_to_reg (XEXP (operands[1], 0)));
4992 /* Handle loading a large integer during reload. */
4993 else if (GET_CODE (operands[1]) == CONST_INT
4994 && !CONST_OK_FOR_LETTER_P (INTVAL (operands[1]), 'I'))
4996 /* Writing a constant to memory needs a scratch, which should
4997 be handled with SECONDARY_RELOADs. */
4998 if (GET_CODE (operands[0]) != REG)
5001 operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
5002 emit_insn (gen_movsi (operands[0], operands[1]));
5010 (define_insn "*arm_movqi_insn"
5011 [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,r,m")
5012 (match_operand:QI 1 "general_operand" "rI,K,m,r"))]
5014 && ( register_operand (operands[0], QImode)
5015 || register_operand (operands[1], QImode))"
5021 [(set_attr "type" "*,*,load1,store1")
5022 (set_attr "predicable" "yes")]
5025 (define_insn "*thumb_movqi_insn"
5026 [(set (match_operand:QI 0 "nonimmediate_operand" "=l,l,m,*r,*h,l")
5027 (match_operand:QI 1 "general_operand" "l, m,l,*h,*r,I"))]
5029 && ( register_operand (operands[0], QImode)
5030 || register_operand (operands[1], QImode))"
5038 [(set_attr "length" "2")
5039 (set_attr "type" "*,load1,store1,*,*,*")
5040 (set_attr "pool_range" "*,32,*,*,*,*")]
5043 (define_expand "movsf"
5044 [(set (match_operand:SF 0 "general_operand" "")
5045 (match_operand:SF 1 "general_operand" ""))]
5050 if (GET_CODE (operands[0]) == MEM)
5051 operands[1] = force_reg (SFmode, operands[1]);
5053 else /* TARGET_THUMB */
5055 if (!no_new_pseudos)
5057 if (GET_CODE (operands[0]) != REG)
5058 operands[1] = force_reg (SFmode, operands[1]);
5065 [(set (match_operand:SF 0 "nonimmediate_operand" "")
5066 (match_operand:SF 1 "immediate_operand" ""))]
5068 && !(TARGET_HARD_FLOAT && TARGET_FPA)
5070 && GET_CODE (operands[1]) == CONST_DOUBLE"
5071 [(set (match_dup 2) (match_dup 3))]
5073 operands[2] = gen_lowpart (SImode, operands[0]);
5074 operands[3] = gen_lowpart (SImode, operands[1]);
5075 if (operands[2] == 0 || operands[3] == 0)
5080 (define_insn "*arm_movsf_soft_insn"
5081 [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,m")
5082 (match_operand:SF 1 "general_operand" "r,mE,r"))]
5084 && TARGET_SOFT_FLOAT
5085 && (GET_CODE (operands[0]) != MEM
5086 || register_operand (operands[1], SFmode))"
5089 ldr%?\\t%0, %1\\t%@ float
5090 str%?\\t%1, %0\\t%@ float"
5091 [(set_attr "length" "4,4,4")
5092 (set_attr "predicable" "yes")
5093 (set_attr "type" "*,load1,store1")
5094 (set_attr "pool_range" "*,4096,*")
5095 (set_attr "neg_pool_range" "*,4084,*")]
5098 ;;; ??? This should have alternatives for constants.
5099 (define_insn "*thumb_movsf_insn"
5100 [(set (match_operand:SF 0 "nonimmediate_operand" "=l,l,>,l, m,*r,*h")
5101 (match_operand:SF 1 "general_operand" "l, >,l,mF,l,*h,*r"))]
5103 && ( register_operand (operands[0], SFmode)
5104 || register_operand (operands[1], SFmode))"
5113 [(set_attr "length" "2")
5114 (set_attr "type" "*,load1,store1,load1,store1,*,*")
5115 (set_attr "pool_range" "*,*,*,1020,*,*,*")]
5118 (define_expand "movdf"
5119 [(set (match_operand:DF 0 "general_operand" "")
5120 (match_operand:DF 1 "general_operand" ""))]
5125 if (GET_CODE (operands[0]) == MEM)
5126 operands[1] = force_reg (DFmode, operands[1]);
5128 else /* TARGET_THUMB */
5130 if (!no_new_pseudos)
5132 if (GET_CODE (operands[0]) != REG)
5133 operands[1] = force_reg (DFmode, operands[1]);
5139 ;; Reloading a df mode value stored in integer regs to memory can require a
5141 (define_expand "reload_outdf"
5142 [(match_operand:DF 0 "arm_reload_memory_operand" "=o")
5143 (match_operand:DF 1 "s_register_operand" "r")
5144 (match_operand:SI 2 "s_register_operand" "=&r")]
5148 enum rtx_code code = GET_CODE (XEXP (operands[0], 0));
5151 operands[2] = XEXP (operands[0], 0);
5152 else if (code == POST_INC || code == PRE_DEC)
5154 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
5155 operands[1] = gen_rtx_SUBREG (DImode, operands[1], 0);
5156 emit_insn (gen_movdi (operands[0], operands[1]));
5159 else if (code == PRE_INC)
5161 rtx reg = XEXP (XEXP (operands[0], 0), 0);
5163 emit_insn (gen_addsi3 (reg, reg, GEN_INT (8)));
5166 else if (code == POST_DEC)
5167 operands[2] = XEXP (XEXP (operands[0], 0), 0);
5169 emit_insn (gen_addsi3 (operands[2], XEXP (XEXP (operands[0], 0), 0),
5170 XEXP (XEXP (operands[0], 0), 1)));
5172 emit_insn (gen_rtx_SET (VOIDmode, gen_rtx_MEM (DFmode, operands[2]),
5175 if (code == POST_DEC)
5176 emit_insn (gen_addsi3 (operands[2], operands[2], GEN_INT (-8)));
5182 (define_insn "*movdf_soft_insn"
5183 [(set (match_operand:DF 0 "nonimmediate_soft_df_operand" "=r,r,m")
5184 (match_operand:DF 1 "soft_df_operand" "r,mF,r"))]
5185 "TARGET_ARM && TARGET_SOFT_FLOAT
5187 "* return output_move_double (operands);"
5188 [(set_attr "length" "8,8,8")
5189 (set_attr "type" "*,load2,store2")
5190 (set_attr "pool_range" "1020")
5191 (set_attr "neg_pool_range" "1008")]
5194 ;;; ??? This should have alternatives for constants.
5195 ;;; ??? This was originally identical to the movdi_insn pattern.
5196 ;;; ??? The 'F' constraint looks funny, but it should always be replaced by
5197 ;;; thumb_reorg with a memory reference.
5198 (define_insn "*thumb_movdf_insn"
5199 [(set (match_operand:DF 0 "nonimmediate_operand" "=l,l,>,l, m,*r")
5200 (match_operand:DF 1 "general_operand" "l, >,l,mF,l,*r"))]
5202 && ( register_operand (operands[0], DFmode)
5203 || register_operand (operands[1], DFmode))"
5205 switch (which_alternative)
5209 if (REGNO (operands[1]) == REGNO (operands[0]) + 1)
5210 return \"add\\t%0, %1, #0\;add\\t%H0, %H1, #0\";
5211 return \"add\\t%H0, %H1, #0\;add\\t%0, %1, #0\";
5213 return \"ldmia\\t%1, {%0, %H0}\";
5215 return \"stmia\\t%0, {%1, %H1}\";
5217 return thumb_load_double_from_address (operands);
5219 operands[2] = gen_rtx_MEM (SImode,
5220 plus_constant (XEXP (operands[0], 0), 4));
5221 output_asm_insn (\"str\\t%1, %0\;str\\t%H1, %2\", operands);
5224 if (REGNO (operands[1]) == REGNO (operands[0]) + 1)
5225 return \"mov\\t%0, %1\;mov\\t%H0, %H1\";
5226 return \"mov\\t%H0, %H1\;mov\\t%0, %1\";
5229 [(set_attr "length" "4,2,2,6,4,4")
5230 (set_attr "type" "*,load2,store2,load2,store2,*")
5231 (set_attr "pool_range" "*,*,*,1020,*,*")]
5235 (define_expand "movv2si"
5236 [(set (match_operand:V2SI 0 "nonimmediate_operand" "")
5237 (match_operand:V2SI 1 "general_operand" ""))]
5238 "TARGET_REALLY_IWMMXT"
5242 (define_expand "movv4hi"
5243 [(set (match_operand:V4HI 0 "nonimmediate_operand" "")
5244 (match_operand:V4HI 1 "general_operand" ""))]
5245 "TARGET_REALLY_IWMMXT"
5249 (define_expand "movv8qi"
5250 [(set (match_operand:V8QI 0 "nonimmediate_operand" "")
5251 (match_operand:V8QI 1 "general_operand" ""))]
5252 "TARGET_REALLY_IWMMXT"
5257 ;; load- and store-multiple insns
5258 ;; The arm can load/store any set of registers, provided that they are in
5259 ;; ascending order; but that is beyond GCC so stick with what it knows.
5261 (define_expand "load_multiple"
5262 [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
5263 (match_operand:SI 1 "" ""))
5264 (use (match_operand:SI 2 "" ""))])]
5267 /* Support only fixed point registers. */
5268 if (GET_CODE (operands[2]) != CONST_INT
5269 || INTVAL (operands[2]) > 14
5270 || INTVAL (operands[2]) < 2
5271 || GET_CODE (operands[1]) != MEM
5272 || GET_CODE (operands[0]) != REG
5273 || REGNO (operands[0]) > (LAST_ARM_REGNUM - 1)
5274 || REGNO (operands[0]) + INTVAL (operands[2]) > LAST_ARM_REGNUM)
5278 = arm_gen_load_multiple (REGNO (operands[0]), INTVAL (operands[2]),
5279 force_reg (SImode, XEXP (operands[1], 0)),
5280 TRUE, FALSE, RTX_UNCHANGING_P(operands[1]),
5281 MEM_IN_STRUCT_P(operands[1]),
5282 MEM_SCALAR_P (operands[1]));
5286 ;; Load multiple with write-back
5288 (define_insn "*ldmsi_postinc4"
5289 [(match_parallel 0 "load_multiple_operation"
5290 [(set (match_operand:SI 1 "s_register_operand" "=r")
5291 (plus:SI (match_operand:SI 2 "s_register_operand" "1")
5293 (set (match_operand:SI 3 "arm_hard_register_operand" "")
5294 (mem:SI (match_dup 2)))
5295 (set (match_operand:SI 4 "arm_hard_register_operand" "")
5296 (mem:SI (plus:SI (match_dup 2) (const_int 4))))
5297 (set (match_operand:SI 5 "arm_hard_register_operand" "")
5298 (mem:SI (plus:SI (match_dup 2) (const_int 8))))
5299 (set (match_operand:SI 6 "arm_hard_register_operand" "")
5300 (mem:SI (plus:SI (match_dup 2) (const_int 12))))])]
5301 "TARGET_ARM && XVECLEN (operands[0], 0) == 5"
5302 "ldm%?ia\\t%1!, {%3, %4, %5, %6}"
5303 [(set_attr "type" "load4")
5304 (set_attr "predicable" "yes")]
5307 (define_insn "*ldmsi_postinc3"
5308 [(match_parallel 0 "load_multiple_operation"
5309 [(set (match_operand:SI 1 "s_register_operand" "=r")
5310 (plus:SI (match_operand:SI 2 "s_register_operand" "1")
5312 (set (match_operand:SI 3 "arm_hard_register_operand" "")
5313 (mem:SI (match_dup 2)))
5314 (set (match_operand:SI 4 "arm_hard_register_operand" "")
5315 (mem:SI (plus:SI (match_dup 2) (const_int 4))))
5316 (set (match_operand:SI 5 "arm_hard_register_operand" "")
5317 (mem:SI (plus:SI (match_dup 2) (const_int 8))))])]
5318 "TARGET_ARM && XVECLEN (operands[0], 0) == 4"
5319 "ldm%?ia\\t%1!, {%3, %4, %5}"
5320 [(set_attr "type" "load3")
5321 (set_attr "predicable" "yes")]
5324 (define_insn "*ldmsi_postinc2"
5325 [(match_parallel 0 "load_multiple_operation"
5326 [(set (match_operand:SI 1 "s_register_operand" "=r")
5327 (plus:SI (match_operand:SI 2 "s_register_operand" "1")
5329 (set (match_operand:SI 3 "arm_hard_register_operand" "")
5330 (mem:SI (match_dup 2)))
5331 (set (match_operand:SI 4 "arm_hard_register_operand" "")
5332 (mem:SI (plus:SI (match_dup 2) (const_int 4))))])]
5333 "TARGET_ARM && XVECLEN (operands[0], 0) == 3"
5334 "ldm%?ia\\t%1!, {%3, %4}"
5335 [(set_attr "type" "load2")
5336 (set_attr "predicable" "yes")]
5339 ;; Ordinary load multiple
5341 (define_insn "*ldmsi4"
5342 [(match_parallel 0 "load_multiple_operation"
5343 [(set (match_operand:SI 2 "arm_hard_register_operand" "")
5344 (mem:SI (match_operand:SI 1 "s_register_operand" "r")))
5345 (set (match_operand:SI 3 "arm_hard_register_operand" "")
5346 (mem:SI (plus:SI (match_dup 1) (const_int 4))))
5347 (set (match_operand:SI 4 "arm_hard_register_operand" "")
5348 (mem:SI (plus:SI (match_dup 1) (const_int 8))))
5349 (set (match_operand:SI 5 "arm_hard_register_operand" "")
5350 (mem:SI (plus:SI (match_dup 1) (const_int 12))))])]
5351 "TARGET_ARM && XVECLEN (operands[0], 0) == 4"
5352 "ldm%?ia\\t%1, {%2, %3, %4, %5}"
5353 [(set_attr "type" "load4")
5354 (set_attr "predicable" "yes")]
5357 (define_insn "*ldmsi3"
5358 [(match_parallel 0 "load_multiple_operation"
5359 [(set (match_operand:SI 2 "arm_hard_register_operand" "")
5360 (mem:SI (match_operand:SI 1 "s_register_operand" "r")))
5361 (set (match_operand:SI 3 "arm_hard_register_operand" "")
5362 (mem:SI (plus:SI (match_dup 1) (const_int 4))))
5363 (set (match_operand:SI 4 "arm_hard_register_operand" "")
5364 (mem:SI (plus:SI (match_dup 1) (const_int 8))))])]
5365 "TARGET_ARM && XVECLEN (operands[0], 0) == 3"
5366 "ldm%?ia\\t%1, {%2, %3, %4}"
5367 [(set_attr "type" "load3")
5368 (set_attr "predicable" "yes")]
5371 (define_insn "*ldmsi2"
5372 [(match_parallel 0 "load_multiple_operation"
5373 [(set (match_operand:SI 2 "arm_hard_register_operand" "")
5374 (mem:SI (match_operand:SI 1 "s_register_operand" "r")))
5375 (set (match_operand:SI 3 "arm_hard_register_operand" "")
5376 (mem:SI (plus:SI (match_dup 1) (const_int 4))))])]
5377 "TARGET_ARM && XVECLEN (operands[0], 0) == 2"
5378 "ldm%?ia\\t%1, {%2, %3}"
5379 [(set_attr "type" "load2")
5380 (set_attr "predicable" "yes")]
5383 (define_expand "store_multiple"
5384 [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
5385 (match_operand:SI 1 "" ""))
5386 (use (match_operand:SI 2 "" ""))])]
5389 /* Support only fixed point registers. */
5390 if (GET_CODE (operands[2]) != CONST_INT
5391 || INTVAL (operands[2]) > 14
5392 || INTVAL (operands[2]) < 2
5393 || GET_CODE (operands[1]) != REG
5394 || GET_CODE (operands[0]) != MEM
5395 || REGNO (operands[1]) > (LAST_ARM_REGNUM - 1)
5396 || REGNO (operands[1]) + INTVAL (operands[2]) > LAST_ARM_REGNUM)
5400 = arm_gen_store_multiple (REGNO (operands[1]), INTVAL (operands[2]),
5401 force_reg (SImode, XEXP (operands[0], 0)),
5402 TRUE, FALSE, RTX_UNCHANGING_P (operands[0]),
5403 MEM_IN_STRUCT_P(operands[0]),
5404 MEM_SCALAR_P (operands[0]));
5408 ;; Store multiple with write-back
5410 (define_insn "*stmsi_postinc4"
5411 [(match_parallel 0 "store_multiple_operation"
5412 [(set (match_operand:SI 1 "s_register_operand" "=r")
5413 (plus:SI (match_operand:SI 2 "s_register_operand" "1")
5415 (set (mem:SI (match_dup 2))
5416 (match_operand:SI 3 "arm_hard_register_operand" ""))
5417 (set (mem:SI (plus:SI (match_dup 2) (const_int 4)))
5418 (match_operand:SI 4 "arm_hard_register_operand" ""))
5419 (set (mem:SI (plus:SI (match_dup 2) (const_int 8)))
5420 (match_operand:SI 5 "arm_hard_register_operand" ""))
5421 (set (mem:SI (plus:SI (match_dup 2) (const_int 12)))
5422 (match_operand:SI 6 "arm_hard_register_operand" ""))])]
5423 "TARGET_ARM && XVECLEN (operands[0], 0) == 5"
5424 "stm%?ia\\t%1!, {%3, %4, %5, %6}"
5425 [(set_attr "predicable" "yes")
5426 (set_attr "type" "store4")]
5429 (define_insn "*stmsi_postinc3"
5430 [(match_parallel 0 "store_multiple_operation"
5431 [(set (match_operand:SI 1 "s_register_operand" "=r")
5432 (plus:SI (match_operand:SI 2 "s_register_operand" "1")
5434 (set (mem:SI (match_dup 2))
5435 (match_operand:SI 3 "arm_hard_register_operand" ""))
5436 (set (mem:SI (plus:SI (match_dup 2) (const_int 4)))
5437 (match_operand:SI 4 "arm_hard_register_operand" ""))
5438 (set (mem:SI (plus:SI (match_dup 2) (const_int 8)))
5439 (match_operand:SI 5 "arm_hard_register_operand" ""))])]
5440 "TARGET_ARM && XVECLEN (operands[0], 0) == 4"
5441 "stm%?ia\\t%1!, {%3, %4, %5}"
5442 [(set_attr "predicable" "yes")
5443 (set_attr "type" "store3")]
5446 (define_insn "*stmsi_postinc2"
5447 [(match_parallel 0 "store_multiple_operation"
5448 [(set (match_operand:SI 1 "s_register_operand" "=r")
5449 (plus:SI (match_operand:SI 2 "s_register_operand" "1")
5451 (set (mem:SI (match_dup 2))
5452 (match_operand:SI 3 "arm_hard_register_operand" ""))
5453 (set (mem:SI (plus:SI (match_dup 2) (const_int 4)))
5454 (match_operand:SI 4 "arm_hard_register_operand" ""))])]
5455 "TARGET_ARM && XVECLEN (operands[0], 0) == 3"
5456 "stm%?ia\\t%1!, {%3, %4}"
5457 [(set_attr "predicable" "yes")
5458 (set_attr "type" "store2")]
5461 ;; Ordinary store multiple
5463 (define_insn "*stmsi4"
5464 [(match_parallel 0 "store_multiple_operation"
5465 [(set (mem:SI (match_operand:SI 1 "s_register_operand" "r"))
5466 (match_operand:SI 2 "arm_hard_register_operand" ""))
5467 (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
5468 (match_operand:SI 3 "arm_hard_register_operand" ""))
5469 (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
5470 (match_operand:SI 4 "arm_hard_register_operand" ""))
5471 (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
5472 (match_operand:SI 5 "arm_hard_register_operand" ""))])]
5473 "TARGET_ARM && XVECLEN (operands[0], 0) == 4"
5474 "stm%?ia\\t%1, {%2, %3, %4, %5}"
5475 [(set_attr "predicable" "yes")
5476 (set_attr "type" "store4")]
5479 (define_insn "*stmsi3"
5480 [(match_parallel 0 "store_multiple_operation"
5481 [(set (mem:SI (match_operand:SI 1 "s_register_operand" "r"))
5482 (match_operand:SI 2 "arm_hard_register_operand" ""))
5483 (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
5484 (match_operand:SI 3 "arm_hard_register_operand" ""))
5485 (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
5486 (match_operand:SI 4 "arm_hard_register_operand" ""))])]
5487 "TARGET_ARM && XVECLEN (operands[0], 0) == 3"
5488 "stm%?ia\\t%1, {%2, %3, %4}"
5489 [(set_attr "predicable" "yes")
5490 (set_attr "type" "store3")]
5493 (define_insn "*stmsi2"
5494 [(match_parallel 0 "store_multiple_operation"
5495 [(set (mem:SI (match_operand:SI 1 "s_register_operand" "r"))
5496 (match_operand:SI 2 "arm_hard_register_operand" ""))
5497 (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
5498 (match_operand:SI 3 "arm_hard_register_operand" ""))])]
5499 "TARGET_ARM && XVECLEN (operands[0], 0) == 2"
5500 "stm%?ia\\t%1, {%2, %3}"
5501 [(set_attr "predicable" "yes")
5502 (set_attr "type" "store2")]
5505 ;; Move a block of memory if it is word aligned and MORE than 2 words long.
5506 ;; We could let this apply for blocks of less than this, but it clobbers so
5507 ;; many registers that there is then probably a better way.
5509 (define_expand "movstrqi"
5510 [(match_operand:BLK 0 "general_operand" "")
5511 (match_operand:BLK 1 "general_operand" "")
5512 (match_operand:SI 2 "const_int_operand" "")
5513 (match_operand:SI 3 "const_int_operand" "")]
5518 if (arm_gen_movstrqi (operands))
5522 else /* TARGET_THUMB */
5524 if ( INTVAL (operands[3]) != 4
5525 || INTVAL (operands[2]) > 48)
5528 thumb_expand_movstrqi (operands);
5534 ;; Thumb block-move insns
5536 (define_insn "movmem12b"
5537 [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
5538 (mem:SI (match_operand:SI 3 "register_operand" "1")))
5539 (set (mem:SI (plus:SI (match_dup 2) (const_int 4)))
5540 (mem:SI (plus:SI (match_dup 3) (const_int 4))))
5541 (set (mem:SI (plus:SI (match_dup 2) (const_int 8)))
5542 (mem:SI (plus:SI (match_dup 3) (const_int 8))))
5543 (set (match_operand:SI 0 "register_operand" "=l")
5544 (plus:SI (match_dup 2) (const_int 12)))
5545 (set (match_operand:SI 1 "register_operand" "=l")
5546 (plus:SI (match_dup 3) (const_int 12)))
5547 (clobber (match_scratch:SI 4 "=&l"))
5548 (clobber (match_scratch:SI 5 "=&l"))
5549 (clobber (match_scratch:SI 6 "=&l"))]
5551 "* return thumb_output_move_mem_multiple (3, operands);"
5552 [(set_attr "length" "4")
5553 ; This isn't entirely accurate... It loads as well, but in terms of
5554 ; scheduling the following insn it is better to consider it as a store
5555 (set_attr "type" "store3")]
5558 (define_insn "movmem8b"
5559 [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
5560 (mem:SI (match_operand:SI 3 "register_operand" "1")))
5561 (set (mem:SI (plus:SI (match_dup 2) (const_int 4)))
5562 (mem:SI (plus:SI (match_dup 3) (const_int 4))))
5563 (set (match_operand:SI 0 "register_operand" "=l")
5564 (plus:SI (match_dup 2) (const_int 8)))
5565 (set (match_operand:SI 1 "register_operand" "=l")
5566 (plus:SI (match_dup 3) (const_int 8)))
5567 (clobber (match_scratch:SI 4 "=&l"))
5568 (clobber (match_scratch:SI 5 "=&l"))]
5570 "* return thumb_output_move_mem_multiple (2, operands);"
5571 [(set_attr "length" "4")
5572 ; This isn't entirely accurate... It loads as well, but in terms of
5573 ; scheduling the following insn it is better to consider it as a store
5574 (set_attr "type" "store2")]
5579 ;; Compare & branch insns
5580 ;; The range calculations are based as follows:
5581 ;; For forward branches, the address calculation returns the address of
5582 ;; the next instruction. This is 2 beyond the branch instruction.
5583 ;; For backward branches, the address calculation returns the address of
5584 ;; the first instruction in this pattern (cmp). This is 2 before the branch
5585 ;; instruction for the shortest sequence, and 4 before the branch instruction
5586 ;; if we have to jump around an unconditional branch.
5587 ;; To the basic branch range the PC offset must be added (this is +4).
5588 ;; So for forward branches we have
5589 ;; (pos_range - pos_base_offs + pc_offs) = (pos_range - 2 + 4).
5590 ;; And for backward branches we have
5591 ;; (neg_range - neg_base_offs + pc_offs) = (neg_range - (-2 or -4) + 4).
5593 ;; For a 'b' pos_range = 2046, neg_range = -2048 giving (-2040->2048).
5594 ;; For a 'b<cond>' pos_range = 254, neg_range = -256 giving (-250 ->256).
5596 (define_expand "cbranchsi4"
5597 [(set (pc) (if_then_else
5598 (match_operator 0 "arm_comparison_operator"
5599 [(match_operand:SI 1 "s_register_operand" "")
5600 (match_operand:SI 2 "nonmemory_operand" "")])
5601 (label_ref (match_operand 3 "" ""))
5605 if (thumb_cmpneg_operand (operands[2], SImode))
5607 emit_jump_insn (gen_cbranchsi4_scratch (NULL, operands[1], operands[2],
5608 operands[3], operands[0]));
5611 if (!thumb_cmp_operand (operands[2], SImode))
5612 operands[2] = force_reg (SImode, operands[2]);
5615 (define_insn "*cbranchsi4_insn"
5616 [(set (pc) (if_then_else
5617 (match_operator 0 "arm_comparison_operator"
5618 [(match_operand:SI 1 "s_register_operand" "l,*h")
5619 (match_operand:SI 2 "thumb_cmp_operand" "lI*h,*r")])
5620 (label_ref (match_operand 3 "" ""))
5624 output_asm_insn (\"cmp\\t%1, %2\", operands);
5626 switch (get_attr_length (insn))
5628 case 4: return \"b%d0\\t%l3\";
5629 case 6: return \"b%D0\\t.LCB%=\;b\\t%l3\\t%@long jump\\n.LCB%=:\";
5630 default: return \"b%D0\\t.LCB%=\;bl\\t%l3\\t%@far jump\\n.LCB%=:\";
5633 [(set (attr "far_jump")
5635 (eq_attr "length" "8")
5636 (const_string "yes")
5637 (const_string "no")))
5638 (set (attr "length")
5640 (and (ge (minus (match_dup 3) (pc)) (const_int -250))
5641 (le (minus (match_dup 3) (pc)) (const_int 256)))
5644 (and (ge (minus (match_dup 3) (pc)) (const_int -2040))
5645 (le (minus (match_dup 3) (pc)) (const_int 2048)))
5650 (define_insn "cbranchsi4_scratch"
5651 [(set (pc) (if_then_else
5652 (match_operator 4 "arm_comparison_operator"
5653 [(match_operand:SI 1 "s_register_operand" "l,0")
5654 (match_operand:SI 2 "thumb_cmpneg_operand" "L,J")])
5655 (label_ref (match_operand 3 "" ""))
5657 (clobber (match_scratch:SI 0 "=l,l"))]
5660 output_asm_insn (\"add\\t%0, %1, #%n2\", operands);
5662 switch (get_attr_length (insn))
5664 case 4: return \"b%d4\\t%l3\";
5665 case 6: return \"b%D4\\t.LCB%=\;b\\t%l3\\t%@long jump\\n.LCB%=:\";
5666 default: return \"b%D4\\t.LCB%=\;bl\\t%l3\\t%@far jump\\n.LCB%=:\";
5669 [(set (attr "far_jump")
5671 (eq_attr "length" "8")
5672 (const_string "yes")
5673 (const_string "no")))
5674 (set (attr "length")
5676 (and (ge (minus (match_dup 3) (pc)) (const_int -250))
5677 (le (minus (match_dup 3) (pc)) (const_int 256)))
5680 (and (ge (minus (match_dup 3) (pc)) (const_int -2040))
5681 (le (minus (match_dup 3) (pc)) (const_int 2048)))
5685 (define_insn "*movsi_cbranchsi4"
5688 (match_operator 3 "arm_comparison_operator"
5689 [(match_operand:SI 1 "s_register_operand" "0,l,l,l")
5691 (label_ref (match_operand 2 "" ""))
5693 (set (match_operand:SI 0 "thumb_cbrch_target_operand" "=l,l,*h,*m")
5697 if (which_alternative == 0)
5698 output_asm_insn (\"cmp\t%0, #0\", operands);
5699 else if (which_alternative == 1)
5700 output_asm_insn (\"sub\t%0, %1, #0\", operands);
5703 output_asm_insn (\"cmp\t%1, #0\", operands);
5704 if (which_alternative == 2)
5705 output_asm_insn (\"mov\t%0, %1\", operands);
5707 output_asm_insn (\"str\t%1, %0\", operands);
5709 switch (get_attr_length (insn) - ((which_alternative > 1) ? 2 : 0))
5711 case 4: return \"b%d3\\t%l2\";
5712 case 6: return \"b%D3\\t.LCB%=\;b\\t%l2\\t%@long jump\\n.LCB%=:\";
5713 default: return \"b%D3\\t.LCB%=\;bl\\t%l2\\t%@far jump\\n.LCB%=:\";
5716 [(set (attr "far_jump")
5718 (ior (and (gt (symbol_ref ("which_alternative"))
5720 (eq_attr "length" "8"))
5721 (eq_attr "length" "10"))
5722 (const_string "yes")
5723 (const_string "no")))
5724 (set (attr "length")
5726 (le (symbol_ref ("which_alternative"))
5729 (and (ge (minus (match_dup 2) (pc)) (const_int -250))
5730 (le (minus (match_dup 2) (pc)) (const_int 256)))
5733 (and (ge (minus (match_dup 2) (pc)) (const_int -2040))
5734 (le (minus (match_dup 2) (pc)) (const_int 2048)))
5738 (and (ge (minus (match_dup 2) (pc)) (const_int -248))
5739 (le (minus (match_dup 2) (pc)) (const_int 256)))
5742 (and (ge (minus (match_dup 2) (pc)) (const_int -2038))
5743 (le (minus (match_dup 2) (pc)) (const_int 2048)))
5748 (define_insn "*negated_cbranchsi4"
5751 (match_operator 0 "arm_comparison_operator"
5752 [(match_operand:SI 1 "s_register_operand" "l")
5753 (neg:SI (match_operand:SI 2 "s_register_operand" "l"))])
5754 (label_ref (match_operand 3 "" ""))
5758 output_asm_insn (\"cmn\\t%1, %2\", operands);
5759 switch (get_attr_length (insn))
5761 case 4: return \"b%d0\\t%l3\";
5762 case 6: return \"b%D0\\t.LCB%=\;b\\t%l3\\t%@long jump\\n.LCB%=:\";
5763 default: return \"b%D0\\t.LCB%=\;bl\\t%l3\\t%@far jump\\n.LCB%=:\";
5766 [(set (attr "far_jump")
5768 (eq_attr "length" "8")
5769 (const_string "yes")
5770 (const_string "no")))
5771 (set (attr "length")
5773 (and (ge (minus (match_dup 3) (pc)) (const_int -250))
5774 (le (minus (match_dup 3) (pc)) (const_int 256)))
5777 (and (ge (minus (match_dup 3) (pc)) (const_int -2040))
5778 (le (minus (match_dup 3) (pc)) (const_int 2048)))
5783 (define_insn "*tbit_cbranch"
5786 (match_operator 0 "equality_operator"
5787 [(zero_extract:SI (match_operand:SI 1 "s_register_operand" "l")
5789 (match_operand:SI 2 "const_int_operand" "i"))
5791 (label_ref (match_operand 3 "" ""))
5793 (clobber (match_scratch:SI 4 "=l"))]
5798 op[0] = operands[4];
5799 op[1] = operands[1];
5800 op[2] = GEN_INT (32 - 1 - INTVAL (operands[2]));
5802 output_asm_insn (\"lsl\\t%0, %1, %2\", op);
5803 switch (get_attr_length (insn))
5805 case 4: return \"b%d0\\t%l3\";
5806 case 6: return \"b%D0\\t.LCB%=\;b\\t%l3\\t%@long jump\\n.LCB%=:\";
5807 default: return \"b%D0\\t.LCB%=\;bl\\t%l3\\t%@far jump\\n.LCB%=:\";
5810 [(set (attr "far_jump")
5812 (eq_attr "length" "8")
5813 (const_string "yes")
5814 (const_string "no")))
5815 (set (attr "length")
5817 (and (ge (minus (match_dup 3) (pc)) (const_int -250))
5818 (le (minus (match_dup 3) (pc)) (const_int 256)))
5821 (and (ge (minus (match_dup 3) (pc)) (const_int -2040))
5822 (le (minus (match_dup 3) (pc)) (const_int 2048)))
5827 (define_insn "*tstsi3_cbranch"
5830 (match_operator 3 "equality_operator"
5831 [(and:SI (match_operand:SI 0 "s_register_operand" "%l")
5832 (match_operand:SI 1 "s_register_operand" "l"))
5834 (label_ref (match_operand 2 "" ""))
5839 output_asm_insn (\"tst\\t%0, %1\", operands);
5840 switch (get_attr_length (insn))
5842 case 4: return \"b%d3\\t%l2\";
5843 case 6: return \"b%D3\\t.LCB%=\;b\\t%l2\\t%@long jump\\n.LCB%=:\";
5844 default: return \"b%D3\\t.LCB%=\;bl\\t%l2\\t%@far jump\\n.LCB%=:\";
5847 [(set (attr "far_jump")
5849 (eq_attr "length" "8")
5850 (const_string "yes")
5851 (const_string "no")))
5852 (set (attr "length")
5854 (and (ge (minus (match_dup 2) (pc)) (const_int -250))
5855 (le (minus (match_dup 2) (pc)) (const_int 256)))
5858 (and (ge (minus (match_dup 2) (pc)) (const_int -2040))
5859 (le (minus (match_dup 2) (pc)) (const_int 2048)))
5864 (define_insn "*andsi3_cbranch"
5867 (match_operator 5 "equality_operator"
5868 [(and:SI (match_operand:SI 2 "s_register_operand" "%0,1,1,1")
5869 (match_operand:SI 3 "s_register_operand" "l,l,l,l"))
5871 (label_ref (match_operand 4 "" ""))
5873 (set (match_operand:SI 0 "thumb_cbrch_target_operand" "=l,*?h,*?m,*?m")
5874 (and:SI (match_dup 2) (match_dup 3)))
5875 (clobber (match_scratch:SI 1 "=X,l,&l,&l"))]
5879 if (which_alternative == 0)
5880 output_asm_insn (\"and\\t%0, %3\", operands);
5881 else if (which_alternative == 1)
5883 output_asm_insn (\"and\\t%1, %3\", operands);
5884 output_asm_insn (\"mov\\t%0, %1\", operands);
5888 output_asm_insn (\"and\\t%1, %3\", operands);
5889 output_asm_insn (\"str\\t%1, %0\", operands);
5892 switch (get_attr_length (insn) - (which_alternative ? 2 : 0))
5894 case 4: return \"b%d5\\t%l4\";
5895 case 6: return \"b%D5\\t.LCB%=\;b\\t%l4\\t%@long jump\\n.LCB%=:\";
5896 default: return \"b%D5\\t.LCB%=\;bl\\t%l4\\t%@far jump\\n.LCB%=:\";
5899 [(set (attr "far_jump")
5901 (ior (and (eq (symbol_ref ("which_alternative"))
5903 (eq_attr "length" "8"))
5904 (eq_attr "length" "10"))
5905 (const_string "yes")
5906 (const_string "no")))
5907 (set (attr "length")
5909 (eq (symbol_ref ("which_alternative"))
5912 (and (ge (minus (match_dup 4) (pc)) (const_int -250))
5913 (le (minus (match_dup 4) (pc)) (const_int 256)))
5916 (and (ge (minus (match_dup 4) (pc)) (const_int -2040))
5917 (le (minus (match_dup 4) (pc)) (const_int 2048)))
5921 (and (ge (minus (match_dup 4) (pc)) (const_int -248))
5922 (le (minus (match_dup 4) (pc)) (const_int 256)))
5925 (and (ge (minus (match_dup 4) (pc)) (const_int -2038))
5926 (le (minus (match_dup 4) (pc)) (const_int 2048)))
5931 (define_insn "*orrsi3_cbranch_scratch"
5934 (match_operator 4 "equality_operator"
5935 [(ior:SI (match_operand:SI 1 "s_register_operand" "%0")
5936 (match_operand:SI 2 "s_register_operand" "l"))
5938 (label_ref (match_operand 3 "" ""))
5940 (clobber (match_scratch:SI 0 "=l"))]
5944 output_asm_insn (\"orr\\t%0, %2\", operands);
5945 switch (get_attr_length (insn))
5947 case 4: return \"b%d4\\t%l3\";
5948 case 6: return \"b%D4\\t.LCB%=\;b\\t%l3\\t%@long jump\\n.LCB%=:\";
5949 default: return \"b%D4\\t.LCB%=\;bl\\t%l3\\t%@far jump\\n.LCB%=:\";
5952 [(set (attr "far_jump")
5954 (eq_attr "length" "8")
5955 (const_string "yes")
5956 (const_string "no")))
5957 (set (attr "length")
5959 (and (ge (minus (match_dup 3) (pc)) (const_int -250))
5960 (le (minus (match_dup 3) (pc)) (const_int 256)))
5963 (and (ge (minus (match_dup 3) (pc)) (const_int -2040))
5964 (le (minus (match_dup 3) (pc)) (const_int 2048)))
5969 (define_insn "*orrsi3_cbranch"
5972 (match_operator 5 "equality_operator"
5973 [(ior:SI (match_operand:SI 2 "s_register_operand" "%0,1,1,1")
5974 (match_operand:SI 3 "s_register_operand" "l,l,l,l"))
5976 (label_ref (match_operand 4 "" ""))
5978 (set (match_operand:SI 0 "thumb_cbrch_target_operand" "=l,*?h,*?m,*?m")
5979 (ior:SI (match_dup 2) (match_dup 3)))
5980 (clobber (match_scratch:SI 1 "=X,l,&l,&l"))]
5984 if (which_alternative == 0)
5985 output_asm_insn (\"orr\\t%0, %3\", operands);
5986 else if (which_alternative == 1)
5988 output_asm_insn (\"orr\\t%1, %3\", operands);
5989 output_asm_insn (\"mov\\t%0, %1\", operands);
5993 output_asm_insn (\"orr\\t%1, %3\", operands);
5994 output_asm_insn (\"str\\t%1, %0\", operands);
5997 switch (get_attr_length (insn) - (which_alternative ? 2 : 0))
5999 case 4: return \"b%d5\\t%l4\";
6000 case 6: return \"b%D5\\t.LCB%=\;b\\t%l4\\t%@long jump\\n.LCB%=:\";
6001 default: return \"b%D5\\t.LCB%=\;bl\\t%l4\\t%@far jump\\n.LCB%=:\";
6004 [(set (attr "far_jump")
6006 (ior (and (eq (symbol_ref ("which_alternative"))
6008 (eq_attr "length" "8"))
6009 (eq_attr "length" "10"))
6010 (const_string "yes")
6011 (const_string "no")))
6012 (set (attr "length")
6014 (eq (symbol_ref ("which_alternative"))
6017 (and (ge (minus (match_dup 4) (pc)) (const_int -250))
6018 (le (minus (match_dup 4) (pc)) (const_int 256)))
6021 (and (ge (minus (match_dup 4) (pc)) (const_int -2040))
6022 (le (minus (match_dup 4) (pc)) (const_int 2048)))
6026 (and (ge (minus (match_dup 4) (pc)) (const_int -248))
6027 (le (minus (match_dup 4) (pc)) (const_int 256)))
6030 (and (ge (minus (match_dup 4) (pc)) (const_int -2038))
6031 (le (minus (match_dup 4) (pc)) (const_int 2048)))
6036 (define_insn "*xorsi3_cbranch_scratch"
6039 (match_operator 4 "equality_operator"
6040 [(xor:SI (match_operand:SI 1 "s_register_operand" "%0")
6041 (match_operand:SI 2 "s_register_operand" "l"))
6043 (label_ref (match_operand 3 "" ""))
6045 (clobber (match_scratch:SI 0 "=l"))]
6049 output_asm_insn (\"eor\\t%0, %2\", operands);
6050 switch (get_attr_length (insn))
6052 case 4: return \"b%d4\\t%l3\";
6053 case 6: return \"b%D4\\t.LCB%=\;b\\t%l3\\t%@long jump\\n.LCB%=:\";
6054 default: return \"b%D4\\t.LCB%=\;bl\\t%l3\\t%@far jump\\n.LCB%=:\";
6057 [(set (attr "far_jump")
6059 (eq_attr "length" "8")
6060 (const_string "yes")
6061 (const_string "no")))
6062 (set (attr "length")
6064 (and (ge (minus (match_dup 3) (pc)) (const_int -250))
6065 (le (minus (match_dup 3) (pc)) (const_int 256)))
6068 (and (ge (minus (match_dup 3) (pc)) (const_int -2040))
6069 (le (minus (match_dup 3) (pc)) (const_int 2048)))
6074 (define_insn "*xorsi3_cbranch"
6077 (match_operator 5 "equality_operator"
6078 [(xor:SI (match_operand:SI 2 "s_register_operand" "%0,1,1,1")
6079 (match_operand:SI 3 "s_register_operand" "l,l,l,l"))
6081 (label_ref (match_operand 4 "" ""))
6083 (set (match_operand:SI 0 "thumb_cbrch_target_operand" "=l,*?h,*?m,*?m")
6084 (xor:SI (match_dup 2) (match_dup 3)))
6085 (clobber (match_scratch:SI 1 "=X,l,&l,&l"))]
6089 if (which_alternative == 0)
6090 output_asm_insn (\"eor\\t%0, %3\", operands);
6091 else if (which_alternative == 1)
6093 output_asm_insn (\"eor\\t%1, %3\", operands);
6094 output_asm_insn (\"mov\\t%0, %1\", operands);
6098 output_asm_insn (\"eor\\t%1, %3\", operands);
6099 output_asm_insn (\"str\\t%1, %0\", operands);
6102 switch (get_attr_length (insn) - (which_alternative ? 2 : 0))
6104 case 4: return \"b%d5\\t%l4\";
6105 case 6: return \"b%D5\\t.LCB%=\;b\\t%l4\\t%@long jump\\n.LCB%=:\";
6106 default: return \"b%D5\\t.LCB%=\;bl\\t%l4\\t%@far jump\\n.LCB%=:\";
6109 [(set (attr "far_jump")
6111 (ior (and (eq (symbol_ref ("which_alternative"))
6113 (eq_attr "length" "8"))
6114 (eq_attr "length" "10"))
6115 (const_string "yes")
6116 (const_string "no")))
6117 (set (attr "length")
6119 (eq (symbol_ref ("which_alternative"))
6122 (and (ge (minus (match_dup 4) (pc)) (const_int -250))
6123 (le (minus (match_dup 4) (pc)) (const_int 256)))
6126 (and (ge (minus (match_dup 4) (pc)) (const_int -2040))
6127 (le (minus (match_dup 4) (pc)) (const_int 2048)))
6131 (and (ge (minus (match_dup 4) (pc)) (const_int -248))
6132 (le (minus (match_dup 4) (pc)) (const_int 256)))
6135 (and (ge (minus (match_dup 4) (pc)) (const_int -2038))
6136 (le (minus (match_dup 4) (pc)) (const_int 2048)))
6141 (define_insn "*bicsi3_cbranch_scratch"
6144 (match_operator 4 "equality_operator"
6145 [(and:SI (not:SI (match_operand:SI 2 "s_register_operand" "l"))
6146 (match_operand:SI 1 "s_register_operand" "0"))
6148 (label_ref (match_operand 3 "" ""))
6150 (clobber (match_scratch:SI 0 "=l"))]
6154 output_asm_insn (\"bic\\t%0, %2\", operands);
6155 switch (get_attr_length (insn))
6157 case 4: return \"b%d4\\t%l3\";
6158 case 6: return \"b%D4\\t.LCB%=\;b\\t%l3\\t%@long jump\\n.LCB%=:\";
6159 default: return \"b%D4\\t.LCB%=\;bl\\t%l3\\t%@far jump\\n.LCB%=:\";
6162 [(set (attr "far_jump")
6164 (eq_attr "length" "8")
6165 (const_string "yes")
6166 (const_string "no")))
6167 (set (attr "length")
6169 (and (ge (minus (match_dup 3) (pc)) (const_int -250))
6170 (le (minus (match_dup 3) (pc)) (const_int 256)))
6173 (and (ge (minus (match_dup 3) (pc)) (const_int -2040))
6174 (le (minus (match_dup 3) (pc)) (const_int 2048)))
6179 (define_insn "*bicsi3_cbranch"
6182 (match_operator 5 "equality_operator"
6183 [(and:SI (not:SI (match_operand:SI 3 "s_register_operand" "l,l,l,l"))
6184 (match_operand:SI 2 "s_register_operand" "0,1,1,1"))
6186 (label_ref (match_operand 4 "" ""))
6188 (set (match_operand:SI 0 "thumb_cbrch_target_operand" "=l,*?h,*?m,*?m")
6189 (and:SI (not:SI (match_dup 3)) (match_dup 2)))
6190 (clobber (match_scratch:SI 1 "=X,l,&l,&l"))]
6194 if (which_alternative == 0)
6195 output_asm_insn (\"bic\\t%0, %3\", operands);
6196 else if (which_alternative == 1)
6198 output_asm_insn (\"bic\\t%1, %3\", operands);
6199 output_asm_insn (\"mov\\t%0, %1\", operands);
6203 output_asm_insn (\"bic\\t%1, %3\", operands);
6204 output_asm_insn (\"str\\t%1, %0\", operands);
6207 switch (get_attr_length (insn) - (which_alternative ? 2 : 0))
6209 case 4: return \"b%d5\\t%l4\";
6210 case 6: return \"b%D5\\t.LCB%=\;b\\t%l4\\t%@long jump\\n.LCB%=:\";
6211 default: return \"b%D5\\t.LCB%=\;bl\\t%l4\\t%@far jump\\n.LCB%=:\";
6214 [(set (attr "far_jump")
6216 (ior (and (eq (symbol_ref ("which_alternative"))
6218 (eq_attr "length" "8"))
6219 (eq_attr "length" "10"))
6220 (const_string "yes")
6221 (const_string "no")))
6222 (set (attr "length")
6224 (eq (symbol_ref ("which_alternative"))
6227 (and (ge (minus (match_dup 4) (pc)) (const_int -250))
6228 (le (minus (match_dup 4) (pc)) (const_int 256)))
6231 (and (ge (minus (match_dup 4) (pc)) (const_int -2040))
6232 (le (minus (match_dup 4) (pc)) (const_int 2048)))
6236 (and (ge (minus (match_dup 4) (pc)) (const_int -248))
6237 (le (minus (match_dup 4) (pc)) (const_int 256)))
6240 (and (ge (minus (match_dup 4) (pc)) (const_int -2038))
6241 (le (minus (match_dup 4) (pc)) (const_int 2048)))
6246 (define_insn "*cbranchne_decr1"
6248 (if_then_else (match_operator 3 "equality_operator"
6249 [(match_operand:SI 2 "s_register_operand" "l,l,1,l")
6251 (label_ref (match_operand 4 "" ""))
6253 (set (match_operand:SI 0 "thumb_cbrch_target_operand" "=l,*?h,*?m,*?m")
6254 (plus:SI (match_dup 2) (const_int -1)))
6255 (clobber (match_scratch:SI 1 "=X,l,&l,&l"))]
6260 cond[0] = gen_rtx_fmt_ee ((GET_CODE (operands[3]) == NE
6262 VOIDmode, operands[2], const1_rtx);
6263 cond[1] = operands[4];
6265 if (which_alternative == 0)
6266 output_asm_insn (\"sub\\t%0, %2, #1\", operands);
6267 else if (which_alternative == 1)
6269 /* We must provide an alternative for a hi reg because reload
6270 cannot handle output reloads on a jump instruction, but we
6271 can't subtract into that. Fortunately a mov from lo to hi
6272 does not clobber the condition codes. */
6273 output_asm_insn (\"sub\\t%1, %2, #1\", operands);
6274 output_asm_insn (\"mov\\t%0, %1\", operands);
6278 /* Similarly, but the target is memory. */
6279 output_asm_insn (\"sub\\t%1, %2, #1\", operands);
6280 output_asm_insn (\"str\\t%1, %0\", operands);
6283 switch (get_attr_length (insn) - (which_alternative ? 2 : 0))
6286 output_asm_insn (\"b%d0\\t%l1\", cond);
6289 output_asm_insn (\"b%D0\\t.LCB%=\", cond);
6290 return \"b\\t%l4\\t%@long jump\\n.LCB%=:\";
6292 output_asm_insn (\"b%D0\\t.LCB%=\", cond);
6293 return \"bl\\t%l4\\t%@far jump\\n.LCB%=:\";
6297 [(set (attr "far_jump")
6299 (ior (and (eq (symbol_ref ("which_alternative"))
6301 (eq_attr "length" "8"))
6302 (eq_attr "length" "10"))
6303 (const_string "yes")
6304 (const_string "no")))
6305 (set_attr_alternative "length"
6309 (and (ge (minus (match_dup 4) (pc)) (const_int -250))
6310 (le (minus (match_dup 4) (pc)) (const_int 256)))
6313 (and (ge (minus (match_dup 4) (pc)) (const_int -2040))
6314 (le (minus (match_dup 4) (pc)) (const_int 2048)))
6319 (and (ge (minus (match_dup 4) (pc)) (const_int -248))
6320 (le (minus (match_dup 4) (pc)) (const_int 256)))
6323 (and (ge (minus (match_dup 4) (pc)) (const_int -2038))
6324 (le (minus (match_dup 4) (pc)) (const_int 2048)))
6329 (and (ge (minus (match_dup 4) (pc)) (const_int -248))
6330 (le (minus (match_dup 4) (pc)) (const_int 256)))
6333 (and (ge (minus (match_dup 4) (pc)) (const_int -2038))
6334 (le (minus (match_dup 4) (pc)) (const_int 2048)))
6339 (and (ge (minus (match_dup 4) (pc)) (const_int -248))
6340 (le (minus (match_dup 4) (pc)) (const_int 256)))
6343 (and (ge (minus (match_dup 4) (pc)) (const_int -2038))
6344 (le (minus (match_dup 4) (pc)) (const_int 2048)))
6349 (define_insn "*addsi3_cbranch"
6352 (match_operator 4 "comparison_operator"
6354 (match_operand:SI 2 "s_register_operand" "%l,0,*0,1,1,1")
6355 (match_operand:SI 3 "reg_or_int_operand" "lL,IJ,*r,lIJ,lIJ,lIJ"))
6357 (label_ref (match_operand 5 "" ""))
6360 (match_operand:SI 0 "thumb_cbrch_target_operand" "=l,l,*!h,*?h,*?m,*?m")
6361 (plus:SI (match_dup 2) (match_dup 3)))
6362 (clobber (match_scratch:SI 1 "=X,X,X,l,&l,&l"))]
6364 && (GET_CODE (operands[4]) == EQ
6365 || GET_CODE (operands[4]) == NE
6366 || GET_CODE (operands[4]) == GE
6367 || GET_CODE (operands[4]) == LT)"
6373 cond[0] = (which_alternative < 3) ? operands[0] : operands[1];
6374 cond[1] = operands[2];
6375 cond[2] = operands[3];
6377 if (GET_CODE (cond[2]) == CONST_INT && INTVAL (cond[2]) < 0)
6378 output_asm_insn (\"sub\\t%0, %1, #%n2\", cond);
6380 output_asm_insn (\"add\\t%0, %1, %2\", cond);
6382 if (which_alternative >= 3
6383 && which_alternative < 4)
6384 output_asm_insn (\"mov\\t%0, %1\", operands);
6385 else if (which_alternative >= 4)
6386 output_asm_insn (\"str\\t%1, %0\", operands);
6388 switch (get_attr_length (insn) - ((which_alternative >= 3) ? 2 : 0))
6391 return \"b%d4\\t%l5\";
6393 return \"b%D4\\t.LCB%=\;b\\t%l5\\t%@long jump\\n.LCB%=:\";
6395 return \"b%D4\\t.LCB%=\;bl\\t%l5\\t%@far jump\\n.LCB%=:\";
6399 [(set (attr "far_jump")
6401 (ior (and (lt (symbol_ref ("which_alternative"))
6403 (eq_attr "length" "8"))
6404 (eq_attr "length" "10"))
6405 (const_string "yes")
6406 (const_string "no")))
6407 (set (attr "length")
6409 (lt (symbol_ref ("which_alternative"))
6412 (and (ge (minus (match_dup 5) (pc)) (const_int -250))
6413 (le (minus (match_dup 5) (pc)) (const_int 256)))
6416 (and (ge (minus (match_dup 5) (pc)) (const_int -2040))
6417 (le (minus (match_dup 5) (pc)) (const_int 2048)))
6421 (and (ge (minus (match_dup 5) (pc)) (const_int -248))
6422 (le (minus (match_dup 5) (pc)) (const_int 256)))
6425 (and (ge (minus (match_dup 5) (pc)) (const_int -2038))
6426 (le (minus (match_dup 5) (pc)) (const_int 2048)))
6431 (define_insn "*addsi3_cbranch_scratch"
6434 (match_operator 3 "comparison_operator"
6436 (match_operand:SI 1 "s_register_operand" "%l,l,l,0")
6437 (match_operand:SI 2 "reg_or_int_operand" "J,l,I,L"))
6439 (label_ref (match_operand 4 "" ""))
6441 (clobber (match_scratch:SI 0 "=X,X,l,l"))]
6443 && (GET_CODE (operands[3]) == EQ
6444 || GET_CODE (operands[3]) == NE
6445 || GET_CODE (operands[3]) == GE
6446 || GET_CODE (operands[3]) == LT)"
6449 switch (which_alternative)
6452 output_asm_insn (\"cmp\t%1, #%n2\", operands);
6455 output_asm_insn (\"cmn\t%1, %2\", operands);
6458 output_asm_insn (\"add\t%0, %1, %2\", operands);
6461 output_asm_insn (\"add\t%0, %0, %2\", operands);
6465 switch (get_attr_length (insn))
6468 return \"b%d3\\t%l4\";
6470 return \"b%D3\\t.LCB%=\;b\\t%l4\\t%@long jump\\n.LCB%=:\";
6472 return \"b%D3\\t.LCB%=\;bl\\t%l4\\t%@far jump\\n.LCB%=:\";
6476 [(set (attr "far_jump")
6478 (eq_attr "length" "8")
6479 (const_string "yes")
6480 (const_string "no")))
6481 (set (attr "length")
6483 (and (ge (minus (match_dup 4) (pc)) (const_int -250))
6484 (le (minus (match_dup 4) (pc)) (const_int 256)))
6487 (and (ge (minus (match_dup 4) (pc)) (const_int -2040))
6488 (le (minus (match_dup 4) (pc)) (const_int 2048)))
6493 (define_insn "*subsi3_cbranch"
6496 (match_operator 4 "comparison_operator"
6498 (match_operand:SI 2 "s_register_operand" "l,l,1,l")
6499 (match_operand:SI 3 "s_register_operand" "l,l,l,l"))
6501 (label_ref (match_operand 5 "" ""))
6503 (set (match_operand:SI 0 "thumb_cbrch_target_operand" "=l,*?h,*?m,*?m")
6504 (minus:SI (match_dup 2) (match_dup 3)))
6505 (clobber (match_scratch:SI 1 "=X,l,&l,&l"))]
6507 && (GET_CODE (operands[4]) == EQ
6508 || GET_CODE (operands[4]) == NE
6509 || GET_CODE (operands[4]) == GE
6510 || GET_CODE (operands[4]) == LT)"
6513 if (which_alternative == 0)
6514 output_asm_insn (\"sub\\t%0, %2, %3\", operands);
6515 else if (which_alternative == 1)
6517 /* We must provide an alternative for a hi reg because reload
6518 cannot handle output reloads on a jump instruction, but we
6519 can't subtract into that. Fortunately a mov from lo to hi
6520 does not clobber the condition codes. */
6521 output_asm_insn (\"sub\\t%1, %2, %3\", operands);
6522 output_asm_insn (\"mov\\t%0, %1\", operands);
6526 /* Similarly, but the target is memory. */
6527 output_asm_insn (\"sub\\t%1, %2, %3\", operands);
6528 output_asm_insn (\"str\\t%1, %0\", operands);
6531 switch (get_attr_length (insn) - ((which_alternative != 0) ? 2 : 0))
6534 return \"b%d4\\t%l5\";
6536 return \"b%D4\\t.LCB%=\;b\\t%l5\\t%@long jump\\n.LCB%=:\";
6538 return \"b%D4\\t.LCB%=\;bl\\t%l5\\t%@far jump\\n.LCB%=:\";
6542 [(set (attr "far_jump")
6544 (ior (and (eq (symbol_ref ("which_alternative"))
6546 (eq_attr "length" "8"))
6547 (eq_attr "length" "10"))
6548 (const_string "yes")
6549 (const_string "no")))
6550 (set (attr "length")
6552 (eq (symbol_ref ("which_alternative"))
6555 (and (ge (minus (match_dup 5) (pc)) (const_int -250))
6556 (le (minus (match_dup 5) (pc)) (const_int 256)))
6559 (and (ge (minus (match_dup 5) (pc)) (const_int -2040))
6560 (le (minus (match_dup 5) (pc)) (const_int 2048)))
6564 (and (ge (minus (match_dup 5) (pc)) (const_int -248))
6565 (le (minus (match_dup 5) (pc)) (const_int 256)))
6568 (and (ge (minus (match_dup 5) (pc)) (const_int -2038))
6569 (le (minus (match_dup 5) (pc)) (const_int 2048)))
6574 (define_insn "*subsi3_cbranch_scratch"
6577 (match_operator 0 "arm_comparison_operator"
6578 [(minus:SI (match_operand:SI 1 "register_operand" "l")
6579 (match_operand:SI 2 "nonmemory_operand" "l"))
6581 (label_ref (match_operand 3 "" ""))
6584 && (GET_CODE (operands[0]) == EQ
6585 || GET_CODE (operands[0]) == NE
6586 || GET_CODE (operands[0]) == GE
6587 || GET_CODE (operands[0]) == LT)"
6589 output_asm_insn (\"cmp\\t%1, %2\", operands);
6590 switch (get_attr_length (insn))
6592 case 4: return \"b%d0\\t%l3\";
6593 case 6: return \"b%D0\\t.LCB%=\;b\\t%l3\\t%@long jump\\n.LCB%=:\";
6594 default: return \"b%D0\\t.LCB%=\;bl\\t%l3\\t%@far jump\\n.LCB%=:\";
6597 [(set (attr "far_jump")
6599 (eq_attr "length" "8")
6600 (const_string "yes")
6601 (const_string "no")))
6602 (set (attr "length")
6604 (and (ge (minus (match_dup 3) (pc)) (const_int -250))
6605 (le (minus (match_dup 3) (pc)) (const_int 256)))
6608 (and (ge (minus (match_dup 3) (pc)) (const_int -2040))
6609 (le (minus (match_dup 3) (pc)) (const_int 2048)))
6614 ;; Comparison and test insns
6616 (define_expand "cmpsi"
6617 [(match_operand:SI 0 "s_register_operand" "")
6618 (match_operand:SI 1 "arm_add_operand" "")]
6621 arm_compare_op0 = operands[0];
6622 arm_compare_op1 = operands[1];
6627 (define_expand "cmpsf"
6628 [(match_operand:SF 0 "s_register_operand" "")
6629 (match_operand:SF 1 "arm_float_compare_operand" "")]
6630 "TARGET_ARM && TARGET_HARD_FLOAT"
6632 arm_compare_op0 = operands[0];
6633 arm_compare_op1 = operands[1];
6638 (define_expand "cmpdf"
6639 [(match_operand:DF 0 "s_register_operand" "")
6640 (match_operand:DF 1 "arm_float_compare_operand" "")]
6641 "TARGET_ARM && TARGET_HARD_FLOAT"
6643 arm_compare_op0 = operands[0];
6644 arm_compare_op1 = operands[1];
6649 (define_insn "*arm_cmpsi_insn"
6650 [(set (reg:CC CC_REGNUM)
6651 (compare:CC (match_operand:SI 0 "s_register_operand" "r,r")
6652 (match_operand:SI 1 "arm_add_operand" "rI,L")))]
6657 [(set_attr "conds" "set")]
6660 (define_insn "*cmpsi_shiftsi"
6661 [(set (reg:CC CC_REGNUM)
6662 (compare:CC (match_operand:SI 0 "s_register_operand" "r")
6663 (match_operator:SI 3 "shift_operator"
6664 [(match_operand:SI 1 "s_register_operand" "r")
6665 (match_operand:SI 2 "arm_rhs_operand" "rM")])))]
6668 [(set_attr "conds" "set")
6669 (set_attr "shift" "1")
6670 (set (attr "type") (if_then_else (match_operand 2 "const_int_operand" "")
6671 (const_string "alu_shift")
6672 (const_string "alu_shift_reg")))]
6675 (define_insn "*cmpsi_shiftsi_swp"
6676 [(set (reg:CC_SWP CC_REGNUM)
6677 (compare:CC_SWP (match_operator:SI 3 "shift_operator"
6678 [(match_operand:SI 1 "s_register_operand" "r")
6679 (match_operand:SI 2 "reg_or_int_operand" "rM")])
6680 (match_operand:SI 0 "s_register_operand" "r")))]
6683 [(set_attr "conds" "set")
6684 (set_attr "shift" "1")
6685 (set (attr "type") (if_then_else (match_operand 2 "const_int_operand" "")
6686 (const_string "alu_shift")
6687 (const_string "alu_shift_reg")))]
6690 (define_insn "*cmpsi_neg_shiftsi"
6691 [(set (reg:CC CC_REGNUM)
6692 (compare:CC (match_operand:SI 0 "s_register_operand" "r")
6693 (neg:SI (match_operator:SI 3 "shift_operator"
6694 [(match_operand:SI 1 "s_register_operand" "r")
6695 (match_operand:SI 2 "arm_rhs_operand" "rM")]))))]
6698 [(set_attr "conds" "set")
6699 (set_attr "shift" "1")
6700 (set (attr "type") (if_then_else (match_operand 2 "const_int_operand" "")
6701 (const_string "alu_shift")
6702 (const_string "alu_shift_reg")))]
6705 ;; Cirrus SF compare instruction
6706 (define_insn "*cirrus_cmpsf"
6707 [(set (reg:CCFP CC_REGNUM)
6708 (compare:CCFP (match_operand:SF 0 "cirrus_fp_register" "v")
6709 (match_operand:SF 1 "cirrus_fp_register" "v")))]
6710 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_MAVERICK"
6711 "cfcmps%?\\tr15, %V0, %V1"
6712 [(set_attr "type" "mav_farith")
6713 (set_attr "cirrus" "compare")]
6716 ;; Cirrus DF compare instruction
6717 (define_insn "*cirrus_cmpdf"
6718 [(set (reg:CCFP CC_REGNUM)
6719 (compare:CCFP (match_operand:DF 0 "cirrus_fp_register" "v")
6720 (match_operand:DF 1 "cirrus_fp_register" "v")))]
6721 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_MAVERICK"
6722 "cfcmpd%?\\tr15, %V0, %V1"
6723 [(set_attr "type" "mav_farith")
6724 (set_attr "cirrus" "compare")]
6727 ;; Cirrus DI compare instruction
6728 (define_expand "cmpdi"
6729 [(match_operand:DI 0 "cirrus_fp_register" "")
6730 (match_operand:DI 1 "cirrus_fp_register" "")]
6731 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_MAVERICK"
6733 arm_compare_op0 = operands[0];
6734 arm_compare_op1 = operands[1];
6738 (define_insn "*cirrus_cmpdi"
6739 [(set (reg:CC CC_REGNUM)
6740 (compare:CC (match_operand:DI 0 "cirrus_fp_register" "v")
6741 (match_operand:DI 1 "cirrus_fp_register" "v")))]
6742 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_MAVERICK"
6743 "cfcmp64%?\\tr15, %V0, %V1"
6744 [(set_attr "type" "mav_farith")
6745 (set_attr "cirrus" "compare")]
6748 ; This insn allows redundant compares to be removed by cse, nothing should
6749 ; ever appear in the output file since (set (reg x) (reg x)) is a no-op that
6750 ; is deleted later on. The match_dup will match the mode here, so that
6751 ; mode changes of the condition codes aren't lost by this even though we don't
6752 ; specify what they are.
6754 (define_insn "*deleted_compare"
6755 [(set (match_operand 0 "cc_register" "") (match_dup 0))]
6757 "\\t%@ deleted compare"
6758 [(set_attr "conds" "set")
6759 (set_attr "length" "0")]
6763 ;; Conditional branch insns
6765 (define_expand "beq"
6767 (if_then_else (eq (match_dup 1) (const_int 0))
6768 (label_ref (match_operand 0 "" ""))
6771 "operands[1] = arm_gen_compare_reg (EQ, arm_compare_op0, arm_compare_op1);"
6774 (define_expand "bne"
6776 (if_then_else (ne (match_dup 1) (const_int 0))
6777 (label_ref (match_operand 0 "" ""))
6780 "operands[1] = arm_gen_compare_reg (NE, arm_compare_op0, arm_compare_op1);"
6783 (define_expand "bgt"
6785 (if_then_else (gt (match_dup 1) (const_int 0))
6786 (label_ref (match_operand 0 "" ""))
6789 "operands[1] = arm_gen_compare_reg (GT, arm_compare_op0, arm_compare_op1);"
6792 (define_expand "ble"
6794 (if_then_else (le (match_dup 1) (const_int 0))
6795 (label_ref (match_operand 0 "" ""))
6798 "operands[1] = arm_gen_compare_reg (LE, arm_compare_op0, arm_compare_op1);"
6801 (define_expand "bge"
6803 (if_then_else (ge (match_dup 1) (const_int 0))
6804 (label_ref (match_operand 0 "" ""))
6807 "operands[1] = arm_gen_compare_reg (GE, arm_compare_op0, arm_compare_op1);"
6810 (define_expand "blt"
6812 (if_then_else (lt (match_dup 1) (const_int 0))
6813 (label_ref (match_operand 0 "" ""))
6816 "operands[1] = arm_gen_compare_reg (LT, arm_compare_op0, arm_compare_op1);"
6819 (define_expand "bgtu"
6821 (if_then_else (gtu (match_dup 1) (const_int 0))
6822 (label_ref (match_operand 0 "" ""))
6825 "operands[1] = arm_gen_compare_reg (GTU, arm_compare_op0, arm_compare_op1);"
6828 (define_expand "bleu"
6830 (if_then_else (leu (match_dup 1) (const_int 0))
6831 (label_ref (match_operand 0 "" ""))
6834 "operands[1] = arm_gen_compare_reg (LEU, arm_compare_op0, arm_compare_op1);"
6837 (define_expand "bgeu"
6839 (if_then_else (geu (match_dup 1) (const_int 0))
6840 (label_ref (match_operand 0 "" ""))
6843 "operands[1] = arm_gen_compare_reg (GEU, arm_compare_op0, arm_compare_op1);"
6846 (define_expand "bltu"
6848 (if_then_else (ltu (match_dup 1) (const_int 0))
6849 (label_ref (match_operand 0 "" ""))
6852 "operands[1] = arm_gen_compare_reg (LTU, arm_compare_op0, arm_compare_op1);"
6855 (define_expand "bunordered"
6857 (if_then_else (unordered (match_dup 1) (const_int 0))
6858 (label_ref (match_operand 0 "" ""))
6860 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
6861 "operands[1] = arm_gen_compare_reg (UNORDERED, arm_compare_op0,
6865 (define_expand "bordered"
6867 (if_then_else (ordered (match_dup 1) (const_int 0))
6868 (label_ref (match_operand 0 "" ""))
6870 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
6871 "operands[1] = arm_gen_compare_reg (ORDERED, arm_compare_op0,
6875 (define_expand "bungt"
6877 (if_then_else (ungt (match_dup 1) (const_int 0))
6878 (label_ref (match_operand 0 "" ""))
6880 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
6881 "operands[1] = arm_gen_compare_reg (UNGT, arm_compare_op0, arm_compare_op1);"
6884 (define_expand "bunlt"
6886 (if_then_else (unlt (match_dup 1) (const_int 0))
6887 (label_ref (match_operand 0 "" ""))
6889 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
6890 "operands[1] = arm_gen_compare_reg (UNLT, arm_compare_op0, arm_compare_op1);"
6893 (define_expand "bunge"
6895 (if_then_else (unge (match_dup 1) (const_int 0))
6896 (label_ref (match_operand 0 "" ""))
6898 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
6899 "operands[1] = arm_gen_compare_reg (UNGE, arm_compare_op0, arm_compare_op1);"
6902 (define_expand "bunle"
6904 (if_then_else (unle (match_dup 1) (const_int 0))
6905 (label_ref (match_operand 0 "" ""))
6907 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
6908 "operands[1] = arm_gen_compare_reg (UNLE, arm_compare_op0, arm_compare_op1);"
6911 ;; The following two patterns need two branch instructions, since there is
6912 ;; no single instruction that will handle all cases.
6913 (define_expand "buneq"
6915 (if_then_else (uneq (match_dup 1) (const_int 0))
6916 (label_ref (match_operand 0 "" ""))
6918 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
6919 "operands[1] = arm_gen_compare_reg (UNEQ, arm_compare_op0, arm_compare_op1);"
6922 (define_expand "bltgt"
6924 (if_then_else (ltgt (match_dup 1) (const_int 0))
6925 (label_ref (match_operand 0 "" ""))
6927 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
6928 "operands[1] = arm_gen_compare_reg (LTGT, arm_compare_op0, arm_compare_op1);"
6932 ;; Patterns to match conditional branch insns.
6935 ; Special pattern to match UNEQ.
6936 (define_insn "*arm_buneq"
6938 (if_then_else (uneq (match_operand 1 "cc_register" "") (const_int 0))
6939 (label_ref (match_operand 0 "" ""))
6941 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
6943 if (arm_ccfsm_state != 0)
6946 return \"bvs\\t%l0\;beq\\t%l0\";
6948 [(set_attr "conds" "jump_clob")
6949 (set_attr "length" "8")]
6952 ; Special pattern to match LTGT.
6953 (define_insn "*arm_bltgt"
6955 (if_then_else (ltgt (match_operand 1 "cc_register" "") (const_int 0))
6956 (label_ref (match_operand 0 "" ""))
6958 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
6960 if (arm_ccfsm_state != 0)
6963 return \"bmi\\t%l0\;bgt\\t%l0\";
6965 [(set_attr "conds" "jump_clob")
6966 (set_attr "length" "8")]
6969 (define_insn "*arm_cond_branch"
6971 (if_then_else (match_operator 1 "arm_comparison_operator"
6972 [(match_operand 2 "cc_register" "") (const_int 0)])
6973 (label_ref (match_operand 0 "" ""))
6977 if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
6979 arm_ccfsm_state += 2;
6982 return \"b%d1\\t%l0\";
6984 [(set_attr "conds" "use")
6985 (set_attr "type" "branch")]
6988 ; Special pattern to match reversed UNEQ.
6989 (define_insn "*arm_buneq_reversed"
6991 (if_then_else (uneq (match_operand 1 "cc_register" "") (const_int 0))
6993 (label_ref (match_operand 0 "" ""))))]
6994 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
6996 if (arm_ccfsm_state != 0)
6999 return \"bmi\\t%l0\;bgt\\t%l0\";
7001 [(set_attr "conds" "jump_clob")
7002 (set_attr "length" "8")]
7005 ; Special pattern to match reversed LTGT.
7006 (define_insn "*arm_bltgt_reversed"
7008 (if_then_else (ltgt (match_operand 1 "cc_register" "") (const_int 0))
7010 (label_ref (match_operand 0 "" ""))))]
7011 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
7013 if (arm_ccfsm_state != 0)
7016 return \"bvs\\t%l0\;beq\\t%l0\";
7018 [(set_attr "conds" "jump_clob")
7019 (set_attr "length" "8")]
7022 (define_insn "*arm_cond_branch_reversed"
7024 (if_then_else (match_operator 1 "arm_comparison_operator"
7025 [(match_operand 2 "cc_register" "") (const_int 0)])
7027 (label_ref (match_operand 0 "" ""))))]
7030 if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
7032 arm_ccfsm_state += 2;
7035 return \"b%D1\\t%l0\";
7037 [(set_attr "conds" "use")
7038 (set_attr "type" "branch")]
7045 (define_expand "seq"
7046 [(set (match_operand:SI 0 "s_register_operand" "")
7047 (eq:SI (match_dup 1) (const_int 0)))]
7049 "operands[1] = arm_gen_compare_reg (EQ, arm_compare_op0, arm_compare_op1);"
7052 (define_expand "sne"
7053 [(set (match_operand:SI 0 "s_register_operand" "")
7054 (ne:SI (match_dup 1) (const_int 0)))]
7056 "operands[1] = arm_gen_compare_reg (NE, arm_compare_op0, arm_compare_op1);"
7059 (define_expand "sgt"
7060 [(set (match_operand:SI 0 "s_register_operand" "")
7061 (gt:SI (match_dup 1) (const_int 0)))]
7063 "operands[1] = arm_gen_compare_reg (GT, arm_compare_op0, arm_compare_op1);"
7066 (define_expand "sle"
7067 [(set (match_operand:SI 0 "s_register_operand" "")
7068 (le:SI (match_dup 1) (const_int 0)))]
7070 "operands[1] = arm_gen_compare_reg (LE, arm_compare_op0, arm_compare_op1);"
7073 (define_expand "sge"
7074 [(set (match_operand:SI 0 "s_register_operand" "")
7075 (ge:SI (match_dup 1) (const_int 0)))]
7077 "operands[1] = arm_gen_compare_reg (GE, arm_compare_op0, arm_compare_op1);"
7080 (define_expand "slt"
7081 [(set (match_operand:SI 0 "s_register_operand" "")
7082 (lt:SI (match_dup 1) (const_int 0)))]
7084 "operands[1] = arm_gen_compare_reg (LT, arm_compare_op0, arm_compare_op1);"
7087 (define_expand "sgtu"
7088 [(set (match_operand:SI 0 "s_register_operand" "")
7089 (gtu:SI (match_dup 1) (const_int 0)))]
7091 "operands[1] = arm_gen_compare_reg (GTU, arm_compare_op0, arm_compare_op1);"
7094 (define_expand "sleu"
7095 [(set (match_operand:SI 0 "s_register_operand" "")
7096 (leu:SI (match_dup 1) (const_int 0)))]
7098 "operands[1] = arm_gen_compare_reg (LEU, arm_compare_op0, arm_compare_op1);"
7101 (define_expand "sgeu"
7102 [(set (match_operand:SI 0 "s_register_operand" "")
7103 (geu:SI (match_dup 1) (const_int 0)))]
7105 "operands[1] = arm_gen_compare_reg (GEU, arm_compare_op0, arm_compare_op1);"
7108 (define_expand "sltu"
7109 [(set (match_operand:SI 0 "s_register_operand" "")
7110 (ltu:SI (match_dup 1) (const_int 0)))]
7112 "operands[1] = arm_gen_compare_reg (LTU, arm_compare_op0, arm_compare_op1);"
7115 (define_expand "sunordered"
7116 [(set (match_operand:SI 0 "s_register_operand" "")
7117 (unordered:SI (match_dup 1) (const_int 0)))]
7118 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
7119 "operands[1] = arm_gen_compare_reg (UNORDERED, arm_compare_op0,
7123 (define_expand "sordered"
7124 [(set (match_operand:SI 0 "s_register_operand" "")
7125 (ordered:SI (match_dup 1) (const_int 0)))]
7126 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
7127 "operands[1] = arm_gen_compare_reg (ORDERED, arm_compare_op0,
7131 (define_expand "sungt"
7132 [(set (match_operand:SI 0 "s_register_operand" "")
7133 (ungt:SI (match_dup 1) (const_int 0)))]
7134 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
7135 "operands[1] = arm_gen_compare_reg (UNGT, arm_compare_op0,
7139 (define_expand "sunge"
7140 [(set (match_operand:SI 0 "s_register_operand" "")
7141 (unge:SI (match_dup 1) (const_int 0)))]
7142 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
7143 "operands[1] = arm_gen_compare_reg (UNGE, arm_compare_op0,
7147 (define_expand "sunlt"
7148 [(set (match_operand:SI 0 "s_register_operand" "")
7149 (unlt:SI (match_dup 1) (const_int 0)))]
7150 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
7151 "operands[1] = arm_gen_compare_reg (UNLT, arm_compare_op0,
7155 (define_expand "sunle"
7156 [(set (match_operand:SI 0 "s_register_operand" "")
7157 (unle:SI (match_dup 1) (const_int 0)))]
7158 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
7159 "operands[1] = arm_gen_compare_reg (UNLE, arm_compare_op0,
7163 ;;; DO NOT add patterns for SUNEQ or SLTGT, these can't be represented with
7164 ;;; simple ARM instructions.
7166 ; (define_expand "suneq"
7167 ; [(set (match_operand:SI 0 "s_register_operand" "")
7168 ; (uneq:SI (match_dup 1) (const_int 0)))]
7169 ; "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
7173 ; (define_expand "sltgt"
7174 ; [(set (match_operand:SI 0 "s_register_operand" "")
7175 ; (ltgt:SI (match_dup 1) (const_int 0)))]
7176 ; "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
7180 (define_insn "*mov_scc"
7181 [(set (match_operand:SI 0 "s_register_operand" "=r")
7182 (match_operator:SI 1 "arm_comparison_operator"
7183 [(match_operand 2 "cc_register" "") (const_int 0)]))]
7185 "mov%D1\\t%0, #0\;mov%d1\\t%0, #1"
7186 [(set_attr "conds" "use")
7187 (set_attr "length" "8")]
7190 (define_insn "*mov_negscc"
7191 [(set (match_operand:SI 0 "s_register_operand" "=r")
7192 (neg:SI (match_operator:SI 1 "arm_comparison_operator"
7193 [(match_operand 2 "cc_register" "") (const_int 0)])))]
7195 "mov%D1\\t%0, #0\;mvn%d1\\t%0, #0"
7196 [(set_attr "conds" "use")
7197 (set_attr "length" "8")]
7200 (define_insn "*mov_notscc"
7201 [(set (match_operand:SI 0 "s_register_operand" "=r")
7202 (not:SI (match_operator:SI 1 "arm_comparison_operator"
7203 [(match_operand 2 "cc_register" "") (const_int 0)])))]
7205 "mov%D1\\t%0, #0\;mvn%d1\\t%0, #1"
7206 [(set_attr "conds" "use")
7207 (set_attr "length" "8")]
7211 ;; Conditional move insns
7213 (define_expand "movsicc"
7214 [(set (match_operand:SI 0 "s_register_operand" "")
7215 (if_then_else:SI (match_operand 1 "arm_comparison_operator" "")
7216 (match_operand:SI 2 "arm_not_operand" "")
7217 (match_operand:SI 3 "arm_not_operand" "")))]
7221 enum rtx_code code = GET_CODE (operands[1]);
7224 if (code == UNEQ || code == LTGT)
7227 ccreg = arm_gen_compare_reg (code, arm_compare_op0, arm_compare_op1);
7228 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
7232 (define_expand "movsfcc"
7233 [(set (match_operand:SF 0 "s_register_operand" "")
7234 (if_then_else:SF (match_operand 1 "arm_comparison_operator" "")
7235 (match_operand:SF 2 "s_register_operand" "")
7236 (match_operand:SF 3 "nonmemory_operand" "")))]
7240 enum rtx_code code = GET_CODE (operands[1]);
7243 if (code == UNEQ || code == LTGT)
7246 /* When compiling for SOFT_FLOAT, ensure both arms are in registers.
7247 Otherwise, ensure it is a valid FP add operand */
7248 if ((!(TARGET_HARD_FLOAT && TARGET_FPA))
7249 || (!arm_float_add_operand (operands[3], SFmode)))
7250 operands[3] = force_reg (SFmode, operands[3]);
7252 ccreg = arm_gen_compare_reg (code, arm_compare_op0, arm_compare_op1);
7253 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
7257 (define_expand "movdfcc"
7258 [(set (match_operand:DF 0 "s_register_operand" "")
7259 (if_then_else:DF (match_operand 1 "arm_comparison_operator" "")
7260 (match_operand:DF 2 "s_register_operand" "")
7261 (match_operand:DF 3 "arm_float_add_operand" "")))]
7262 "TARGET_ARM && TARGET_HARD_FLOAT && (TARGET_FPA || TARGET_VFP)"
7265 enum rtx_code code = GET_CODE (operands[1]);
7268 if (code == UNEQ || code == LTGT)
7271 ccreg = arm_gen_compare_reg (code, arm_compare_op0, arm_compare_op1);
7272 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
7276 (define_insn "*movsicc_insn"
7277 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r,r,r,r,r")
7279 (match_operator 3 "arm_comparison_operator"
7280 [(match_operand 4 "cc_register" "") (const_int 0)])
7281 (match_operand:SI 1 "arm_not_operand" "0,0,rI,K,rI,rI,K,K")
7282 (match_operand:SI 2 "arm_not_operand" "rI,K,0,0,rI,K,rI,K")))]
7289 mov%d3\\t%0, %1\;mov%D3\\t%0, %2
7290 mov%d3\\t%0, %1\;mvn%D3\\t%0, #%B2
7291 mvn%d3\\t%0, #%B1\;mov%D3\\t%0, %2
7292 mvn%d3\\t%0, #%B1\;mvn%D3\\t%0, #%B2"
7293 [(set_attr "length" "4,4,4,4,8,8,8,8")
7294 (set_attr "conds" "use")]
7297 (define_insn "*movsfcc_soft_insn"
7298 [(set (match_operand:SF 0 "s_register_operand" "=r,r")
7299 (if_then_else:SF (match_operator 3 "arm_comparison_operator"
7300 [(match_operand 4 "cc_register" "") (const_int 0)])
7301 (match_operand:SF 1 "s_register_operand" "0,r")
7302 (match_operand:SF 2 "s_register_operand" "r,0")))]
7303 "TARGET_ARM && TARGET_SOFT_FLOAT"
7307 [(set_attr "conds" "use")]
7311 ;; Jump and linkage insns
7313 (define_expand "jump"
7315 (label_ref (match_operand 0 "" "")))]
7320 (define_insn "*arm_jump"
7322 (label_ref (match_operand 0 "" "")))]
7326 if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
7328 arm_ccfsm_state += 2;
7331 return \"b%?\\t%l0\";
7334 [(set_attr "predicable" "yes")]
7337 (define_insn "*thumb_jump"
7339 (label_ref (match_operand 0 "" "")))]
7342 if (get_attr_length (insn) == 2)
7344 return \"bl\\t%l0\\t%@ far jump\";
7346 [(set (attr "far_jump")
7348 (eq_attr "length" "4")
7349 (const_string "yes")
7350 (const_string "no")))
7351 (set (attr "length")
7353 (and (ge (minus (match_dup 0) (pc)) (const_int -2048))
7354 (le (minus (match_dup 0) (pc)) (const_int 2044)))
7359 (define_expand "call"
7360 [(parallel [(call (match_operand 0 "memory_operand" "")
7361 (match_operand 1 "general_operand" ""))
7362 (use (match_operand 2 "" ""))
7363 (clobber (reg:SI LR_REGNUM))])]
7369 /* In an untyped call, we can get NULL for operand 2. */
7370 if (operands[2] == NULL_RTX)
7371 operands[2] = const0_rtx;
7373 /* This is to decide if we should generate indirect calls by loading the
7374 32 bit address of the callee into a register before performing the
7375 branch and link. operand[2] encodes the long_call/short_call
7376 attribute of the function being called. This attribute is set whenever
7377 __attribute__((long_call/short_call)) or #pragma long_call/no_long_call
7378 is used, and the short_call attribute can also be set if function is
7379 declared as static or if it has already been defined in the current
7380 compilation unit. See arm.c and arm.h for info about this. The third
7381 parameter to arm_is_longcall_p is used to tell it which pattern
7383 callee = XEXP (operands[0], 0);
7385 if (GET_CODE (callee) != REG
7386 && arm_is_longcall_p (operands[0], INTVAL (operands[2]), 0))
7387 XEXP (operands[0], 0) = force_reg (Pmode, callee);
7391 (define_insn "*call_reg"
7392 [(call (mem:SI (match_operand:SI 0 "s_register_operand" "r"))
7393 (match_operand 1 "" ""))
7394 (use (match_operand 2 "" ""))
7395 (clobber (reg:SI LR_REGNUM))]
7398 return output_call (operands);
7400 ;; length is worst case, normally it is only two
7401 [(set_attr "length" "12")
7402 (set_attr "type" "call")]
7405 (define_insn "*call_mem"
7406 [(call (mem:SI (match_operand:SI 0 "memory_operand" "m"))
7407 (match_operand 1 "" ""))
7408 (use (match_operand 2 "" ""))
7409 (clobber (reg:SI LR_REGNUM))]
7412 return output_call_mem (operands);
7414 [(set_attr "length" "12")
7415 (set_attr "type" "call")]
7418 (define_insn "*call_indirect"
7419 [(call (mem:SI (match_operand:SI 0 "register_operand" "l*r"))
7420 (match_operand 1 "" ""))
7421 (use (match_operand 2 "" ""))
7422 (clobber (reg:SI LR_REGNUM))]
7426 if (TARGET_CALLER_INTERWORKING)
7427 return \"bl\\t%__interwork_call_via_%0\";
7429 return \"bl\\t%__call_via_%0\";
7431 [(set_attr "type" "call")]
7434 (define_insn "*call_value_indirect"
7435 [(set (match_operand 0 "" "")
7436 (call (mem:SI (match_operand:SI 1 "register_operand" "l*r"))
7437 (match_operand 2 "" "")))
7438 (use (match_operand 3 "" ""))
7439 (clobber (reg:SI LR_REGNUM))]
7443 if (TARGET_CALLER_INTERWORKING)
7444 return \"bl\\t%__interwork_call_via_%1\";
7446 return \"bl\\t%__call_via_%1\";
7448 [(set_attr "type" "call")]
7451 (define_expand "call_value"
7452 [(parallel [(set (match_operand 0 "" "")
7453 (call (match_operand 1 "memory_operand" "")
7454 (match_operand 2 "general_operand" "")))
7455 (use (match_operand 3 "" ""))
7456 (clobber (reg:SI LR_REGNUM))])]
7460 rtx callee = XEXP (operands[1], 0);
7462 /* In an untyped call, we can get NULL for operand 2. */
7463 if (operands[3] == 0)
7464 operands[3] = const0_rtx;
7466 /* See the comment in define_expand \"call\". */
7467 if (GET_CODE (callee) != REG
7468 && arm_is_longcall_p (operands[1], INTVAL (operands[3]), 0))
7469 XEXP (operands[1], 0) = force_reg (Pmode, callee);
7473 (define_insn "*call_value_reg"
7474 [(set (match_operand 0 "" "")
7475 (call (mem:SI (match_operand:SI 1 "s_register_operand" "r"))
7476 (match_operand 2 "" "")))
7477 (use (match_operand 3 "" ""))
7478 (clobber (reg:SI LR_REGNUM))]
7481 return output_call (&operands[1]);
7483 [(set_attr "length" "12")
7484 (set_attr "type" "call")]
7487 (define_insn "*call_value_mem"
7488 [(set (match_operand 0 "" "")
7489 (call (mem:SI (match_operand:SI 1 "memory_operand" "m"))
7490 (match_operand 2 "" "")))
7491 (use (match_operand 3 "" ""))
7492 (clobber (reg:SI LR_REGNUM))]
7493 "TARGET_ARM && (!CONSTANT_ADDRESS_P (XEXP (operands[1], 0)))"
7495 return output_call_mem (&operands[1]);
7497 [(set_attr "length" "12")
7498 (set_attr "type" "call")]
7501 ;; Allow calls to SYMBOL_REFs specially as they are not valid general addresses
7502 ;; The 'a' causes the operand to be treated as an address, i.e. no '#' output.
7504 (define_insn "*call_symbol"
7505 [(call (mem:SI (match_operand:SI 0 "" ""))
7506 (match_operand 1 "" ""))
7507 (use (match_operand 2 "" ""))
7508 (clobber (reg:SI LR_REGNUM))]
7510 && (GET_CODE (operands[0]) == SYMBOL_REF)
7511 && !arm_is_longcall_p (operands[0], INTVAL (operands[2]), 1)"
7514 return NEED_PLT_RELOC ? \"bl%?\\t%a0(PLT)\" : \"bl%?\\t%a0\";
7516 [(set_attr "type" "call")]
7519 (define_insn "*call_value_symbol"
7520 [(set (match_operand 0 "s_register_operand" "")
7521 (call (mem:SI (match_operand:SI 1 "" ""))
7522 (match_operand:SI 2 "" "")))
7523 (use (match_operand 3 "" ""))
7524 (clobber (reg:SI LR_REGNUM))]
7526 && (GET_CODE (operands[1]) == SYMBOL_REF)
7527 && !arm_is_longcall_p (operands[1], INTVAL (operands[3]), 1)"
7530 return NEED_PLT_RELOC ? \"bl%?\\t%a1(PLT)\" : \"bl%?\\t%a1\";
7532 [(set_attr "type" "call")]
7535 (define_insn "*call_insn"
7536 [(call (mem:SI (match_operand:SI 0 "" ""))
7537 (match_operand:SI 1 "" ""))
7538 (use (match_operand 2 "" ""))
7539 (clobber (reg:SI LR_REGNUM))]
7541 && GET_CODE (operands[0]) == SYMBOL_REF
7542 && !arm_is_longcall_p (operands[0], INTVAL (operands[2]), 1)"
7544 [(set_attr "length" "4")
7545 (set_attr "type" "call")]
7548 (define_insn "*call_value_insn"
7549 [(set (match_operand 0 "register_operand" "")
7550 (call (mem:SI (match_operand 1 "" ""))
7551 (match_operand 2 "" "")))
7552 (use (match_operand 3 "" ""))
7553 (clobber (reg:SI LR_REGNUM))]
7555 && GET_CODE (operands[1]) == SYMBOL_REF
7556 && !arm_is_longcall_p (operands[1], INTVAL (operands[3]), 1)"
7558 [(set_attr "length" "4")
7559 (set_attr "type" "call")]
7562 ;; We may also be able to do sibcalls for Thumb, but it's much harder...
7563 (define_expand "sibcall"
7564 [(parallel [(call (match_operand 0 "memory_operand" "")
7565 (match_operand 1 "general_operand" ""))
7567 (use (match_operand 2 "" ""))])]
7571 if (operands[2] == NULL_RTX)
7572 operands[2] = const0_rtx;
7576 (define_expand "sibcall_value"
7577 [(parallel [(set (match_operand 0 "register_operand" "")
7578 (call (match_operand 1 "memory_operand" "")
7579 (match_operand 2 "general_operand" "")))
7581 (use (match_operand 3 "" ""))])]
7585 if (operands[3] == NULL_RTX)
7586 operands[3] = const0_rtx;
7590 (define_insn "*sibcall_insn"
7591 [(call (mem:SI (match_operand:SI 0 "" "X"))
7592 (match_operand 1 "" ""))
7594 (use (match_operand 2 "" ""))]
7595 "TARGET_ARM && GET_CODE (operands[0]) == SYMBOL_REF"
7597 return NEED_PLT_RELOC ? \"b%?\\t%a0(PLT)\" : \"b%?\\t%a0\";
7599 [(set_attr "type" "call")]
7602 (define_insn "*sibcall_value_insn"
7603 [(set (match_operand 0 "s_register_operand" "")
7604 (call (mem:SI (match_operand:SI 1 "" "X"))
7605 (match_operand 2 "" "")))
7607 (use (match_operand 3 "" ""))]
7608 "TARGET_ARM && GET_CODE (operands[1]) == SYMBOL_REF"
7610 return NEED_PLT_RELOC ? \"b%?\\t%a1(PLT)\" : \"b%?\\t%a1\";
7612 [(set_attr "type" "call")]
7615 ;; Often the return insn will be the same as loading from memory, so set attr
7616 (define_insn "return"
7618 "TARGET_ARM && USE_RETURN_INSN (FALSE)"
7621 if (arm_ccfsm_state == 2)
7623 arm_ccfsm_state += 2;
7626 return output_return_instruction (const_true_rtx, TRUE, FALSE);
7628 [(set_attr "type" "load1")
7629 (set_attr "length" "12")
7630 (set_attr "predicable" "yes")]
7633 (define_insn "*cond_return"
7635 (if_then_else (match_operator 0 "arm_comparison_operator"
7636 [(match_operand 1 "cc_register" "") (const_int 0)])
7639 "TARGET_ARM && USE_RETURN_INSN (TRUE)"
7642 if (arm_ccfsm_state == 2)
7644 arm_ccfsm_state += 2;
7647 return output_return_instruction (operands[0], TRUE, FALSE);
7649 [(set_attr "conds" "use")
7650 (set_attr "length" "12")
7651 (set_attr "type" "load1")]
7654 (define_insn "*cond_return_inverted"
7656 (if_then_else (match_operator 0 "arm_comparison_operator"
7657 [(match_operand 1 "cc_register" "") (const_int 0)])
7660 "TARGET_ARM && USE_RETURN_INSN (TRUE)"
7663 if (arm_ccfsm_state == 2)
7665 arm_ccfsm_state += 2;
7668 return output_return_instruction (operands[0], TRUE, TRUE);
7670 [(set_attr "conds" "use")
7671 (set_attr "type" "load1")]
7674 ;; Generate a sequence of instructions to determine if the processor is
7675 ;; in 26-bit or 32-bit mode, and return the appropriate return address
7678 (define_expand "return_addr_mask"
7680 (compare:CC_NOOV (unspec [(const_int 0)] UNSPEC_CHECK_ARCH)
7682 (set (match_operand:SI 0 "s_register_operand" "")
7683 (if_then_else:SI (eq (match_dup 1) (const_int 0))
7685 (const_int 67108860)))] ; 0x03fffffc
7688 operands[1] = gen_rtx_REG (CC_NOOVmode, CC_REGNUM);
7691 (define_insn "*check_arch2"
7692 [(set (match_operand:CC_NOOV 0 "cc_register" "")
7693 (compare:CC_NOOV (unspec [(const_int 0)] UNSPEC_CHECK_ARCH)
7696 "teq\\t%|r0, %|r0\;teq\\t%|pc, %|pc"
7697 [(set_attr "length" "8")
7698 (set_attr "conds" "set")]
7701 ;; Call subroutine returning any type.
7703 (define_expand "untyped_call"
7704 [(parallel [(call (match_operand 0 "" "")
7706 (match_operand 1 "" "")
7707 (match_operand 2 "" "")])]
7713 emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, const0_rtx));
7715 for (i = 0; i < XVECLEN (operands[2], 0); i++)
7717 rtx set = XVECEXP (operands[2], 0, i);
7719 emit_move_insn (SET_DEST (set), SET_SRC (set));
7722 /* The optimizer does not know that the call sets the function value
7723 registers we stored in the result block. We avoid problems by
7724 claiming that all hard registers are used and clobbered at this
7726 emit_insn (gen_blockage ());
7732 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
7733 ;; all of memory. This blocks insns from being moved across this point.
7735 (define_insn "blockage"
7736 [(unspec_volatile [(const_int 0)] VUNSPEC_BLOCKAGE)]
7739 [(set_attr "length" "0")
7740 (set_attr "type" "block")]
7743 (define_expand "casesi"
7744 [(match_operand:SI 0 "s_register_operand" "") ; index to jump on
7745 (match_operand:SI 1 "const_int_operand" "") ; lower bound
7746 (match_operand:SI 2 "const_int_operand" "") ; total range
7747 (match_operand:SI 3 "" "") ; table label
7748 (match_operand:SI 4 "" "")] ; Out of range label
7753 if (operands[1] != const0_rtx)
7755 reg = gen_reg_rtx (SImode);
7757 emit_insn (gen_addsi3 (reg, operands[0],
7758 GEN_INT (-INTVAL (operands[1]))));
7762 if (!const_ok_for_arm (INTVAL (operands[2])))
7763 operands[2] = force_reg (SImode, operands[2]);
7765 emit_jump_insn (gen_casesi_internal (operands[0], operands[2], operands[3],
7771 ;; The USE in this pattern is needed to tell flow analysis that this is
7772 ;; a CASESI insn. It has no other purpose.
7773 (define_insn "casesi_internal"
7774 [(parallel [(set (pc)
7776 (leu (match_operand:SI 0 "s_register_operand" "r")
7777 (match_operand:SI 1 "arm_rhs_operand" "rI"))
7778 (mem:SI (plus:SI (mult:SI (match_dup 0) (const_int 4))
7779 (label_ref (match_operand 2 "" ""))))
7780 (label_ref (match_operand 3 "" ""))))
7781 (clobber (reg:CC CC_REGNUM))
7782 (use (label_ref (match_dup 2)))])]
7786 return \"cmp\\t%0, %1\;addls\\t%|pc, %|pc, %0, asl #2\;b\\t%l3\";
7787 return \"cmp\\t%0, %1\;ldrls\\t%|pc, [%|pc, %0, asl #2]\;b\\t%l3\";
7789 [(set_attr "conds" "clob")
7790 (set_attr "length" "12")]
7793 (define_expand "indirect_jump"
7795 (match_operand:SI 0 "s_register_operand" ""))]
7800 (define_insn "*arm_indirect_jump"
7802 (match_operand:SI 0 "s_register_operand" "r"))]
7804 "mov%?\\t%|pc, %0\\t%@ indirect register jump"
7805 [(set_attr "predicable" "yes")]
7808 ;; Although not supported by the define_expand above,
7809 ;; cse/combine may generate this form.
7810 (define_insn "*load_indirect_jump"
7812 (match_operand:SI 0 "memory_operand" "m"))]
7814 "ldr%?\\t%|pc, %0\\t%@ indirect memory jump"
7815 [(set_attr "type" "load1")
7816 (set_attr "pool_range" "4096")
7817 (set_attr "neg_pool_range" "4084")
7818 (set_attr "predicable" "yes")]
7821 (define_insn "*thumb_indirect_jump"
7823 (match_operand:SI 0 "register_operand" "l*r"))]
7826 [(set_attr "conds" "clob")
7827 (set_attr "length" "2")]
7838 return \"mov%?\\t%|r0, %|r0\\t%@ nop\";
7839 return \"mov\\tr8, r8\";
7841 [(set (attr "length")
7842 (if_then_else (eq_attr "is_thumb" "yes")
7848 ;; Patterns to allow combination of arithmetic, cond code and shifts
7850 (define_insn "*arith_shiftsi"
7851 [(set (match_operand:SI 0 "s_register_operand" "=r")
7852 (match_operator:SI 1 "shiftable_operator"
7853 [(match_operator:SI 3 "shift_operator"
7854 [(match_operand:SI 4 "s_register_operand" "r")
7855 (match_operand:SI 5 "reg_or_int_operand" "rI")])
7856 (match_operand:SI 2 "s_register_operand" "r")]))]
7858 "%i1%?\\t%0, %2, %4%S3"
7859 [(set_attr "predicable" "yes")
7860 (set_attr "shift" "4")
7861 (set (attr "type") (if_then_else (match_operand 5 "const_int_operand" "")
7862 (const_string "alu_shift")
7863 (const_string "alu_shift_reg")))]
7867 [(set (match_operand:SI 0 "s_register_operand" "")
7868 (match_operator:SI 1 "shiftable_operator"
7869 [(match_operator:SI 2 "shiftable_operator"
7870 [(match_operator:SI 3 "shift_operator"
7871 [(match_operand:SI 4 "s_register_operand" "")
7872 (match_operand:SI 5 "reg_or_int_operand" "")])
7873 (match_operand:SI 6 "s_register_operand" "")])
7874 (match_operand:SI 7 "arm_rhs_operand" "")]))
7875 (clobber (match_operand:SI 8 "s_register_operand" ""))]
7878 (match_op_dup 2 [(match_op_dup 3 [(match_dup 4) (match_dup 5)])
7881 (match_op_dup 1 [(match_dup 8) (match_dup 7)]))]
7884 (define_insn "*arith_shiftsi_compare0"
7885 [(set (reg:CC_NOOV CC_REGNUM)
7886 (compare:CC_NOOV (match_operator:SI 1 "shiftable_operator"
7887 [(match_operator:SI 3 "shift_operator"
7888 [(match_operand:SI 4 "s_register_operand" "r")
7889 (match_operand:SI 5 "reg_or_int_operand" "rI")])
7890 (match_operand:SI 2 "s_register_operand" "r")])
7892 (set (match_operand:SI 0 "s_register_operand" "=r")
7893 (match_op_dup 1 [(match_op_dup 3 [(match_dup 4) (match_dup 5)])
7896 "%i1%?s\\t%0, %2, %4%S3"
7897 [(set_attr "conds" "set")
7898 (set_attr "shift" "4")
7899 (set (attr "type") (if_then_else (match_operand 5 "const_int_operand" "")
7900 (const_string "alu_shift")
7901 (const_string "alu_shift_reg")))]
7904 (define_insn "*arith_shiftsi_compare0_scratch"
7905 [(set (reg:CC_NOOV CC_REGNUM)
7906 (compare:CC_NOOV (match_operator:SI 1 "shiftable_operator"
7907 [(match_operator:SI 3 "shift_operator"
7908 [(match_operand:SI 4 "s_register_operand" "r")
7909 (match_operand:SI 5 "reg_or_int_operand" "rI")])
7910 (match_operand:SI 2 "s_register_operand" "r")])
7912 (clobber (match_scratch:SI 0 "=r"))]
7914 "%i1%?s\\t%0, %2, %4%S3"
7915 [(set_attr "conds" "set")
7916 (set_attr "shift" "4")
7917 (set (attr "type") (if_then_else (match_operand 5 "const_int_operand" "")
7918 (const_string "alu_shift")
7919 (const_string "alu_shift_reg")))]
7922 (define_insn "*sub_shiftsi"
7923 [(set (match_operand:SI 0 "s_register_operand" "=r")
7924 (minus:SI (match_operand:SI 1 "s_register_operand" "r")
7925 (match_operator:SI 2 "shift_operator"
7926 [(match_operand:SI 3 "s_register_operand" "r")
7927 (match_operand:SI 4 "reg_or_int_operand" "rM")])))]
7929 "sub%?\\t%0, %1, %3%S2"
7930 [(set_attr "predicable" "yes")
7931 (set_attr "shift" "3")
7932 (set (attr "type") (if_then_else (match_operand 4 "const_int_operand" "")
7933 (const_string "alu_shift")
7934 (const_string "alu_shift_reg")))]
7937 (define_insn "*sub_shiftsi_compare0"
7938 [(set (reg:CC_NOOV CC_REGNUM)
7940 (minus:SI (match_operand:SI 1 "s_register_operand" "r")
7941 (match_operator:SI 2 "shift_operator"
7942 [(match_operand:SI 3 "s_register_operand" "r")
7943 (match_operand:SI 4 "reg_or_int_operand" "rM")]))
7945 (set (match_operand:SI 0 "s_register_operand" "=r")
7946 (minus:SI (match_dup 1) (match_op_dup 2 [(match_dup 3)
7949 "sub%?s\\t%0, %1, %3%S2"
7950 [(set_attr "conds" "set")
7951 (set_attr "shift" "3")
7952 (set (attr "type") (if_then_else (match_operand 4 "const_int_operand" "")
7953 (const_string "alu_shift")
7954 (const_string "alu_shift_reg")))]
7957 (define_insn "*sub_shiftsi_compare0_scratch"
7958 [(set (reg:CC_NOOV CC_REGNUM)
7960 (minus:SI (match_operand:SI 1 "s_register_operand" "r")
7961 (match_operator:SI 2 "shift_operator"
7962 [(match_operand:SI 3 "s_register_operand" "r")
7963 (match_operand:SI 4 "reg_or_int_operand" "rM")]))
7965 (clobber (match_scratch:SI 0 "=r"))]
7967 "sub%?s\\t%0, %1, %3%S2"
7968 [(set_attr "conds" "set")
7969 (set_attr "shift" "3")
7970 (set (attr "type") (if_then_else (match_operand 4 "const_int_operand" "")
7971 (const_string "alu_shift")
7972 (const_string "alu_shift_reg")))]
7977 (define_insn "*and_scc"
7978 [(set (match_operand:SI 0 "s_register_operand" "=r")
7979 (and:SI (match_operator:SI 1 "arm_comparison_operator"
7980 [(match_operand 3 "cc_register" "") (const_int 0)])
7981 (match_operand:SI 2 "s_register_operand" "r")))]
7983 "mov%D1\\t%0, #0\;and%d1\\t%0, %2, #1"
7984 [(set_attr "conds" "use")
7985 (set_attr "length" "8")]
7988 (define_insn "*ior_scc"
7989 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
7990 (ior:SI (match_operator:SI 2 "arm_comparison_operator"
7991 [(match_operand 3 "cc_register" "") (const_int 0)])
7992 (match_operand:SI 1 "s_register_operand" "0,?r")))]
7996 mov%D2\\t%0, %1\;orr%d2\\t%0, %1, #1"
7997 [(set_attr "conds" "use")
7998 (set_attr "length" "4,8")]
8001 (define_insn "*compare_scc"
8002 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8003 (match_operator:SI 1 "arm_comparison_operator"
8004 [(match_operand:SI 2 "s_register_operand" "r,r")
8005 (match_operand:SI 3 "arm_add_operand" "rI,L")]))
8006 (clobber (reg:CC CC_REGNUM))]
8009 if (operands[3] == const0_rtx)
8011 if (GET_CODE (operands[1]) == LT)
8012 return \"mov\\t%0, %2, lsr #31\";
8014 if (GET_CODE (operands[1]) == GE)
8015 return \"mvn\\t%0, %2\;mov\\t%0, %0, lsr #31\";
8017 if (GET_CODE (operands[1]) == EQ)
8018 return \"rsbs\\t%0, %2, #1\;movcc\\t%0, #0\";
8021 if (GET_CODE (operands[1]) == NE)
8023 if (which_alternative == 1)
8024 return \"adds\\t%0, %2, #%n3\;movne\\t%0, #1\";
8025 return \"subs\\t%0, %2, %3\;movne\\t%0, #1\";
8027 if (which_alternative == 1)
8028 output_asm_insn (\"cmn\\t%2, #%n3\", operands);
8030 output_asm_insn (\"cmp\\t%2, %3\", operands);
8031 return \"mov%D1\\t%0, #0\;mov%d1\\t%0, #1\";
8033 [(set_attr "conds" "clob")
8034 (set_attr "length" "12")]
8037 (define_insn "*cond_move"
8038 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
8039 (if_then_else:SI (match_operator 3 "equality_operator"
8040 [(match_operator 4 "arm_comparison_operator"
8041 [(match_operand 5 "cc_register" "") (const_int 0)])
8043 (match_operand:SI 1 "arm_rhs_operand" "0,rI,?rI")
8044 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))]
8047 if (GET_CODE (operands[3]) == NE)
8049 if (which_alternative != 1)
8050 output_asm_insn (\"mov%D4\\t%0, %2\", operands);
8051 if (which_alternative != 0)
8052 output_asm_insn (\"mov%d4\\t%0, %1\", operands);
8055 if (which_alternative != 0)
8056 output_asm_insn (\"mov%D4\\t%0, %1\", operands);
8057 if (which_alternative != 1)
8058 output_asm_insn (\"mov%d4\\t%0, %2\", operands);
8061 [(set_attr "conds" "use")
8062 (set_attr "length" "4,4,8")]
8065 (define_insn "*cond_arith"
8066 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8067 (match_operator:SI 5 "shiftable_operator"
8068 [(match_operator:SI 4 "arm_comparison_operator"
8069 [(match_operand:SI 2 "s_register_operand" "r,r")
8070 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
8071 (match_operand:SI 1 "s_register_operand" "0,?r")]))
8072 (clobber (reg:CC CC_REGNUM))]
8075 if (GET_CODE (operands[4]) == LT && operands[3] == const0_rtx)
8076 return \"%i5\\t%0, %1, %2, lsr #31\";
8078 output_asm_insn (\"cmp\\t%2, %3\", operands);
8079 if (GET_CODE (operands[5]) == AND)
8080 output_asm_insn (\"mov%D4\\t%0, #0\", operands);
8081 else if (GET_CODE (operands[5]) == MINUS)
8082 output_asm_insn (\"rsb%D4\\t%0, %1, #0\", operands);
8083 else if (which_alternative != 0)
8084 output_asm_insn (\"mov%D4\\t%0, %1\", operands);
8085 return \"%i5%d4\\t%0, %1, #1\";
8087 [(set_attr "conds" "clob")
8088 (set_attr "length" "12")]
8091 (define_insn "*cond_sub"
8092 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8093 (minus:SI (match_operand:SI 1 "s_register_operand" "0,?r")
8094 (match_operator:SI 4 "arm_comparison_operator"
8095 [(match_operand:SI 2 "s_register_operand" "r,r")
8096 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))
8097 (clobber (reg:CC CC_REGNUM))]
8100 output_asm_insn (\"cmp\\t%2, %3\", operands);
8101 if (which_alternative != 0)
8102 output_asm_insn (\"mov%D4\\t%0, %1\", operands);
8103 return \"sub%d4\\t%0, %1, #1\";
8105 [(set_attr "conds" "clob")
8106 (set_attr "length" "8,12")]
8109 (define_insn "*cmp_ite0"
8110 [(set (match_operand 6 "dominant_cc_register" "")
8113 (match_operator 4 "arm_comparison_operator"
8114 [(match_operand:SI 0 "s_register_operand" "r,r,r,r")
8115 (match_operand:SI 1 "arm_add_operand" "rI,L,rI,L")])
8116 (match_operator:SI 5 "arm_comparison_operator"
8117 [(match_operand:SI 2 "s_register_operand" "r,r,r,r")
8118 (match_operand:SI 3 "arm_add_operand" "rI,rI,L,L")])
8124 static const char * const opcodes[4][2] =
8126 {\"cmp\\t%2, %3\;cmp%d5\\t%0, %1\",
8127 \"cmp\\t%0, %1\;cmp%d4\\t%2, %3\"},
8128 {\"cmp\\t%2, %3\;cmn%d5\\t%0, #%n1\",
8129 \"cmn\\t%0, #%n1\;cmp%d4\\t%2, %3\"},
8130 {\"cmn\\t%2, #%n3\;cmp%d5\\t%0, %1\",
8131 \"cmp\\t%0, %1\;cmn%d4\\t%2, #%n3\"},
8132 {\"cmn\\t%2, #%n3\;cmn%d5\\t%0, #%n1\",
8133 \"cmn\\t%0, #%n1\;cmn%d4\\t%2, #%n3\"}
8136 comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4]));
8138 return opcodes[which_alternative][swap];
8140 [(set_attr "conds" "set")
8141 (set_attr "length" "8")]
8144 (define_insn "*cmp_ite1"
8145 [(set (match_operand 6 "dominant_cc_register" "")
8148 (match_operator 4 "arm_comparison_operator"
8149 [(match_operand:SI 0 "s_register_operand" "r,r,r,r")
8150 (match_operand:SI 1 "arm_add_operand" "rI,L,rI,L")])
8151 (match_operator:SI 5 "arm_comparison_operator"
8152 [(match_operand:SI 2 "s_register_operand" "r,r,r,r")
8153 (match_operand:SI 3 "arm_add_operand" "rI,rI,L,L")])
8159 static const char * const opcodes[4][2] =
8161 {\"cmp\\t%0, %1\;cmp%d4\\t%2, %3\",
8162 \"cmp\\t%2, %3\;cmp%D5\\t%0, %1\"},
8163 {\"cmn\\t%0, #%n1\;cmp%d4\\t%2, %3\",
8164 \"cmp\\t%2, %3\;cmn%D5\\t%0, #%n1\"},
8165 {\"cmp\\t%0, %1\;cmn%d4\\t%2, #%n3\",
8166 \"cmn\\t%2, #%n3\;cmp%D5\\t%0, %1\"},
8167 {\"cmn\\t%0, #%n1\;cmn%d4\\t%2, #%n3\",
8168 \"cmn\\t%2, #%n3\;cmn%D5\\t%0, #%n1\"}
8171 comparison_dominates_p (GET_CODE (operands[5]),
8172 reverse_condition (GET_CODE (operands[4])));
8174 return opcodes[which_alternative][swap];
8176 [(set_attr "conds" "set")
8177 (set_attr "length" "8")]
8180 (define_insn "*cmp_and"
8181 [(set (match_operand 6 "dominant_cc_register" "")
8184 (match_operator 4 "arm_comparison_operator"
8185 [(match_operand:SI 0 "s_register_operand" "r,r,r,r")
8186 (match_operand:SI 1 "arm_add_operand" "rI,L,rI,L")])
8187 (match_operator:SI 5 "arm_comparison_operator"
8188 [(match_operand:SI 2 "s_register_operand" "r,r,r,r")
8189 (match_operand:SI 3 "arm_add_operand" "rI,rI,L,L")]))
8194 static const char *const opcodes[4][2] =
8196 {\"cmp\\t%2, %3\;cmp%d5\\t%0, %1\",
8197 \"cmp\\t%0, %1\;cmp%d4\\t%2, %3\"},
8198 {\"cmp\\t%2, %3\;cmn%d5\\t%0, #%n1\",
8199 \"cmn\\t%0, #%n1\;cmp%d4\\t%2, %3\"},
8200 {\"cmn\\t%2, #%n3\;cmp%d5\\t%0, %1\",
8201 \"cmp\\t%0, %1\;cmn%d4\\t%2, #%n3\"},
8202 {\"cmn\\t%2, #%n3\;cmn%d5\\t%0, #%n1\",
8203 \"cmn\\t%0, #%n1\;cmn%d4\\t%2, #%n3\"}
8206 comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4]));
8208 return opcodes[which_alternative][swap];
8210 [(set_attr "conds" "set")
8211 (set_attr "predicable" "no")
8212 (set_attr "length" "8")]
8215 (define_insn "*cmp_ior"
8216 [(set (match_operand 6 "dominant_cc_register" "")
8219 (match_operator 4 "arm_comparison_operator"
8220 [(match_operand:SI 0 "s_register_operand" "r,r,r,r")
8221 (match_operand:SI 1 "arm_add_operand" "rI,L,rI,L")])
8222 (match_operator:SI 5 "arm_comparison_operator"
8223 [(match_operand:SI 2 "s_register_operand" "r,r,r,r")
8224 (match_operand:SI 3 "arm_add_operand" "rI,rI,L,L")]))
8229 static const char *const opcodes[4][2] =
8231 {\"cmp\\t%0, %1\;cmp%D4\\t%2, %3\",
8232 \"cmp\\t%2, %3\;cmp%D5\\t%0, %1\"},
8233 {\"cmn\\t%0, #%n1\;cmp%D4\\t%2, %3\",
8234 \"cmp\\t%2, %3\;cmn%D5\\t%0, #%n1\"},
8235 {\"cmp\\t%0, %1\;cmn%D4\\t%2, #%n3\",
8236 \"cmn\\t%2, #%n3\;cmp%D5\\t%0, %1\"},
8237 {\"cmn\\t%0, #%n1\;cmn%D4\\t%2, #%n3\",
8238 \"cmn\\t%2, #%n3\;cmn%D5\\t%0, #%n1\"}
8241 comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4]));
8243 return opcodes[which_alternative][swap];
8246 [(set_attr "conds" "set")
8247 (set_attr "length" "8")]
8250 (define_insn_and_split "*ior_scc_scc"
8251 [(set (match_operand:SI 0 "s_register_operand" "=r")
8252 (ior:SI (match_operator:SI 3 "arm_comparison_operator"
8253 [(match_operand:SI 1 "s_register_operand" "r")
8254 (match_operand:SI 2 "arm_add_operand" "rIL")])
8255 (match_operator:SI 6 "arm_comparison_operator"
8256 [(match_operand:SI 4 "s_register_operand" "r")
8257 (match_operand:SI 5 "arm_add_operand" "rIL")])))
8258 (clobber (reg:CC CC_REGNUM))]
8260 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_OR_Y)
8263 "TARGET_ARM && reload_completed"
8267 (match_op_dup 3 [(match_dup 1) (match_dup 2)])
8268 (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
8270 (set (match_dup 0) (ne:SI (match_dup 7) (const_int 0)))]
8272 = gen_rtx_REG (arm_select_dominance_cc_mode (operands[3], operands[6],
8275 [(set_attr "conds" "clob")
8276 (set_attr "length" "16")])
8278 ; If the above pattern is followed by a CMP insn, then the compare is
8279 ; redundant, since we can rework the conditional instruction that follows.
8280 (define_insn_and_split "*ior_scc_scc_cmp"
8281 [(set (match_operand 0 "dominant_cc_register" "")
8282 (compare (ior:SI (match_operator:SI 3 "arm_comparison_operator"
8283 [(match_operand:SI 1 "s_register_operand" "r")
8284 (match_operand:SI 2 "arm_add_operand" "rIL")])
8285 (match_operator:SI 6 "arm_comparison_operator"
8286 [(match_operand:SI 4 "s_register_operand" "r")
8287 (match_operand:SI 5 "arm_add_operand" "rIL")]))
8289 (set (match_operand:SI 7 "s_register_operand" "=r")
8290 (ior:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)])
8291 (match_op_dup 6 [(match_dup 4) (match_dup 5)])))]
8294 "TARGET_ARM && reload_completed"
8298 (match_op_dup 3 [(match_dup 1) (match_dup 2)])
8299 (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
8301 (set (match_dup 7) (ne:SI (match_dup 0) (const_int 0)))]
8303 [(set_attr "conds" "set")
8304 (set_attr "length" "16")])
8306 (define_insn_and_split "*and_scc_scc"
8307 [(set (match_operand:SI 0 "s_register_operand" "=r")
8308 (and:SI (match_operator:SI 3 "arm_comparison_operator"
8309 [(match_operand:SI 1 "s_register_operand" "r")
8310 (match_operand:SI 2 "arm_add_operand" "rIL")])
8311 (match_operator:SI 6 "arm_comparison_operator"
8312 [(match_operand:SI 4 "s_register_operand" "r")
8313 (match_operand:SI 5 "arm_add_operand" "rIL")])))
8314 (clobber (reg:CC CC_REGNUM))]
8316 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y)
8319 "TARGET_ARM && reload_completed
8320 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y)
8325 (match_op_dup 3 [(match_dup 1) (match_dup 2)])
8326 (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
8328 (set (match_dup 0) (ne:SI (match_dup 7) (const_int 0)))]
8330 = gen_rtx_REG (arm_select_dominance_cc_mode (operands[3], operands[6],
8333 [(set_attr "conds" "clob")
8334 (set_attr "length" "16")])
8336 ; If the above pattern is followed by a CMP insn, then the compare is
8337 ; redundant, since we can rework the conditional instruction that follows.
8338 (define_insn_and_split "*and_scc_scc_cmp"
8339 [(set (match_operand 0 "dominant_cc_register" "")
8340 (compare (and:SI (match_operator:SI 3 "arm_comparison_operator"
8341 [(match_operand:SI 1 "s_register_operand" "r")
8342 (match_operand:SI 2 "arm_add_operand" "rIL")])
8343 (match_operator:SI 6 "arm_comparison_operator"
8344 [(match_operand:SI 4 "s_register_operand" "r")
8345 (match_operand:SI 5 "arm_add_operand" "rIL")]))
8347 (set (match_operand:SI 7 "s_register_operand" "=r")
8348 (and:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)])
8349 (match_op_dup 6 [(match_dup 4) (match_dup 5)])))]
8352 "TARGET_ARM && reload_completed"
8356 (match_op_dup 3 [(match_dup 1) (match_dup 2)])
8357 (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
8359 (set (match_dup 7) (ne:SI (match_dup 0) (const_int 0)))]
8361 [(set_attr "conds" "set")
8362 (set_attr "length" "16")])
8364 ;; If there is no dominance in the comparison, then we can still save an
8365 ;; instruction in the AND case, since we can know that the second compare
8366 ;; need only zero the value if false (if true, then the value is already
8368 (define_insn_and_split "*and_scc_scc_nodom"
8369 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r")
8370 (and:SI (match_operator:SI 3 "arm_comparison_operator"
8371 [(match_operand:SI 1 "s_register_operand" "r,r,0")
8372 (match_operand:SI 2 "arm_add_operand" "rIL,0,rIL")])
8373 (match_operator:SI 6 "arm_comparison_operator"
8374 [(match_operand:SI 4 "s_register_operand" "r,r,r")
8375 (match_operand:SI 5 "arm_add_operand" "rIL,rIL,rIL")])))
8376 (clobber (reg:CC CC_REGNUM))]
8378 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y)
8381 "TARGET_ARM && reload_completed"
8382 [(parallel [(set (match_dup 0)
8383 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
8384 (clobber (reg:CC CC_REGNUM))])
8385 (set (match_dup 7) (match_op_dup 8 [(match_dup 4) (match_dup 5)]))
8387 (if_then_else:SI (match_op_dup 6 [(match_dup 7) (const_int 0)])
8390 "operands[7] = gen_rtx_REG (SELECT_CC_MODE (GET_CODE (operands[6]),
8391 operands[4], operands[5]),
8393 operands[8] = gen_rtx_COMPARE (GET_MODE (operands[7]), operands[4],
8395 [(set_attr "conds" "clob")
8396 (set_attr "length" "20")])
8399 [(set (reg:CC_NOOV CC_REGNUM)
8400 (compare:CC_NOOV (ior:SI
8401 (and:SI (match_operand:SI 0 "s_register_operand" "")
8403 (match_operator:SI 1 "comparison_operator"
8404 [(match_operand:SI 2 "s_register_operand" "")
8405 (match_operand:SI 3 "arm_add_operand" "")]))
8407 (clobber (match_operand:SI 4 "s_register_operand" ""))]
8410 (ior:SI (match_op_dup 1 [(match_dup 2) (match_dup 3)])
8412 (set (reg:CC_NOOV CC_REGNUM)
8413 (compare:CC_NOOV (and:SI (match_dup 4) (const_int 1))
8418 [(set (reg:CC_NOOV CC_REGNUM)
8419 (compare:CC_NOOV (ior:SI
8420 (match_operator:SI 1 "comparison_operator"
8421 [(match_operand:SI 2 "s_register_operand" "")
8422 (match_operand:SI 3 "arm_add_operand" "")])
8423 (and:SI (match_operand:SI 0 "s_register_operand" "")
8426 (clobber (match_operand:SI 4 "s_register_operand" ""))]
8429 (ior:SI (match_op_dup 1 [(match_dup 2) (match_dup 3)])
8431 (set (reg:CC_NOOV CC_REGNUM)
8432 (compare:CC_NOOV (and:SI (match_dup 4) (const_int 1))
8436 (define_insn "*negscc"
8437 [(set (match_operand:SI 0 "s_register_operand" "=r")
8438 (neg:SI (match_operator 3 "arm_comparison_operator"
8439 [(match_operand:SI 1 "s_register_operand" "r")
8440 (match_operand:SI 2 "arm_rhs_operand" "rI")])))
8441 (clobber (reg:CC CC_REGNUM))]
8444 if (GET_CODE (operands[3]) == LT && operands[3] == const0_rtx)
8445 return \"mov\\t%0, %1, asr #31\";
8447 if (GET_CODE (operands[3]) == NE)
8448 return \"subs\\t%0, %1, %2\;mvnne\\t%0, #0\";
8450 if (GET_CODE (operands[3]) == GT)
8451 return \"subs\\t%0, %1, %2\;mvnne\\t%0, %0, asr #31\";
8453 output_asm_insn (\"cmp\\t%1, %2\", operands);
8454 output_asm_insn (\"mov%D3\\t%0, #0\", operands);
8455 return \"mvn%d3\\t%0, #0\";
8457 [(set_attr "conds" "clob")
8458 (set_attr "length" "12")]
8461 (define_insn "movcond"
8462 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
8464 (match_operator 5 "arm_comparison_operator"
8465 [(match_operand:SI 3 "s_register_operand" "r,r,r")
8466 (match_operand:SI 4 "arm_add_operand" "rIL,rIL,rIL")])
8467 (match_operand:SI 1 "arm_rhs_operand" "0,rI,?rI")
8468 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
8469 (clobber (reg:CC CC_REGNUM))]
8472 if (GET_CODE (operands[5]) == LT
8473 && (operands[4] == const0_rtx))
8475 if (which_alternative != 1 && GET_CODE (operands[1]) == REG)
8477 if (operands[2] == const0_rtx)
8478 return \"and\\t%0, %1, %3, asr #31\";
8479 return \"ands\\t%0, %1, %3, asr #32\;movcc\\t%0, %2\";
8481 else if (which_alternative != 0 && GET_CODE (operands[2]) == REG)
8483 if (operands[1] == const0_rtx)
8484 return \"bic\\t%0, %2, %3, asr #31\";
8485 return \"bics\\t%0, %2, %3, asr #32\;movcs\\t%0, %1\";
8487 /* The only case that falls through to here is when both ops 1 & 2
8491 if (GET_CODE (operands[5]) == GE
8492 && (operands[4] == const0_rtx))
8494 if (which_alternative != 1 && GET_CODE (operands[1]) == REG)
8496 if (operands[2] == const0_rtx)
8497 return \"bic\\t%0, %1, %3, asr #31\";
8498 return \"bics\\t%0, %1, %3, asr #32\;movcs\\t%0, %2\";
8500 else if (which_alternative != 0 && GET_CODE (operands[2]) == REG)
8502 if (operands[1] == const0_rtx)
8503 return \"and\\t%0, %2, %3, asr #31\";
8504 return \"ands\\t%0, %2, %3, asr #32\;movcc\\t%0, %1\";
8506 /* The only case that falls through to here is when both ops 1 & 2
8509 if (GET_CODE (operands[4]) == CONST_INT
8510 && !const_ok_for_arm (INTVAL (operands[4])))
8511 output_asm_insn (\"cmn\\t%3, #%n4\", operands);
8513 output_asm_insn (\"cmp\\t%3, %4\", operands);
8514 if (which_alternative != 0)
8515 output_asm_insn (\"mov%d5\\t%0, %1\", operands);
8516 if (which_alternative != 1)
8517 output_asm_insn (\"mov%D5\\t%0, %2\", operands);
8520 [(set_attr "conds" "clob")
8521 (set_attr "length" "8,8,12")]
8524 (define_insn "*ifcompare_plus_move"
8525 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8526 (if_then_else:SI (match_operator 6 "arm_comparison_operator"
8527 [(match_operand:SI 4 "s_register_operand" "r,r")
8528 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
8530 (match_operand:SI 2 "s_register_operand" "r,r")
8531 (match_operand:SI 3 "arm_add_operand" "rIL,rIL"))
8532 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))
8533 (clobber (reg:CC CC_REGNUM))]
8536 [(set_attr "conds" "clob")
8537 (set_attr "length" "8,12")]
8540 (define_insn "*if_plus_move"
8541 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r")
8543 (match_operator 4 "arm_comparison_operator"
8544 [(match_operand 5 "cc_register" "") (const_int 0)])
8546 (match_operand:SI 2 "s_register_operand" "r,r,r,r")
8547 (match_operand:SI 3 "arm_add_operand" "rI,L,rI,L"))
8548 (match_operand:SI 1 "arm_rhs_operand" "0,0,?rI,?rI")))]
8552 sub%d4\\t%0, %2, #%n3
8553 add%d4\\t%0, %2, %3\;mov%D4\\t%0, %1
8554 sub%d4\\t%0, %2, #%n3\;mov%D4\\t%0, %1"
8555 [(set_attr "conds" "use")
8556 (set_attr "length" "4,4,8,8")
8557 (set_attr "type" "*,*,*,*")]
8560 (define_insn "*ifcompare_move_plus"
8561 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8562 (if_then_else:SI (match_operator 6 "arm_comparison_operator"
8563 [(match_operand:SI 4 "s_register_operand" "r,r")
8564 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
8565 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
8567 (match_operand:SI 2 "s_register_operand" "r,r")
8568 (match_operand:SI 3 "arm_add_operand" "rIL,rIL"))))
8569 (clobber (reg:CC CC_REGNUM))]
8572 [(set_attr "conds" "clob")
8573 (set_attr "length" "8,12")]
8576 (define_insn "*if_move_plus"
8577 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r")
8579 (match_operator 4 "arm_comparison_operator"
8580 [(match_operand 5 "cc_register" "") (const_int 0)])
8581 (match_operand:SI 1 "arm_rhs_operand" "0,0,?rI,?rI")
8583 (match_operand:SI 2 "s_register_operand" "r,r,r,r")
8584 (match_operand:SI 3 "arm_add_operand" "rI,L,rI,L"))))]
8588 sub%D4\\t%0, %2, #%n3
8589 add%D4\\t%0, %2, %3\;mov%d4\\t%0, %1
8590 sub%D4\\t%0, %2, #%n3\;mov%d4\\t%0, %1"
8591 [(set_attr "conds" "use")
8592 (set_attr "length" "4,4,8,8")
8593 (set_attr "type" "*,*,*,*")]
8596 (define_insn "*ifcompare_arith_arith"
8597 [(set (match_operand:SI 0 "s_register_operand" "=r")
8598 (if_then_else:SI (match_operator 9 "arm_comparison_operator"
8599 [(match_operand:SI 5 "s_register_operand" "r")
8600 (match_operand:SI 6 "arm_add_operand" "rIL")])
8601 (match_operator:SI 8 "shiftable_operator"
8602 [(match_operand:SI 1 "s_register_operand" "r")
8603 (match_operand:SI 2 "arm_rhs_operand" "rI")])
8604 (match_operator:SI 7 "shiftable_operator"
8605 [(match_operand:SI 3 "s_register_operand" "r")
8606 (match_operand:SI 4 "arm_rhs_operand" "rI")])))
8607 (clobber (reg:CC CC_REGNUM))]
8610 [(set_attr "conds" "clob")
8611 (set_attr "length" "12")]
8614 (define_insn "*if_arith_arith"
8615 [(set (match_operand:SI 0 "s_register_operand" "=r")
8616 (if_then_else:SI (match_operator 5 "arm_comparison_operator"
8617 [(match_operand 8 "cc_register" "") (const_int 0)])
8618 (match_operator:SI 6 "shiftable_operator"
8619 [(match_operand:SI 1 "s_register_operand" "r")
8620 (match_operand:SI 2 "arm_rhs_operand" "rI")])
8621 (match_operator:SI 7 "shiftable_operator"
8622 [(match_operand:SI 3 "s_register_operand" "r")
8623 (match_operand:SI 4 "arm_rhs_operand" "rI")])))]
8625 "%I6%d5\\t%0, %1, %2\;%I7%D5\\t%0, %3, %4"
8626 [(set_attr "conds" "use")
8627 (set_attr "length" "8")]
8630 (define_insn "*ifcompare_arith_move"
8631 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8632 (if_then_else:SI (match_operator 6 "arm_comparison_operator"
8633 [(match_operand:SI 2 "s_register_operand" "r,r")
8634 (match_operand:SI 3 "arm_add_operand" "rIL,rIL")])
8635 (match_operator:SI 7 "shiftable_operator"
8636 [(match_operand:SI 4 "s_register_operand" "r,r")
8637 (match_operand:SI 5 "arm_rhs_operand" "rI,rI")])
8638 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))
8639 (clobber (reg:CC CC_REGNUM))]
8642 /* If we have an operation where (op x 0) is the identity operation and
8643 the conditional operator is LT or GE and we are comparing against zero and
8644 everything is in registers then we can do this in two instructions. */
8645 if (operands[3] == const0_rtx
8646 && GET_CODE (operands[7]) != AND
8647 && GET_CODE (operands[5]) == REG
8648 && GET_CODE (operands[1]) == REG
8649 && REGNO (operands[1]) == REGNO (operands[4])
8650 && REGNO (operands[4]) != REGNO (operands[0]))
8652 if (GET_CODE (operands[6]) == LT)
8653 return \"and\\t%0, %5, %2, asr #31\;%I7\\t%0, %4, %0\";
8654 else if (GET_CODE (operands[6]) == GE)
8655 return \"bic\\t%0, %5, %2, asr #31\;%I7\\t%0, %4, %0\";
8657 if (GET_CODE (operands[3]) == CONST_INT
8658 && !const_ok_for_arm (INTVAL (operands[3])))
8659 output_asm_insn (\"cmn\\t%2, #%n3\", operands);
8661 output_asm_insn (\"cmp\\t%2, %3\", operands);
8662 output_asm_insn (\"%I7%d6\\t%0, %4, %5\", operands);
8663 if (which_alternative != 0)
8664 return \"mov%D6\\t%0, %1\";
8667 [(set_attr "conds" "clob")
8668 (set_attr "length" "8,12")]
8671 (define_insn "*if_arith_move"
8672 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8673 (if_then_else:SI (match_operator 4 "arm_comparison_operator"
8674 [(match_operand 6 "cc_register" "") (const_int 0)])
8675 (match_operator:SI 5 "shiftable_operator"
8676 [(match_operand:SI 2 "s_register_operand" "r,r")
8677 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
8678 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))]
8682 %I5%d4\\t%0, %2, %3\;mov%D4\\t%0, %1"
8683 [(set_attr "conds" "use")
8684 (set_attr "length" "4,8")
8685 (set_attr "type" "*,*")]
8688 (define_insn "*ifcompare_move_arith"
8689 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8690 (if_then_else:SI (match_operator 6 "arm_comparison_operator"
8691 [(match_operand:SI 4 "s_register_operand" "r,r")
8692 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
8693 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
8694 (match_operator:SI 7 "shiftable_operator"
8695 [(match_operand:SI 2 "s_register_operand" "r,r")
8696 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))
8697 (clobber (reg:CC CC_REGNUM))]
8700 /* If we have an operation where (op x 0) is the identity operation and
8701 the conditional operator is LT or GE and we are comparing against zero and
8702 everything is in registers then we can do this in two instructions */
8703 if (operands[5] == const0_rtx
8704 && GET_CODE (operands[7]) != AND
8705 && GET_CODE (operands[3]) == REG
8706 && GET_CODE (operands[1]) == REG
8707 && REGNO (operands[1]) == REGNO (operands[2])
8708 && REGNO (operands[2]) != REGNO (operands[0]))
8710 if (GET_CODE (operands[6]) == GE)
8711 return \"and\\t%0, %3, %4, asr #31\;%I7\\t%0, %2, %0\";
8712 else if (GET_CODE (operands[6]) == LT)
8713 return \"bic\\t%0, %3, %4, asr #31\;%I7\\t%0, %2, %0\";
8716 if (GET_CODE (operands[5]) == CONST_INT
8717 && !const_ok_for_arm (INTVAL (operands[5])))
8718 output_asm_insn (\"cmn\\t%4, #%n5\", operands);
8720 output_asm_insn (\"cmp\\t%4, %5\", operands);
8722 if (which_alternative != 0)
8723 output_asm_insn (\"mov%d6\\t%0, %1\", operands);
8724 return \"%I7%D6\\t%0, %2, %3\";
8726 [(set_attr "conds" "clob")
8727 (set_attr "length" "8,12")]
8730 (define_insn "*if_move_arith"
8731 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8733 (match_operator 4 "arm_comparison_operator"
8734 [(match_operand 6 "cc_register" "") (const_int 0)])
8735 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
8736 (match_operator:SI 5 "shiftable_operator"
8737 [(match_operand:SI 2 "s_register_operand" "r,r")
8738 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))]
8742 %I5%D4\\t%0, %2, %3\;mov%d4\\t%0, %1"
8743 [(set_attr "conds" "use")
8744 (set_attr "length" "4,8")
8745 (set_attr "type" "*,*")]
8748 (define_insn "*ifcompare_move_not"
8749 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8751 (match_operator 5 "arm_comparison_operator"
8752 [(match_operand:SI 3 "s_register_operand" "r,r")
8753 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
8754 (match_operand:SI 1 "arm_not_operand" "0,?rIK")
8756 (match_operand:SI 2 "s_register_operand" "r,r"))))
8757 (clobber (reg:CC CC_REGNUM))]
8760 [(set_attr "conds" "clob")
8761 (set_attr "length" "8,12")]
8764 (define_insn "*if_move_not"
8765 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
8767 (match_operator 4 "arm_comparison_operator"
8768 [(match_operand 3 "cc_register" "") (const_int 0)])
8769 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")
8770 (not:SI (match_operand:SI 2 "s_register_operand" "r,r,r"))))]
8774 mov%d4\\t%0, %1\;mvn%D4\\t%0, %2
8775 mvn%d4\\t%0, #%B1\;mvn%D4\\t%0, %2"
8776 [(set_attr "conds" "use")
8777 (set_attr "length" "4,8,8")]
8780 (define_insn "*ifcompare_not_move"
8781 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8783 (match_operator 5 "arm_comparison_operator"
8784 [(match_operand:SI 3 "s_register_operand" "r,r")
8785 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
8787 (match_operand:SI 2 "s_register_operand" "r,r"))
8788 (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
8789 (clobber (reg:CC CC_REGNUM))]
8792 [(set_attr "conds" "clob")
8793 (set_attr "length" "8,12")]
8796 (define_insn "*if_not_move"
8797 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
8799 (match_operator 4 "arm_comparison_operator"
8800 [(match_operand 3 "cc_register" "") (const_int 0)])
8801 (not:SI (match_operand:SI 2 "s_register_operand" "r,r,r"))
8802 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")))]
8806 mov%D4\\t%0, %1\;mvn%d4\\t%0, %2
8807 mvn%D4\\t%0, #%B1\;mvn%d4\\t%0, %2"
8808 [(set_attr "conds" "use")
8809 (set_attr "length" "4,8,8")]
8812 (define_insn "*ifcompare_shift_move"
8813 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8815 (match_operator 6 "arm_comparison_operator"
8816 [(match_operand:SI 4 "s_register_operand" "r,r")
8817 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
8818 (match_operator:SI 7 "shift_operator"
8819 [(match_operand:SI 2 "s_register_operand" "r,r")
8820 (match_operand:SI 3 "arm_rhs_operand" "rM,rM")])
8821 (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
8822 (clobber (reg:CC CC_REGNUM))]
8825 [(set_attr "conds" "clob")
8826 (set_attr "length" "8,12")]
8829 (define_insn "*if_shift_move"
8830 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
8832 (match_operator 5 "arm_comparison_operator"
8833 [(match_operand 6 "cc_register" "") (const_int 0)])
8834 (match_operator:SI 4 "shift_operator"
8835 [(match_operand:SI 2 "s_register_operand" "r,r,r")
8836 (match_operand:SI 3 "arm_rhs_operand" "rM,rM,rM")])
8837 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")))]
8841 mov%D5\\t%0, %1\;mov%d5\\t%0, %2%S4
8842 mvn%D5\\t%0, #%B1\;mov%d5\\t%0, %2%S4"
8843 [(set_attr "conds" "use")
8844 (set_attr "shift" "2")
8845 (set_attr "length" "4,8,8")
8846 (set (attr "type") (if_then_else (match_operand 3 "const_int_operand" "")
8847 (const_string "alu_shift")
8848 (const_string "alu_shift_reg")))]
8851 (define_insn "*ifcompare_move_shift"
8852 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8854 (match_operator 6 "arm_comparison_operator"
8855 [(match_operand:SI 4 "s_register_operand" "r,r")
8856 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
8857 (match_operand:SI 1 "arm_not_operand" "0,?rIK")
8858 (match_operator:SI 7 "shift_operator"
8859 [(match_operand:SI 2 "s_register_operand" "r,r")
8860 (match_operand:SI 3 "arm_rhs_operand" "rM,rM")])))
8861 (clobber (reg:CC CC_REGNUM))]
8864 [(set_attr "conds" "clob")
8865 (set_attr "length" "8,12")]
8868 (define_insn "*if_move_shift"
8869 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
8871 (match_operator 5 "arm_comparison_operator"
8872 [(match_operand 6 "cc_register" "") (const_int 0)])
8873 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")
8874 (match_operator:SI 4 "shift_operator"
8875 [(match_operand:SI 2 "s_register_operand" "r,r,r")
8876 (match_operand:SI 3 "arm_rhs_operand" "rM,rM,rM")])))]
8880 mov%d5\\t%0, %1\;mov%D5\\t%0, %2%S4
8881 mvn%d5\\t%0, #%B1\;mov%D5\\t%0, %2%S4"
8882 [(set_attr "conds" "use")
8883 (set_attr "shift" "2")
8884 (set_attr "length" "4,8,8")
8885 (set (attr "type") (if_then_else (match_operand 3 "const_int_operand" "")
8886 (const_string "alu_shift")
8887 (const_string "alu_shift_reg")))]
8890 (define_insn "*ifcompare_shift_shift"
8891 [(set (match_operand:SI 0 "s_register_operand" "=r")
8893 (match_operator 7 "arm_comparison_operator"
8894 [(match_operand:SI 5 "s_register_operand" "r")
8895 (match_operand:SI 6 "arm_add_operand" "rIL")])
8896 (match_operator:SI 8 "shift_operator"
8897 [(match_operand:SI 1 "s_register_operand" "r")
8898 (match_operand:SI 2 "arm_rhs_operand" "rM")])
8899 (match_operator:SI 9 "shift_operator"
8900 [(match_operand:SI 3 "s_register_operand" "r")
8901 (match_operand:SI 4 "arm_rhs_operand" "rM")])))
8902 (clobber (reg:CC CC_REGNUM))]
8905 [(set_attr "conds" "clob")
8906 (set_attr "length" "12")]
8909 (define_insn "*if_shift_shift"
8910 [(set (match_operand:SI 0 "s_register_operand" "=r")
8912 (match_operator 5 "arm_comparison_operator"
8913 [(match_operand 8 "cc_register" "") (const_int 0)])
8914 (match_operator:SI 6 "shift_operator"
8915 [(match_operand:SI 1 "s_register_operand" "r")
8916 (match_operand:SI 2 "arm_rhs_operand" "rM")])
8917 (match_operator:SI 7 "shift_operator"
8918 [(match_operand:SI 3 "s_register_operand" "r")
8919 (match_operand:SI 4 "arm_rhs_operand" "rM")])))]
8921 "mov%d5\\t%0, %1%S6\;mov%D5\\t%0, %3%S7"
8922 [(set_attr "conds" "use")
8923 (set_attr "shift" "1")
8924 (set_attr "length" "8")
8925 (set (attr "type") (if_then_else
8926 (and (match_operand 2 "const_int_operand" "")
8927 (match_operand 4 "const_int_operand" ""))
8928 (const_string "alu_shift")
8929 (const_string "alu_shift_reg")))]
8932 (define_insn "*ifcompare_not_arith"
8933 [(set (match_operand:SI 0 "s_register_operand" "=r")
8935 (match_operator 6 "arm_comparison_operator"
8936 [(match_operand:SI 4 "s_register_operand" "r")
8937 (match_operand:SI 5 "arm_add_operand" "rIL")])
8938 (not:SI (match_operand:SI 1 "s_register_operand" "r"))
8939 (match_operator:SI 7 "shiftable_operator"
8940 [(match_operand:SI 2 "s_register_operand" "r")
8941 (match_operand:SI 3 "arm_rhs_operand" "rI")])))
8942 (clobber (reg:CC CC_REGNUM))]
8945 [(set_attr "conds" "clob")
8946 (set_attr "length" "12")]
8949 (define_insn "*if_not_arith"
8950 [(set (match_operand:SI 0 "s_register_operand" "=r")
8952 (match_operator 5 "arm_comparison_operator"
8953 [(match_operand 4 "cc_register" "") (const_int 0)])
8954 (not:SI (match_operand:SI 1 "s_register_operand" "r"))
8955 (match_operator:SI 6 "shiftable_operator"
8956 [(match_operand:SI 2 "s_register_operand" "r")
8957 (match_operand:SI 3 "arm_rhs_operand" "rI")])))]
8959 "mvn%d5\\t%0, %1\;%I6%D5\\t%0, %2, %3"
8960 [(set_attr "conds" "use")
8961 (set_attr "length" "8")]
8964 (define_insn "*ifcompare_arith_not"
8965 [(set (match_operand:SI 0 "s_register_operand" "=r")
8967 (match_operator 6 "arm_comparison_operator"
8968 [(match_operand:SI 4 "s_register_operand" "r")
8969 (match_operand:SI 5 "arm_add_operand" "rIL")])
8970 (match_operator:SI 7 "shiftable_operator"
8971 [(match_operand:SI 2 "s_register_operand" "r")
8972 (match_operand:SI 3 "arm_rhs_operand" "rI")])
8973 (not:SI (match_operand:SI 1 "s_register_operand" "r"))))
8974 (clobber (reg:CC CC_REGNUM))]
8977 [(set_attr "conds" "clob")
8978 (set_attr "length" "12")]
8981 (define_insn "*if_arith_not"
8982 [(set (match_operand:SI 0 "s_register_operand" "=r")
8984 (match_operator 5 "arm_comparison_operator"
8985 [(match_operand 4 "cc_register" "") (const_int 0)])
8986 (match_operator:SI 6 "shiftable_operator"
8987 [(match_operand:SI 2 "s_register_operand" "r")
8988 (match_operand:SI 3 "arm_rhs_operand" "rI")])
8989 (not:SI (match_operand:SI 1 "s_register_operand" "r"))))]
8991 "mvn%D5\\t%0, %1\;%I6%d5\\t%0, %2, %3"
8992 [(set_attr "conds" "use")
8993 (set_attr "length" "8")]
8996 (define_insn "*ifcompare_neg_move"
8997 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8999 (match_operator 5 "arm_comparison_operator"
9000 [(match_operand:SI 3 "s_register_operand" "r,r")
9001 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
9002 (neg:SI (match_operand:SI 2 "s_register_operand" "r,r"))
9003 (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
9004 (clobber (reg:CC CC_REGNUM))]
9007 [(set_attr "conds" "clob")
9008 (set_attr "length" "8,12")]
9011 (define_insn "*if_neg_move"
9012 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9014 (match_operator 4 "arm_comparison_operator"
9015 [(match_operand 3 "cc_register" "") (const_int 0)])
9016 (neg:SI (match_operand:SI 2 "s_register_operand" "r,r,r"))
9017 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")))]
9021 mov%D4\\t%0, %1\;rsb%d4\\t%0, %2, #0
9022 mvn%D4\\t%0, #%B1\;rsb%d4\\t%0, %2, #0"
9023 [(set_attr "conds" "use")
9024 (set_attr "length" "4,8,8")]
9027 (define_insn "*ifcompare_move_neg"
9028 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9030 (match_operator 5 "arm_comparison_operator"
9031 [(match_operand:SI 3 "s_register_operand" "r,r")
9032 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
9033 (match_operand:SI 1 "arm_not_operand" "0,?rIK")
9034 (neg:SI (match_operand:SI 2 "s_register_operand" "r,r"))))
9035 (clobber (reg:CC CC_REGNUM))]
9038 [(set_attr "conds" "clob")
9039 (set_attr "length" "8,12")]
9042 (define_insn "*if_move_neg"
9043 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9045 (match_operator 4 "arm_comparison_operator"
9046 [(match_operand 3 "cc_register" "") (const_int 0)])
9047 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")
9048 (neg:SI (match_operand:SI 2 "s_register_operand" "r,r,r"))))]
9052 mov%d4\\t%0, %1\;rsb%D4\\t%0, %2, #0
9053 mvn%d4\\t%0, #%B1\;rsb%D4\\t%0, %2, #0"
9054 [(set_attr "conds" "use")
9055 (set_attr "length" "4,8,8")]
9058 (define_insn "*arith_adjacentmem"
9059 [(set (match_operand:SI 0 "s_register_operand" "=r")
9060 (match_operator:SI 1 "shiftable_operator"
9061 [(match_operand:SI 2 "memory_operand" "m")
9062 (match_operand:SI 3 "memory_operand" "m")]))
9063 (clobber (match_scratch:SI 4 "=r"))]
9064 "TARGET_ARM && adjacent_mem_locations (operands[2], operands[3])"
9069 int val1 = 0, val2 = 0;
9071 if (REGNO (operands[0]) > REGNO (operands[4]))
9073 ldm[1] = operands[4];
9074 ldm[2] = operands[0];
9078 ldm[1] = operands[0];
9079 ldm[2] = operands[4];
9081 if (GET_CODE (XEXP (operands[2], 0)) != REG)
9082 val1 = INTVAL (XEXP (XEXP (operands[2], 0), 1));
9083 if (GET_CODE (XEXP (operands[3], 0)) != REG)
9084 val2 = INTVAL (XEXP (XEXP (operands[3], 0), 1));
9085 arith[0] = operands[0];
9086 arith[3] = operands[1];
9100 ldm[0] = ops[0] = operands[4];
9101 ops[1] = XEXP (XEXP (operands[2], 0), 0);
9102 ops[2] = XEXP (XEXP (operands[2], 0), 1);
9103 output_add_immediate (ops);
9105 output_asm_insn (\"ldm%?ia\\t%0, {%1, %2}\", ldm);
9107 output_asm_insn (\"ldm%?da\\t%0, {%1, %2}\", ldm);
9111 ldm[0] = XEXP (operands[3], 0);
9113 output_asm_insn (\"ldm%?da\\t%0, {%1, %2}\", ldm);
9115 output_asm_insn (\"ldm%?ia\\t%0, {%1, %2}\", ldm);
9119 ldm[0] = XEXP (operands[2], 0);
9121 output_asm_insn (\"ldm%?ia\\t%0, {%1, %2}\", ldm);
9123 output_asm_insn (\"ldm%?da\\t%0, {%1, %2}\", ldm);
9125 output_asm_insn (\"%I3%?\\t%0, %1, %2\", arith);
9128 [(set_attr "length" "12")
9129 (set_attr "predicable" "yes")
9130 (set_attr "type" "load1")]
9133 ;; the arm can support extended pre-inc instructions
9135 ;; In all these cases, we use operands 0 and 1 for the register being
9136 ;; incremented because those are the operands that local-alloc will
9137 ;; tie and these are the pair most likely to be tieable (and the ones
9138 ;; that will benefit the most).
9140 ;; We reject the frame pointer if it occurs anywhere in these patterns since
9141 ;; elimination will cause too many headaches.
9143 (define_insn "*strqi_preinc"
9144 [(set (mem:QI (plus:SI (match_operand:SI 1 "s_register_operand" "%0")
9145 (match_operand:SI 2 "index_operand" "rJ")))
9146 (match_operand:QI 3 "s_register_operand" "r"))
9147 (set (match_operand:SI 0 "s_register_operand" "=r")
9148 (plus:SI (match_dup 1) (match_dup 2)))]
9150 && REGNO (operands[0]) != FRAME_POINTER_REGNUM
9151 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
9152 && (GET_CODE (operands[2]) != REG
9153 || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
9154 "str%?b\\t%3, [%0, %2]!"
9155 [(set_attr "type" "store1")
9156 (set_attr "predicable" "yes")]
9159 (define_insn "*strqi_predec"
9160 [(set (mem:QI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
9161 (match_operand:SI 2 "s_register_operand" "r")))
9162 (match_operand:QI 3 "s_register_operand" "r"))
9163 (set (match_operand:SI 0 "s_register_operand" "=r")
9164 (minus:SI (match_dup 1) (match_dup 2)))]
9166 && REGNO (operands[0]) != FRAME_POINTER_REGNUM
9167 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
9168 && (GET_CODE (operands[2]) != REG
9169 || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
9170 "str%?b\\t%3, [%0, -%2]!"
9171 [(set_attr "type" "store1")
9172 (set_attr "predicable" "yes")]
9175 (define_insn "*loadqi_preinc"
9176 [(set (match_operand:QI 3 "s_register_operand" "=r")
9177 (mem:QI (plus:SI (match_operand:SI 1 "s_register_operand" "%0")
9178 (match_operand:SI 2 "index_operand" "rJ"))))
9179 (set (match_operand:SI 0 "s_register_operand" "=r")
9180 (plus:SI (match_dup 1) (match_dup 2)))]
9182 && REGNO (operands[0]) != FRAME_POINTER_REGNUM
9183 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
9184 && (GET_CODE (operands[2]) != REG
9185 || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
9186 "ldr%?b\\t%3, [%0, %2]!"
9187 [(set_attr "type" "load_byte")
9188 (set_attr "predicable" "yes")]
9191 (define_insn "*loadqi_predec"
9192 [(set (match_operand:QI 3 "s_register_operand" "=r")
9193 (mem:QI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
9194 (match_operand:SI 2 "s_register_operand" "r"))))
9195 (set (match_operand:SI 0 "s_register_operand" "=r")
9196 (minus:SI (match_dup 1) (match_dup 2)))]
9198 && REGNO (operands[0]) != FRAME_POINTER_REGNUM
9199 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
9200 && (GET_CODE (operands[2]) != REG
9201 || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
9202 "ldr%?b\\t%3, [%0, -%2]!"
9203 [(set_attr "type" "load_byte")
9204 (set_attr "predicable" "yes")]
9207 (define_insn "*loadqisi_preinc"
9208 [(set (match_operand:SI 3 "s_register_operand" "=r")
9210 (mem:QI (plus:SI (match_operand:SI 1 "s_register_operand" "%0")
9211 (match_operand:SI 2 "index_operand" "rJ")))))
9212 (set (match_operand:SI 0 "s_register_operand" "=r")
9213 (plus:SI (match_dup 1) (match_dup 2)))]
9215 && REGNO (operands[0]) != FRAME_POINTER_REGNUM
9216 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
9217 && (GET_CODE (operands[2]) != REG
9218 || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
9219 "ldr%?b\\t%3, [%0, %2]!\\t%@ z_extendqisi"
9220 [(set_attr "type" "load_byte")
9221 (set_attr "predicable" "yes")]
9224 (define_insn "*loadqisi_predec"
9225 [(set (match_operand:SI 3 "s_register_operand" "=r")
9227 (mem:QI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
9228 (match_operand:SI 2 "s_register_operand" "r")))))
9229 (set (match_operand:SI 0 "s_register_operand" "=r")
9230 (minus:SI (match_dup 1) (match_dup 2)))]
9232 && REGNO (operands[0]) != FRAME_POINTER_REGNUM
9233 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
9234 && (GET_CODE (operands[2]) != REG
9235 || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
9236 "ldr%?b\\t%3, [%0, -%2]!\\t%@ z_extendqisi"
9237 [(set_attr "type" "load_byte")
9238 (set_attr "predicable" "yes")]
9241 (define_insn "*strsi_preinc"
9242 [(set (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "%0")
9243 (match_operand:SI 2 "index_operand" "rJ")))
9244 (match_operand:SI 3 "s_register_operand" "r"))
9245 (set (match_operand:SI 0 "s_register_operand" "=r")
9246 (plus:SI (match_dup 1) (match_dup 2)))]
9248 && REGNO (operands[0]) != FRAME_POINTER_REGNUM
9249 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
9250 && (GET_CODE (operands[2]) != REG
9251 || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
9252 "str%?\\t%3, [%0, %2]!"
9253 [(set_attr "type" "store1")
9254 (set_attr "predicable" "yes")]
9257 (define_insn "*strsi_predec"
9258 [(set (mem:SI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
9259 (match_operand:SI 2 "s_register_operand" "r")))
9260 (match_operand:SI 3 "s_register_operand" "r"))
9261 (set (match_operand:SI 0 "s_register_operand" "=r")
9262 (minus:SI (match_dup 1) (match_dup 2)))]
9264 && REGNO (operands[0]) != FRAME_POINTER_REGNUM
9265 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
9266 && (GET_CODE (operands[2]) != REG
9267 || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
9268 "str%?\\t%3, [%0, -%2]!"
9269 [(set_attr "type" "store1")
9270 (set_attr "predicable" "yes")]
9273 (define_insn "*loadsi_preinc"
9274 [(set (match_operand:SI 3 "s_register_operand" "=r")
9275 (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "%0")
9276 (match_operand:SI 2 "index_operand" "rJ"))))
9277 (set (match_operand:SI 0 "s_register_operand" "=r")
9278 (plus:SI (match_dup 1) (match_dup 2)))]
9280 && REGNO (operands[0]) != FRAME_POINTER_REGNUM
9281 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
9282 && (GET_CODE (operands[2]) != REG
9283 || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
9284 "ldr%?\\t%3, [%0, %2]!"
9285 [(set_attr "type" "load1")
9286 (set_attr "predicable" "yes")]
9289 (define_insn "*loadsi_predec"
9290 [(set (match_operand:SI 3 "s_register_operand" "=r")
9291 (mem:SI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
9292 (match_operand:SI 2 "s_register_operand" "r"))))
9293 (set (match_operand:SI 0 "s_register_operand" "=r")
9294 (minus:SI (match_dup 1) (match_dup 2)))]
9296 && REGNO (operands[0]) != FRAME_POINTER_REGNUM
9297 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
9298 && (GET_CODE (operands[2]) != REG
9299 || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
9300 "ldr%?\\t%3, [%0, -%2]!"
9301 [(set_attr "type" "load1")
9302 (set_attr "predicable" "yes")]
9305 (define_insn "*loadhi_preinc"
9306 [(set (match_operand:HI 3 "s_register_operand" "=r")
9307 (mem:HI (plus:SI (match_operand:SI 1 "s_register_operand" "%0")
9308 (match_operand:SI 2 "index_operand" "rJ"))))
9309 (set (match_operand:SI 0 "s_register_operand" "=r")
9310 (plus:SI (match_dup 1) (match_dup 2)))]
9312 && !BYTES_BIG_ENDIAN
9313 && !TARGET_MMU_TRAPS
9315 && REGNO (operands[0]) != FRAME_POINTER_REGNUM
9316 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
9317 && (GET_CODE (operands[2]) != REG
9318 || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
9319 "ldr%?\\t%3, [%0, %2]!\\t%@ loadhi"
9320 [(set_attr "type" "load_byte")
9321 (set_attr "predicable" "yes")]
9324 (define_insn "*loadhi_predec"
9325 [(set (match_operand:HI 3 "s_register_operand" "=r")
9326 (mem:HI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
9327 (match_operand:SI 2 "s_register_operand" "r"))))
9328 (set (match_operand:SI 0 "s_register_operand" "=r")
9329 (minus:SI (match_dup 1) (match_dup 2)))]
9331 && !BYTES_BIG_ENDIAN
9332 && !TARGET_MMU_TRAPS
9334 && REGNO (operands[0]) != FRAME_POINTER_REGNUM
9335 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
9336 && (GET_CODE (operands[2]) != REG
9337 || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
9338 "ldr%?\\t%3, [%0, -%2]!\\t%@ loadhi"
9339 [(set_attr "type" "load_byte")
9340 (set_attr "predicable" "yes")]
9343 (define_insn "*strqi_shiftpreinc"
9344 [(set (mem:QI (plus:SI (match_operator:SI 2 "shift_operator"
9345 [(match_operand:SI 3 "s_register_operand" "r")
9346 (match_operand:SI 4 "const_shift_operand" "n")])
9347 (match_operand:SI 1 "s_register_operand" "0")))
9348 (match_operand:QI 5 "s_register_operand" "r"))
9349 (set (match_operand:SI 0 "s_register_operand" "=r")
9350 (plus:SI (match_op_dup 2 [(match_dup 3) (match_dup 4)])
9353 && REGNO (operands[0]) != FRAME_POINTER_REGNUM
9354 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
9355 && REGNO (operands[3]) != FRAME_POINTER_REGNUM"
9356 "str%?b\\t%5, [%0, %3%S2]!"
9357 [(set_attr "type" "store1")
9358 (set_attr "predicable" "yes")]
9361 (define_insn "*strqi_shiftpredec"
9362 [(set (mem:QI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
9363 (match_operator:SI 2 "shift_operator"
9364 [(match_operand:SI 3 "s_register_operand" "r")
9365 (match_operand:SI 4 "const_shift_operand" "n")])))
9366 (match_operand:QI 5 "s_register_operand" "r"))
9367 (set (match_operand:SI 0 "s_register_operand" "=r")
9368 (minus:SI (match_dup 1) (match_op_dup 2 [(match_dup 3)
9371 && REGNO (operands[0]) != FRAME_POINTER_REGNUM
9372 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
9373 && REGNO (operands[3]) != FRAME_POINTER_REGNUM"
9374 "str%?b\\t%5, [%0, -%3%S2]!"
9375 [(set_attr "type" "store1")
9376 (set_attr "predicable" "yes")]
9379 (define_insn "*loadqi_shiftpreinc"
9380 [(set (match_operand:QI 5 "s_register_operand" "=r")
9381 (mem:QI (plus:SI (match_operator:SI 2 "shift_operator"
9382 [(match_operand:SI 3 "s_register_operand" "r")
9383 (match_operand:SI 4 "const_shift_operand" "n")])
9384 (match_operand:SI 1 "s_register_operand" "0"))))
9385 (set (match_operand:SI 0 "s_register_operand" "=r")
9386 (plus:SI (match_op_dup 2 [(match_dup 3) (match_dup 4)])
9389 && REGNO (operands[0]) != FRAME_POINTER_REGNUM
9390 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
9391 && REGNO (operands[3]) != FRAME_POINTER_REGNUM"
9392 "ldr%?b\\t%5, [%0, %3%S2]!"
9393 [(set_attr "type" "load_byte")
9394 (set_attr "predicable" "yes")]
9397 (define_insn "*loadqi_shiftpredec"
9398 [(set (match_operand:QI 5 "s_register_operand" "=r")
9399 (mem:QI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
9400 (match_operator:SI 2 "shift_operator"
9401 [(match_operand:SI 3 "s_register_operand" "r")
9402 (match_operand:SI 4 "const_shift_operand" "n")]))))
9403 (set (match_operand:SI 0 "s_register_operand" "=r")
9404 (minus:SI (match_dup 1) (match_op_dup 2 [(match_dup 3)
9407 && REGNO (operands[0]) != FRAME_POINTER_REGNUM
9408 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
9409 && REGNO (operands[3]) != FRAME_POINTER_REGNUM"
9410 "ldr%?b\\t%5, [%0, -%3%S2]!"
9411 [(set_attr "type" "load_byte")
9412 (set_attr "predicable" "yes")]
9415 (define_insn "*strsi_shiftpreinc"
9416 [(set (mem:SI (plus:SI (match_operator:SI 2 "shift_operator"
9417 [(match_operand:SI 3 "s_register_operand" "r")
9418 (match_operand:SI 4 "const_shift_operand" "n")])
9419 (match_operand:SI 1 "s_register_operand" "0")))
9420 (match_operand:SI 5 "s_register_operand" "r"))
9421 (set (match_operand:SI 0 "s_register_operand" "=r")
9422 (plus:SI (match_op_dup 2 [(match_dup 3) (match_dup 4)])
9425 && REGNO (operands[0]) != FRAME_POINTER_REGNUM
9426 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
9427 && REGNO (operands[3]) != FRAME_POINTER_REGNUM"
9428 "str%?\\t%5, [%0, %3%S2]!"
9429 [(set_attr "type" "store1")
9430 (set_attr "predicable" "yes")]
9433 (define_insn "*strsi_shiftpredec"
9434 [(set (mem:SI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
9435 (match_operator:SI 2 "shift_operator"
9436 [(match_operand:SI 3 "s_register_operand" "r")
9437 (match_operand:SI 4 "const_shift_operand" "n")])))
9438 (match_operand:SI 5 "s_register_operand" "r"))
9439 (set (match_operand:SI 0 "s_register_operand" "=r")
9440 (minus:SI (match_dup 1) (match_op_dup 2 [(match_dup 3)
9443 && REGNO (operands[0]) != FRAME_POINTER_REGNUM
9444 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
9445 && REGNO (operands[3]) != FRAME_POINTER_REGNUM"
9446 "str%?\\t%5, [%0, -%3%S2]!"
9447 [(set_attr "type" "store1")
9448 (set_attr "predicable" "yes")]
9451 (define_insn "*loadsi_shiftpreinc"
9452 [(set (match_operand:SI 5 "s_register_operand" "=r")
9453 (mem:SI (plus:SI (match_operator:SI 2 "shift_operator"
9454 [(match_operand:SI 3 "s_register_operand" "r")
9455 (match_operand:SI 4 "const_shift_operand" "n")])
9456 (match_operand:SI 1 "s_register_operand" "0"))))
9457 (set (match_operand:SI 0 "s_register_operand" "=r")
9458 (plus:SI (match_op_dup 2 [(match_dup 3) (match_dup 4)])
9461 && REGNO (operands[0]) != FRAME_POINTER_REGNUM
9462 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
9463 && REGNO (operands[3]) != FRAME_POINTER_REGNUM"
9464 "ldr%?\\t%5, [%0, %3%S2]!"
9465 [(set_attr "type" "load1")
9466 (set_attr "predicable" "yes")]
9469 (define_insn "*loadsi_shiftpredec"
9470 [(set (match_operand:SI 5 "s_register_operand" "=r")
9471 (mem:SI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
9472 (match_operator:SI 2 "shift_operator"
9473 [(match_operand:SI 3 "s_register_operand" "r")
9474 (match_operand:SI 4 "const_shift_operand" "n")]))))
9475 (set (match_operand:SI 0 "s_register_operand" "=r")
9476 (minus:SI (match_dup 1) (match_op_dup 2 [(match_dup 3)
9479 && REGNO (operands[0]) != FRAME_POINTER_REGNUM
9480 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
9481 && REGNO (operands[3]) != FRAME_POINTER_REGNUM"
9482 "ldr%?\\t%5, [%0, -%3%S2]!"
9483 [(set_attr "type" "load1")
9484 (set_attr "predicable" "yes")])
9486 (define_insn "*loadhi_shiftpreinc"
9487 [(set (match_operand:HI 5 "s_register_operand" "=r")
9488 (mem:HI (plus:SI (match_operator:SI 2 "shift_operator"
9489 [(match_operand:SI 3 "s_register_operand" "r")
9490 (match_operand:SI 4 "const_shift_operand" "n")])
9491 (match_operand:SI 1 "s_register_operand" "0"))))
9492 (set (match_operand:SI 0 "s_register_operand" "=r")
9493 (plus:SI (match_op_dup 2 [(match_dup 3) (match_dup 4)])
9496 && !BYTES_BIG_ENDIAN
9497 && !TARGET_MMU_TRAPS
9499 && REGNO (operands[0]) != FRAME_POINTER_REGNUM
9500 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
9501 && REGNO (operands[3]) != FRAME_POINTER_REGNUM"
9502 "ldr%?\\t%5, [%0, %3%S2]!\\t%@ loadhi"
9503 [(set_attr "type" "load_byte")
9504 (set_attr "predicable" "yes")]
9507 (define_insn "*loadhi_shiftpredec"
9508 [(set (match_operand:HI 5 "s_register_operand" "=r")
9509 (mem:HI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
9510 (match_operator:SI 2 "shift_operator"
9511 [(match_operand:SI 3 "s_register_operand" "r")
9512 (match_operand:SI 4 "const_shift_operand" "n")]))))
9513 (set (match_operand:SI 0 "s_register_operand" "=r")
9514 (minus:SI (match_dup 1) (match_op_dup 2 [(match_dup 3)
9517 && !BYTES_BIG_ENDIAN
9518 && !TARGET_MMU_TRAPS
9520 && REGNO (operands[0]) != FRAME_POINTER_REGNUM
9521 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
9522 && REGNO (operands[3]) != FRAME_POINTER_REGNUM"
9523 "ldr%?\\t%5, [%0, -%3%S2]!\\t%@ loadhi"
9524 [(set_attr "type" "load_byte")
9525 (set_attr "predicable" "yes")]
9528 ; It can also support extended post-inc expressions, but combine doesn't
9530 ; It doesn't seem worth adding peepholes for anything but the most common
9531 ; cases since, unlike combine, the increment must immediately follow the load
9532 ; for this pattern to match.
9533 ; We must watch to see that the source/destination register isn't also the
9534 ; same as the base address register, and that if the index is a register,
9535 ; that it is not the same as the base address register. In such cases the
9536 ; instruction that we would generate would have UNPREDICTABLE behavior so
9540 [(set (mem:QI (match_operand:SI 0 "s_register_operand" "+r"))
9541 (match_operand:QI 2 "s_register_operand" "r"))
9543 (plus:SI (match_dup 0) (match_operand:SI 1 "index_operand" "rJ")))]
9545 && (REGNO (operands[2]) != REGNO (operands[0]))
9546 && (GET_CODE (operands[1]) != REG
9547 || (REGNO (operands[1]) != REGNO (operands[0])))"
9548 "str%?b\\t%2, [%0], %1"
9552 [(set (match_operand:QI 0 "s_register_operand" "=r")
9553 (mem:QI (match_operand:SI 1 "s_register_operand" "+r")))
9555 (plus:SI (match_dup 1) (match_operand:SI 2 "index_operand" "rJ")))]
9557 && REGNO (operands[0]) != REGNO(operands[1])
9558 && (GET_CODE (operands[2]) != REG
9559 || REGNO(operands[0]) != REGNO (operands[2]))"
9560 "ldr%?b\\t%0, [%1], %2"
9564 [(set (mem:SI (match_operand:SI 0 "s_register_operand" "+r"))
9565 (match_operand:SI 2 "s_register_operand" "r"))
9567 (plus:SI (match_dup 0) (match_operand:SI 1 "index_operand" "rJ")))]
9569 && (REGNO (operands[2]) != REGNO (operands[0]))
9570 && (GET_CODE (operands[1]) != REG
9571 || (REGNO (operands[1]) != REGNO (operands[0])))"
9572 "str%?\\t%2, [%0], %1"
9576 [(set (match_operand:HI 0 "s_register_operand" "=r")
9577 (mem:HI (match_operand:SI 1 "s_register_operand" "+r")))
9579 (plus:SI (match_dup 1) (match_operand:SI 2 "index_operand" "rJ")))]
9581 && !BYTES_BIG_ENDIAN
9582 && !TARGET_MMU_TRAPS
9584 && REGNO (operands[0]) != REGNO(operands[1])
9585 && (GET_CODE (operands[2]) != REG
9586 || REGNO(operands[0]) != REGNO (operands[2]))"
9587 "ldr%?\\t%0, [%1], %2\\t%@ loadhi"
9591 [(set (match_operand:SI 0 "s_register_operand" "=r")
9592 (mem:SI (match_operand:SI 1 "s_register_operand" "+r")))
9594 (plus:SI (match_dup 1) (match_operand:SI 2 "index_operand" "rJ")))]
9596 && REGNO (operands[0]) != REGNO(operands[1])
9597 && (GET_CODE (operands[2]) != REG
9598 || REGNO(operands[0]) != REGNO (operands[2]))"
9599 "ldr%?\\t%0, [%1], %2"
9603 [(set (mem:QI (plus:SI (match_operand:SI 0 "s_register_operand" "+r")
9604 (match_operand:SI 1 "index_operand" "rJ")))
9605 (match_operand:QI 2 "s_register_operand" "r"))
9606 (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))]
9608 && (REGNO (operands[2]) != REGNO (operands[0]))
9609 && (GET_CODE (operands[1]) != REG
9610 || (REGNO (operands[1]) != REGNO (operands[0])))"
9611 "str%?b\\t%2, [%0, %1]!"
9615 [(set (mem:QI (plus:SI (match_operator:SI 4 "shift_operator"
9616 [(match_operand:SI 0 "s_register_operand" "r")
9617 (match_operand:SI 1 "const_int_operand" "n")])
9618 (match_operand:SI 2 "s_register_operand" "+r")))
9619 (match_operand:QI 3 "s_register_operand" "r"))
9620 (set (match_dup 2) (plus:SI (match_op_dup 4 [(match_dup 0) (match_dup 1)])
9623 && (REGNO (operands[3]) != REGNO (operands[2]))
9624 && (REGNO (operands[0]) != REGNO (operands[2]))"
9625 "str%?b\\t%3, [%2, %0%S4]!"
9628 ; This pattern is never tried by combine, so do it as a peephole
9631 [(set (match_operand:SI 0 "s_register_operand" "")
9632 (match_operand:SI 1 "s_register_operand" ""))
9633 (set (reg:CC CC_REGNUM)
9634 (compare:CC (match_dup 1) (const_int 0)))]
9636 && (!(TARGET_HARD_FLOAT && TARGET_MAVERICK)
9637 || (!cirrus_fp_register (operands[0], SImode)
9638 && !cirrus_fp_register (operands[1], SImode)))
9640 [(parallel [(set (reg:CC CC_REGNUM) (compare:CC (match_dup 1) (const_int 0)))
9641 (set (match_dup 0) (match_dup 1))])]
9645 ; Peepholes to spot possible load- and store-multiples, if the ordering is
9646 ; reversed, check that the memory references aren't volatile.
9649 [(set (match_operand:SI 0 "s_register_operand" "=r")
9650 (match_operand:SI 4 "memory_operand" "m"))
9651 (set (match_operand:SI 1 "s_register_operand" "=r")
9652 (match_operand:SI 5 "memory_operand" "m"))
9653 (set (match_operand:SI 2 "s_register_operand" "=r")
9654 (match_operand:SI 6 "memory_operand" "m"))
9655 (set (match_operand:SI 3 "s_register_operand" "=r")
9656 (match_operand:SI 7 "memory_operand" "m"))]
9657 "TARGET_ARM && load_multiple_sequence (operands, 4, NULL, NULL, NULL)"
9659 return emit_ldm_seq (operands, 4);
9664 [(set (match_operand:SI 0 "s_register_operand" "=r")
9665 (match_operand:SI 3 "memory_operand" "m"))
9666 (set (match_operand:SI 1 "s_register_operand" "=r")
9667 (match_operand:SI 4 "memory_operand" "m"))
9668 (set (match_operand:SI 2 "s_register_operand" "=r")
9669 (match_operand:SI 5 "memory_operand" "m"))]
9670 "TARGET_ARM && load_multiple_sequence (operands, 3, NULL, NULL, NULL)"
9672 return emit_ldm_seq (operands, 3);
9677 [(set (match_operand:SI 0 "s_register_operand" "=r")
9678 (match_operand:SI 2 "memory_operand" "m"))
9679 (set (match_operand:SI 1 "s_register_operand" "=r")
9680 (match_operand:SI 3 "memory_operand" "m"))]
9681 "TARGET_ARM && load_multiple_sequence (operands, 2, NULL, NULL, NULL)"
9683 return emit_ldm_seq (operands, 2);
9688 [(set (match_operand:SI 4 "memory_operand" "=m")
9689 (match_operand:SI 0 "s_register_operand" "r"))
9690 (set (match_operand:SI 5 "memory_operand" "=m")
9691 (match_operand:SI 1 "s_register_operand" "r"))
9692 (set (match_operand:SI 6 "memory_operand" "=m")
9693 (match_operand:SI 2 "s_register_operand" "r"))
9694 (set (match_operand:SI 7 "memory_operand" "=m")
9695 (match_operand:SI 3 "s_register_operand" "r"))]
9696 "TARGET_ARM && store_multiple_sequence (operands, 4, NULL, NULL, NULL)"
9698 return emit_stm_seq (operands, 4);
9703 [(set (match_operand:SI 3 "memory_operand" "=m")
9704 (match_operand:SI 0 "s_register_operand" "r"))
9705 (set (match_operand:SI 4 "memory_operand" "=m")
9706 (match_operand:SI 1 "s_register_operand" "r"))
9707 (set (match_operand:SI 5 "memory_operand" "=m")
9708 (match_operand:SI 2 "s_register_operand" "r"))]
9709 "TARGET_ARM && store_multiple_sequence (operands, 3, NULL, NULL, NULL)"
9711 return emit_stm_seq (operands, 3);
9716 [(set (match_operand:SI 2 "memory_operand" "=m")
9717 (match_operand:SI 0 "s_register_operand" "r"))
9718 (set (match_operand:SI 3 "memory_operand" "=m")
9719 (match_operand:SI 1 "s_register_operand" "r"))]
9720 "TARGET_ARM && store_multiple_sequence (operands, 2, NULL, NULL, NULL)"
9722 return emit_stm_seq (operands, 2);
9727 [(set (match_operand:SI 0 "s_register_operand" "")
9728 (and:SI (ge:SI (match_operand:SI 1 "s_register_operand" "")
9730 (neg:SI (match_operator:SI 2 "arm_comparison_operator"
9731 [(match_operand:SI 3 "s_register_operand" "")
9732 (match_operand:SI 4 "arm_rhs_operand" "")]))))
9733 (clobber (match_operand:SI 5 "s_register_operand" ""))]
9735 [(set (match_dup 5) (not:SI (ashiftrt:SI (match_dup 1) (const_int 31))))
9736 (set (match_dup 0) (and:SI (match_op_dup 2 [(match_dup 3) (match_dup 4)])
9741 ;; This split can be used because CC_Z mode implies that the following
9742 ;; branch will be an equality, or an unsigned inequality, so the sign
9743 ;; extension is not needed.
9746 [(set (reg:CC_Z CC_REGNUM)
9748 (ashift:SI (subreg:SI (match_operand:QI 0 "memory_operand" "") 0)
9750 (match_operand 1 "const_int_operand" "")))
9751 (clobber (match_scratch:SI 2 ""))]
9753 && (((unsigned HOST_WIDE_INT) INTVAL (operands[1]))
9754 == (((unsigned HOST_WIDE_INT) INTVAL (operands[1])) >> 24) << 24)"
9755 [(set (match_dup 2) (zero_extend:SI (match_dup 0)))
9756 (set (reg:CC CC_REGNUM) (compare:CC (match_dup 2) (match_dup 1)))]
9758 operands[1] = GEN_INT (((unsigned long) INTVAL (operands[1])) >> 24);
9762 (define_expand "prologue"
9763 [(clobber (const_int 0))]
9766 arm_expand_prologue ();
9768 thumb_expand_prologue ();
9773 (define_expand "epilogue"
9774 [(unspec_volatile [(return)] VUNSPEC_EPILOGUE)]
9778 thumb_expand_epilogue ();
9779 else if (USE_RETURN_INSN (FALSE))
9781 emit_jump_insn (gen_return ());
9784 emit_jump_insn (gen_rtx_UNSPEC_VOLATILE (VOIDmode,
9786 gen_rtx_RETURN (VOIDmode)),
9792 ;; Note - although unspec_volatile's USE all hard registers,
9793 ;; USEs are ignored after relaod has completed. Thus we need
9794 ;; to add an unspec of the link register to ensure that flow
9795 ;; does not think that it is unused by the sibcall branch that
9796 ;; will replace the standard function epilogue.
9797 (define_insn "sibcall_epilogue"
9798 [(parallel [(unspec:SI [(reg:SI LR_REGNUM)] UNSPEC_PROLOGUE_USE)
9799 (unspec_volatile [(return)] VUNSPEC_EPILOGUE)])]
9802 if (use_return_insn (FALSE, next_nonnote_insn (insn)))
9803 return output_return_instruction (const_true_rtx, FALSE, FALSE);
9804 return arm_output_epilogue (next_nonnote_insn (insn));
9806 ;; Length is absolute worst case
9807 [(set_attr "length" "44")
9808 (set_attr "type" "block")
9809 ;; We don't clobber the conditions, but the potential length of this
9810 ;; operation is sufficient to make conditionalizing the sequence
9811 ;; unlikely to be profitable.
9812 (set_attr "conds" "clob")]
9815 (define_insn "*epilogue_insns"
9816 [(unspec_volatile [(return)] VUNSPEC_EPILOGUE)]
9820 return arm_output_epilogue (NULL);
9821 else /* TARGET_THUMB */
9822 return thumb_unexpanded_epilogue ();
9824 ; Length is absolute worst case
9825 [(set_attr "length" "44")
9826 (set_attr "type" "block")
9827 ;; We don't clobber the conditions, but the potential length of this
9828 ;; operation is sufficient to make conditionalizing the sequence
9829 ;; unlikely to be profitable.
9830 (set_attr "conds" "clob")]
9833 (define_expand "eh_epilogue"
9834 [(use (match_operand:SI 0 "register_operand" ""))
9835 (use (match_operand:SI 1 "register_operand" ""))
9836 (use (match_operand:SI 2 "register_operand" ""))]
9840 cfun->machine->eh_epilogue_sp_ofs = operands[1];
9841 if (GET_CODE (operands[2]) != REG || REGNO (operands[2]) != 2)
9843 rtx ra = gen_rtx_REG (Pmode, 2);
9845 emit_move_insn (ra, operands[2]);
9848 /* This is a hack -- we may have crystalized the function type too
9850 cfun->machine->func_type = 0;
9854 ;; This split is only used during output to reduce the number of patterns
9855 ;; that need assembler instructions adding to them. We allowed the setting
9856 ;; of the conditions to be implicit during rtl generation so that
9857 ;; the conditional compare patterns would work. However this conflicts to
9858 ;; some extent with the conditional data operations, so we have to split them
9862 [(set (match_operand:SI 0 "s_register_operand" "")
9863 (if_then_else:SI (match_operator 1 "arm_comparison_operator"
9864 [(match_operand 2 "" "") (match_operand 3 "" "")])
9866 (match_operand 4 "" "")))
9867 (clobber (reg:CC CC_REGNUM))]
9868 "TARGET_ARM && reload_completed"
9869 [(set (match_dup 5) (match_dup 6))
9870 (cond_exec (match_dup 7)
9871 (set (match_dup 0) (match_dup 4)))]
9874 enum machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
9875 operands[2], operands[3]);
9876 enum rtx_code rc = GET_CODE (operands[1]);
9878 operands[5] = gen_rtx_REG (mode, CC_REGNUM);
9879 operands[6] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
9880 if (mode == CCFPmode || mode == CCFPEmode)
9881 rc = reverse_condition_maybe_unordered (rc);
9883 rc = reverse_condition (rc);
9885 operands[7] = gen_rtx_fmt_ee (rc, VOIDmode, operands[5], const0_rtx);
9890 [(set (match_operand:SI 0 "s_register_operand" "")
9891 (if_then_else:SI (match_operator 1 "arm_comparison_operator"
9892 [(match_operand 2 "" "") (match_operand 3 "" "")])
9893 (match_operand 4 "" "")
9895 (clobber (reg:CC CC_REGNUM))]
9896 "TARGET_ARM && reload_completed"
9897 [(set (match_dup 5) (match_dup 6))
9898 (cond_exec (match_op_dup 1 [(match_dup 5) (const_int 0)])
9899 (set (match_dup 0) (match_dup 4)))]
9902 enum machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
9903 operands[2], operands[3]);
9905 operands[5] = gen_rtx_REG (mode, CC_REGNUM);
9906 operands[6] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
9911 [(set (match_operand:SI 0 "s_register_operand" "")
9912 (if_then_else:SI (match_operator 1 "arm_comparison_operator"
9913 [(match_operand 2 "" "") (match_operand 3 "" "")])
9914 (match_operand 4 "" "")
9915 (match_operand 5 "" "")))
9916 (clobber (reg:CC CC_REGNUM))]
9917 "TARGET_ARM && reload_completed"
9918 [(set (match_dup 6) (match_dup 7))
9919 (cond_exec (match_op_dup 1 [(match_dup 6) (const_int 0)])
9920 (set (match_dup 0) (match_dup 4)))
9921 (cond_exec (match_dup 8)
9922 (set (match_dup 0) (match_dup 5)))]
9925 enum machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
9926 operands[2], operands[3]);
9927 enum rtx_code rc = GET_CODE (operands[1]);
9929 operands[6] = gen_rtx_REG (mode, CC_REGNUM);
9930 operands[7] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
9931 if (mode == CCFPmode || mode == CCFPEmode)
9932 rc = reverse_condition_maybe_unordered (rc);
9934 rc = reverse_condition (rc);
9936 operands[8] = gen_rtx_fmt_ee (rc, VOIDmode, operands[6], const0_rtx);
9941 [(set (match_operand:SI 0 "s_register_operand" "")
9942 (if_then_else:SI (match_operator 1 "arm_comparison_operator"
9943 [(match_operand:SI 2 "s_register_operand" "")
9944 (match_operand:SI 3 "arm_add_operand" "")])
9945 (match_operand:SI 4 "arm_rhs_operand" "")
9947 (match_operand:SI 5 "s_register_operand" ""))))
9948 (clobber (reg:CC CC_REGNUM))]
9949 "TARGET_ARM && reload_completed"
9950 [(set (match_dup 6) (match_dup 7))
9951 (cond_exec (match_op_dup 1 [(match_dup 6) (const_int 0)])
9952 (set (match_dup 0) (match_dup 4)))
9953 (cond_exec (match_dup 8)
9954 (set (match_dup 0) (not:SI (match_dup 5))))]
9957 enum machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
9958 operands[2], operands[3]);
9959 enum rtx_code rc = GET_CODE (operands[1]);
9961 operands[6] = gen_rtx_REG (mode, CC_REGNUM);
9962 operands[7] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
9963 if (mode == CCFPmode || mode == CCFPEmode)
9964 rc = reverse_condition_maybe_unordered (rc);
9966 rc = reverse_condition (rc);
9968 operands[8] = gen_rtx_fmt_ee (rc, VOIDmode, operands[6], const0_rtx);
9972 (define_insn "*cond_move_not"
9973 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9974 (if_then_else:SI (match_operator 4 "arm_comparison_operator"
9975 [(match_operand 3 "cc_register" "") (const_int 0)])
9976 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
9978 (match_operand:SI 2 "s_register_operand" "r,r"))))]
9982 mov%d4\\t%0, %1\;mvn%D4\\t%0, %2"
9983 [(set_attr "conds" "use")
9984 (set_attr "length" "4,8")]
9987 ;; The next two patterns occur when an AND operation is followed by a
9988 ;; scc insn sequence
9990 (define_insn "*sign_extract_onebit"
9991 [(set (match_operand:SI 0 "s_register_operand" "=r")
9992 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
9994 (match_operand:SI 2 "const_int_operand" "n")))
9995 (clobber (reg:CC CC_REGNUM))]
9998 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
9999 output_asm_insn (\"ands\\t%0, %1, %2\", operands);
10000 return \"mvnne\\t%0, #0\";
10002 [(set_attr "conds" "clob")
10003 (set_attr "length" "8")]
10006 (define_insn "*not_signextract_onebit"
10007 [(set (match_operand:SI 0 "s_register_operand" "=r")
10009 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
10011 (match_operand:SI 2 "const_int_operand" "n"))))
10012 (clobber (reg:CC CC_REGNUM))]
10015 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
10016 output_asm_insn (\"tst\\t%1, %2\", operands);
10017 output_asm_insn (\"mvneq\\t%0, #0\", operands);
10018 return \"movne\\t%0, #0\";
10020 [(set_attr "conds" "clob")
10021 (set_attr "length" "12")]
10024 ;; Push multiple registers to the stack. Registers are in parallel (use ...)
10025 ;; expressions. For simplicity, the first register is also in the unspec
10027 (define_insn "*push_multi"
10028 [(match_parallel 2 "multi_register_push"
10029 [(set (match_operand:BLK 0 "memory_operand" "=m")
10030 (unspec:BLK [(match_operand:SI 1 "s_register_operand" "r")]
10031 UNSPEC_PUSH_MULT))])]
10035 int num_saves = XVECLEN (operands[2], 0);
10037 /* For the StrongARM at least it is faster to
10038 use STR to store only a single register. */
10039 if (num_saves == 1)
10040 output_asm_insn (\"str\\t%1, [%m0, #-4]!\", operands);
10046 strcpy (pattern, \"stmfd\\t%m0!, {%1\");
10048 for (i = 1; i < num_saves; i++)
10050 strcat (pattern, \", %|\");
10052 reg_names[REGNO (XEXP (XVECEXP (operands[2], 0, i), 0))]);
10055 strcat (pattern, \"}\");
10056 output_asm_insn (pattern, operands);
10061 [(set_attr "type" "store4")]
10064 (define_insn "stack_tie"
10065 [(set (mem:BLK (scratch))
10066 (unspec:BLK [(match_operand:SI 0 "s_register_operand" "r")
10067 (match_operand:SI 1 "s_register_operand" "r")]
10071 [(set_attr "length" "0")]
10074 ;; Similarly for the floating point registers
10075 (define_insn "*push_fp_multi"
10076 [(match_parallel 2 "multi_register_push"
10077 [(set (match_operand:BLK 0 "memory_operand" "=m")
10078 (unspec:BLK [(match_operand:XF 1 "f_register_operand" "f")]
10079 UNSPEC_PUSH_MULT))])]
10080 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
10085 sprintf (pattern, \"sfmfd\\t%%1, %d, [%%m0]!\", XVECLEN (operands[2], 0));
10086 output_asm_insn (pattern, operands);
10089 [(set_attr "type" "f_store")]
10092 ;; Special patterns for dealing with the constant pool
10094 (define_insn "align_4"
10095 [(unspec_volatile [(const_int 0)] VUNSPEC_ALIGN)]
10098 assemble_align (32);
10103 (define_insn "align_8"
10104 [(unspec_volatile [(const_int 0)] VUNSPEC_ALIGN8)]
10107 assemble_align (64);
10112 (define_insn "consttable_end"
10113 [(unspec_volatile [(const_int 0)] VUNSPEC_POOL_END)]
10116 making_const_table = FALSE;
10121 (define_insn "consttable_1"
10122 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_1)]
10125 making_const_table = TRUE;
10126 assemble_integer (operands[0], 1, BITS_PER_WORD, 1);
10127 assemble_zeros (3);
10130 [(set_attr "length" "4")]
10133 (define_insn "consttable_2"
10134 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_2)]
10137 making_const_table = TRUE;
10138 assemble_integer (operands[0], 2, BITS_PER_WORD, 1);
10139 assemble_zeros (2);
10142 [(set_attr "length" "4")]
10145 (define_insn "consttable_4"
10146 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_4)]
10150 making_const_table = TRUE;
10151 switch (GET_MODE_CLASS (GET_MODE (operands[0])))
10156 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[0]);
10157 assemble_real (r, GET_MODE (operands[0]), BITS_PER_WORD);
10161 assemble_integer (operands[0], 4, BITS_PER_WORD, 1);
10166 [(set_attr "length" "4")]
10169 (define_insn "consttable_8"
10170 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_8)]
10174 making_const_table = TRUE;
10175 switch (GET_MODE_CLASS (GET_MODE (operands[0])))
10180 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[0]);
10181 assemble_real (r, GET_MODE (operands[0]), BITS_PER_WORD);
10185 assemble_integer (operands[0], 8, BITS_PER_WORD, 1);
10190 [(set_attr "length" "8")]
10193 ;; Miscellaneous Thumb patterns
10195 (define_expand "tablejump"
10196 [(parallel [(set (pc) (match_operand:SI 0 "register_operand" ""))
10197 (use (label_ref (match_operand 1 "" "")))])]
10202 /* Hopefully, CSE will eliminate this copy. */
10203 rtx reg1 = copy_addr_to_reg (gen_rtx_LABEL_REF (Pmode, operands[1]));
10204 rtx reg2 = gen_reg_rtx (SImode);
10206 emit_insn (gen_addsi3 (reg2, operands[0], reg1));
10207 operands[0] = reg2;
10212 (define_insn "*thumb_tablejump"
10213 [(set (pc) (match_operand:SI 0 "register_operand" "l*r"))
10214 (use (label_ref (match_operand 1 "" "")))]
10217 [(set_attr "length" "2")]
10220 ;; V5 Instructions,
10222 (define_insn "clzsi2"
10223 [(set (match_operand:SI 0 "s_register_operand" "=r")
10224 (clz:SI (match_operand:SI 1 "s_register_operand" "r")))]
10225 "TARGET_ARM && arm_arch5"
10227 [(set_attr "predicable" "yes")])
10229 (define_expand "ffssi2"
10230 [(set (match_operand:SI 0 "s_register_operand" "")
10231 (ffs:SI (match_operand:SI 1 "s_register_operand" "")))]
10232 "TARGET_ARM && arm_arch5"
10237 t1 = gen_reg_rtx (SImode);
10238 t2 = gen_reg_rtx (SImode);
10239 t3 = gen_reg_rtx (SImode);
10241 emit_insn (gen_negsi2 (t1, operands[1]));
10242 emit_insn (gen_andsi3 (t2, operands[1], t1));
10243 emit_insn (gen_clzsi2 (t3, t2));
10244 emit_insn (gen_subsi3 (operands[0], GEN_INT (32), t3));
10249 (define_expand "ctzsi2"
10250 [(set (match_operand:SI 0 "s_register_operand" "")
10251 (ctz:SI (match_operand:SI 1 "s_register_operand" "")))]
10252 "TARGET_ARM && arm_arch5"
10257 t1 = gen_reg_rtx (SImode);
10258 t2 = gen_reg_rtx (SImode);
10259 t3 = gen_reg_rtx (SImode);
10261 emit_insn (gen_negsi2 (t1, operands[1]));
10262 emit_insn (gen_andsi3 (t2, operands[1], t1));
10263 emit_insn (gen_clzsi2 (t3, t2));
10264 emit_insn (gen_subsi3 (operands[0], GEN_INT (31), t3));
10269 ;; V5E instructions.
10271 (define_insn "prefetch"
10272 [(prefetch (match_operand:SI 0 "address_operand" "p")
10273 (match_operand:SI 1 "" "")
10274 (match_operand:SI 2 "" ""))]
10275 "TARGET_ARM && arm_arch5e"
10278 ;; General predication pattern
10281 [(match_operator 0 "arm_comparison_operator"
10282 [(match_operand 1 "cc_register" "")
10288 (define_insn "prologue_use"
10289 [(unspec:SI [(match_operand:SI 0 "register_operand" "")] UNSPEC_PROLOGUE_USE)]
10291 "%@ %0 needed for prologue"
10294 ;; Load the FPA co-processor patterns
10296 ;; Load the Maverick co-processor patterns
10297 (include "cirrus.md")
10298 ;; Load the Intel Wireless Multimedia Extension patterns
10299 (include "iwmmxt.md")
10300 ;; Load the VFP co-processor patterns