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
120 (VUNSPEC_EH_RETURN 20); Use to overrite the return address for exception
125 ;;---------------------------------------------------------------------------
128 ; IS_THUMB is set to 'yes' when we are generating Thumb code, and 'no' when
129 ; generating ARM code. This is used to control the length of some insn
130 ; patterns that share the same RTL in both ARM and Thumb code.
131 (define_attr "is_thumb" "no,yes" (const (symbol_ref "thumb_code")))
133 ; IS_STRONGARM is set to 'yes' when compiling for StrongARM, it affects
134 ; scheduling decisions for the load unit and the multiplier.
135 (define_attr "is_strongarm" "no,yes" (const (symbol_ref "arm_is_strong")))
137 ; IS_XSCALE is set to 'yes' when compiling for XScale.
138 (define_attr "is_xscale" "no,yes" (const (symbol_ref "arm_tune_xscale")))
140 ;; Operand number of an input operand that is shifted. Zero if the
141 ;; given instruction does not shift one of its input operands.
142 (define_attr "shift" "" (const_int 0))
144 ; Floating Point Unit. If we only have floating point emulation, then there
145 ; is no point in scheduling the floating point insns. (Well, for best
146 ; performance we should try and group them together).
147 (define_attr "fpu" "none,fpa,fpe2,fpe3,maverick,vfp"
148 (const (symbol_ref "arm_fpu_attr")))
150 ; LENGTH of an instruction (in bytes)
151 (define_attr "length" "" (const_int 4))
153 ; POOL_RANGE is how far away from a constant pool entry that this insn
154 ; can be placed. If the distance is zero, then this insn will never
155 ; reference the pool.
156 ; NEG_POOL_RANGE is nonzero for insns that can reference a constant pool entry
157 ; before its address.
158 (define_attr "pool_range" "" (const_int 0))
159 (define_attr "neg_pool_range" "" (const_int 0))
161 ; An assembler sequence may clobber the condition codes without us knowing.
162 ; If such an insn references the pool, then we have no way of knowing how,
163 ; so use the most conservative value for pool_range.
164 (define_asm_attributes
165 [(set_attr "conds" "clob")
166 (set_attr "length" "4")
167 (set_attr "pool_range" "250")])
169 ;; The instruction used to implement a particular pattern. This
170 ;; information is used by pipeline descriptions to provide accurate
171 ;; scheduling information.
174 "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"
175 (const_string "other"))
177 ; TYPE attribute is used to detect floating point instructions which, if
178 ; running on a co-processor can run in parallel with other, basic instructions
179 ; If write-buffer scheduling is enabled then it can also be used in the
180 ; scheduling of writes.
182 ; Classification of each insn
183 ; alu any alu instruction that doesn't hit memory or fp
184 ; regs or have a shifted source operand
185 ; alu_shift any data instruction that doesn't hit memory or fp
186 ; regs, but has a source operand shifted by a constant
187 ; alu_shift_reg any data instruction that doesn't hit memory or fp
188 ; regs, but has a source operand shifted by a register value
189 ; mult a multiply instruction
190 ; block blockage insn, this blocks all functional units
191 ; float a floating point arithmetic operation (subject to expansion)
192 ; fdivd DFmode floating point division
193 ; fdivs SFmode floating point division
194 ; fmul Floating point multiply
195 ; ffmul Fast floating point multiply
196 ; farith Floating point arithmetic (4 cycle)
197 ; ffarith Fast floating point arithmetic (2 cycle)
198 ; float_em a floating point arithmetic operation that is normally emulated
199 ; even on a machine with an fpa.
200 ; f_load a floating point load from memory
201 ; f_store a floating point store to memory
202 ; f_mem_r a transfer of a floating point register to a real reg via mem
203 ; r_mem_f the reverse of f_mem_r
204 ; f_2_r fast transfer float to arm (no memory needed)
205 ; r_2_f fast transfer arm to float
207 ; call a subroutine call
208 ; load_byte load byte(s) from memory to arm registers
209 ; load1 load 1 word from memory to arm registers
210 ; load2 load 2 words from memory to arm registers
211 ; load3 load 3 words from memory to arm registers
212 ; load4 load 4 words from memory to arm registers
213 ; store store 1 word to memory from arm registers
214 ; store2 store 2 words
215 ; store3 store 3 words
216 ; store4 store 4 (or more) words
217 ; Additions for Cirrus Maverick co-processor:
218 ; mav_farith Floating point arithmetic (4 cycle)
219 ; mav_dmult Double multiplies (7 cycle)
222 "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"
224 (eq_attr "insn" "smulxy,smlaxy,smlalxy,smulwy,smlawx,mul,muls,mla,mlas,umull,umulls,umlal,umlals,smull,smulls,smlal,smlals")
225 (const_string "mult")
226 (const_string "alu")))
228 ; Load scheduling, set from the arm_ld_sched variable
229 ; initialized by arm_override_options()
230 (define_attr "ldsched" "no,yes" (const (symbol_ref "arm_ld_sched")))
232 ; condition codes: this one is used by final_prescan_insn to speed up
233 ; conditionalizing instructions. It saves having to scan the rtl to see if
234 ; it uses or alters the condition codes.
236 ; USE means that the condition codes are used by the insn in the process of
237 ; outputting code, this means (at present) that we can't use the insn in
240 ; SET means that the purpose of the insn is to set the condition codes in a
241 ; well defined manner.
243 ; CLOB means that the condition codes are altered in an undefined manner, if
244 ; they are altered at all
246 ; JUMP_CLOB is used when the condition cannot be represented by a single
247 ; instruction (UNEQ and LTGT). These cannot be predicated.
249 ; NOCOND means that the condition codes are neither altered nor affect the
250 ; output of this insn
252 (define_attr "conds" "use,set,clob,jump_clob,nocond"
253 (if_then_else (eq_attr "type" "call")
254 (const_string "clob")
255 (const_string "nocond")))
257 ; Predicable means that the insn can be conditionally executed based on
258 ; an automatically added predicate (additional patterns are generated by
259 ; gen...). We default to 'no' because no Thumb patterns match this rule
260 ; and not all ARM patterns do.
261 (define_attr "predicable" "no,yes" (const_string "no"))
263 ; Only model the write buffer for ARM6 and ARM7. Earlier processors don't
264 ; have one. Later ones, such as StrongARM, have write-back caches, so don't
265 ; suffer blockages enough to warrant modelling this (and it can adversely
266 ; affect the schedule).
267 (define_attr "model_wbuf" "no,yes" (const (symbol_ref "arm_is_6_or_7")))
269 ; WRITE_CONFLICT implies that a read following an unrelated write is likely
270 ; to stall the processor. Used with model_wbuf above.
271 (define_attr "write_conflict" "no,yes"
272 (if_then_else (eq_attr "type"
273 "block,float_em,f_load,f_store,f_mem_r,r_mem_f,call,load1")
275 (const_string "no")))
277 ; Classify the insns into those that take one cycle and those that take more
278 ; than one on the main cpu execution unit.
279 (define_attr "core_cycles" "single,multi"
280 (if_then_else (eq_attr "type"
281 "alu,alu_shift,float,fdivx,fdivd,fdivs,fmul,ffmul,farith,ffarith")
282 (const_string "single")
283 (const_string "multi")))
285 ;; FAR_JUMP is "yes" if a BL instruction is used to generate a branch to a
286 ;; distant label. Only applicable to Thumb code.
287 (define_attr "far_jump" "yes,no" (const_string "no"))
289 ;;---------------------------------------------------------------------------
290 ;; Pipeline descriptions
292 ;; Processor type. This is created automatically from arm-cores.def.
293 (include "arm-tune.md")
295 ;; True if the generic scheduling description should be used.
297 (define_attr "generic_sched" "yes,no"
299 (eq_attr "tune" "arm926ejs,arm1026ejs,arm1136js,arm1136jfs")
301 (const_string "yes")))
303 (include "arm-generic.md")
304 (include "arm926ejs.md")
305 (include "arm1026ejs.md")
306 (include "arm1136jfs.md")
309 ;;---------------------------------------------------------------------------
314 ;; Note: For DImode insns, there is normally no reason why operands should
315 ;; not be in the same register, what we don't want is for something being
316 ;; written to partially overlap something that is an input.
317 ;; Cirrus 64bit additions should not be split because we have a native
318 ;; 64bit addition instructions.
320 (define_expand "adddi3"
322 [(set (match_operand:DI 0 "s_register_operand" "")
323 (plus:DI (match_operand:DI 1 "s_register_operand" "")
324 (match_operand:DI 2 "s_register_operand" "")))
325 (clobber (reg:CC CC_REGNUM))])]
328 if (TARGET_HARD_FLOAT && TARGET_MAVERICK)
330 if (!cirrus_fp_register (operands[0], DImode))
331 operands[0] = force_reg (DImode, operands[0]);
332 if (!cirrus_fp_register (operands[1], DImode))
333 operands[1] = force_reg (DImode, operands[1]);
334 emit_insn (gen_cirrus_adddi3 (operands[0], operands[1], operands[2]));
340 if (GET_CODE (operands[1]) != REG)
341 operands[1] = force_reg (SImode, operands[1]);
342 if (GET_CODE (operands[2]) != REG)
343 operands[2] = force_reg (SImode, operands[2]);
348 (define_insn "*thumb_adddi3"
349 [(set (match_operand:DI 0 "register_operand" "=l")
350 (plus:DI (match_operand:DI 1 "register_operand" "%0")
351 (match_operand:DI 2 "register_operand" "l")))
352 (clobber (reg:CC CC_REGNUM))
355 "add\\t%Q0, %Q0, %Q2\;adc\\t%R0, %R0, %R2"
356 [(set_attr "length" "4")]
359 (define_insn_and_split "*arm_adddi3"
360 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
361 (plus:DI (match_operand:DI 1 "s_register_operand" "%0, 0")
362 (match_operand:DI 2 "s_register_operand" "r, 0")))
363 (clobber (reg:CC CC_REGNUM))]
364 "TARGET_ARM && !(TARGET_HARD_FLOAT && TARGET_MAVERICK)"
366 "TARGET_ARM && reload_completed"
367 [(parallel [(set (reg:CC_C CC_REGNUM)
368 (compare:CC_C (plus:SI (match_dup 1) (match_dup 2))
370 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
371 (set (match_dup 3) (plus:SI (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))
372 (plus:SI (match_dup 4) (match_dup 5))))]
375 operands[3] = gen_highpart (SImode, operands[0]);
376 operands[0] = gen_lowpart (SImode, operands[0]);
377 operands[4] = gen_highpart (SImode, operands[1]);
378 operands[1] = gen_lowpart (SImode, operands[1]);
379 operands[5] = gen_highpart (SImode, operands[2]);
380 operands[2] = gen_lowpart (SImode, operands[2]);
382 [(set_attr "conds" "clob")
383 (set_attr "length" "8")]
386 (define_insn_and_split "*adddi_sesidi_di"
387 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
388 (plus:DI (sign_extend:DI
389 (match_operand:SI 2 "s_register_operand" "r,r"))
390 (match_operand:DI 1 "s_register_operand" "r,0")))
391 (clobber (reg:CC CC_REGNUM))]
392 "TARGET_ARM && !(TARGET_HARD_FLOAT && TARGET_MAVERICK)"
394 "TARGET_ARM && reload_completed"
395 [(parallel [(set (reg:CC_C CC_REGNUM)
396 (compare:CC_C (plus:SI (match_dup 1) (match_dup 2))
398 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
399 (set (match_dup 3) (plus:SI (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))
400 (plus:SI (ashiftrt:SI (match_dup 2)
405 operands[3] = gen_highpart (SImode, operands[0]);
406 operands[0] = gen_lowpart (SImode, operands[0]);
407 operands[4] = gen_highpart (SImode, operands[1]);
408 operands[1] = gen_lowpart (SImode, operands[1]);
409 operands[2] = gen_lowpart (SImode, operands[2]);
411 [(set_attr "conds" "clob")
412 (set_attr "length" "8")]
415 (define_insn_and_split "*adddi_zesidi_di"
416 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
417 (plus:DI (zero_extend:DI
418 (match_operand:SI 2 "s_register_operand" "r,r"))
419 (match_operand:DI 1 "s_register_operand" "r,0")))
420 (clobber (reg:CC CC_REGNUM))]
421 "TARGET_ARM && !(TARGET_HARD_FLOAT && TARGET_MAVERICK)"
423 "TARGET_ARM && reload_completed"
424 [(parallel [(set (reg:CC_C CC_REGNUM)
425 (compare:CC_C (plus:SI (match_dup 1) (match_dup 2))
427 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
428 (set (match_dup 3) (plus:SI (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))
429 (plus:SI (match_dup 4) (const_int 0))))]
432 operands[3] = gen_highpart (SImode, operands[0]);
433 operands[0] = gen_lowpart (SImode, operands[0]);
434 operands[4] = gen_highpart (SImode, operands[1]);
435 operands[1] = gen_lowpart (SImode, operands[1]);
436 operands[2] = gen_lowpart (SImode, operands[2]);
438 [(set_attr "conds" "clob")
439 (set_attr "length" "8")]
442 (define_expand "addsi3"
443 [(set (match_operand:SI 0 "s_register_operand" "")
444 (plus:SI (match_operand:SI 1 "s_register_operand" "")
445 (match_operand:SI 2 "reg_or_int_operand" "")))]
448 if (TARGET_ARM && GET_CODE (operands[2]) == CONST_INT)
450 arm_split_constant (PLUS, SImode, NULL_RTX,
451 INTVAL (operands[2]), operands[0], operands[1],
452 optimize && !no_new_pseudos);
458 ; If there is a scratch available, this will be faster than synthesizing the
461 [(match_scratch:SI 3 "r")
462 (set (match_operand:SI 0 "arm_general_register_operand" "")
463 (plus:SI (match_operand:SI 1 "arm_general_register_operand" "")
464 (match_operand:SI 2 "const_int_operand" "")))]
466 !(const_ok_for_arm (INTVAL (operands[2]))
467 || const_ok_for_arm (-INTVAL (operands[2])))
468 && const_ok_for_arm (~INTVAL (operands[2]))"
469 [(set (match_dup 3) (match_dup 2))
470 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 3)))]
474 (define_insn_and_split "*arm_addsi3"
475 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
476 (plus:SI (match_operand:SI 1 "s_register_operand" "%r,r,r")
477 (match_operand:SI 2 "reg_or_int_operand" "rI,L,?n")))]
484 GET_CODE (operands[2]) == CONST_INT
485 && !(const_ok_for_arm (INTVAL (operands[2]))
486 || const_ok_for_arm (-INTVAL (operands[2])))"
487 [(clobber (const_int 0))]
489 arm_split_constant (PLUS, SImode, curr_insn,
490 INTVAL (operands[2]), operands[0],
494 [(set_attr "length" "4,4,16")
495 (set_attr "predicable" "yes")]
498 ;; Register group 'k' is a single register group containing only the stack
499 ;; register. Trying to reload it will always fail catastrophically,
500 ;; so never allow those alternatives to match if reloading is needed.
502 (define_insn "*thumb_addsi3"
503 [(set (match_operand:SI 0 "register_operand" "=l,l,l,*r,*h,l,!k")
504 (plus:SI (match_operand:SI 1 "register_operand" "%0,0,l,*0,*0,!k,!k")
505 (match_operand:SI 2 "nonmemory_operand" "I,J,lL,*h,*r,!M,!O")))]
508 static const char * const asms[] =
510 \"add\\t%0, %0, %2\",
511 \"sub\\t%0, %0, #%n2\",
512 \"add\\t%0, %1, %2\",
513 \"add\\t%0, %0, %2\",
514 \"add\\t%0, %0, %2\",
515 \"add\\t%0, %1, %2\",
518 if ((which_alternative == 2 || which_alternative == 6)
519 && GET_CODE (operands[2]) == CONST_INT
520 && INTVAL (operands[2]) < 0)
521 return \"sub\\t%0, %1, #%n2\";
522 return asms[which_alternative];
524 [(set_attr "length" "2")]
527 ;; Reloading and elimination of the frame pointer can
528 ;; sometimes cause this optimization to be missed.
530 [(set (match_operand:SI 0 "arm_general_register_operand" "")
531 (match_operand:SI 1 "const_int_operand" ""))
533 (plus:SI (match_dup 0) (reg:SI SP_REGNUM)))]
535 && (unsigned HOST_WIDE_INT) (INTVAL (operands[1])) < 1024
536 && (INTVAL (operands[1]) & 3) == 0"
537 [(set (match_dup 0) (plus:SI (reg:SI SP_REGNUM) (match_dup 1)))]
541 (define_insn "*addsi3_compare0"
542 [(set (reg:CC_NOOV CC_REGNUM)
544 (plus:SI (match_operand:SI 1 "s_register_operand" "r, r")
545 (match_operand:SI 2 "arm_add_operand" "rI,L"))
547 (set (match_operand:SI 0 "s_register_operand" "=r,r")
548 (plus:SI (match_dup 1) (match_dup 2)))]
552 sub%?s\\t%0, %1, #%n2"
553 [(set_attr "conds" "set")]
556 (define_insn "*addsi3_compare0_scratch"
557 [(set (reg:CC_NOOV CC_REGNUM)
559 (plus:SI (match_operand:SI 0 "s_register_operand" "r, r")
560 (match_operand:SI 1 "arm_add_operand" "rI,L"))
566 [(set_attr "conds" "set")]
569 ;; These patterns are the same ones as the two regular addsi3_compare0
570 ;; patterns, except we write them slightly different - the combiner
571 ;; tends to generate them this way.
572 (define_insn "*addsi3_compare0_for_combiner"
573 [(set (reg:CC CC_REGNUM)
575 (match_operand:SI 1 "s_register_operand" "r,r")
576 (neg:SI (match_operand:SI 2 "arm_add_operand" "rI,L"))))
577 (set (match_operand:SI 0 "s_register_operand" "=r,r")
578 (plus:SI (match_dup 1) (match_dup 2)))]
582 sub%?s\\t%0, %1, #%n2"
583 [(set_attr "conds" "set")]
586 (define_insn "*addsi3_compare0_scratch_for_combiner"
587 [(set (reg:CC CC_REGNUM)
589 (match_operand:SI 0 "s_register_operand" "r,r")
590 (neg:SI (match_operand:SI 1 "arm_add_operand" "rI,L"))))]
595 [(set_attr "conds" "set")]
598 ;; This is the canonicalization of addsi3_compare0_for_combiner when the
599 ;; addend is a constant.
600 (define_insn "*cmpsi2_addneg"
601 [(set (reg:CC CC_REGNUM)
603 (match_operand:SI 1 "s_register_operand" "r,r")
604 (match_operand:SI 2 "arm_addimm_operand" "I,L")))
605 (set (match_operand:SI 0 "s_register_operand" "=r,r")
606 (plus:SI (match_dup 1)
607 (match_operand:SI 3 "arm_addimm_operand" "L,I")))]
608 "TARGET_ARM && INTVAL (operands[2]) == -INTVAL (operands[3])"
611 add%?s\\t%0, %1, #%n2"
612 [(set_attr "conds" "set")]
615 ;; Convert the sequence
617 ;; cmn rd, #1 (equivalent to cmp rd, #-1)
621 ;; bcs dest ((unsigned)rn >= 1)
622 ;; similarly for the beq variant using bcc.
623 ;; This is a common looping idiom (while (n--))
625 [(set (match_operand:SI 0 "arm_general_register_operand" "")
626 (plus:SI (match_operand:SI 1 "arm_general_register_operand" "")
628 (set (match_operand 2 "cc_register" "")
629 (compare (match_dup 0) (const_int -1)))
631 (if_then_else (match_operator 3 "equality_operator"
632 [(match_dup 2) (const_int 0)])
633 (match_operand 4 "" "")
634 (match_operand 5 "" "")))]
635 "TARGET_ARM && peep2_reg_dead_p (3, operands[2])"
639 (match_dup 1) (const_int 1)))
640 (set (match_dup 0) (plus:SI (match_dup 1) (const_int -1)))])
642 (if_then_else (match_op_dup 3 [(match_dup 2) (const_int 0)])
645 "operands[2] = gen_rtx_REG (CCmode, CC_REGNUM);
646 operands[3] = gen_rtx_fmt_ee ((GET_CODE (operands[3]) == NE
649 operands[2], const0_rtx);"
652 ;; The next four insns work because they compare the result with one of
653 ;; the operands, and we know that the use of the condition code is
654 ;; either GEU or LTU, so we can use the carry flag from the addition
655 ;; instead of doing the compare a second time.
656 (define_insn "*addsi3_compare_op1"
657 [(set (reg:CC_C CC_REGNUM)
659 (plus:SI (match_operand:SI 1 "s_register_operand" "r,r")
660 (match_operand:SI 2 "arm_add_operand" "rI,L"))
662 (set (match_operand:SI 0 "s_register_operand" "=r,r")
663 (plus:SI (match_dup 1) (match_dup 2)))]
667 sub%?s\\t%0, %1, #%n2"
668 [(set_attr "conds" "set")]
671 (define_insn "*addsi3_compare_op2"
672 [(set (reg:CC_C CC_REGNUM)
674 (plus:SI (match_operand:SI 1 "s_register_operand" "r,r")
675 (match_operand:SI 2 "arm_add_operand" "rI,L"))
677 (set (match_operand:SI 0 "s_register_operand" "=r,r")
678 (plus:SI (match_dup 1) (match_dup 2)))]
682 sub%?s\\t%0, %1, #%n2"
683 [(set_attr "conds" "set")]
686 (define_insn "*compare_addsi2_op0"
687 [(set (reg:CC_C CC_REGNUM)
689 (plus:SI (match_operand:SI 0 "s_register_operand" "r,r")
690 (match_operand:SI 1 "arm_add_operand" "rI,L"))
696 [(set_attr "conds" "set")]
699 (define_insn "*compare_addsi2_op1"
700 [(set (reg:CC_C CC_REGNUM)
702 (plus:SI (match_operand:SI 0 "s_register_operand" "r,r")
703 (match_operand:SI 1 "arm_add_operand" "rI,L"))
709 [(set_attr "conds" "set")]
712 (define_insn "*addsi3_carryin"
713 [(set (match_operand:SI 0 "s_register_operand" "=r")
714 (plus:SI (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))
715 (plus:SI (match_operand:SI 1 "s_register_operand" "r")
716 (match_operand:SI 2 "arm_rhs_operand" "rI"))))]
719 [(set_attr "conds" "use")]
722 (define_insn "*addsi3_carryin_shift"
723 [(set (match_operand:SI 0 "s_register_operand" "=r")
724 (plus:SI (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))
726 (match_operator:SI 2 "shift_operator"
727 [(match_operand:SI 3 "s_register_operand" "r")
728 (match_operand:SI 4 "reg_or_int_operand" "rM")])
729 (match_operand:SI 1 "s_register_operand" "r"))))]
731 "adc%?\\t%0, %1, %3%S2"
732 [(set_attr "conds" "use")
733 (set (attr "type") (if_then_else (match_operand 4 "const_int_operand" "")
734 (const_string "alu_shift")
735 (const_string "alu_shift_reg")))]
738 (define_insn "*addsi3_carryin_alt1"
739 [(set (match_operand:SI 0 "s_register_operand" "=r")
740 (plus:SI (plus:SI (match_operand:SI 1 "s_register_operand" "r")
741 (match_operand:SI 2 "arm_rhs_operand" "rI"))
742 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
745 [(set_attr "conds" "use")]
748 (define_insn "*addsi3_carryin_alt2"
749 [(set (match_operand:SI 0 "s_register_operand" "=r")
750 (plus:SI (plus:SI (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))
751 (match_operand:SI 1 "s_register_operand" "r"))
752 (match_operand:SI 2 "arm_rhs_operand" "rI")))]
755 [(set_attr "conds" "use")]
758 (define_insn "*addsi3_carryin_alt3"
759 [(set (match_operand:SI 0 "s_register_operand" "=r")
760 (plus:SI (plus:SI (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))
761 (match_operand:SI 2 "arm_rhs_operand" "rI"))
762 (match_operand:SI 1 "s_register_operand" "r")))]
765 [(set_attr "conds" "use")]
768 (define_insn "incscc"
769 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
770 (plus:SI (match_operator:SI 2 "arm_comparison_operator"
771 [(match_operand:CC 3 "cc_register" "") (const_int 0)])
772 (match_operand:SI 1 "s_register_operand" "0,?r")))]
776 mov%D2\\t%0, %1\;add%d2\\t%0, %1, #1"
777 [(set_attr "conds" "use")
778 (set_attr "length" "4,8")]
781 ; transform ((x << y) - 1) to ~(~(x-1) << y) Where X is a constant.
783 [(set (match_operand:SI 0 "s_register_operand" "")
784 (plus:SI (ashift:SI (match_operand:SI 1 "const_int_operand" "")
785 (match_operand:SI 2 "s_register_operand" ""))
787 (clobber (match_operand:SI 3 "s_register_operand" ""))]
789 [(set (match_dup 3) (match_dup 1))
790 (set (match_dup 0) (not:SI (ashift:SI (match_dup 3) (match_dup 2))))]
792 operands[1] = GEN_INT (~(INTVAL (operands[1]) - 1));
795 (define_expand "addsf3"
796 [(set (match_operand:SF 0 "s_register_operand" "")
797 (plus:SF (match_operand:SF 1 "s_register_operand" "")
798 (match_operand:SF 2 "arm_float_add_operand" "")))]
799 "TARGET_ARM && TARGET_HARD_FLOAT"
802 && !cirrus_fp_register (operands[2], SFmode))
803 operands[2] = force_reg (SFmode, operands[2]);
806 (define_expand "adddf3"
807 [(set (match_operand:DF 0 "s_register_operand" "")
808 (plus:DF (match_operand:DF 1 "s_register_operand" "")
809 (match_operand:DF 2 "arm_float_add_operand" "")))]
810 "TARGET_ARM && TARGET_HARD_FLOAT"
813 && !cirrus_fp_register (operands[2], DFmode))
814 operands[2] = force_reg (DFmode, operands[2]);
817 (define_expand "subdi3"
819 [(set (match_operand:DI 0 "s_register_operand" "")
820 (minus:DI (match_operand:DI 1 "s_register_operand" "")
821 (match_operand:DI 2 "s_register_operand" "")))
822 (clobber (reg:CC CC_REGNUM))])]
825 if (TARGET_HARD_FLOAT && TARGET_MAVERICK
827 && cirrus_fp_register (operands[0], DImode)
828 && cirrus_fp_register (operands[1], DImode))
830 emit_insn (gen_cirrus_subdi3 (operands[0], operands[1], operands[2]));
836 if (GET_CODE (operands[1]) != REG)
837 operands[1] = force_reg (SImode, operands[1]);
838 if (GET_CODE (operands[2]) != REG)
839 operands[2] = force_reg (SImode, operands[2]);
844 (define_insn "*arm_subdi3"
845 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r,&r")
846 (minus:DI (match_operand:DI 1 "s_register_operand" "0,r,0")
847 (match_operand:DI 2 "s_register_operand" "r,0,0")))
848 (clobber (reg:CC CC_REGNUM))]
850 "subs\\t%Q0, %Q1, %Q2\;sbc\\t%R0, %R1, %R2"
851 [(set_attr "conds" "clob")
852 (set_attr "length" "8")]
855 (define_insn "*thumb_subdi3"
856 [(set (match_operand:DI 0 "register_operand" "=l")
857 (minus:DI (match_operand:DI 1 "register_operand" "0")
858 (match_operand:DI 2 "register_operand" "l")))
859 (clobber (reg:CC CC_REGNUM))]
861 "sub\\t%Q0, %Q0, %Q2\;sbc\\t%R0, %R0, %R2"
862 [(set_attr "length" "4")]
865 (define_insn "*subdi_di_zesidi"
866 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
867 (minus:DI (match_operand:DI 1 "s_register_operand" "?r,0")
869 (match_operand:SI 2 "s_register_operand" "r,r"))))
870 (clobber (reg:CC CC_REGNUM))]
872 "subs\\t%Q0, %Q1, %2\;sbc\\t%R0, %R1, #0"
873 [(set_attr "conds" "clob")
874 (set_attr "length" "8")]
877 (define_insn "*subdi_di_sesidi"
878 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
879 (minus:DI (match_operand:DI 1 "s_register_operand" "r,0")
881 (match_operand:SI 2 "s_register_operand" "r,r"))))
882 (clobber (reg:CC CC_REGNUM))]
884 "subs\\t%Q0, %Q1, %2\;sbc\\t%R0, %R1, %2, asr #31"
885 [(set_attr "conds" "clob")
886 (set_attr "length" "8")]
889 (define_insn "*subdi_zesidi_di"
890 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
891 (minus:DI (zero_extend:DI
892 (match_operand:SI 2 "s_register_operand" "r,r"))
893 (match_operand:DI 1 "s_register_operand" "?r,0")))
894 (clobber (reg:CC CC_REGNUM))]
896 "rsbs\\t%Q0, %Q1, %2\;rsc\\t%R0, %R1, #0"
897 [(set_attr "conds" "clob")
898 (set_attr "length" "8")]
901 (define_insn "*subdi_sesidi_di"
902 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
903 (minus:DI (sign_extend:DI
904 (match_operand:SI 2 "s_register_operand" "r,r"))
905 (match_operand:DI 1 "s_register_operand" "?r,0")))
906 (clobber (reg:CC CC_REGNUM))]
908 "rsbs\\t%Q0, %Q1, %2\;rsc\\t%R0, %R1, %2, asr #31"
909 [(set_attr "conds" "clob")
910 (set_attr "length" "8")]
913 (define_insn "*subdi_zesidi_zesidi"
914 [(set (match_operand:DI 0 "s_register_operand" "=r")
915 (minus:DI (zero_extend:DI
916 (match_operand:SI 1 "s_register_operand" "r"))
918 (match_operand:SI 2 "s_register_operand" "r"))))
919 (clobber (reg:CC CC_REGNUM))]
921 "subs\\t%Q0, %1, %2\;rsc\\t%R0, %1, %1"
922 [(set_attr "conds" "clob")
923 (set_attr "length" "8")]
926 (define_expand "subsi3"
927 [(set (match_operand:SI 0 "s_register_operand" "")
928 (minus:SI (match_operand:SI 1 "reg_or_int_operand" "")
929 (match_operand:SI 2 "s_register_operand" "")))]
932 if (GET_CODE (operands[1]) == CONST_INT)
936 arm_split_constant (MINUS, SImode, NULL_RTX,
937 INTVAL (operands[1]), operands[0],
938 operands[2], optimize && !no_new_pseudos);
941 else /* TARGET_THUMB */
942 operands[1] = force_reg (SImode, operands[1]);
947 (define_insn "*thumb_subsi3_insn"
948 [(set (match_operand:SI 0 "register_operand" "=l")
949 (minus:SI (match_operand:SI 1 "register_operand" "l")
950 (match_operand:SI 2 "register_operand" "l")))]
953 [(set_attr "length" "2")]
956 (define_insn_and_split "*arm_subsi3_insn"
957 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
958 (minus:SI (match_operand:SI 1 "reg_or_int_operand" "rI,?n")
959 (match_operand:SI 2 "s_register_operand" "r,r")))]
965 && GET_CODE (operands[1]) == CONST_INT
966 && !const_ok_for_arm (INTVAL (operands[1]))"
967 [(clobber (const_int 0))]
969 arm_split_constant (MINUS, SImode, curr_insn,
970 INTVAL (operands[1]), operands[0], operands[2], 0);
973 [(set_attr "length" "4,16")
974 (set_attr "predicable" "yes")]
978 [(match_scratch:SI 3 "r")
979 (set (match_operand:SI 0 "arm_general_register_operand" "")
980 (minus:SI (match_operand:SI 1 "const_int_operand" "")
981 (match_operand:SI 2 "arm_general_register_operand" "")))]
983 && !const_ok_for_arm (INTVAL (operands[1]))
984 && const_ok_for_arm (~INTVAL (operands[1]))"
985 [(set (match_dup 3) (match_dup 1))
986 (set (match_dup 0) (minus:SI (match_dup 3) (match_dup 2)))]
990 (define_insn "*subsi3_compare0"
991 [(set (reg:CC_NOOV CC_REGNUM)
993 (minus:SI (match_operand:SI 1 "arm_rhs_operand" "r,I")
994 (match_operand:SI 2 "arm_rhs_operand" "rI,r"))
996 (set (match_operand:SI 0 "s_register_operand" "=r,r")
997 (minus:SI (match_dup 1) (match_dup 2)))]
1001 rsb%?s\\t%0, %2, %1"
1002 [(set_attr "conds" "set")]
1005 (define_insn "decscc"
1006 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
1007 (minus:SI (match_operand:SI 1 "s_register_operand" "0,?r")
1008 (match_operator:SI 2 "arm_comparison_operator"
1009 [(match_operand 3 "cc_register" "") (const_int 0)])))]
1013 mov%D2\\t%0, %1\;sub%d2\\t%0, %1, #1"
1014 [(set_attr "conds" "use")
1015 (set_attr "length" "*,8")]
1018 (define_expand "subsf3"
1019 [(set (match_operand:SF 0 "s_register_operand" "")
1020 (minus:SF (match_operand:SF 1 "arm_float_rhs_operand" "")
1021 (match_operand:SF 2 "arm_float_rhs_operand" "")))]
1022 "TARGET_ARM && TARGET_HARD_FLOAT"
1024 if (TARGET_MAVERICK)
1026 if (!cirrus_fp_register (operands[1], SFmode))
1027 operands[1] = force_reg (SFmode, operands[1]);
1028 if (!cirrus_fp_register (operands[2], SFmode))
1029 operands[2] = force_reg (SFmode, operands[2]);
1033 (define_expand "subdf3"
1034 [(set (match_operand:DF 0 "s_register_operand" "")
1035 (minus:DF (match_operand:DF 1 "arm_float_rhs_operand" "")
1036 (match_operand:DF 2 "arm_float_rhs_operand" "")))]
1037 "TARGET_ARM && TARGET_HARD_FLOAT"
1039 if (TARGET_MAVERICK)
1041 if (!cirrus_fp_register (operands[1], DFmode))
1042 operands[1] = force_reg (DFmode, operands[1]);
1043 if (!cirrus_fp_register (operands[2], DFmode))
1044 operands[2] = force_reg (DFmode, operands[2]);
1049 ;; Multiplication insns
1051 (define_expand "mulsi3"
1052 [(set (match_operand:SI 0 "s_register_operand" "")
1053 (mult:SI (match_operand:SI 2 "s_register_operand" "")
1054 (match_operand:SI 1 "s_register_operand" "")))]
1059 ;; Use `&' and then `0' to prevent the operands 0 and 1 being the same
1060 (define_insn "*arm_mulsi3"
1061 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r")
1062 (mult:SI (match_operand:SI 2 "s_register_operand" "r,r")
1063 (match_operand:SI 1 "s_register_operand" "%?r,0")))]
1065 "mul%?\\t%0, %2, %1"
1066 [(set_attr "insn" "mul")
1067 (set_attr "predicable" "yes")]
1070 ; Unfortunately with the Thumb the '&'/'0' trick can fails when operands
1071 ; 1 and 2; are the same, because reload will make operand 0 match
1072 ; operand 1 without realizing that this conflicts with operand 2. We fix
1073 ; this by adding another alternative to match this case, and then `reload'
1074 ; it ourselves. This alternative must come first.
1075 (define_insn "*thumb_mulsi3"
1076 [(set (match_operand:SI 0 "register_operand" "=&l,&l,&l")
1077 (mult:SI (match_operand:SI 1 "register_operand" "%l,*h,0")
1078 (match_operand:SI 2 "register_operand" "l,l,l")))]
1081 if (which_alternative < 2)
1082 return \"mov\\t%0, %1\;mul\\t%0, %0, %2\";
1084 return \"mul\\t%0, %0, %2\";
1086 [(set_attr "length" "4,4,2")
1087 (set_attr "insn" "mul")]
1090 (define_insn "*mulsi3_compare0"
1091 [(set (reg:CC_NOOV CC_REGNUM)
1092 (compare:CC_NOOV (mult:SI
1093 (match_operand:SI 2 "s_register_operand" "r,r")
1094 (match_operand:SI 1 "s_register_operand" "%?r,0"))
1096 (set (match_operand:SI 0 "s_register_operand" "=&r,&r")
1097 (mult:SI (match_dup 2) (match_dup 1)))]
1098 "TARGET_ARM && !arm_arch_xscale"
1099 "mul%?s\\t%0, %2, %1"
1100 [(set_attr "conds" "set")
1101 (set_attr "insn" "muls")]
1104 (define_insn "*mulsi_compare0_scratch"
1105 [(set (reg:CC_NOOV CC_REGNUM)
1106 (compare:CC_NOOV (mult:SI
1107 (match_operand:SI 2 "s_register_operand" "r,r")
1108 (match_operand:SI 1 "s_register_operand" "%?r,0"))
1110 (clobber (match_scratch:SI 0 "=&r,&r"))]
1111 "TARGET_ARM && !arm_arch_xscale"
1112 "mul%?s\\t%0, %2, %1"
1113 [(set_attr "conds" "set")
1114 (set_attr "insn" "muls")]
1117 ;; Unnamed templates to match MLA instruction.
1119 (define_insn "*mulsi3addsi"
1120 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r,&r")
1122 (mult:SI (match_operand:SI 2 "s_register_operand" "r,r,r,r")
1123 (match_operand:SI 1 "s_register_operand" "%r,0,r,0"))
1124 (match_operand:SI 3 "s_register_operand" "?r,r,0,0")))]
1126 "mla%?\\t%0, %2, %1, %3"
1127 [(set_attr "insn" "mla")
1128 (set_attr "predicable" "yes")]
1131 (define_insn "*mulsi3addsi_compare0"
1132 [(set (reg:CC_NOOV CC_REGNUM)
1135 (match_operand:SI 2 "s_register_operand" "r,r,r,r")
1136 (match_operand:SI 1 "s_register_operand" "%r,0,r,0"))
1137 (match_operand:SI 3 "s_register_operand" "?r,r,0,0"))
1139 (set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r,&r")
1140 (plus:SI (mult:SI (match_dup 2) (match_dup 1))
1142 "TARGET_ARM && !arm_arch_xscale"
1143 "mla%?s\\t%0, %2, %1, %3"
1144 [(set_attr "conds" "set")
1145 (set_attr "insn" "mlas")]
1148 (define_insn "*mulsi3addsi_compare0_scratch"
1149 [(set (reg:CC_NOOV CC_REGNUM)
1152 (match_operand:SI 2 "s_register_operand" "r,r,r,r")
1153 (match_operand:SI 1 "s_register_operand" "%r,0,r,0"))
1154 (match_operand:SI 3 "s_register_operand" "?r,r,0,0"))
1156 (clobber (match_scratch:SI 0 "=&r,&r,&r,&r"))]
1157 "TARGET_ARM && !arm_arch_xscale"
1158 "mla%?s\\t%0, %2, %1, %3"
1159 [(set_attr "conds" "set")
1160 (set_attr "insn" "mlas")]
1163 ;; Unnamed template to match long long multiply-accumulate (smlal)
1165 (define_insn "*mulsidi3adddi"
1166 [(set (match_operand:DI 0 "s_register_operand" "=&r")
1169 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "%r"))
1170 (sign_extend:DI (match_operand:SI 3 "s_register_operand" "r")))
1171 (match_operand:DI 1 "s_register_operand" "0")))]
1172 "TARGET_ARM && arm_arch3m"
1173 "smlal%?\\t%Q0, %R0, %3, %2"
1174 [(set_attr "insn" "smlal")
1175 (set_attr "predicable" "yes")]
1178 (define_insn "mulsidi3"
1179 [(set (match_operand:DI 0 "s_register_operand" "=&r")
1181 (sign_extend:DI (match_operand:SI 1 "s_register_operand" "%r"))
1182 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))]
1183 "TARGET_ARM && arm_arch3m"
1184 "smull%?\\t%Q0, %R0, %1, %2"
1185 [(set_attr "insn" "smull")
1186 (set_attr "predicable" "yes")]
1189 (define_insn "umulsidi3"
1190 [(set (match_operand:DI 0 "s_register_operand" "=&r")
1192 (zero_extend:DI (match_operand:SI 1 "s_register_operand" "%r"))
1193 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))]
1194 "TARGET_ARM && arm_arch3m"
1195 "umull%?\\t%Q0, %R0, %1, %2"
1196 [(set_attr "insn" "umull")
1197 (set_attr "predicable" "yes")]
1200 ;; Unnamed template to match long long unsigned multiply-accumulate (umlal)
1202 (define_insn "*umulsidi3adddi"
1203 [(set (match_operand:DI 0 "s_register_operand" "=&r")
1206 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "%r"))
1207 (zero_extend:DI (match_operand:SI 3 "s_register_operand" "r")))
1208 (match_operand:DI 1 "s_register_operand" "0")))]
1209 "TARGET_ARM && arm_arch3m"
1210 "umlal%?\\t%Q0, %R0, %3, %2"
1211 [(set_attr "insn" "umlal")
1212 (set_attr "predicable" "yes")]
1215 (define_insn "smulsi3_highpart"
1216 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r")
1220 (sign_extend:DI (match_operand:SI 1 "s_register_operand" "%r,0"))
1221 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r,r")))
1223 (clobber (match_scratch:SI 3 "=&r,&r"))]
1224 "TARGET_ARM && arm_arch3m"
1225 "smull%?\\t%3, %0, %2, %1"
1226 [(set_attr "insn" "smull")
1227 (set_attr "predicable" "yes")]
1230 (define_insn "umulsi3_highpart"
1231 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r")
1235 (zero_extend:DI (match_operand:SI 1 "s_register_operand" "%r,0"))
1236 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r,r")))
1238 (clobber (match_scratch:SI 3 "=&r,&r"))]
1239 "TARGET_ARM && arm_arch3m"
1240 "umull%?\\t%3, %0, %2, %1"
1241 [(set_attr "insn" "umull")
1242 (set_attr "predicable" "yes")]
1245 (define_insn "mulhisi3"
1246 [(set (match_operand:SI 0 "s_register_operand" "=r")
1247 (mult:SI (sign_extend:SI
1248 (match_operand:HI 1 "s_register_operand" "%r"))
1250 (match_operand:HI 2 "s_register_operand" "r"))))]
1251 "TARGET_ARM && arm_arch5e"
1252 "smulbb%?\\t%0, %1, %2"
1253 [(set_attr "insn" "smulxy")
1254 (set_attr "predicable" "yes")]
1257 (define_insn "*mulhisi3tb"
1258 [(set (match_operand:SI 0 "s_register_operand" "=r")
1259 (mult:SI (ashiftrt:SI
1260 (match_operand:SI 1 "s_register_operand" "r")
1263 (match_operand:HI 2 "s_register_operand" "r"))))]
1264 "TARGET_ARM && arm_arch5e"
1265 "smultb%?\\t%0, %1, %2"
1266 [(set_attr "insn" "smulxy")
1267 (set_attr "predicable" "yes")]
1270 (define_insn "*mulhisi3bt"
1271 [(set (match_operand:SI 0 "s_register_operand" "=r")
1272 (mult:SI (sign_extend:SI
1273 (match_operand:HI 1 "s_register_operand" "r"))
1275 (match_operand:SI 2 "s_register_operand" "r")
1277 "TARGET_ARM && arm_arch5e"
1278 "smulbt%?\\t%0, %1, %2"
1279 [(set_attr "insn" "smulxy")
1280 (set_attr "predicable" "yes")]
1283 (define_insn "*mulhisi3tt"
1284 [(set (match_operand:SI 0 "s_register_operand" "=r")
1285 (mult:SI (ashiftrt:SI
1286 (match_operand:SI 1 "s_register_operand" "r")
1289 (match_operand:SI 2 "s_register_operand" "r")
1291 "TARGET_ARM && arm_arch5e"
1292 "smultt%?\\t%0, %1, %2"
1293 [(set_attr "insn" "smulxy")
1294 (set_attr "predicable" "yes")]
1297 (define_insn "*mulhisi3addsi"
1298 [(set (match_operand:SI 0 "s_register_operand" "=r")
1299 (plus:SI (match_operand:SI 1 "s_register_operand" "r")
1300 (mult:SI (sign_extend:SI
1301 (match_operand:HI 2 "s_register_operand" "%r"))
1303 (match_operand:HI 3 "s_register_operand" "r")))))]
1304 "TARGET_ARM && arm_arch5e"
1305 "smlabb%?\\t%0, %2, %3, %1"
1306 [(set_attr "insn" "smlaxy")
1307 (set_attr "predicable" "yes")]
1310 (define_insn "*mulhidi3adddi"
1311 [(set (match_operand:DI 0 "s_register_operand" "=r")
1313 (match_operand:DI 1 "s_register_operand" "0")
1314 (mult:DI (sign_extend:DI
1315 (match_operand:HI 2 "s_register_operand" "%r"))
1317 (match_operand:HI 3 "s_register_operand" "r")))))]
1318 "TARGET_ARM && arm_arch5e"
1319 "smlalbb%?\\t%Q0, %R0, %2, %3"
1320 [(set_attr "insn" "smlalxy")
1321 (set_attr "predicable" "yes")])
1323 (define_expand "mulsf3"
1324 [(set (match_operand:SF 0 "s_register_operand" "")
1325 (mult:SF (match_operand:SF 1 "s_register_operand" "")
1326 (match_operand:SF 2 "arm_float_rhs_operand" "")))]
1327 "TARGET_ARM && TARGET_HARD_FLOAT"
1330 && !cirrus_fp_register (operands[2], SFmode))
1331 operands[2] = force_reg (SFmode, operands[2]);
1334 (define_expand "muldf3"
1335 [(set (match_operand:DF 0 "s_register_operand" "")
1336 (mult:DF (match_operand:DF 1 "s_register_operand" "")
1337 (match_operand:DF 2 "arm_float_rhs_operand" "")))]
1338 "TARGET_ARM && TARGET_HARD_FLOAT"
1341 && !cirrus_fp_register (operands[2], DFmode))
1342 operands[2] = force_reg (DFmode, operands[2]);
1347 (define_expand "divsf3"
1348 [(set (match_operand:SF 0 "s_register_operand" "")
1349 (div:SF (match_operand:SF 1 "arm_float_rhs_operand" "")
1350 (match_operand:SF 2 "arm_float_rhs_operand" "")))]
1351 "TARGET_ARM && TARGET_HARD_FLOAT && (TARGET_FPA || TARGET_VFP)"
1354 (define_expand "divdf3"
1355 [(set (match_operand:DF 0 "s_register_operand" "")
1356 (div:DF (match_operand:DF 1 "arm_float_rhs_operand" "")
1357 (match_operand:DF 2 "arm_float_rhs_operand" "")))]
1358 "TARGET_ARM && TARGET_HARD_FLOAT && (TARGET_FPA || TARGET_VFP)"
1363 (define_expand "modsf3"
1364 [(set (match_operand:SF 0 "s_register_operand" "")
1365 (mod:SF (match_operand:SF 1 "s_register_operand" "")
1366 (match_operand:SF 2 "arm_float_rhs_operand" "")))]
1367 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
1370 (define_expand "moddf3"
1371 [(set (match_operand:DF 0 "s_register_operand" "")
1372 (mod:DF (match_operand:DF 1 "s_register_operand" "")
1373 (match_operand:DF 2 "arm_float_rhs_operand" "")))]
1374 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
1377 ;; Boolean and,ior,xor insns
1379 ;; Split up double word logical operations
1381 ;; Split up simple DImode logical operations. Simply perform the logical
1382 ;; operation on the upper and lower halves of the registers.
1384 [(set (match_operand:DI 0 "s_register_operand" "")
1385 (match_operator:DI 6 "logical_binary_operator"
1386 [(match_operand:DI 1 "s_register_operand" "")
1387 (match_operand:DI 2 "s_register_operand" "")]))]
1388 "TARGET_ARM && reload_completed && ! IS_IWMMXT_REGNUM (REGNO (operands[0]))"
1389 [(set (match_dup 0) (match_op_dup:SI 6 [(match_dup 1) (match_dup 2)]))
1390 (set (match_dup 3) (match_op_dup:SI 6 [(match_dup 4) (match_dup 5)]))]
1393 operands[3] = gen_highpart (SImode, operands[0]);
1394 operands[0] = gen_lowpart (SImode, operands[0]);
1395 operands[4] = gen_highpart (SImode, operands[1]);
1396 operands[1] = gen_lowpart (SImode, operands[1]);
1397 operands[5] = gen_highpart (SImode, operands[2]);
1398 operands[2] = gen_lowpart (SImode, operands[2]);
1403 [(set (match_operand:DI 0 "s_register_operand" "")
1404 (match_operator:DI 6 "logical_binary_operator"
1405 [(sign_extend:DI (match_operand:SI 2 "s_register_operand" ""))
1406 (match_operand:DI 1 "s_register_operand" "")]))]
1407 "TARGET_ARM && reload_completed"
1408 [(set (match_dup 0) (match_op_dup:SI 6 [(match_dup 1) (match_dup 2)]))
1409 (set (match_dup 3) (match_op_dup:SI 6
1410 [(ashiftrt:SI (match_dup 2) (const_int 31))
1414 operands[3] = gen_highpart (SImode, operands[0]);
1415 operands[0] = gen_lowpart (SImode, operands[0]);
1416 operands[4] = gen_highpart (SImode, operands[1]);
1417 operands[1] = gen_lowpart (SImode, operands[1]);
1418 operands[5] = gen_highpart (SImode, operands[2]);
1419 operands[2] = gen_lowpart (SImode, operands[2]);
1423 ;; The zero extend of operand 2 means we can just copy the high part of
1424 ;; operand1 into operand0.
1426 [(set (match_operand:DI 0 "s_register_operand" "")
1428 (zero_extend:DI (match_operand:SI 2 "s_register_operand" ""))
1429 (match_operand:DI 1 "s_register_operand" "")))]
1430 "TARGET_ARM && operands[0] != operands[1] && reload_completed"
1431 [(set (match_dup 0) (ior:SI (match_dup 1) (match_dup 2)))
1432 (set (match_dup 3) (match_dup 4))]
1435 operands[4] = gen_highpart (SImode, operands[1]);
1436 operands[3] = gen_highpart (SImode, operands[0]);
1437 operands[0] = gen_lowpart (SImode, operands[0]);
1438 operands[1] = gen_lowpart (SImode, operands[1]);
1442 ;; The zero extend of operand 2 means we can just copy the high part of
1443 ;; operand1 into operand0.
1445 [(set (match_operand:DI 0 "s_register_operand" "")
1447 (zero_extend:DI (match_operand:SI 2 "s_register_operand" ""))
1448 (match_operand:DI 1 "s_register_operand" "")))]
1449 "TARGET_ARM && operands[0] != operands[1] && reload_completed"
1450 [(set (match_dup 0) (xor:SI (match_dup 1) (match_dup 2)))
1451 (set (match_dup 3) (match_dup 4))]
1454 operands[4] = gen_highpart (SImode, operands[1]);
1455 operands[3] = gen_highpart (SImode, operands[0]);
1456 operands[0] = gen_lowpart (SImode, operands[0]);
1457 operands[1] = gen_lowpart (SImode, operands[1]);
1461 (define_insn "anddi3"
1462 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1463 (and:DI (match_operand:DI 1 "s_register_operand" "%0,r")
1464 (match_operand:DI 2 "s_register_operand" "r,r")))]
1465 "TARGET_ARM && ! TARGET_IWMMXT"
1467 [(set_attr "length" "8")]
1470 (define_insn_and_split "*anddi_zesidi_di"
1471 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1472 (and:DI (zero_extend:DI
1473 (match_operand:SI 2 "s_register_operand" "r,r"))
1474 (match_operand:DI 1 "s_register_operand" "?r,0")))]
1477 "TARGET_ARM && reload_completed"
1478 ; The zero extend of operand 2 clears the high word of the output
1480 [(set (match_dup 0) (and:SI (match_dup 1) (match_dup 2)))
1481 (set (match_dup 3) (const_int 0))]
1484 operands[3] = gen_highpart (SImode, operands[0]);
1485 operands[0] = gen_lowpart (SImode, operands[0]);
1486 operands[1] = gen_lowpart (SImode, operands[1]);
1488 [(set_attr "length" "8")]
1491 (define_insn "*anddi_sesdi_di"
1492 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1493 (and:DI (sign_extend:DI
1494 (match_operand:SI 2 "s_register_operand" "r,r"))
1495 (match_operand:DI 1 "s_register_operand" "?r,0")))]
1498 [(set_attr "length" "8")]
1501 (define_expand "andsi3"
1502 [(set (match_operand:SI 0 "s_register_operand" "")
1503 (and:SI (match_operand:SI 1 "s_register_operand" "")
1504 (match_operand:SI 2 "reg_or_int_operand" "")))]
1509 if (GET_CODE (operands[2]) == CONST_INT)
1511 arm_split_constant (AND, SImode, NULL_RTX,
1512 INTVAL (operands[2]), operands[0],
1513 operands[1], optimize && !no_new_pseudos);
1518 else /* TARGET_THUMB */
1520 if (GET_CODE (operands[2]) != CONST_INT)
1521 operands[2] = force_reg (SImode, operands[2]);
1526 if (((unsigned HOST_WIDE_INT) ~INTVAL (operands[2])) < 256)
1528 operands[2] = force_reg (SImode,
1529 GEN_INT (~INTVAL (operands[2])));
1531 emit_insn (gen_bicsi3 (operands[0], operands[2], operands[1]));
1536 for (i = 9; i <= 31; i++)
1538 if ((((HOST_WIDE_INT) 1) << i) - 1 == INTVAL (operands[2]))
1540 emit_insn (gen_extzv (operands[0], operands[1], GEN_INT (i),
1544 else if ((((HOST_WIDE_INT) 1) << i) - 1
1545 == ~INTVAL (operands[2]))
1547 rtx shift = GEN_INT (i);
1548 rtx reg = gen_reg_rtx (SImode);
1550 emit_insn (gen_lshrsi3 (reg, operands[1], shift));
1551 emit_insn (gen_ashlsi3 (operands[0], reg, shift));
1557 operands[2] = force_reg (SImode, operands[2]);
1563 (define_insn_and_split "*arm_andsi3_insn"
1564 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
1565 (and:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
1566 (match_operand:SI 2 "reg_or_int_operand" "rI,K,?n")))]
1570 bic%?\\t%0, %1, #%B2
1573 && GET_CODE (operands[2]) == CONST_INT
1574 && !(const_ok_for_arm (INTVAL (operands[2]))
1575 || const_ok_for_arm (~INTVAL (operands[2])))"
1576 [(clobber (const_int 0))]
1578 arm_split_constant (AND, SImode, curr_insn,
1579 INTVAL (operands[2]), operands[0], operands[1], 0);
1582 [(set_attr "length" "4,4,16")
1583 (set_attr "predicable" "yes")]
1586 (define_insn "*thumb_andsi3_insn"
1587 [(set (match_operand:SI 0 "register_operand" "=l")
1588 (and:SI (match_operand:SI 1 "register_operand" "%0")
1589 (match_operand:SI 2 "register_operand" "l")))]
1592 [(set_attr "length" "2")]
1595 (define_insn "*andsi3_compare0"
1596 [(set (reg:CC_NOOV CC_REGNUM)
1598 (and:SI (match_operand:SI 1 "s_register_operand" "r,r")
1599 (match_operand:SI 2 "arm_not_operand" "rI,K"))
1601 (set (match_operand:SI 0 "s_register_operand" "=r,r")
1602 (and:SI (match_dup 1) (match_dup 2)))]
1606 bic%?s\\t%0, %1, #%B2"
1607 [(set_attr "conds" "set")]
1610 (define_insn "*andsi3_compare0_scratch"
1611 [(set (reg:CC_NOOV CC_REGNUM)
1613 (and:SI (match_operand:SI 0 "s_register_operand" "r,r")
1614 (match_operand:SI 1 "arm_not_operand" "rI,K"))
1616 (clobber (match_scratch:SI 2 "=X,r"))]
1620 bic%?s\\t%2, %0, #%B1"
1621 [(set_attr "conds" "set")]
1624 (define_insn "*zeroextractsi_compare0_scratch"
1625 [(set (reg:CC_NOOV CC_REGNUM)
1626 (compare:CC_NOOV (zero_extract:SI
1627 (match_operand:SI 0 "s_register_operand" "r")
1628 (match_operand 1 "const_int_operand" "n")
1629 (match_operand 2 "const_int_operand" "n"))
1632 && (INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) < 32
1633 && INTVAL (operands[1]) > 0
1634 && INTVAL (operands[1]) + (INTVAL (operands[2]) & 1) <= 8
1635 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32)"
1637 operands[1] = GEN_INT (((1 << INTVAL (operands[1])) - 1)
1638 << INTVAL (operands[2]));
1639 output_asm_insn (\"tst%?\\t%0, %1\", operands);
1642 [(set_attr "conds" "set")]
1645 (define_insn_and_split "*ne_zeroextractsi"
1646 [(set (match_operand:SI 0 "s_register_operand" "=r")
1647 (ne:SI (zero_extract:SI
1648 (match_operand:SI 1 "s_register_operand" "r")
1649 (match_operand:SI 2 "const_int_operand" "n")
1650 (match_operand:SI 3 "const_int_operand" "n"))
1652 (clobber (reg:CC CC_REGNUM))]
1654 && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
1655 && INTVAL (operands[2]) > 0
1656 && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
1657 && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)"
1660 && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
1661 && INTVAL (operands[2]) > 0
1662 && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
1663 && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)"
1664 [(parallel [(set (reg:CC_NOOV CC_REGNUM)
1665 (compare:CC_NOOV (and:SI (match_dup 1) (match_dup 2))
1667 (set (match_dup 0) (and:SI (match_dup 1) (match_dup 2)))])
1669 (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
1670 (match_dup 0) (const_int 1)))]
1672 operands[2] = GEN_INT (((1 << INTVAL (operands[2])) - 1)
1673 << INTVAL (operands[3]));
1675 [(set_attr "conds" "clob")
1676 (set_attr "length" "8")]
1679 (define_insn_and_split "*ne_zeroextractsi_shifted"
1680 [(set (match_operand:SI 0 "s_register_operand" "=r")
1681 (ne:SI (zero_extract:SI
1682 (match_operand:SI 1 "s_register_operand" "r")
1683 (match_operand:SI 2 "const_int_operand" "n")
1686 (clobber (reg:CC CC_REGNUM))]
1690 [(parallel [(set (reg:CC_NOOV CC_REGNUM)
1691 (compare:CC_NOOV (ashift:SI (match_dup 1) (match_dup 2))
1693 (set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 2)))])
1695 (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
1696 (match_dup 0) (const_int 1)))]
1698 operands[2] = GEN_INT (32 - INTVAL (operands[2]));
1700 [(set_attr "conds" "clob")
1701 (set_attr "length" "8")]
1704 (define_insn_and_split "*ite_ne_zeroextractsi"
1705 [(set (match_operand:SI 0 "s_register_operand" "=r")
1706 (if_then_else:SI (ne (zero_extract:SI
1707 (match_operand:SI 1 "s_register_operand" "r")
1708 (match_operand:SI 2 "const_int_operand" "n")
1709 (match_operand:SI 3 "const_int_operand" "n"))
1711 (match_operand:SI 4 "arm_not_operand" "rIK")
1713 (clobber (reg:CC CC_REGNUM))]
1715 && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
1716 && INTVAL (operands[2]) > 0
1717 && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
1718 && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)
1719 && !reg_overlap_mentioned_p (operands[0], operands[4])"
1722 && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
1723 && INTVAL (operands[2]) > 0
1724 && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
1725 && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)
1726 && !reg_overlap_mentioned_p (operands[0], operands[4])"
1727 [(parallel [(set (reg:CC_NOOV CC_REGNUM)
1728 (compare:CC_NOOV (and:SI (match_dup 1) (match_dup 2))
1730 (set (match_dup 0) (and:SI (match_dup 1) (match_dup 2)))])
1732 (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
1733 (match_dup 0) (match_dup 4)))]
1735 operands[2] = GEN_INT (((1 << INTVAL (operands[2])) - 1)
1736 << INTVAL (operands[3]));
1738 [(set_attr "conds" "clob")
1739 (set_attr "length" "8")]
1742 (define_insn_and_split "*ite_ne_zeroextractsi_shifted"
1743 [(set (match_operand:SI 0 "s_register_operand" "=r")
1744 (if_then_else:SI (ne (zero_extract:SI
1745 (match_operand:SI 1 "s_register_operand" "r")
1746 (match_operand:SI 2 "const_int_operand" "n")
1749 (match_operand:SI 3 "arm_not_operand" "rIK")
1751 (clobber (reg:CC CC_REGNUM))]
1752 "TARGET_ARM && !reg_overlap_mentioned_p (operands[0], operands[3])"
1754 "TARGET_ARM && !reg_overlap_mentioned_p (operands[0], operands[3])"
1755 [(parallel [(set (reg:CC_NOOV CC_REGNUM)
1756 (compare:CC_NOOV (ashift:SI (match_dup 1) (match_dup 2))
1758 (set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 2)))])
1760 (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
1761 (match_dup 0) (match_dup 3)))]
1763 operands[2] = GEN_INT (32 - INTVAL (operands[2]));
1765 [(set_attr "conds" "clob")
1766 (set_attr "length" "8")]
1770 [(set (match_operand:SI 0 "s_register_operand" "")
1771 (zero_extract:SI (match_operand:SI 1 "s_register_operand" "")
1772 (match_operand:SI 2 "const_int_operand" "")
1773 (match_operand:SI 3 "const_int_operand" "")))
1774 (clobber (match_operand:SI 4 "s_register_operand" ""))]
1776 [(set (match_dup 4) (ashift:SI (match_dup 1) (match_dup 2)))
1777 (set (match_dup 0) (lshiftrt:SI (match_dup 4) (match_dup 3)))]
1779 HOST_WIDE_INT temp = INTVAL (operands[2]);
1781 operands[2] = GEN_INT (32 - temp - INTVAL (operands[3]));
1782 operands[3] = GEN_INT (32 - temp);
1787 [(set (match_operand:SI 0 "s_register_operand" "")
1788 (match_operator:SI 1 "shiftable_operator"
1789 [(zero_extract:SI (match_operand:SI 2 "s_register_operand" "")
1790 (match_operand:SI 3 "const_int_operand" "")
1791 (match_operand:SI 4 "const_int_operand" ""))
1792 (match_operand:SI 5 "s_register_operand" "")]))
1793 (clobber (match_operand:SI 6 "s_register_operand" ""))]
1795 [(set (match_dup 6) (ashift:SI (match_dup 2) (match_dup 3)))
1798 [(lshiftrt:SI (match_dup 6) (match_dup 4))
1801 HOST_WIDE_INT temp = INTVAL (operands[3]);
1803 operands[3] = GEN_INT (32 - temp - INTVAL (operands[4]));
1804 operands[4] = GEN_INT (32 - temp);
1809 [(set (match_operand:SI 0 "s_register_operand" "")
1810 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "")
1811 (match_operand:SI 2 "const_int_operand" "")
1812 (match_operand:SI 3 "const_int_operand" "")))]
1814 [(set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 2)))
1815 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (match_dup 3)))]
1817 HOST_WIDE_INT temp = INTVAL (operands[2]);
1819 operands[2] = GEN_INT (32 - temp - INTVAL (operands[3]));
1820 operands[3] = GEN_INT (32 - temp);
1825 [(set (match_operand:SI 0 "s_register_operand" "")
1826 (match_operator:SI 1 "shiftable_operator"
1827 [(sign_extract:SI (match_operand:SI 2 "s_register_operand" "")
1828 (match_operand:SI 3 "const_int_operand" "")
1829 (match_operand:SI 4 "const_int_operand" ""))
1830 (match_operand:SI 5 "s_register_operand" "")]))
1831 (clobber (match_operand:SI 6 "s_register_operand" ""))]
1833 [(set (match_dup 6) (ashift:SI (match_dup 2) (match_dup 3)))
1836 [(ashiftrt:SI (match_dup 6) (match_dup 4))
1839 HOST_WIDE_INT temp = INTVAL (operands[3]);
1841 operands[3] = GEN_INT (32 - temp - INTVAL (operands[4]));
1842 operands[4] = GEN_INT (32 - temp);
1846 ;;; ??? This pattern is bogus. If operand3 has bits outside the range
1847 ;;; represented by the bitfield, then this will produce incorrect results.
1848 ;;; Somewhere, the value needs to be truncated. On targets like the m68k,
1849 ;;; which have a real bit-field insert instruction, the truncation happens
1850 ;;; in the bit-field insert instruction itself. Since arm does not have a
1851 ;;; bit-field insert instruction, we would have to emit code here to truncate
1852 ;;; the value before we insert. This loses some of the advantage of having
1853 ;;; this insv pattern, so this pattern needs to be reevalutated.
1855 (define_expand "insv"
1856 [(set (zero_extract:SI (match_operand:SI 0 "s_register_operand" "")
1857 (match_operand:SI 1 "general_operand" "")
1858 (match_operand:SI 2 "general_operand" ""))
1859 (match_operand:SI 3 "reg_or_int_operand" ""))]
1863 int start_bit = INTVAL (operands[2]);
1864 int width = INTVAL (operands[1]);
1865 HOST_WIDE_INT mask = (((HOST_WIDE_INT)1) << width) - 1;
1866 rtx target, subtarget;
1868 target = operands[0];
1869 /* Avoid using a subreg as a subtarget, and avoid writing a paradoxical
1870 subreg as the final target. */
1871 if (GET_CODE (target) == SUBREG)
1873 subtarget = gen_reg_rtx (SImode);
1874 if (GET_MODE_SIZE (GET_MODE (SUBREG_REG (target)))
1875 < GET_MODE_SIZE (SImode))
1876 target = SUBREG_REG (target);
1881 if (GET_CODE (operands[3]) == CONST_INT)
1883 /* Since we are inserting a known constant, we may be able to
1884 reduce the number of bits that we have to clear so that
1885 the mask becomes simple. */
1886 /* ??? This code does not check to see if the new mask is actually
1887 simpler. It may not be. */
1888 rtx op1 = gen_reg_rtx (SImode);
1889 /* ??? Truncate operand3 to fit in the bitfield. See comment before
1890 start of this pattern. */
1891 HOST_WIDE_INT op3_value = mask & INTVAL (operands[3]);
1892 HOST_WIDE_INT mask2 = ((mask & ~op3_value) << start_bit);
1894 emit_insn (gen_andsi3 (op1, operands[0], GEN_INT (~mask2)));
1895 emit_insn (gen_iorsi3 (subtarget, op1,
1896 GEN_INT (op3_value << start_bit)));
1898 else if (start_bit == 0
1899 && !(const_ok_for_arm (mask)
1900 || const_ok_for_arm (~mask)))
1902 /* A Trick, since we are setting the bottom bits in the word,
1903 we can shift operand[3] up, operand[0] down, OR them together
1904 and rotate the result back again. This takes 3 insns, and
1905 the third might be mergeable into another op. */
1906 /* The shift up copes with the possibility that operand[3] is
1907 wider than the bitfield. */
1908 rtx op0 = gen_reg_rtx (SImode);
1909 rtx op1 = gen_reg_rtx (SImode);
1911 emit_insn (gen_ashlsi3 (op0, operands[3], GEN_INT (32 - width)));
1912 emit_insn (gen_lshrsi3 (op1, operands[0], operands[1]));
1913 emit_insn (gen_iorsi3 (op1, op1, op0));
1914 emit_insn (gen_rotlsi3 (subtarget, op1, operands[1]));
1916 else if ((width + start_bit == 32)
1917 && !(const_ok_for_arm (mask)
1918 || const_ok_for_arm (~mask)))
1920 /* Similar trick, but slightly less efficient. */
1922 rtx op0 = gen_reg_rtx (SImode);
1923 rtx op1 = gen_reg_rtx (SImode);
1925 emit_insn (gen_ashlsi3 (op0, operands[3], GEN_INT (32 - width)));
1926 emit_insn (gen_ashlsi3 (op1, operands[0], operands[1]));
1927 emit_insn (gen_lshrsi3 (op1, op1, operands[1]));
1928 emit_insn (gen_iorsi3 (subtarget, op1, op0));
1932 rtx op0 = GEN_INT (mask);
1933 rtx op1 = gen_reg_rtx (SImode);
1934 rtx op2 = gen_reg_rtx (SImode);
1936 if (!(const_ok_for_arm (mask) || const_ok_for_arm (~mask)))
1938 rtx tmp = gen_reg_rtx (SImode);
1940 emit_insn (gen_movsi (tmp, op0));
1944 /* Mask out any bits in operand[3] that are not needed. */
1945 emit_insn (gen_andsi3 (op1, operands[3], op0));
1947 if (GET_CODE (op0) == CONST_INT
1948 && (const_ok_for_arm (mask << start_bit)
1949 || const_ok_for_arm (~(mask << start_bit))))
1951 op0 = GEN_INT (~(mask << start_bit));
1952 emit_insn (gen_andsi3 (op2, operands[0], op0));
1956 if (GET_CODE (op0) == CONST_INT)
1958 rtx tmp = gen_reg_rtx (SImode);
1960 emit_insn (gen_movsi (tmp, op0));
1965 emit_insn (gen_ashlsi3 (op0, op0, operands[2]));
1967 emit_insn (gen_andsi_notsi_si (op2, operands[0], op0));
1971 emit_insn (gen_ashlsi3 (op1, op1, operands[2]));
1973 emit_insn (gen_iorsi3 (subtarget, op1, op2));
1976 if (subtarget != target)
1978 /* If TARGET is still a SUBREG, then it must be wider than a word,
1979 so we must be careful only to set the subword we were asked to. */
1980 if (GET_CODE (target) == SUBREG)
1981 emit_move_insn (target, subtarget);
1983 emit_move_insn (target, gen_lowpart (GET_MODE (target), subtarget));
1990 ; constants for op 2 will never be given to these patterns.
1991 (define_insn_and_split "*anddi_notdi_di"
1992 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1993 (and:DI (not:DI (match_operand:DI 1 "s_register_operand" "r,0"))
1994 (match_operand:DI 2 "s_register_operand" "0,r")))]
1997 "TARGET_ARM && reload_completed && ! IS_IWMMXT_REGNUM (REGNO (operands[0]))"
1998 [(set (match_dup 0) (and:SI (not:SI (match_dup 1)) (match_dup 2)))
1999 (set (match_dup 3) (and:SI (not:SI (match_dup 4)) (match_dup 5)))]
2002 operands[3] = gen_highpart (SImode, operands[0]);
2003 operands[0] = gen_lowpart (SImode, operands[0]);
2004 operands[4] = gen_highpart (SImode, operands[1]);
2005 operands[1] = gen_lowpart (SImode, operands[1]);
2006 operands[5] = gen_highpart (SImode, operands[2]);
2007 operands[2] = gen_lowpart (SImode, operands[2]);
2009 [(set_attr "length" "8")
2010 (set_attr "predicable" "yes")]
2013 (define_insn_and_split "*anddi_notzesidi_di"
2014 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2015 (and:DI (not:DI (zero_extend:DI
2016 (match_operand:SI 2 "s_register_operand" "r,r")))
2017 (match_operand:DI 1 "s_register_operand" "0,?r")))]
2020 bic%?\\t%Q0, %Q1, %2
2022 ; (not (zero_extend ...)) allows us to just copy the high word from
2023 ; operand1 to operand0.
2026 && operands[0] != operands[1]"
2027 [(set (match_dup 0) (and:SI (not:SI (match_dup 2)) (match_dup 1)))
2028 (set (match_dup 3) (match_dup 4))]
2031 operands[3] = gen_highpart (SImode, operands[0]);
2032 operands[0] = gen_lowpart (SImode, operands[0]);
2033 operands[4] = gen_highpart (SImode, operands[1]);
2034 operands[1] = gen_lowpart (SImode, operands[1]);
2036 [(set_attr "length" "4,8")
2037 (set_attr "predicable" "yes")]
2040 (define_insn_and_split "*anddi_notsesidi_di"
2041 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2042 (and:DI (not:DI (sign_extend:DI
2043 (match_operand:SI 2 "s_register_operand" "r,r")))
2044 (match_operand:DI 1 "s_register_operand" "0,r")))]
2047 "TARGET_ARM && reload_completed"
2048 [(set (match_dup 0) (and:SI (not:SI (match_dup 2)) (match_dup 1)))
2049 (set (match_dup 3) (and:SI (not:SI
2050 (ashiftrt:SI (match_dup 2) (const_int 31)))
2054 operands[3] = gen_highpart (SImode, operands[0]);
2055 operands[0] = gen_lowpart (SImode, operands[0]);
2056 operands[4] = gen_highpart (SImode, operands[1]);
2057 operands[1] = gen_lowpart (SImode, operands[1]);
2059 [(set_attr "length" "8")
2060 (set_attr "predicable" "yes")]
2063 (define_insn "andsi_notsi_si"
2064 [(set (match_operand:SI 0 "s_register_operand" "=r")
2065 (and:SI (not:SI (match_operand:SI 2 "s_register_operand" "r"))
2066 (match_operand:SI 1 "s_register_operand" "r")))]
2068 "bic%?\\t%0, %1, %2"
2069 [(set_attr "predicable" "yes")]
2072 (define_insn "bicsi3"
2073 [(set (match_operand:SI 0 "register_operand" "=l")
2074 (and:SI (not:SI (match_operand:SI 1 "register_operand" "l"))
2075 (match_operand:SI 2 "register_operand" "0")))]
2078 [(set_attr "length" "2")]
2081 (define_insn "andsi_not_shiftsi_si"
2082 [(set (match_operand:SI 0 "s_register_operand" "=r")
2083 (and:SI (not:SI (match_operator:SI 4 "shift_operator"
2084 [(match_operand:SI 2 "s_register_operand" "r")
2085 (match_operand:SI 3 "arm_rhs_operand" "rM")]))
2086 (match_operand:SI 1 "s_register_operand" "r")))]
2088 "bic%?\\t%0, %1, %2%S4"
2089 [(set_attr "predicable" "yes")
2090 (set_attr "shift" "2")
2091 (set (attr "type") (if_then_else (match_operand 3 "const_int_operand" "")
2092 (const_string "alu_shift")
2093 (const_string "alu_shift_reg")))]
2096 (define_insn "*andsi_notsi_si_compare0"
2097 [(set (reg:CC_NOOV CC_REGNUM)
2099 (and:SI (not:SI (match_operand:SI 2 "s_register_operand" "r"))
2100 (match_operand:SI 1 "s_register_operand" "r"))
2102 (set (match_operand:SI 0 "s_register_operand" "=r")
2103 (and:SI (not:SI (match_dup 2)) (match_dup 1)))]
2105 "bic%?s\\t%0, %1, %2"
2106 [(set_attr "conds" "set")]
2109 (define_insn "*andsi_notsi_si_compare0_scratch"
2110 [(set (reg:CC_NOOV CC_REGNUM)
2112 (and:SI (not:SI (match_operand:SI 2 "s_register_operand" "r"))
2113 (match_operand:SI 1 "s_register_operand" "r"))
2115 (clobber (match_scratch:SI 0 "=r"))]
2117 "bic%?s\\t%0, %1, %2"
2118 [(set_attr "conds" "set")]
2121 (define_insn "iordi3"
2122 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2123 (ior:DI (match_operand:DI 1 "s_register_operand" "%0,r")
2124 (match_operand:DI 2 "s_register_operand" "r,r")))]
2125 "TARGET_ARM && ! TARGET_IWMMXT"
2127 [(set_attr "length" "8")
2128 (set_attr "predicable" "yes")]
2131 (define_insn "*iordi_zesidi_di"
2132 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2133 (ior:DI (zero_extend:DI
2134 (match_operand:SI 2 "s_register_operand" "r,r"))
2135 (match_operand:DI 1 "s_register_operand" "0,?r")))]
2138 orr%?\\t%Q0, %Q1, %2
2140 [(set_attr "length" "4,8")
2141 (set_attr "predicable" "yes")]
2144 (define_insn "*iordi_sesidi_di"
2145 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2146 (ior:DI (sign_extend:DI
2147 (match_operand:SI 2 "s_register_operand" "r,r"))
2148 (match_operand:DI 1 "s_register_operand" "?r,0")))]
2151 [(set_attr "length" "8")
2152 (set_attr "predicable" "yes")]
2155 (define_expand "iorsi3"
2156 [(set (match_operand:SI 0 "s_register_operand" "")
2157 (ior:SI (match_operand:SI 1 "s_register_operand" "")
2158 (match_operand:SI 2 "reg_or_int_operand" "")))]
2161 if (GET_CODE (operands[2]) == CONST_INT)
2165 arm_split_constant (IOR, SImode, NULL_RTX,
2166 INTVAL (operands[2]), operands[0], operands[1],
2167 optimize && !no_new_pseudos);
2170 else /* TARGET_THUMB */
2171 operands [2] = force_reg (SImode, operands [2]);
2176 (define_insn_and_split "*arm_iorsi3"
2177 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
2178 (ior:SI (match_operand:SI 1 "s_register_operand" "r,r")
2179 (match_operand:SI 2 "reg_or_int_operand" "rI,?n")))]
2185 && GET_CODE (operands[2]) == CONST_INT
2186 && !const_ok_for_arm (INTVAL (operands[2]))"
2187 [(clobber (const_int 0))]
2189 arm_split_constant (IOR, SImode, curr_insn,
2190 INTVAL (operands[2]), operands[0], operands[1], 0);
2193 [(set_attr "length" "4,16")
2194 (set_attr "predicable" "yes")]
2197 (define_insn "*thumb_iorsi3"
2198 [(set (match_operand:SI 0 "register_operand" "=l")
2199 (ior:SI (match_operand:SI 1 "register_operand" "%0")
2200 (match_operand:SI 2 "register_operand" "l")))]
2203 [(set_attr "length" "2")]
2207 [(match_scratch:SI 3 "r")
2208 (set (match_operand:SI 0 "arm_general_register_operand" "")
2209 (ior:SI (match_operand:SI 1 "arm_general_register_operand" "")
2210 (match_operand:SI 2 "const_int_operand" "")))]
2212 && !const_ok_for_arm (INTVAL (operands[2]))
2213 && const_ok_for_arm (~INTVAL (operands[2]))"
2214 [(set (match_dup 3) (match_dup 2))
2215 (set (match_dup 0) (ior:SI (match_dup 1) (match_dup 3)))]
2219 (define_insn "*iorsi3_compare0"
2220 [(set (reg:CC_NOOV CC_REGNUM)
2221 (compare:CC_NOOV (ior:SI (match_operand:SI 1 "s_register_operand" "%r")
2222 (match_operand:SI 2 "arm_rhs_operand" "rI"))
2224 (set (match_operand:SI 0 "s_register_operand" "=r")
2225 (ior:SI (match_dup 1) (match_dup 2)))]
2227 "orr%?s\\t%0, %1, %2"
2228 [(set_attr "conds" "set")]
2231 (define_insn "*iorsi3_compare0_scratch"
2232 [(set (reg:CC_NOOV CC_REGNUM)
2233 (compare:CC_NOOV (ior:SI (match_operand:SI 1 "s_register_operand" "%r")
2234 (match_operand:SI 2 "arm_rhs_operand" "rI"))
2236 (clobber (match_scratch:SI 0 "=r"))]
2238 "orr%?s\\t%0, %1, %2"
2239 [(set_attr "conds" "set")]
2242 (define_insn "xordi3"
2243 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2244 (xor:DI (match_operand:DI 1 "s_register_operand" "%0,r")
2245 (match_operand:DI 2 "s_register_operand" "r,r")))]
2246 "TARGET_ARM && !TARGET_IWMMXT"
2248 [(set_attr "length" "8")
2249 (set_attr "predicable" "yes")]
2252 (define_insn "*xordi_zesidi_di"
2253 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2254 (xor:DI (zero_extend:DI
2255 (match_operand:SI 2 "s_register_operand" "r,r"))
2256 (match_operand:DI 1 "s_register_operand" "0,?r")))]
2259 eor%?\\t%Q0, %Q1, %2
2261 [(set_attr "length" "4,8")
2262 (set_attr "predicable" "yes")]
2265 (define_insn "*xordi_sesidi_di"
2266 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2267 (xor:DI (sign_extend:DI
2268 (match_operand:SI 2 "s_register_operand" "r,r"))
2269 (match_operand:DI 1 "s_register_operand" "?r,0")))]
2272 [(set_attr "length" "8")
2273 (set_attr "predicable" "yes")]
2276 (define_expand "xorsi3"
2277 [(set (match_operand:SI 0 "s_register_operand" "")
2278 (xor:SI (match_operand:SI 1 "s_register_operand" "")
2279 (match_operand:SI 2 "arm_rhs_operand" "")))]
2282 if (GET_CODE (operands[2]) == CONST_INT)
2283 operands[2] = force_reg (SImode, operands[2]);
2287 (define_insn "*arm_xorsi3"
2288 [(set (match_operand:SI 0 "s_register_operand" "=r")
2289 (xor:SI (match_operand:SI 1 "s_register_operand" "r")
2290 (match_operand:SI 2 "arm_rhs_operand" "rI")))]
2292 "eor%?\\t%0, %1, %2"
2293 [(set_attr "predicable" "yes")]
2296 (define_insn "*thumb_xorsi3"
2297 [(set (match_operand:SI 0 "register_operand" "=l")
2298 (xor:SI (match_operand:SI 1 "register_operand" "%0")
2299 (match_operand:SI 2 "register_operand" "l")))]
2302 [(set_attr "length" "2")]
2305 (define_insn "*xorsi3_compare0"
2306 [(set (reg:CC_NOOV CC_REGNUM)
2307 (compare:CC_NOOV (xor:SI (match_operand:SI 1 "s_register_operand" "r")
2308 (match_operand:SI 2 "arm_rhs_operand" "rI"))
2310 (set (match_operand:SI 0 "s_register_operand" "=r")
2311 (xor:SI (match_dup 1) (match_dup 2)))]
2313 "eor%?s\\t%0, %1, %2"
2314 [(set_attr "conds" "set")]
2317 (define_insn "*xorsi3_compare0_scratch"
2318 [(set (reg:CC_NOOV CC_REGNUM)
2319 (compare:CC_NOOV (xor:SI (match_operand:SI 0 "s_register_operand" "r")
2320 (match_operand:SI 1 "arm_rhs_operand" "rI"))
2324 [(set_attr "conds" "set")]
2327 ; By splitting (IOR (AND (NOT A) (NOT B)) C) as D = AND (IOR A B) (NOT C),
2328 ; (NOT D) we can sometimes merge the final NOT into one of the following
2332 [(set (match_operand:SI 0 "s_register_operand" "")
2333 (ior:SI (and:SI (not:SI (match_operand:SI 1 "s_register_operand" ""))
2334 (not:SI (match_operand:SI 2 "arm_rhs_operand" "")))
2335 (match_operand:SI 3 "arm_rhs_operand" "")))
2336 (clobber (match_operand:SI 4 "s_register_operand" ""))]
2338 [(set (match_dup 4) (and:SI (ior:SI (match_dup 1) (match_dup 2))
2339 (not:SI (match_dup 3))))
2340 (set (match_dup 0) (not:SI (match_dup 4)))]
2344 (define_insn "*andsi_iorsi3_notsi"
2345 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r")
2346 (and:SI (ior:SI (match_operand:SI 1 "s_register_operand" "r,r,0")
2347 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI"))
2348 (not:SI (match_operand:SI 3 "arm_rhs_operand" "rI,rI,rI"))))]
2350 "orr%?\\t%0, %1, %2\;bic%?\\t%0, %0, %3"
2351 [(set_attr "length" "8")
2352 (set_attr "predicable" "yes")]
2356 [(set (match_operand:SI 0 "s_register_operand" "")
2357 (match_operator:SI 1 "logical_binary_operator"
2358 [(zero_extract:SI (match_operand:SI 2 "s_register_operand" "")
2359 (match_operand:SI 3 "const_int_operand" "")
2360 (match_operand:SI 4 "const_int_operand" ""))
2361 (match_operator:SI 9 "logical_binary_operator"
2362 [(lshiftrt:SI (match_operand:SI 5 "s_register_operand" "")
2363 (match_operand:SI 6 "const_int_operand" ""))
2364 (match_operand:SI 7 "s_register_operand" "")])]))
2365 (clobber (match_operand:SI 8 "s_register_operand" ""))]
2367 && GET_CODE (operands[1]) == GET_CODE (operands[9])
2368 && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
2371 [(ashift:SI (match_dup 2) (match_dup 4))
2375 [(lshiftrt:SI (match_dup 8) (match_dup 6))
2378 operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
2382 [(set (match_operand:SI 0 "s_register_operand" "")
2383 (match_operator:SI 1 "logical_binary_operator"
2384 [(match_operator:SI 9 "logical_binary_operator"
2385 [(lshiftrt:SI (match_operand:SI 5 "s_register_operand" "")
2386 (match_operand:SI 6 "const_int_operand" ""))
2387 (match_operand:SI 7 "s_register_operand" "")])
2388 (zero_extract:SI (match_operand:SI 2 "s_register_operand" "")
2389 (match_operand:SI 3 "const_int_operand" "")
2390 (match_operand:SI 4 "const_int_operand" ""))]))
2391 (clobber (match_operand:SI 8 "s_register_operand" ""))]
2393 && GET_CODE (operands[1]) == GET_CODE (operands[9])
2394 && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
2397 [(ashift:SI (match_dup 2) (match_dup 4))
2401 [(lshiftrt:SI (match_dup 8) (match_dup 6))
2404 operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
2408 [(set (match_operand:SI 0 "s_register_operand" "")
2409 (match_operator:SI 1 "logical_binary_operator"
2410 [(sign_extract:SI (match_operand:SI 2 "s_register_operand" "")
2411 (match_operand:SI 3 "const_int_operand" "")
2412 (match_operand:SI 4 "const_int_operand" ""))
2413 (match_operator:SI 9 "logical_binary_operator"
2414 [(ashiftrt:SI (match_operand:SI 5 "s_register_operand" "")
2415 (match_operand:SI 6 "const_int_operand" ""))
2416 (match_operand:SI 7 "s_register_operand" "")])]))
2417 (clobber (match_operand:SI 8 "s_register_operand" ""))]
2419 && GET_CODE (operands[1]) == GET_CODE (operands[9])
2420 && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
2423 [(ashift:SI (match_dup 2) (match_dup 4))
2427 [(ashiftrt:SI (match_dup 8) (match_dup 6))
2430 operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
2434 [(set (match_operand:SI 0 "s_register_operand" "")
2435 (match_operator:SI 1 "logical_binary_operator"
2436 [(match_operator:SI 9 "logical_binary_operator"
2437 [(ashiftrt:SI (match_operand:SI 5 "s_register_operand" "")
2438 (match_operand:SI 6 "const_int_operand" ""))
2439 (match_operand:SI 7 "s_register_operand" "")])
2440 (sign_extract:SI (match_operand:SI 2 "s_register_operand" "")
2441 (match_operand:SI 3 "const_int_operand" "")
2442 (match_operand:SI 4 "const_int_operand" ""))]))
2443 (clobber (match_operand:SI 8 "s_register_operand" ""))]
2445 && GET_CODE (operands[1]) == GET_CODE (operands[9])
2446 && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
2449 [(ashift:SI (match_dup 2) (match_dup 4))
2453 [(ashiftrt:SI (match_dup 8) (match_dup 6))
2456 operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
2460 ;; Minimum and maximum insns
2462 (define_insn "smaxsi3"
2463 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
2464 (smax:SI (match_operand:SI 1 "s_register_operand" "0,r,?r")
2465 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
2466 (clobber (reg:CC CC_REGNUM))]
2469 cmp\\t%1, %2\;movlt\\t%0, %2
2470 cmp\\t%1, %2\;movge\\t%0, %1
2471 cmp\\t%1, %2\;movge\\t%0, %1\;movlt\\t%0, %2"
2472 [(set_attr "conds" "clob")
2473 (set_attr "length" "8,8,12")]
2476 (define_insn "sminsi3"
2477 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
2478 (smin:SI (match_operand:SI 1 "s_register_operand" "0,r,?r")
2479 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
2480 (clobber (reg:CC CC_REGNUM))]
2483 cmp\\t%1, %2\;movge\\t%0, %2
2484 cmp\\t%1, %2\;movlt\\t%0, %1
2485 cmp\\t%1, %2\;movlt\\t%0, %1\;movge\\t%0, %2"
2486 [(set_attr "conds" "clob")
2487 (set_attr "length" "8,8,12")]
2490 (define_insn "umaxsi3"
2491 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
2492 (umax:SI (match_operand:SI 1 "s_register_operand" "0,r,?r")
2493 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
2494 (clobber (reg:CC CC_REGNUM))]
2497 cmp\\t%1, %2\;movcc\\t%0, %2
2498 cmp\\t%1, %2\;movcs\\t%0, %1
2499 cmp\\t%1, %2\;movcs\\t%0, %1\;movcc\\t%0, %2"
2500 [(set_attr "conds" "clob")
2501 (set_attr "length" "8,8,12")]
2504 (define_insn "uminsi3"
2505 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
2506 (umin:SI (match_operand:SI 1 "s_register_operand" "0,r,?r")
2507 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
2508 (clobber (reg:CC CC_REGNUM))]
2511 cmp\\t%1, %2\;movcs\\t%0, %2
2512 cmp\\t%1, %2\;movcc\\t%0, %1
2513 cmp\\t%1, %2\;movcc\\t%0, %1\;movcs\\t%0, %2"
2514 [(set_attr "conds" "clob")
2515 (set_attr "length" "8,8,12")]
2518 (define_insn "*store_minmaxsi"
2519 [(set (match_operand:SI 0 "memory_operand" "=m")
2520 (match_operator:SI 3 "minmax_operator"
2521 [(match_operand:SI 1 "s_register_operand" "r")
2522 (match_operand:SI 2 "s_register_operand" "r")]))
2523 (clobber (reg:CC CC_REGNUM))]
2526 operands[3] = gen_rtx_fmt_ee (minmax_code (operands[3]), SImode,
2527 operands[1], operands[2]);
2528 output_asm_insn (\"cmp\\t%1, %2\", operands);
2529 output_asm_insn (\"str%d3\\t%1, %0\", operands);
2530 output_asm_insn (\"str%D3\\t%2, %0\", operands);
2533 [(set_attr "conds" "clob")
2534 (set_attr "length" "12")
2535 (set_attr "type" "store1")]
2538 ; Reject the frame pointer in operand[1], since reloading this after
2539 ; it has been eliminated can cause carnage.
2540 (define_insn "*minmax_arithsi"
2541 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
2542 (match_operator:SI 4 "shiftable_operator"
2543 [(match_operator:SI 5 "minmax_operator"
2544 [(match_operand:SI 2 "s_register_operand" "r,r")
2545 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
2546 (match_operand:SI 1 "s_register_operand" "0,?r")]))
2547 (clobber (reg:CC CC_REGNUM))]
2549 && (GET_CODE (operands[1]) != REG
2550 || (REGNO(operands[1]) != FRAME_POINTER_REGNUM
2551 && REGNO(operands[1]) != ARG_POINTER_REGNUM))"
2554 enum rtx_code code = GET_CODE (operands[4]);
2556 operands[5] = gen_rtx_fmt_ee (minmax_code (operands[5]), SImode,
2557 operands[2], operands[3]);
2558 output_asm_insn (\"cmp\\t%2, %3\", operands);
2559 output_asm_insn (\"%i4%d5\\t%0, %1, %2\", operands);
2560 if (which_alternative != 0 || operands[3] != const0_rtx
2561 || (code != PLUS && code != MINUS && code != IOR && code != XOR))
2562 output_asm_insn (\"%i4%D5\\t%0, %1, %3\", operands);
2565 [(set_attr "conds" "clob")
2566 (set_attr "length" "12")]
2570 ;; Shift and rotation insns
2572 (define_expand "ashldi3"
2573 [(set (match_operand:DI 0 "s_register_operand" "")
2574 (ashift:DI (match_operand:DI 1 "s_register_operand" "")
2575 (match_operand:SI 2 "reg_or_int_operand" "")))]
2578 if (GET_CODE (operands[2]) == CONST_INT)
2580 if ((HOST_WIDE_INT) INTVAL (operands[2]) == 1)
2582 emit_insn (gen_arm_ashldi3_1bit (operands[0], operands[1]));
2585 /* Ideally we shouldn't fail here if we could know that operands[1]
2586 ends up already living in an iwmmxt register. Otherwise it's
2587 cheaper to have the alternate code being generated than moving
2588 values to iwmmxt regs and back. */
2591 else if (!TARGET_REALLY_IWMMXT && !(TARGET_HARD_FLOAT && TARGET_MAVERICK))
2596 (define_insn "arm_ashldi3_1bit"
2597 [(set (match_operand:DI 0 "s_register_operand" "=&r,r")
2598 (ashift:DI (match_operand:DI 1 "s_register_operand" "?r,0")
2600 (clobber (reg:CC CC_REGNUM))]
2602 "movs\\t%Q0, %Q1, asl #1\;adc\\t%R0, %R1, %R1"
2603 [(set_attr "conds" "clob")
2604 (set_attr "length" "8")]
2607 (define_expand "ashlsi3"
2608 [(set (match_operand:SI 0 "s_register_operand" "")
2609 (ashift:SI (match_operand:SI 1 "s_register_operand" "")
2610 (match_operand:SI 2 "arm_rhs_operand" "")))]
2613 if (GET_CODE (operands[2]) == CONST_INT
2614 && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) > 31)
2616 emit_insn (gen_movsi (operands[0], const0_rtx));
2622 (define_insn "*thumb_ashlsi3"
2623 [(set (match_operand:SI 0 "register_operand" "=l,l")
2624 (ashift:SI (match_operand:SI 1 "register_operand" "l,0")
2625 (match_operand:SI 2 "nonmemory_operand" "N,l")))]
2628 [(set_attr "length" "2")]
2631 (define_expand "ashrdi3"
2632 [(set (match_operand:DI 0 "s_register_operand" "")
2633 (ashiftrt:DI (match_operand:DI 1 "s_register_operand" "")
2634 (match_operand:SI 2 "reg_or_int_operand" "")))]
2637 if (GET_CODE (operands[2]) == CONST_INT)
2639 if ((HOST_WIDE_INT) INTVAL (operands[2]) == 1)
2641 emit_insn (gen_arm_ashrdi3_1bit (operands[0], operands[1]));
2644 /* Ideally we shouldn't fail here if we could know that operands[1]
2645 ends up already living in an iwmmxt register. Otherwise it's
2646 cheaper to have the alternate code being generated than moving
2647 values to iwmmxt regs and back. */
2650 else if (!TARGET_REALLY_IWMMXT)
2655 (define_insn "arm_ashrdi3_1bit"
2656 [(set (match_operand:DI 0 "s_register_operand" "=&r,r")
2657 (ashiftrt:DI (match_operand:DI 1 "s_register_operand" "?r,0")
2659 (clobber (reg:CC CC_REGNUM))]
2661 "movs\\t%R0, %R1, asr #1\;mov\\t%Q0, %Q1, rrx"
2662 [(set_attr "conds" "clob")
2663 (set_attr "length" "8")]
2666 (define_expand "ashrsi3"
2667 [(set (match_operand:SI 0 "s_register_operand" "")
2668 (ashiftrt:SI (match_operand:SI 1 "s_register_operand" "")
2669 (match_operand:SI 2 "arm_rhs_operand" "")))]
2672 if (GET_CODE (operands[2]) == CONST_INT
2673 && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) > 31)
2674 operands[2] = GEN_INT (31);
2678 (define_insn "*thumb_ashrsi3"
2679 [(set (match_operand:SI 0 "register_operand" "=l,l")
2680 (ashiftrt:SI (match_operand:SI 1 "register_operand" "l,0")
2681 (match_operand:SI 2 "nonmemory_operand" "N,l")))]
2684 [(set_attr "length" "2")]
2687 (define_expand "lshrdi3"
2688 [(set (match_operand:DI 0 "s_register_operand" "")
2689 (lshiftrt:DI (match_operand:DI 1 "s_register_operand" "")
2690 (match_operand:SI 2 "reg_or_int_operand" "")))]
2693 if (GET_CODE (operands[2]) == CONST_INT)
2695 if ((HOST_WIDE_INT) INTVAL (operands[2]) == 1)
2697 emit_insn (gen_arm_lshrdi3_1bit (operands[0], operands[1]));
2700 /* Ideally we shouldn't fail here if we could know that operands[1]
2701 ends up already living in an iwmmxt register. Otherwise it's
2702 cheaper to have the alternate code being generated than moving
2703 values to iwmmxt regs and back. */
2706 else if (!TARGET_REALLY_IWMMXT)
2711 (define_insn "arm_lshrdi3_1bit"
2712 [(set (match_operand:DI 0 "s_register_operand" "=&r,r")
2713 (lshiftrt:DI (match_operand:DI 1 "s_register_operand" "?r,0")
2715 (clobber (reg:CC CC_REGNUM))]
2717 "movs\\t%R0, %R1, lsr #1\;mov\\t%Q0, %Q1, rrx"
2718 [(set_attr "conds" "clob")
2719 (set_attr "length" "8")]
2722 (define_expand "lshrsi3"
2723 [(set (match_operand:SI 0 "s_register_operand" "")
2724 (lshiftrt:SI (match_operand:SI 1 "s_register_operand" "")
2725 (match_operand:SI 2 "arm_rhs_operand" "")))]
2728 if (GET_CODE (operands[2]) == CONST_INT
2729 && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) > 31)
2731 emit_insn (gen_movsi (operands[0], const0_rtx));
2737 (define_insn "*thumb_lshrsi3"
2738 [(set (match_operand:SI 0 "register_operand" "=l,l")
2739 (lshiftrt:SI (match_operand:SI 1 "register_operand" "l,0")
2740 (match_operand:SI 2 "nonmemory_operand" "N,l")))]
2743 [(set_attr "length" "2")]
2746 (define_expand "rotlsi3"
2747 [(set (match_operand:SI 0 "s_register_operand" "")
2748 (rotatert:SI (match_operand:SI 1 "s_register_operand" "")
2749 (match_operand:SI 2 "reg_or_int_operand" "")))]
2752 if (GET_CODE (operands[2]) == CONST_INT)
2753 operands[2] = GEN_INT ((32 - INTVAL (operands[2])) % 32);
2756 rtx reg = gen_reg_rtx (SImode);
2757 emit_insn (gen_subsi3 (reg, GEN_INT (32), operands[2]));
2763 (define_expand "rotrsi3"
2764 [(set (match_operand:SI 0 "s_register_operand" "")
2765 (rotatert:SI (match_operand:SI 1 "s_register_operand" "")
2766 (match_operand:SI 2 "arm_rhs_operand" "")))]
2771 if (GET_CODE (operands[2]) == CONST_INT
2772 && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) > 31)
2773 operands[2] = GEN_INT (INTVAL (operands[2]) % 32);
2775 else /* TARGET_THUMB */
2777 if (GET_CODE (operands [2]) == CONST_INT)
2778 operands [2] = force_reg (SImode, operands[2]);
2783 (define_insn "*thumb_rotrsi3"
2784 [(set (match_operand:SI 0 "register_operand" "=l")
2785 (rotatert:SI (match_operand:SI 1 "register_operand" "0")
2786 (match_operand:SI 2 "register_operand" "l")))]
2789 [(set_attr "length" "2")]
2792 (define_insn "*arm_shiftsi3"
2793 [(set (match_operand:SI 0 "s_register_operand" "=r")
2794 (match_operator:SI 3 "shift_operator"
2795 [(match_operand:SI 1 "s_register_operand" "r")
2796 (match_operand:SI 2 "reg_or_int_operand" "rM")]))]
2799 [(set_attr "predicable" "yes")
2800 (set_attr "shift" "1")
2801 (set (attr "type") (if_then_else (match_operand 2 "const_int_operand" "")
2802 (const_string "alu_shift")
2803 (const_string "alu_shift_reg")))]
2806 (define_insn "*shiftsi3_compare0"
2807 [(set (reg:CC_NOOV CC_REGNUM)
2808 (compare:CC_NOOV (match_operator:SI 3 "shift_operator"
2809 [(match_operand:SI 1 "s_register_operand" "r")
2810 (match_operand:SI 2 "arm_rhs_operand" "rM")])
2812 (set (match_operand:SI 0 "s_register_operand" "=r")
2813 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))]
2815 "mov%?s\\t%0, %1%S3"
2816 [(set_attr "conds" "set")
2817 (set_attr "shift" "1")
2818 (set (attr "type") (if_then_else (match_operand 2 "const_int_operand" "")
2819 (const_string "alu_shift")
2820 (const_string "alu_shift_reg")))]
2823 (define_insn "*shiftsi3_compare0_scratch"
2824 [(set (reg:CC_NOOV CC_REGNUM)
2825 (compare:CC_NOOV (match_operator:SI 3 "shift_operator"
2826 [(match_operand:SI 1 "s_register_operand" "r")
2827 (match_operand:SI 2 "arm_rhs_operand" "rM")])
2829 (clobber (match_scratch:SI 0 "=r"))]
2831 "mov%?s\\t%0, %1%S3"
2832 [(set_attr "conds" "set")
2833 (set_attr "shift" "1")]
2836 (define_insn "*notsi_shiftsi"
2837 [(set (match_operand:SI 0 "s_register_operand" "=r")
2838 (not:SI (match_operator:SI 3 "shift_operator"
2839 [(match_operand:SI 1 "s_register_operand" "r")
2840 (match_operand:SI 2 "arm_rhs_operand" "rM")])))]
2843 [(set_attr "predicable" "yes")
2844 (set_attr "shift" "1")
2845 (set (attr "type") (if_then_else (match_operand 2 "const_int_operand" "")
2846 (const_string "alu_shift")
2847 (const_string "alu_shift_reg")))]
2850 (define_insn "*notsi_shiftsi_compare0"
2851 [(set (reg:CC_NOOV CC_REGNUM)
2852 (compare:CC_NOOV (not:SI (match_operator:SI 3 "shift_operator"
2853 [(match_operand:SI 1 "s_register_operand" "r")
2854 (match_operand:SI 2 "arm_rhs_operand" "rM")]))
2856 (set (match_operand:SI 0 "s_register_operand" "=r")
2857 (not:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)])))]
2859 "mvn%?s\\t%0, %1%S3"
2860 [(set_attr "conds" "set")
2861 (set_attr "shift" "1")
2862 (set (attr "type") (if_then_else (match_operand 2 "const_int_operand" "")
2863 (const_string "alu_shift")
2864 (const_string "alu_shift_reg")))]
2867 (define_insn "*not_shiftsi_compare0_scratch"
2868 [(set (reg:CC_NOOV CC_REGNUM)
2869 (compare:CC_NOOV (not:SI (match_operator:SI 3 "shift_operator"
2870 [(match_operand:SI 1 "s_register_operand" "r")
2871 (match_operand:SI 2 "arm_rhs_operand" "rM")]))
2873 (clobber (match_scratch:SI 0 "=r"))]
2875 "mvn%?s\\t%0, %1%S3"
2876 [(set_attr "conds" "set")
2877 (set_attr "shift" "1")
2878 (set (attr "type") (if_then_else (match_operand 2 "const_int_operand" "")
2879 (const_string "alu_shift")
2880 (const_string "alu_shift_reg")))]
2883 ;; We don't really have extzv, but defining this using shifts helps
2884 ;; to reduce register pressure later on.
2886 (define_expand "extzv"
2888 (ashift:SI (match_operand:SI 1 "register_operand" "")
2889 (match_operand:SI 2 "const_int_operand" "")))
2890 (set (match_operand:SI 0 "register_operand" "")
2891 (lshiftrt:SI (match_dup 4)
2892 (match_operand:SI 3 "const_int_operand" "")))]
2896 HOST_WIDE_INT lshift = 32 - INTVAL (operands[2]) - INTVAL (operands[3]);
2897 HOST_WIDE_INT rshift = 32 - INTVAL (operands[2]);
2899 operands[3] = GEN_INT (rshift);
2903 emit_insn (gen_lshrsi3 (operands[0], operands[1], operands[3]));
2907 operands[2] = GEN_INT (lshift);
2908 operands[4] = gen_reg_rtx (SImode);
2913 ;; Unary arithmetic insns
2915 (define_expand "negdi2"
2917 [(set (match_operand:DI 0 "s_register_operand" "")
2918 (neg:DI (match_operand:DI 1 "s_register_operand" "")))
2919 (clobber (reg:CC CC_REGNUM))])]
2924 if (GET_CODE (operands[1]) != REG)
2925 operands[1] = force_reg (SImode, operands[1]);
2930 ;; The constraints here are to prevent a *partial* overlap (where %Q0 == %R1).
2931 ;; The second alternative is to allow the common case of a *full* overlap.
2932 (define_insn "*arm_negdi2"
2933 [(set (match_operand:DI 0 "s_register_operand" "=&r,r")
2934 (neg:DI (match_operand:DI 1 "s_register_operand" "?r,0")))
2935 (clobber (reg:CC CC_REGNUM))]
2937 "rsbs\\t%Q0, %Q1, #0\;rsc\\t%R0, %R1, #0"
2938 [(set_attr "conds" "clob")
2939 (set_attr "length" "8")]
2942 (define_insn "*thumb_negdi2"
2943 [(set (match_operand:DI 0 "register_operand" "=&l")
2944 (neg:DI (match_operand:DI 1 "register_operand" "l")))
2945 (clobber (reg:CC CC_REGNUM))]
2947 "mov\\t%R0, #0\;neg\\t%Q0, %Q1\;sbc\\t%R0, %R1"
2948 [(set_attr "length" "6")]
2951 (define_expand "negsi2"
2952 [(set (match_operand:SI 0 "s_register_operand" "")
2953 (neg:SI (match_operand:SI 1 "s_register_operand" "")))]
2958 (define_insn "*arm_negsi2"
2959 [(set (match_operand:SI 0 "s_register_operand" "=r")
2960 (neg:SI (match_operand:SI 1 "s_register_operand" "r")))]
2962 "rsb%?\\t%0, %1, #0"
2963 [(set_attr "predicable" "yes")]
2966 (define_insn "*thumb_negsi2"
2967 [(set (match_operand:SI 0 "register_operand" "=l")
2968 (neg:SI (match_operand:SI 1 "register_operand" "l")))]
2971 [(set_attr "length" "2")]
2974 (define_expand "negsf2"
2975 [(set (match_operand:SF 0 "s_register_operand" "")
2976 (neg:SF (match_operand:SF 1 "s_register_operand" "")))]
2977 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
2981 (define_expand "negdf2"
2982 [(set (match_operand:DF 0 "s_register_operand" "")
2983 (neg:DF (match_operand:DF 1 "s_register_operand" "")))]
2984 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
2987 ;; abssi2 doesn't really clobber the condition codes if a different register
2988 ;; is being set. To keep things simple, assume during rtl manipulations that
2989 ;; it does, but tell the final scan operator the truth. Similarly for
2992 (define_expand "abssi2"
2994 [(set (match_operand:SI 0 "s_register_operand" "")
2995 (abs:SI (match_operand:SI 1 "s_register_operand" "")))
2996 (clobber (reg:CC CC_REGNUM))])]
3000 (define_insn "*arm_abssi2"
3001 [(set (match_operand:SI 0 "s_register_operand" "=r,&r")
3002 (abs:SI (match_operand:SI 1 "s_register_operand" "0,r")))
3003 (clobber (reg:CC CC_REGNUM))]
3006 cmp\\t%0, #0\;rsblt\\t%0, %0, #0
3007 eor%?\\t%0, %1, %1, asr #31\;sub%?\\t%0, %0, %1, asr #31"
3008 [(set_attr "conds" "clob,*")
3009 (set_attr "shift" "1")
3010 ;; predicable can't be set based on the variant, so left as no
3011 (set_attr "length" "8")]
3014 (define_insn "*neg_abssi2"
3015 [(set (match_operand:SI 0 "s_register_operand" "=r,&r")
3016 (neg:SI (abs:SI (match_operand:SI 1 "s_register_operand" "0,r"))))
3017 (clobber (reg:CC CC_REGNUM))]
3020 cmp\\t%0, #0\;rsbgt\\t%0, %0, #0
3021 eor%?\\t%0, %1, %1, asr #31\;rsb%?\\t%0, %0, %1, asr #31"
3022 [(set_attr "conds" "clob,*")
3023 (set_attr "shift" "1")
3024 ;; predicable can't be set based on the variant, so left as no
3025 (set_attr "length" "8")]
3028 (define_expand "abssf2"
3029 [(set (match_operand:SF 0 "s_register_operand" "")
3030 (abs:SF (match_operand:SF 1 "s_register_operand" "")))]
3031 "TARGET_ARM && TARGET_HARD_FLOAT"
3034 (define_expand "absdf2"
3035 [(set (match_operand:DF 0 "s_register_operand" "")
3036 (abs:DF (match_operand:DF 1 "s_register_operand" "")))]
3037 "TARGET_ARM && TARGET_HARD_FLOAT"
3040 (define_expand "sqrtsf2"
3041 [(set (match_operand:SF 0 "s_register_operand" "")
3042 (sqrt:SF (match_operand:SF 1 "s_register_operand" "")))]
3043 "TARGET_ARM && TARGET_HARD_FLOAT && (TARGET_FPA || TARGET_VFP)"
3046 (define_expand "sqrtdf2"
3047 [(set (match_operand:DF 0 "s_register_operand" "")
3048 (sqrt:DF (match_operand:DF 1 "s_register_operand" "")))]
3049 "TARGET_ARM && TARGET_HARD_FLOAT && (TARGET_FPA || TARGET_VFP)"
3052 (define_insn_and_split "one_cmpldi2"
3053 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
3054 (not:DI (match_operand:DI 1 "s_register_operand" "?r,0")))]
3057 "TARGET_ARM && reload_completed"
3058 [(set (match_dup 0) (not:SI (match_dup 1)))
3059 (set (match_dup 2) (not:SI (match_dup 3)))]
3062 operands[2] = gen_highpart (SImode, operands[0]);
3063 operands[0] = gen_lowpart (SImode, operands[0]);
3064 operands[3] = gen_highpart (SImode, operands[1]);
3065 operands[1] = gen_lowpart (SImode, operands[1]);
3067 [(set_attr "length" "8")
3068 (set_attr "predicable" "yes")]
3071 (define_expand "one_cmplsi2"
3072 [(set (match_operand:SI 0 "s_register_operand" "")
3073 (not:SI (match_operand:SI 1 "s_register_operand" "")))]
3078 (define_insn "*arm_one_cmplsi2"
3079 [(set (match_operand:SI 0 "s_register_operand" "=r")
3080 (not:SI (match_operand:SI 1 "s_register_operand" "r")))]
3083 [(set_attr "predicable" "yes")]
3086 (define_insn "*thumb_one_cmplsi2"
3087 [(set (match_operand:SI 0 "register_operand" "=l")
3088 (not:SI (match_operand:SI 1 "register_operand" "l")))]
3091 [(set_attr "length" "2")]
3094 (define_insn "*notsi_compare0"
3095 [(set (reg:CC_NOOV CC_REGNUM)
3096 (compare:CC_NOOV (not:SI (match_operand:SI 1 "s_register_operand" "r"))
3098 (set (match_operand:SI 0 "s_register_operand" "=r")
3099 (not:SI (match_dup 1)))]
3102 [(set_attr "conds" "set")]
3105 (define_insn "*notsi_compare0_scratch"
3106 [(set (reg:CC_NOOV CC_REGNUM)
3107 (compare:CC_NOOV (not:SI (match_operand:SI 1 "s_register_operand" "r"))
3109 (clobber (match_scratch:SI 0 "=r"))]
3112 [(set_attr "conds" "set")]
3115 ;; Fixed <--> Floating conversion insns
3117 (define_expand "floatsisf2"
3118 [(set (match_operand:SF 0 "s_register_operand" "")
3119 (float:SF (match_operand:SI 1 "s_register_operand" "")))]
3120 "TARGET_ARM && TARGET_HARD_FLOAT"
3122 if (TARGET_MAVERICK)
3124 emit_insn (gen_cirrus_floatsisf2 (operands[0], operands[1]));
3129 (define_expand "floatsidf2"
3130 [(set (match_operand:DF 0 "s_register_operand" "")
3131 (float:DF (match_operand:SI 1 "s_register_operand" "")))]
3132 "TARGET_ARM && TARGET_HARD_FLOAT"
3134 if (TARGET_MAVERICK)
3136 emit_insn (gen_cirrus_floatsidf2 (operands[0], operands[1]));
3141 (define_expand "fix_truncsfsi2"
3142 [(set (match_operand:SI 0 "s_register_operand" "")
3143 (fix:SI (fix:SF (match_operand:SF 1 "s_register_operand" ""))))]
3144 "TARGET_ARM && TARGET_HARD_FLOAT"
3146 if (TARGET_MAVERICK)
3148 if (!cirrus_fp_register (operands[0], SImode))
3149 operands[0] = force_reg (SImode, operands[0]);
3150 if (!cirrus_fp_register (operands[1], SFmode))
3151 operands[1] = force_reg (SFmode, operands[0]);
3152 emit_insn (gen_cirrus_truncsfsi2 (operands[0], operands[1]));
3157 (define_expand "fix_truncdfsi2"
3158 [(set (match_operand:SI 0 "s_register_operand" "")
3159 (fix:SI (fix:DF (match_operand:DF 1 "s_register_operand" ""))))]
3160 "TARGET_ARM && TARGET_HARD_FLOAT"
3162 if (TARGET_MAVERICK)
3164 if (!cirrus_fp_register (operands[1], DFmode))
3165 operands[1] = force_reg (DFmode, operands[0]);
3166 emit_insn (gen_cirrus_truncdfsi2 (operands[0], operands[1]));
3173 (define_expand "truncdfsf2"
3174 [(set (match_operand:SF 0 "s_register_operand" "")
3176 (match_operand:DF 1 "s_register_operand" "")))]
3177 "TARGET_ARM && TARGET_HARD_FLOAT"
3181 ;; Zero and sign extension instructions.
3183 (define_insn "zero_extendsidi2"
3184 [(set (match_operand:DI 0 "s_register_operand" "=r")
3185 (zero_extend:DI (match_operand:SI 1 "s_register_operand" "r")))]
3188 if (REGNO (operands[1])
3189 != REGNO (operands[0]) + (WORDS_BIG_ENDIAN ? 1 : 0))
3190 output_asm_insn (\"mov%?\\t%Q0, %1\", operands);
3191 return \"mov%?\\t%R0, #0\";
3193 [(set_attr "length" "8")
3194 (set_attr "predicable" "yes")]
3197 (define_insn "zero_extendqidi2"
3198 [(set (match_operand:DI 0 "s_register_operand" "=r,r")
3199 (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
3202 and%?\\t%Q0, %1, #255\;mov%?\\t%R0, #0
3203 ldr%?b\\t%Q0, %1\;mov%?\\t%R0, #0"
3204 [(set_attr "length" "8")
3205 (set_attr "predicable" "yes")
3206 (set_attr "type" "*,load_byte")
3207 (set_attr "pool_range" "*,4092")
3208 (set_attr "neg_pool_range" "*,4084")]
3211 (define_insn "extendsidi2"
3212 [(set (match_operand:DI 0 "s_register_operand" "=r")
3213 (sign_extend:DI (match_operand:SI 1 "s_register_operand" "r")))]
3216 if (REGNO (operands[1])
3217 != REGNO (operands[0]) + (WORDS_BIG_ENDIAN ? 1 : 0))
3218 output_asm_insn (\"mov%?\\t%Q0, %1\", operands);
3219 return \"mov%?\\t%R0, %Q0, asr #31\";
3221 [(set_attr "length" "8")
3222 (set_attr "shift" "1")
3223 (set_attr "predicable" "yes")]
3226 (define_expand "zero_extendhisi2"
3228 (ashift:SI (match_operand:HI 1 "nonimmediate_operand" "")
3230 (set (match_operand:SI 0 "s_register_operand" "")
3231 (lshiftrt:SI (match_dup 2) (const_int 16)))]
3235 if ((TARGET_THUMB || arm_arch4) && GET_CODE (operands[1]) == MEM)
3237 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
3238 gen_rtx_ZERO_EXTEND (SImode, operands[1])));
3242 if (TARGET_ARM && GET_CODE (operands[1]) == MEM)
3244 emit_insn (gen_movhi_bytes (operands[0], operands[1]));
3248 if (!s_register_operand (operands[1], HImode))
3249 operands[1] = copy_to_mode_reg (HImode, operands[1]);
3253 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
3254 gen_rtx_ZERO_EXTEND (SImode, operands[1])));
3258 operands[1] = gen_lowpart (SImode, operands[1]);
3259 operands[2] = gen_reg_rtx (SImode);
3263 (define_insn "*thumb_zero_extendhisi2"
3264 [(set (match_operand:SI 0 "register_operand" "=l")
3265 (zero_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
3266 "TARGET_THUMB && !arm_arch6"
3268 rtx mem = XEXP (operands[1], 0);
3270 if (GET_CODE (mem) == CONST)
3271 mem = XEXP (mem, 0);
3273 if (GET_CODE (mem) == LABEL_REF)
3274 return \"ldr\\t%0, %1\";
3276 if (GET_CODE (mem) == PLUS)
3278 rtx a = XEXP (mem, 0);
3279 rtx b = XEXP (mem, 1);
3281 /* This can happen due to bugs in reload. */
3282 if (GET_CODE (a) == REG && REGNO (a) == SP_REGNUM)
3285 ops[0] = operands[0];
3288 output_asm_insn (\"mov %0, %1\", ops);
3290 XEXP (mem, 0) = operands[0];
3293 else if ( GET_CODE (a) == LABEL_REF
3294 && GET_CODE (b) == CONST_INT)
3295 return \"ldr\\t%0, %1\";
3298 return \"ldrh\\t%0, %1\";
3300 [(set_attr "length" "4")
3301 (set_attr "type" "load_byte")
3302 (set_attr "pool_range" "60")]
3305 (define_insn "*thumb_zero_extendhisi2_v6"
3306 [(set (match_operand:SI 0 "register_operand" "=l,l")
3307 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "l,m")))]
3308 "TARGET_THUMB && arm_arch6"
3312 if (which_alternative == 0)
3313 return \"uxth\\t%0, %1\";
3315 mem = XEXP (operands[1], 0);
3317 if (GET_CODE (mem) == CONST)
3318 mem = XEXP (mem, 0);
3320 if (GET_CODE (mem) == LABEL_REF)
3321 return \"ldr\\t%0, %1\";
3323 if (GET_CODE (mem) == PLUS)
3325 rtx a = XEXP (mem, 0);
3326 rtx b = XEXP (mem, 1);
3328 /* This can happen due to bugs in reload. */
3329 if (GET_CODE (a) == REG && REGNO (a) == SP_REGNUM)
3332 ops[0] = operands[0];
3335 output_asm_insn (\"mov %0, %1\", ops);
3337 XEXP (mem, 0) = operands[0];
3340 else if ( GET_CODE (a) == LABEL_REF
3341 && GET_CODE (b) == CONST_INT)
3342 return \"ldr\\t%0, %1\";
3345 return \"ldrh\\t%0, %1\";
3347 [(set_attr "length" "2,4")
3348 (set_attr "type" "alu_shift,load_byte")
3349 (set_attr "pool_range" "*,60")]
3352 (define_insn "*arm_zero_extendhisi2"
3353 [(set (match_operand:SI 0 "s_register_operand" "=r")
3354 (zero_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
3355 "TARGET_ARM && arm_arch4 && !arm_arch6"
3357 [(set_attr "type" "load_byte")
3358 (set_attr "predicable" "yes")
3359 (set_attr "pool_range" "256")
3360 (set_attr "neg_pool_range" "244")]
3363 (define_insn "*arm_zero_extendhisi2_v6"
3364 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
3365 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
3366 "TARGET_ARM && arm_arch6"
3370 [(set_attr "type" "alu_shift,load_byte")
3371 (set_attr "predicable" "yes")
3372 (set_attr "pool_range" "*,256")
3373 (set_attr "neg_pool_range" "*,244")]
3376 (define_insn "*arm_zero_extendhisi2addsi"
3377 [(set (match_operand:SI 0 "s_register_operand" "=r")
3378 (plus:SI (zero_extend:SI (match_operand:HI 1 "s_register_operand" "r"))
3379 (match_operand:SI 2 "s_register_operand" "r")))]
3380 "TARGET_ARM && arm_arch6"
3381 "uxtah%?\\t%0, %2, %1"
3382 [(set_attr "type" "alu_shift")
3383 (set_attr "predicable" "yes")]
3387 [(set (match_operand:SI 0 "s_register_operand" "")
3388 (zero_extend:SI (match_operand:HI 1 "alignable_memory_operand" "")))
3389 (clobber (match_operand:SI 2 "s_register_operand" ""))]
3390 "TARGET_ARM && (!arm_arch4)"
3391 [(set (match_dup 2) (match_dup 1))
3392 (set (match_dup 0) (lshiftrt:SI (match_dup 2) (const_int 16)))]
3394 if ((operands[1] = arm_gen_rotated_half_load (operands[1])) == NULL)
3400 [(set (match_operand:SI 0 "s_register_operand" "")
3401 (match_operator:SI 3 "shiftable_operator"
3402 [(zero_extend:SI (match_operand:HI 1 "alignable_memory_operand" ""))
3403 (match_operand:SI 4 "s_register_operand" "")]))
3404 (clobber (match_operand:SI 2 "s_register_operand" ""))]
3405 "TARGET_ARM && (!arm_arch4)"
3406 [(set (match_dup 2) (match_dup 1))
3409 [(lshiftrt:SI (match_dup 2) (const_int 16)) (match_dup 4)]))]
3411 if ((operands[1] = arm_gen_rotated_half_load (operands[1])) == NULL)
3416 (define_expand "zero_extendqisi2"
3417 [(set (match_operand:SI 0 "s_register_operand" "")
3418 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))]
3421 if (!arm_arch6 && GET_CODE (operands[1]) != MEM)
3425 emit_insn (gen_andsi3 (operands[0],
3426 gen_lowpart (SImode, operands[1]),
3429 else /* TARGET_THUMB */
3431 rtx temp = gen_reg_rtx (SImode);
3434 operands[1] = copy_to_mode_reg (QImode, operands[1]);
3435 operands[1] = gen_lowpart (SImode, operands[1]);
3438 ops[1] = operands[1];
3439 ops[2] = GEN_INT (24);
3441 emit_insn (gen_rtx_SET (VOIDmode, ops[0],
3442 gen_rtx_ASHIFT (SImode, ops[1], ops[2])));
3444 ops[0] = operands[0];
3446 ops[2] = GEN_INT (24);
3448 emit_insn (gen_rtx_SET (VOIDmode, ops[0],
3449 gen_rtx_LSHIFTRT (SImode, ops[1], ops[2])));
3456 (define_insn "*thumb_zero_extendqisi2"
3457 [(set (match_operand:SI 0 "register_operand" "=l")
3458 (zero_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
3459 "TARGET_THUMB && !arm_arch6"
3461 [(set_attr "length" "2")
3462 (set_attr "type" "load_byte")
3463 (set_attr "pool_range" "32")]
3466 (define_insn "*thumb_zero_extendqisi2_v6"
3467 [(set (match_operand:SI 0 "register_operand" "=l,l")
3468 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "l,m")))]
3469 "TARGET_THUMB && arm_arch6"
3473 [(set_attr "length" "2,2")
3474 (set_attr "type" "alu_shift,load_byte")
3475 (set_attr "pool_range" "*,32")]
3478 (define_insn "*arm_zero_extendqisi2"
3479 [(set (match_operand:SI 0 "s_register_operand" "=r")
3480 (zero_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
3481 "TARGET_ARM && !arm_arch6"
3482 "ldr%?b\\t%0, %1\\t%@ zero_extendqisi2"
3483 [(set_attr "type" "load_byte")
3484 (set_attr "predicable" "yes")
3485 (set_attr "pool_range" "4096")
3486 (set_attr "neg_pool_range" "4084")]
3489 (define_insn "*arm_zero_extendqisi2_v6"
3490 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
3491 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
3492 "TARGET_ARM && arm_arch6"
3495 ldr%?b\\t%0, %1\\t%@ zero_extendqisi2"
3496 [(set_attr "type" "alu_shift,load_byte")
3497 (set_attr "predicable" "yes")
3498 (set_attr "pool_range" "*,4096")
3499 (set_attr "neg_pool_range" "*,4084")]
3502 (define_insn "*arm_zero_extendqisi2addsi"
3503 [(set (match_operand:SI 0 "s_register_operand" "=r")
3504 (plus:SI (zero_extend:SI (match_operand:QI 1 "s_register_operand" "r"))
3505 (match_operand:SI 2 "s_register_operand" "r")))]
3506 "TARGET_ARM && arm_arch6"
3507 "uxtab%?\\t%0, %2, %1"
3508 [(set_attr "predicable" "yes")
3509 (set_attr "type" "alu_shift")]
3513 [(set (match_operand:SI 0 "s_register_operand" "")
3514 (zero_extend:SI (subreg:QI (match_operand:SI 1 "" "") 0)))
3515 (clobber (match_operand:SI 2 "s_register_operand" ""))]
3516 "TARGET_ARM && (GET_CODE (operands[1]) != MEM) && ! BYTES_BIG_ENDIAN"
3517 [(set (match_dup 2) (match_dup 1))
3518 (set (match_dup 0) (and:SI (match_dup 2) (const_int 255)))]
3522 (define_insn "*compareqi_eq0"
3523 [(set (reg:CC_Z CC_REGNUM)
3524 (compare:CC_Z (match_operand:QI 0 "s_register_operand" "r")
3528 [(set_attr "conds" "set")]
3531 (define_expand "extendhisi2"
3533 (ashift:SI (match_operand:HI 1 "nonimmediate_operand" "")
3535 (set (match_operand:SI 0 "s_register_operand" "")
3536 (ashiftrt:SI (match_dup 2)
3541 if (GET_CODE (operands[1]) == MEM)
3545 emit_insn (gen_thumb_extendhisi2 (operands[0], operands[1]));
3550 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
3551 gen_rtx_SIGN_EXTEND (SImode, operands[1])));
3556 if (TARGET_ARM && GET_CODE (operands[1]) == MEM)
3558 emit_insn (gen_extendhisi2_mem (operands[0], operands[1]));
3562 if (!s_register_operand (operands[1], HImode))
3563 operands[1] = copy_to_mode_reg (HImode, operands[1]);
3568 emit_insn (gen_thumb_extendhisi2 (operands[0], operands[1]));
3570 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
3571 gen_rtx_SIGN_EXTEND (SImode, operands[1])));
3576 operands[1] = gen_lowpart (SImode, operands[1]);
3577 operands[2] = gen_reg_rtx (SImode);
3581 (define_insn "thumb_extendhisi2"
3582 [(set (match_operand:SI 0 "register_operand" "=l")
3583 (sign_extend:SI (match_operand:HI 1 "memory_operand" "m")))
3584 (clobber (match_scratch:SI 2 "=&l"))]
3585 "TARGET_THUMB && !arm_arch6"
3589 rtx mem = XEXP (operands[1], 0);
3591 /* This code used to try to use 'V', and fix the address only if it was
3592 offsettable, but this fails for e.g. REG+48 because 48 is outside the
3593 range of QImode offsets, and offsettable_address_p does a QImode
3596 if (GET_CODE (mem) == CONST)
3597 mem = XEXP (mem, 0);
3599 if (GET_CODE (mem) == LABEL_REF)
3600 return \"ldr\\t%0, %1\";
3602 if (GET_CODE (mem) == PLUS)
3604 rtx a = XEXP (mem, 0);
3605 rtx b = XEXP (mem, 1);
3607 if (GET_CODE (a) == LABEL_REF
3608 && GET_CODE (b) == CONST_INT)
3609 return \"ldr\\t%0, %1\";
3611 if (GET_CODE (b) == REG)
3612 return \"ldrsh\\t%0, %1\";
3620 ops[2] = const0_rtx;
3623 if (GET_CODE (ops[1]) != REG)
3629 ops[0] = operands[0];
3630 ops[3] = operands[2];
3631 output_asm_insn (\"mov\\t%3, %2\;ldrsh\\t%0, [%1, %3]\", ops);
3634 [(set_attr "length" "4")
3635 (set_attr "type" "load_byte")
3636 (set_attr "pool_range" "1020")]
3639 ;; We used to have an early-clobber on the scratch register here.
3640 ;; However, there's a bug somewhere in reload which means that this
3641 ;; can be partially ignored during spill allocation if the memory
3642 ;; address also needs reloading; this causes an abort later on when
3643 ;; we try to verify the operands. Fortunately, we don't really need
3644 ;; the early-clobber: we can always use operand 0 if operand 2
3645 ;; overlaps the address.
3646 (define_insn "*thumb_extendhisi2_insn_v6"
3647 [(set (match_operand:SI 0 "register_operand" "=l,l")
3648 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "l,m")))
3649 (clobber (match_scratch:SI 2 "=X,l"))]
3650 "TARGET_THUMB && arm_arch6"
3656 if (which_alternative == 0)
3657 return \"sxth\\t%0, %1\";
3659 mem = XEXP (operands[1], 0);
3661 /* This code used to try to use 'V', and fix the address only if it was
3662 offsettable, but this fails for e.g. REG+48 because 48 is outside the
3663 range of QImode offsets, and offsettable_address_p does a QImode
3666 if (GET_CODE (mem) == CONST)
3667 mem = XEXP (mem, 0);
3669 if (GET_CODE (mem) == LABEL_REF)
3670 return \"ldr\\t%0, %1\";
3672 if (GET_CODE (mem) == PLUS)
3674 rtx a = XEXP (mem, 0);
3675 rtx b = XEXP (mem, 1);
3677 if (GET_CODE (a) == LABEL_REF
3678 && GET_CODE (b) == CONST_INT)
3679 return \"ldr\\t%0, %1\";
3681 if (GET_CODE (b) == REG)
3682 return \"ldrsh\\t%0, %1\";
3690 ops[2] = const0_rtx;
3693 if (GET_CODE (ops[1]) != REG)
3699 ops[0] = operands[0];
3700 if (reg_mentioned_p (operands[2], ops[1]))
3703 ops[3] = operands[2];
3704 output_asm_insn (\"mov\\t%3, %2\;ldrsh\\t%0, [%1, %3]\", ops);
3707 [(set_attr "length" "2,4")
3708 (set_attr "type" "alu_shift,load_byte")
3709 (set_attr "pool_range" "*,1020")]
3712 (define_expand "extendhisi2_mem"
3713 [(set (match_dup 2) (zero_extend:SI (match_operand:HI 1 "" "")))
3715 (zero_extend:SI (match_dup 7)))
3716 (set (match_dup 6) (ashift:SI (match_dup 4) (const_int 24)))
3717 (set (match_operand:SI 0 "" "")
3718 (ior:SI (ashiftrt:SI (match_dup 6) (const_int 16)) (match_dup 5)))]
3723 rtx addr = copy_to_mode_reg (SImode, XEXP (operands[1], 0));
3725 mem1 = gen_rtx_MEM (QImode, addr);
3726 MEM_COPY_ATTRIBUTES (mem1, operands[1]);
3727 mem2 = gen_rtx_MEM (QImode, plus_constant (addr, 1));
3728 MEM_COPY_ATTRIBUTES (mem2, operands[1]);
3729 operands[0] = gen_lowpart (SImode, operands[0]);
3731 operands[2] = gen_reg_rtx (SImode);
3732 operands[3] = gen_reg_rtx (SImode);
3733 operands[6] = gen_reg_rtx (SImode);
3736 if (BYTES_BIG_ENDIAN)
3738 operands[4] = operands[2];
3739 operands[5] = operands[3];
3743 operands[4] = operands[3];
3744 operands[5] = operands[2];
3749 (define_insn "*arm_extendhisi2"
3750 [(set (match_operand:SI 0 "s_register_operand" "=r")
3751 (sign_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
3752 "TARGET_ARM && arm_arch4 && !arm_arch6"
3754 [(set_attr "type" "load_byte")
3755 (set_attr "predicable" "yes")
3756 (set_attr "pool_range" "256")
3757 (set_attr "neg_pool_range" "244")]
3760 (define_insn "*arm_extendhisi2_v6"
3761 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
3762 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
3763 "TARGET_ARM && arm_arch6"
3767 [(set_attr "type" "alu_shift,load_byte")
3768 (set_attr "predicable" "yes")
3769 (set_attr "pool_range" "*,256")
3770 (set_attr "neg_pool_range" "*,244")]
3773 (define_insn "*arm_extendhisi2addsi"
3774 [(set (match_operand:SI 0 "s_register_operand" "=r")
3775 (plus:SI (sign_extend:SI (match_operand:HI 1 "s_register_operand" "r"))
3776 (match_operand:SI 2 "s_register_operand" "r")))]
3777 "TARGET_ARM && arm_arch6"
3778 "sxtah%?\\t%0, %2, %1"
3782 [(set (match_operand:SI 0 "s_register_operand" "")
3783 (sign_extend:SI (match_operand:HI 1 "alignable_memory_operand" "")))
3784 (clobber (match_operand:SI 2 "s_register_operand" ""))]
3785 "TARGET_ARM && (!arm_arch4)"
3786 [(set (match_dup 2) (match_dup 1))
3787 (set (match_dup 0) (ashiftrt:SI (match_dup 2) (const_int 16)))]
3789 if ((operands[1] = arm_gen_rotated_half_load (operands[1])) == NULL)
3795 [(set (match_operand:SI 0 "s_register_operand" "")
3796 (match_operator:SI 3 "shiftable_operator"
3797 [(sign_extend:SI (match_operand:HI 1 "alignable_memory_operand" ""))
3798 (match_operand:SI 4 "s_register_operand" "")]))
3799 (clobber (match_operand:SI 2 "s_register_operand" ""))]
3800 "TARGET_ARM && (!arm_arch4)"
3801 [(set (match_dup 2) (match_dup 1))
3804 [(ashiftrt:SI (match_dup 2) (const_int 16)) (match_dup 4)]))]
3805 "if ((operands[1] = arm_gen_rotated_half_load (operands[1])) == NULL)
3810 (define_expand "extendqihi2"
3812 (ashift:SI (match_operand:QI 1 "general_operand" "")
3814 (set (match_operand:HI 0 "s_register_operand" "")
3815 (ashiftrt:SI (match_dup 2)
3820 if (arm_arch4 && GET_CODE (operands[1]) == MEM)
3822 emit_insn (gen_rtx_SET (VOIDmode,
3824 gen_rtx_SIGN_EXTEND (HImode, operands[1])));
3827 if (!s_register_operand (operands[1], QImode))
3828 operands[1] = copy_to_mode_reg (QImode, operands[1]);
3829 operands[0] = gen_lowpart (SImode, operands[0]);
3830 operands[1] = gen_lowpart (SImode, operands[1]);
3831 operands[2] = gen_reg_rtx (SImode);
3835 (define_insn "*extendqihi_insn"
3836 [(set (match_operand:HI 0 "s_register_operand" "=r")
3837 (sign_extend:HI (match_operand:QI 1 "memory_operand" "Uq")))]
3838 "TARGET_ARM && arm_arch4"
3840 [(set_attr "type" "load_byte")
3841 (set_attr "predicable" "yes")
3842 (set_attr "pool_range" "256")
3843 (set_attr "neg_pool_range" "244")]
3846 (define_expand "extendqisi2"
3848 (ashift:SI (match_operand:QI 1 "general_operand" "")
3850 (set (match_operand:SI 0 "s_register_operand" "")
3851 (ashiftrt:SI (match_dup 2)
3856 if ((TARGET_THUMB || arm_arch4) && GET_CODE (operands[1]) == MEM)
3858 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
3859 gen_rtx_SIGN_EXTEND (SImode, operands[1])));
3863 if (!s_register_operand (operands[1], QImode))
3864 operands[1] = copy_to_mode_reg (QImode, operands[1]);
3868 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
3869 gen_rtx_SIGN_EXTEND (SImode, operands[1])));
3873 operands[1] = gen_lowpart (SImode, operands[1]);
3874 operands[2] = gen_reg_rtx (SImode);
3878 (define_insn "*arm_extendqisi"
3879 [(set (match_operand:SI 0 "s_register_operand" "=r")
3880 (sign_extend:SI (match_operand:QI 1 "memory_operand" "Uq")))]
3881 "TARGET_ARM && arm_arch4 && !arm_arch6"
3883 [(set_attr "type" "load_byte")
3884 (set_attr "predicable" "yes")
3885 (set_attr "pool_range" "256")
3886 (set_attr "neg_pool_range" "244")]
3889 (define_insn "*arm_extendqisi_v6"
3890 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
3891 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "r,Uq")))]
3892 "TARGET_ARM && arm_arch6"
3896 [(set_attr "type" "alu_shift,load_byte")
3897 (set_attr "predicable" "yes")
3898 (set_attr "pool_range" "*,256")
3899 (set_attr "neg_pool_range" "*,244")]
3902 (define_insn "*arm_extendqisi2addsi"
3903 [(set (match_operand:SI 0 "s_register_operand" "=r")
3904 (plus:SI (sign_extend:SI (match_operand:QI 1 "s_register_operand" "r"))
3905 (match_operand:SI 2 "s_register_operand" "r")))]
3906 "TARGET_ARM && arm_arch6"
3907 "sxtab%?\\t%0, %2, %1"
3908 [(set_attr "type" "alu_shift")
3909 (set_attr "predicable" "yes")]
3912 (define_insn "*thumb_extendqisi2"
3913 [(set (match_operand:SI 0 "register_operand" "=l,l")
3914 (sign_extend:SI (match_operand:QI 1 "memory_operand" "V,m")))]
3915 "TARGET_THUMB && !arm_arch6"
3919 rtx 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 (\"lsl\\t%0, %0, #24\", ops);
3952 output_asm_insn (\"asr\\t%0, %0, #24\", ops);
3955 output_asm_insn (\"mov\\t%0, %2\;ldrsb\\t%0, [%1, %0]\", ops);
3957 else if (GET_CODE (b) != REG)
3961 if (REGNO (b) == REGNO (ops[0]))
3963 output_asm_insn (\"ldrb\\t%0, [%2, %1]\", ops);
3964 output_asm_insn (\"lsl\\t%0, %0, #24\", ops);
3965 output_asm_insn (\"asr\\t%0, %0, #24\", ops);
3968 output_asm_insn (\"mov\\t%0, %2\;ldrsb\\t%0, [%1, %0]\", ops);
3971 else if (GET_CODE (mem) == REG && REGNO (ops[0]) == REGNO (mem))
3973 output_asm_insn (\"ldrb\\t%0, [%0, #0]\", ops);
3974 output_asm_insn (\"lsl\\t%0, %0, #24\", ops);
3975 output_asm_insn (\"asr\\t%0, %0, #24\", ops);
3980 ops[2] = const0_rtx;
3982 output_asm_insn (\"mov\\t%0, %2\;ldrsb\\t%0, [%1, %0]\", ops);
3986 [(set_attr "length" "2,6")
3987 (set_attr "type" "load_byte,load_byte")
3988 (set_attr "pool_range" "32,32")]
3991 (define_insn "*thumb_extendqisi2_v6"
3992 [(set (match_operand:SI 0 "register_operand" "=l,l,l")
3993 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "l,V,m")))]
3994 "TARGET_THUMB && arm_arch6"
4000 if (which_alternative == 0)
4001 return \"sxtb\\t%0, %1\";
4003 mem = XEXP (operands[1], 0);
4005 if (GET_CODE (mem) == CONST)
4006 mem = XEXP (mem, 0);
4008 if (GET_CODE (mem) == LABEL_REF)
4009 return \"ldr\\t%0, %1\";
4011 if (GET_CODE (mem) == PLUS
4012 && GET_CODE (XEXP (mem, 0)) == LABEL_REF)
4013 return \"ldr\\t%0, %1\";
4015 if (which_alternative == 0)
4016 return \"ldrsb\\t%0, %1\";
4018 ops[0] = operands[0];
4020 if (GET_CODE (mem) == PLUS)
4022 rtx a = XEXP (mem, 0);
4023 rtx b = XEXP (mem, 1);
4028 if (GET_CODE (a) == REG)
4030 if (GET_CODE (b) == REG)
4031 output_asm_insn (\"ldrsb\\t%0, [%1, %2]\", ops);
4032 else if (REGNO (a) == REGNO (ops[0]))
4034 output_asm_insn (\"ldrb\\t%0, [%1, %2]\", ops);
4035 output_asm_insn (\"sxtb\\t%0, %0\", ops);
4038 output_asm_insn (\"mov\\t%0, %2\;ldrsb\\t%0, [%1, %0]\", ops);
4040 else if (GET_CODE (b) != REG)
4044 if (REGNO (b) == REGNO (ops[0]))
4046 output_asm_insn (\"ldrb\\t%0, [%2, %1]\", ops);
4047 output_asm_insn (\"sxtb\\t%0, %0\", ops);
4050 output_asm_insn (\"mov\\t%0, %2\;ldrsb\\t%0, [%1, %0]\", ops);
4053 else if (GET_CODE (mem) == REG && REGNO (ops[0]) == REGNO (mem))
4055 output_asm_insn (\"ldrb\\t%0, [%0, #0]\", ops);
4056 output_asm_insn (\"sxtb\\t%0, %0\", ops);
4061 ops[2] = const0_rtx;
4063 output_asm_insn (\"mov\\t%0, %2\;ldrsb\\t%0, [%1, %0]\", ops);
4067 [(set_attr "length" "2,2,4")
4068 (set_attr "type" "alu_shift,load_byte,load_byte")
4069 (set_attr "pool_range" "*,32,32")]
4072 (define_expand "extendsfdf2"
4073 [(set (match_operand:DF 0 "s_register_operand" "")
4074 (float_extend:DF (match_operand:SF 1 "s_register_operand" "")))]
4075 "TARGET_ARM && TARGET_HARD_FLOAT"
4079 ;; Move insns (including loads and stores)
4081 ;; XXX Just some ideas about movti.
4082 ;; I don't think these are a good idea on the arm, there just aren't enough
4084 ;;(define_expand "loadti"
4085 ;; [(set (match_operand:TI 0 "s_register_operand" "")
4086 ;; (mem:TI (match_operand:SI 1 "address_operand" "")))]
4089 ;;(define_expand "storeti"
4090 ;; [(set (mem:TI (match_operand:TI 0 "address_operand" ""))
4091 ;; (match_operand:TI 1 "s_register_operand" ""))]
4094 ;;(define_expand "movti"
4095 ;; [(set (match_operand:TI 0 "general_operand" "")
4096 ;; (match_operand:TI 1 "general_operand" ""))]
4102 ;; if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
4103 ;; operands[1] = copy_to_reg (operands[1]);
4104 ;; if (GET_CODE (operands[0]) == MEM)
4105 ;; insn = gen_storeti (XEXP (operands[0], 0), operands[1]);
4106 ;; else if (GET_CODE (operands[1]) == MEM)
4107 ;; insn = gen_loadti (operands[0], XEXP (operands[1], 0));
4111 ;; emit_insn (insn);
4115 ;; Recognize garbage generated above.
4118 ;; [(set (match_operand:TI 0 "general_operand" "=r,r,r,<,>,m")
4119 ;; (match_operand:TI 1 "general_operand" "<,>,m,r,r,r"))]
4123 ;; register mem = (which_alternative < 3);
4124 ;; register const char *template;
4126 ;; operands[mem] = XEXP (operands[mem], 0);
4127 ;; switch (which_alternative)
4129 ;; case 0: template = \"ldmdb\\t%1!, %M0\"; break;
4130 ;; case 1: template = \"ldmia\\t%1!, %M0\"; break;
4131 ;; case 2: template = \"ldmia\\t%1, %M0\"; break;
4132 ;; case 3: template = \"stmdb\\t%0!, %M1\"; break;
4133 ;; case 4: template = \"stmia\\t%0!, %M1\"; break;
4134 ;; case 5: template = \"stmia\\t%0, %M1\"; break;
4136 ;; output_asm_insn (template, operands);
4140 (define_expand "movdi"
4141 [(set (match_operand:DI 0 "general_operand" "")
4142 (match_operand:DI 1 "general_operand" ""))]
4147 if (!no_new_pseudos)
4149 if (GET_CODE (operands[0]) != REG)
4150 operands[1] = force_reg (DImode, operands[1]);
4156 (define_insn "*arm_movdi"
4157 [(set (match_operand:DI 0 "nonimmediate_di_operand" "=r, r ,m")
4158 (match_operand:DI 1 "di_operand" "rIK,mi,r"))]
4160 && !(TARGET_HARD_FLOAT && (TARGET_MAVERICK || TARGET_VFP))
4163 return (output_move_double (operands));
4165 [(set_attr "length" "8")
4166 (set_attr "type" "*,load2,store2")
4167 (set_attr "pool_range" "*,1020,*")
4168 (set_attr "neg_pool_range" "*,1008,*")]
4171 ;; We can't actually do base+index doubleword loads if the index and
4172 ;; destination overlap. Split here so that we at least have chance to
4175 [(set (match_operand:DI 0 "s_register_operand" "")
4176 (mem:DI (plus:SI (match_operand:SI 1 "s_register_operand" "")
4177 (match_operand:SI 2 "s_register_operand" ""))))]
4179 && reg_overlap_mentioned_p (operands[0], operands[1])
4180 && reg_overlap_mentioned_p (operands[0], operands[2])"
4182 (plus:SI (match_dup 1)
4185 (mem:DI (match_dup 4)))]
4187 operands[4] = gen_rtx_REG (SImode, REGNO(operands[0]));
4191 ;;; ??? This should have alternatives for constants.
4192 ;;; ??? This was originally identical to the movdf_insn pattern.
4193 ;;; ??? The 'i' constraint looks funny, but it should always be replaced by
4194 ;;; thumb_reorg with a memory reference.
4195 (define_insn "*thumb_movdi_insn"
4196 [(set (match_operand:DI 0 "nonimmediate_operand" "=l,l,l,l,>,l, m,*r")
4197 (match_operand:DI 1 "general_operand" "l, I,J,>,l,mi,l,*r"))]
4199 && !(TARGET_HARD_FLOAT && TARGET_MAVERICK)
4200 && ( register_operand (operands[0], DImode)
4201 || register_operand (operands[1], DImode))"
4204 switch (which_alternative)
4208 if (REGNO (operands[1]) == REGNO (operands[0]) + 1)
4209 return \"add\\t%0, %1, #0\;add\\t%H0, %H1, #0\";
4210 return \"add\\t%H0, %H1, #0\;add\\t%0, %1, #0\";
4212 return \"mov\\t%Q0, %1\;mov\\t%R0, #0\";
4214 operands[1] = GEN_INT (- INTVAL (operands[1]));
4215 return \"mov\\t%Q0, %1\;neg\\t%Q0, %Q0\;asr\\t%R0, %Q0, #31\";
4217 return \"ldmia\\t%1, {%0, %H0}\";
4219 return \"stmia\\t%0, {%1, %H1}\";
4221 return thumb_load_double_from_address (operands);
4223 operands[2] = gen_rtx_MEM (SImode,
4224 plus_constant (XEXP (operands[0], 0), 4));
4225 output_asm_insn (\"str\\t%1, %0\;str\\t%H1, %2\", operands);
4228 if (REGNO (operands[1]) == REGNO (operands[0]) + 1)
4229 return \"mov\\t%0, %1\;mov\\t%H0, %H1\";
4230 return \"mov\\t%H0, %H1\;mov\\t%0, %1\";
4233 [(set_attr "length" "4,4,6,2,2,6,4,4")
4234 (set_attr "type" "*,*,*,load2,store2,load2,store2,*")
4235 (set_attr "pool_range" "*,*,*,*,*,1020,*,*")]
4238 (define_expand "movsi"
4239 [(set (match_operand:SI 0 "general_operand" "")
4240 (match_operand:SI 1 "general_operand" ""))]
4245 /* Everything except mem = const or mem = mem can be done easily. */
4246 if (GET_CODE (operands[0]) == MEM)
4247 operands[1] = force_reg (SImode, operands[1]);
4248 if (arm_general_register_operand (operands[0], SImode)
4249 && GET_CODE (operands[1]) == CONST_INT
4250 && !(const_ok_for_arm (INTVAL (operands[1]))
4251 || const_ok_for_arm (~INTVAL (operands[1]))))
4253 arm_split_constant (SET, SImode, NULL_RTX,
4254 INTVAL (operands[1]), operands[0], NULL_RTX,
4255 optimize && !no_new_pseudos);
4259 else /* TARGET_THUMB.... */
4261 if (!no_new_pseudos)
4263 if (GET_CODE (operands[0]) != REG)
4264 operands[1] = force_reg (SImode, operands[1]);
4269 && (CONSTANT_P (operands[1])
4270 || symbol_mentioned_p (operands[1])
4271 || label_mentioned_p (operands[1])))
4272 operands[1] = legitimize_pic_address (operands[1], SImode,
4273 (no_new_pseudos ? operands[0] : 0));
4277 (define_insn "*arm_movsi_insn"
4278 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r, m")
4279 (match_operand:SI 1 "general_operand" "rI,K,mi,r"))]
4280 "TARGET_ARM && ! TARGET_IWMMXT
4281 && !(TARGET_HARD_FLOAT && TARGET_VFP)
4282 && ( register_operand (operands[0], SImode)
4283 || register_operand (operands[1], SImode))"
4289 [(set_attr "type" "*,*,load1,store1")
4290 (set_attr "predicable" "yes")
4291 (set_attr "pool_range" "*,*,4096,*")
4292 (set_attr "neg_pool_range" "*,*,4084,*")]
4296 [(set (match_operand:SI 0 "arm_general_register_operand" "")
4297 (match_operand:SI 1 "const_int_operand" ""))]
4299 && (!(const_ok_for_arm (INTVAL (operands[1]))
4300 || const_ok_for_arm (~INTVAL (operands[1]))))"
4301 [(clobber (const_int 0))]
4303 arm_split_constant (SET, SImode, NULL_RTX,
4304 INTVAL (operands[1]), operands[0], NULL_RTX, 0);
4309 (define_insn "*thumb_movsi_insn"
4310 [(set (match_operand:SI 0 "nonimmediate_operand" "=l,l,l,l,l,>,l, m,*lh")
4311 (match_operand:SI 1 "general_operand" "l, I,J,K,>,l,mi,l,*lh"))]
4313 && ( register_operand (operands[0], SImode)
4314 || register_operand (operands[1], SImode))"
4325 [(set_attr "length" "2,2,4,4,2,2,2,2,2")
4326 (set_attr "type" "*,*,*,*,load1,store1,load1,store1,*")
4327 (set_attr "pool_range" "*,*,*,*,*,*,1020,*,*")]
4331 [(set (match_operand:SI 0 "register_operand" "")
4332 (match_operand:SI 1 "const_int_operand" ""))]
4333 "TARGET_THUMB && CONST_OK_FOR_THUMB_LETTER (INTVAL (operands[1]), 'J')"
4334 [(set (match_dup 0) (match_dup 1))
4335 (set (match_dup 0) (neg:SI (match_dup 0)))]
4336 "operands[1] = GEN_INT (- INTVAL (operands[1]));"
4340 [(set (match_operand:SI 0 "register_operand" "")
4341 (match_operand:SI 1 "const_int_operand" ""))]
4342 "TARGET_THUMB && CONST_OK_FOR_THUMB_LETTER (INTVAL (operands[1]), 'K')"
4343 [(set (match_dup 0) (match_dup 1))
4344 (set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))]
4347 unsigned HOST_WIDE_INT val = INTVAL (operands[1]);
4348 unsigned HOST_WIDE_INT mask = 0xff;
4351 for (i = 0; i < 25; i++)
4352 if ((val & (mask << i)) == val)
4355 /* Shouldn't happen, but we don't want to split if the shift is zero. */
4359 operands[1] = GEN_INT (val >> i);
4360 operands[2] = GEN_INT (i);
4364 ;; When generating pic, we need to load the symbol offset into a register.
4365 ;; So that the optimizer does not confuse this with a normal symbol load
4366 ;; we use an unspec. The offset will be loaded from a constant pool entry,
4367 ;; since that is the only type of relocation we can use.
4369 ;; The rather odd constraints on the following are to force reload to leave
4370 ;; the insn alone, and to force the minipool generation pass to then move
4371 ;; the GOT symbol to memory.
4373 (define_insn "pic_load_addr_arm"
4374 [(set (match_operand:SI 0 "s_register_operand" "=r")
4375 (unspec:SI [(match_operand:SI 1 "" "mX")] UNSPEC_PIC_SYM))]
4376 "TARGET_ARM && flag_pic"
4378 [(set_attr "type" "load1")
4379 (set (attr "pool_range") (const_int 4096))
4380 (set (attr "neg_pool_range") (const_int 4084))]
4383 (define_insn "pic_load_addr_thumb"
4384 [(set (match_operand:SI 0 "s_register_operand" "=l")
4385 (unspec:SI [(match_operand:SI 1 "" "mX")] UNSPEC_PIC_SYM))]
4386 "TARGET_THUMB && flag_pic"
4388 [(set_attr "type" "load1")
4389 (set (attr "pool_range") (const_int 1024))]
4392 ;; This variant is used for AOF assembly, since it needs to mention the
4393 ;; pic register in the rtl.
4394 (define_expand "pic_load_addr_based"
4395 [(set (match_operand:SI 0 "s_register_operand" "")
4396 (unspec:SI [(match_operand 1 "" "") (match_dup 2)] UNSPEC_PIC_SYM))]
4397 "TARGET_ARM && flag_pic"
4398 "operands[2] = pic_offset_table_rtx;"
4401 (define_insn "*pic_load_addr_based_insn"
4402 [(set (match_operand:SI 0 "s_register_operand" "=r")
4403 (unspec:SI [(match_operand 1 "" "")
4404 (match_operand 2 "s_register_operand" "r")]
4406 "TARGET_EITHER && flag_pic && operands[2] == pic_offset_table_rtx"
4408 #ifdef AOF_ASSEMBLER
4409 operands[1] = aof_pic_entry (operands[1]);
4411 output_asm_insn (\"ldr%?\\t%0, %a1\", operands);
4414 [(set_attr "type" "load1")
4415 (set (attr "pool_range")
4416 (if_then_else (eq_attr "is_thumb" "yes")
4419 (set (attr "neg_pool_range")
4420 (if_then_else (eq_attr "is_thumb" "yes")
4425 (define_insn "pic_add_dot_plus_four"
4426 [(set (match_operand:SI 0 "register_operand" "+r")
4427 (unspec:SI [(plus:SI (match_dup 0)
4428 (const (plus:SI (pc) (const_int 4))))]
4430 (use (label_ref (match_operand 1 "" "")))]
4431 "TARGET_THUMB && flag_pic"
4433 (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
4434 CODE_LABEL_NUMBER (operands[1]));
4435 return \"add\\t%0, %|pc\";
4437 [(set_attr "length" "2")]
4440 (define_insn "pic_add_dot_plus_eight"
4441 [(set (match_operand:SI 0 "register_operand" "+r")
4442 (unspec:SI [(plus:SI (match_dup 0)
4443 (const (plus:SI (pc) (const_int 8))))]
4445 (use (label_ref (match_operand 1 "" "")))]
4446 "TARGET_ARM && flag_pic"
4448 (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
4449 CODE_LABEL_NUMBER (operands[1]));
4450 return \"add%?\\t%0, %|pc, %0\";
4452 [(set_attr "predicable" "yes")]
4455 (define_expand "builtin_setjmp_receiver"
4456 [(label_ref (match_operand 0 "" ""))]
4460 arm_load_pic_register ();
4464 ;; If copying one reg to another we can set the condition codes according to
4465 ;; its value. Such a move is common after a return from subroutine and the
4466 ;; result is being tested against zero.
4468 (define_insn "*movsi_compare0"
4469 [(set (reg:CC CC_REGNUM)
4470 (compare:CC (match_operand:SI 1 "s_register_operand" "0,r")
4472 (set (match_operand:SI 0 "s_register_operand" "=r,r")
4477 sub%?s\\t%0, %1, #0"
4478 [(set_attr "conds" "set")]
4481 ;; Subroutine to store a half word from a register into memory.
4482 ;; Operand 0 is the source register (HImode)
4483 ;; Operand 1 is the destination address in a register (SImode)
4485 ;; In both this routine and the next, we must be careful not to spill
4486 ;; a memory address of reg+large_const into a separate PLUS insn, since this
4487 ;; can generate unrecognizable rtl.
4489 (define_expand "storehi"
4490 [;; store the low byte
4491 (set (match_operand 1 "" "") (match_dup 3))
4492 ;; extract the high byte
4494 (ashiftrt:SI (match_operand 0 "" "") (const_int 8)))
4495 ;; store the high byte
4496 (set (match_dup 4) (match_dup 5))]
4500 rtx op1 = operands[1];
4501 rtx addr = XEXP (op1, 0);
4502 enum rtx_code code = GET_CODE (addr);
4504 if ((code == PLUS && GET_CODE (XEXP (addr, 1)) != CONST_INT)
4506 op1 = replace_equiv_address (operands[1], force_reg (SImode, addr));
4508 operands[4] = adjust_address (op1, QImode, 1);
4509 operands[1] = adjust_address (operands[1], QImode, 0);
4510 operands[3] = gen_lowpart (QImode, operands[0]);
4511 operands[0] = gen_lowpart (SImode, operands[0]);
4512 operands[2] = gen_reg_rtx (SImode);
4513 operands[5] = gen_lowpart (QImode, operands[2]);
4517 (define_expand "storehi_bigend"
4518 [(set (match_dup 4) (match_dup 3))
4520 (ashiftrt:SI (match_operand 0 "" "") (const_int 8)))
4521 (set (match_operand 1 "" "") (match_dup 5))]
4525 rtx op1 = operands[1];
4526 rtx addr = XEXP (op1, 0);
4527 enum rtx_code code = GET_CODE (addr);
4529 if ((code == PLUS && GET_CODE (XEXP (addr, 1)) != CONST_INT)
4531 op1 = replace_equiv_address (op1, force_reg (SImode, addr));
4533 operands[4] = adjust_address (op1, QImode, 1);
4534 operands[1] = adjust_address (operands[1], QImode, 0);
4535 operands[3] = gen_lowpart (QImode, operands[0]);
4536 operands[0] = gen_lowpart (SImode, operands[0]);
4537 operands[2] = gen_reg_rtx (SImode);
4538 operands[5] = gen_lowpart (QImode, operands[2]);
4542 ;; Subroutine to store a half word integer constant into memory.
4543 (define_expand "storeinthi"
4544 [(set (match_operand 0 "" "")
4545 (match_operand 1 "" ""))
4546 (set (match_dup 3) (match_dup 2))]
4550 HOST_WIDE_INT value = INTVAL (operands[1]);
4551 rtx addr = XEXP (operands[0], 0);
4552 rtx op0 = operands[0];
4553 enum rtx_code code = GET_CODE (addr);
4555 if ((code == PLUS && GET_CODE (XEXP (addr, 1)) != CONST_INT)
4557 op0 = replace_equiv_address (op0, force_reg (SImode, addr));
4559 operands[1] = gen_reg_rtx (SImode);
4560 if (BYTES_BIG_ENDIAN)
4562 emit_insn (gen_movsi (operands[1], GEN_INT ((value >> 8) & 255)));
4563 if ((value & 255) == ((value >> 8) & 255))
4564 operands[2] = operands[1];
4567 operands[2] = gen_reg_rtx (SImode);
4568 emit_insn (gen_movsi (operands[2], GEN_INT (value & 255)));
4573 emit_insn (gen_movsi (operands[1], GEN_INT (value & 255)));
4574 if ((value & 255) == ((value >> 8) & 255))
4575 operands[2] = operands[1];
4578 operands[2] = gen_reg_rtx (SImode);
4579 emit_insn (gen_movsi (operands[2], GEN_INT ((value >> 8) & 255)));
4583 operands[3] = adjust_address (op0, QImode, 1);
4584 operands[0] = adjust_address (operands[0], QImode, 0);
4585 operands[2] = gen_lowpart (QImode, operands[2]);
4586 operands[1] = gen_lowpart (QImode, operands[1]);
4590 (define_expand "storehi_single_op"
4591 [(set (match_operand:HI 0 "memory_operand" "")
4592 (match_operand:HI 1 "general_operand" ""))]
4593 "TARGET_ARM && arm_arch4"
4595 if (!s_register_operand (operands[1], HImode))
4596 operands[1] = copy_to_mode_reg (HImode, operands[1]);
4600 (define_expand "movhi"
4601 [(set (match_operand:HI 0 "general_operand" "")
4602 (match_operand:HI 1 "general_operand" ""))]
4607 if (!no_new_pseudos)
4609 if (GET_CODE (operands[0]) == MEM)
4613 emit_insn (gen_storehi_single_op (operands[0], operands[1]));
4616 if (GET_CODE (operands[1]) == CONST_INT)
4617 emit_insn (gen_storeinthi (operands[0], operands[1]));
4620 if (GET_CODE (operands[1]) == MEM)
4621 operands[1] = force_reg (HImode, operands[1]);
4622 if (BYTES_BIG_ENDIAN)
4623 emit_insn (gen_storehi_bigend (operands[1], operands[0]));
4625 emit_insn (gen_storehi (operands[1], operands[0]));
4629 /* Sign extend a constant, and keep it in an SImode reg. */
4630 else if (GET_CODE (operands[1]) == CONST_INT)
4632 rtx reg = gen_reg_rtx (SImode);
4633 HOST_WIDE_INT val = INTVAL (operands[1]) & 0xffff;
4635 /* If the constant is already valid, leave it alone. */
4636 if (!const_ok_for_arm (val))
4638 /* If setting all the top bits will make the constant
4639 loadable in a single instruction, then set them.
4640 Otherwise, sign extend the number. */
4642 if (const_ok_for_arm (~(val | ~0xffff)))
4644 else if (val & 0x8000)
4648 emit_insn (gen_movsi (reg, GEN_INT (val)));
4649 operands[1] = gen_lowpart (HImode, reg);
4651 else if (arm_arch4 && optimize && !no_new_pseudos
4652 && GET_CODE (operands[1]) == MEM)
4654 rtx reg = gen_reg_rtx (SImode);
4656 emit_insn (gen_zero_extendhisi2 (reg, operands[1]));
4657 operands[1] = gen_lowpart (HImode, reg);
4659 else if (!arm_arch4)
4661 if (GET_CODE (operands[1]) == MEM)
4664 rtx offset = const0_rtx;
4665 rtx reg = gen_reg_rtx (SImode);
4667 if ((GET_CODE (base = XEXP (operands[1], 0)) == REG
4668 || (GET_CODE (base) == PLUS
4669 && (GET_CODE (offset = XEXP (base, 1))
4671 && ((INTVAL(offset) & 1) != 1)
4672 && GET_CODE (base = XEXP (base, 0)) == REG))
4673 && REGNO_POINTER_ALIGN (REGNO (base)) >= 32)
4675 HOST_WIDE_INT new_offset = INTVAL (offset) & ~3;
4678 new = gen_rtx_MEM (SImode,
4679 plus_constant (base, new_offset));
4680 MEM_COPY_ATTRIBUTES (new, operands[1]);
4681 emit_insn (gen_movsi (reg, new));
4682 if (((INTVAL (offset) & 2) != 0)
4683 ^ (BYTES_BIG_ENDIAN ? 1 : 0))
4685 rtx reg2 = gen_reg_rtx (SImode);
4687 emit_insn (gen_lshrsi3 (reg2, reg, GEN_INT (16)));
4692 emit_insn (gen_movhi_bytes (reg, operands[1]));
4694 operands[1] = gen_lowpart (HImode, reg);
4698 /* Handle loading a large integer during reload. */
4699 else if (GET_CODE (operands[1]) == CONST_INT
4700 && !const_ok_for_arm (INTVAL (operands[1]))
4701 && !const_ok_for_arm (~INTVAL (operands[1])))
4703 /* Writing a constant to memory needs a scratch, which should
4704 be handled with SECONDARY_RELOADs. */
4705 if (GET_CODE (operands[0]) != REG)
4708 operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
4709 emit_insn (gen_movsi (operands[0], operands[1]));
4713 else /* TARGET_THUMB */
4715 if (!no_new_pseudos)
4717 if (GET_CODE (operands[0]) != REG)
4718 operands[1] = force_reg (HImode, operands[1]);
4720 /* ??? We shouldn't really get invalid addresses here, but this can
4721 happen if we are passed a SP (never OK for HImode/QImode) or
4722 virtual register (rejected by GO_IF_LEGITIMATE_ADDRESS for
4723 HImode/QImode) relative address. */
4724 /* ??? This should perhaps be fixed elsewhere, for instance, in
4725 fixup_stack_1, by checking for other kinds of invalid addresses,
4726 e.g. a bare reference to a virtual register. This may confuse the
4727 alpha though, which must handle this case differently. */
4728 if (GET_CODE (operands[0]) == MEM
4729 && !memory_address_p (GET_MODE (operands[0]),
4730 XEXP (operands[0], 0)))
4732 = replace_equiv_address (operands[0],
4733 copy_to_reg (XEXP (operands[0], 0)));
4735 if (GET_CODE (operands[1]) == MEM
4736 && !memory_address_p (GET_MODE (operands[1]),
4737 XEXP (operands[1], 0)))
4739 = replace_equiv_address (operands[1],
4740 copy_to_reg (XEXP (operands[1], 0)));
4742 /* Handle loading a large integer during reload. */
4743 else if (GET_CODE (operands[1]) == CONST_INT
4744 && !CONST_OK_FOR_THUMB_LETTER (INTVAL (operands[1]), 'I'))
4746 /* Writing a constant to memory needs a scratch, which should
4747 be handled with SECONDARY_RELOADs. */
4748 if (GET_CODE (operands[0]) != REG)
4751 operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
4752 emit_insn (gen_movsi (operands[0], operands[1]));
4759 (define_insn "*thumb_movhi_insn"
4760 [(set (match_operand:HI 0 "nonimmediate_operand" "=l,l,m,*r,*h,l")
4761 (match_operand:HI 1 "general_operand" "l,m,l,*h,*r,I"))]
4763 && ( register_operand (operands[0], HImode)
4764 || register_operand (operands[1], HImode))"
4766 switch (which_alternative)
4768 case 0: return \"add %0, %1, #0\";
4769 case 2: return \"strh %1, %0\";
4770 case 3: return \"mov %0, %1\";
4771 case 4: return \"mov %0, %1\";
4772 case 5: return \"mov %0, %1\";
4775 /* The stack pointer can end up being taken as an index register.
4776 Catch this case here and deal with it. */
4777 if (GET_CODE (XEXP (operands[1], 0)) == PLUS
4778 && GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == REG
4779 && REGNO (XEXP (XEXP (operands[1], 0), 0)) == SP_REGNUM)
4782 ops[0] = operands[0];
4783 ops[1] = XEXP (XEXP (operands[1], 0), 0);
4785 output_asm_insn (\"mov %0, %1\", ops);
4787 XEXP (XEXP (operands[1], 0), 0) = operands[0];
4790 return \"ldrh %0, %1\";
4792 [(set_attr "length" "2,4,2,2,2,2")
4793 (set_attr "type" "*,load1,store1,*,*,*")]
4797 (define_expand "movhi_bytes"
4798 [(set (match_dup 2) (zero_extend:SI (match_operand:HI 1 "" "")))
4800 (zero_extend:SI (match_dup 6)))
4801 (set (match_operand:SI 0 "" "")
4802 (ior:SI (ashift:SI (match_dup 4) (const_int 8)) (match_dup 5)))]
4807 rtx addr = copy_to_mode_reg (SImode, XEXP (operands[1], 0));
4809 mem1 = gen_rtx_MEM (QImode, addr);
4810 MEM_COPY_ATTRIBUTES (mem1, operands[1]);
4811 mem2 = gen_rtx_MEM (QImode, plus_constant (addr, 1));
4812 MEM_COPY_ATTRIBUTES (mem2, operands[1]);
4813 operands[0] = gen_lowpart (SImode, operands[0]);
4815 operands[2] = gen_reg_rtx (SImode);
4816 operands[3] = gen_reg_rtx (SImode);
4819 if (BYTES_BIG_ENDIAN)
4821 operands[4] = operands[2];
4822 operands[5] = operands[3];
4826 operands[4] = operands[3];
4827 operands[5] = operands[2];
4832 (define_expand "movhi_bigend"
4834 (rotate:SI (subreg:SI (match_operand:HI 1 "memory_operand" "") 0)
4837 (ashiftrt:SI (match_dup 2) (const_int 16)))
4838 (set (match_operand:HI 0 "s_register_operand" "")
4842 operands[2] = gen_reg_rtx (SImode);
4843 operands[3] = gen_reg_rtx (SImode);
4844 operands[4] = gen_lowpart (HImode, operands[3]);
4848 ;; Pattern to recognize insn generated default case above
4849 (define_insn "*movhi_insn_arch4"
4850 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,m,r")
4851 (match_operand:HI 1 "general_operand" "rI,K,r,m"))]
4854 && (GET_CODE (operands[1]) != CONST_INT
4855 || const_ok_for_arm (INTVAL (operands[1]))
4856 || const_ok_for_arm (~INTVAL (operands[1])))"
4858 mov%?\\t%0, %1\\t%@ movhi
4859 mvn%?\\t%0, #%B1\\t%@ movhi
4860 str%?h\\t%1, %0\\t%@ movhi
4861 ldr%?h\\t%0, %1\\t%@ movhi"
4862 [(set_attr "type" "*,*,store1,load1")
4863 (set_attr "predicable" "yes")
4864 (set_attr "pool_range" "*,*,*,256")
4865 (set_attr "neg_pool_range" "*,*,*,244")]
4868 (define_insn "*movhi_bytes"
4869 [(set (match_operand:HI 0 "s_register_operand" "=r,r")
4870 (match_operand:HI 1 "arm_rhs_operand" "rI,K"))]
4873 mov%?\\t%0, %1\\t%@ movhi
4874 mvn%?\\t%0, #%B1\\t%@ movhi"
4875 [(set_attr "predicable" "yes")]
4878 (define_insn "thumb_movhi_clobber"
4879 [(set (match_operand:HI 0 "memory_operand" "=m")
4880 (match_operand:HI 1 "register_operand" "l"))
4881 (clobber (match_operand:SI 2 "register_operand" "=&l"))]
4887 ;; We use a DImode scratch because we may occasionally need an additional
4888 ;; temporary if the address isn't offsettable -- push_reload doesn't seem
4889 ;; to take any notice of the "o" constraints on reload_memory_operand operand.
4890 (define_expand "reload_outhi"
4891 [(parallel [(match_operand:HI 0 "arm_reload_memory_operand" "=o")
4892 (match_operand:HI 1 "s_register_operand" "r")
4893 (match_operand:DI 2 "s_register_operand" "=&l")])]
4896 arm_reload_out_hi (operands);
4898 thumb_reload_out_hi (operands);
4903 (define_expand "reload_inhi"
4904 [(parallel [(match_operand:HI 0 "s_register_operand" "=r")
4905 (match_operand:HI 1 "arm_reload_memory_operand" "o")
4906 (match_operand:DI 2 "s_register_operand" "=&r")])]
4910 arm_reload_in_hi (operands);
4912 thumb_reload_out_hi (operands);
4916 (define_expand "movqi"
4917 [(set (match_operand:QI 0 "general_operand" "")
4918 (match_operand:QI 1 "general_operand" ""))]
4923 /* Everything except mem = const or mem = mem can be done easily */
4925 if (!no_new_pseudos)
4927 if (GET_CODE (operands[1]) == CONST_INT)
4929 rtx reg = gen_reg_rtx (SImode);
4931 emit_insn (gen_movsi (reg, operands[1]));
4932 operands[1] = gen_lowpart (QImode, reg);
4934 if (GET_CODE (operands[1]) == MEM && optimize > 0)
4936 rtx reg = gen_reg_rtx (SImode);
4938 emit_insn (gen_zero_extendqisi2 (reg, operands[1]));
4939 operands[1] = gen_lowpart (QImode, reg);
4941 if (GET_CODE (operands[0]) == MEM)
4942 operands[1] = force_reg (QImode, operands[1]);
4945 else /* TARGET_THUMB */
4947 if (!no_new_pseudos)
4949 if (GET_CODE (operands[0]) != REG)
4950 operands[1] = force_reg (QImode, operands[1]);
4952 /* ??? We shouldn't really get invalid addresses here, but this can
4953 happen if we are passed a SP (never OK for HImode/QImode) or
4954 virtual register (rejected by GO_IF_LEGITIMATE_ADDRESS for
4955 HImode/QImode) relative address. */
4956 /* ??? This should perhaps be fixed elsewhere, for instance, in
4957 fixup_stack_1, by checking for other kinds of invalid addresses,
4958 e.g. a bare reference to a virtual register. This may confuse the
4959 alpha though, which must handle this case differently. */
4960 if (GET_CODE (operands[0]) == MEM
4961 && !memory_address_p (GET_MODE (operands[0]),
4962 XEXP (operands[0], 0)))
4964 = replace_equiv_address (operands[0],
4965 copy_to_reg (XEXP (operands[0], 0)));
4966 if (GET_CODE (operands[1]) == MEM
4967 && !memory_address_p (GET_MODE (operands[1]),
4968 XEXP (operands[1], 0)))
4970 = replace_equiv_address (operands[1],
4971 copy_to_reg (XEXP (operands[1], 0)));
4973 /* Handle loading a large integer during reload. */
4974 else if (GET_CODE (operands[1]) == CONST_INT
4975 && !CONST_OK_FOR_LETTER_P (INTVAL (operands[1]), 'I'))
4977 /* Writing a constant to memory needs a scratch, which should
4978 be handled with SECONDARY_RELOADs. */
4979 if (GET_CODE (operands[0]) != REG)
4982 operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
4983 emit_insn (gen_movsi (operands[0], operands[1]));
4991 (define_insn "*arm_movqi_insn"
4992 [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,r,m")
4993 (match_operand:QI 1 "general_operand" "rI,K,m,r"))]
4995 && ( register_operand (operands[0], QImode)
4996 || register_operand (operands[1], QImode))"
5002 [(set_attr "type" "*,*,load1,store1")
5003 (set_attr "predicable" "yes")]
5006 (define_insn "*thumb_movqi_insn"
5007 [(set (match_operand:QI 0 "nonimmediate_operand" "=l,l,m,*r,*h,l")
5008 (match_operand:QI 1 "general_operand" "l, m,l,*h,*r,I"))]
5010 && ( register_operand (operands[0], QImode)
5011 || register_operand (operands[1], QImode))"
5019 [(set_attr "length" "2")
5020 (set_attr "type" "*,load1,store1,*,*,*")
5021 (set_attr "pool_range" "*,32,*,*,*,*")]
5024 (define_expand "movsf"
5025 [(set (match_operand:SF 0 "general_operand" "")
5026 (match_operand:SF 1 "general_operand" ""))]
5031 if (GET_CODE (operands[0]) == MEM)
5032 operands[1] = force_reg (SFmode, operands[1]);
5034 else /* TARGET_THUMB */
5036 if (!no_new_pseudos)
5038 if (GET_CODE (operands[0]) != REG)
5039 operands[1] = force_reg (SFmode, operands[1]);
5046 [(set (match_operand:SF 0 "nonimmediate_operand" "")
5047 (match_operand:SF 1 "immediate_operand" ""))]
5049 && !(TARGET_HARD_FLOAT && TARGET_FPA)
5051 && GET_CODE (operands[1]) == CONST_DOUBLE"
5052 [(set (match_dup 2) (match_dup 3))]
5054 operands[2] = gen_lowpart (SImode, operands[0]);
5055 operands[3] = gen_lowpart (SImode, operands[1]);
5056 if (operands[2] == 0 || operands[3] == 0)
5061 (define_insn "*arm_movsf_soft_insn"
5062 [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,m")
5063 (match_operand:SF 1 "general_operand" "r,mE,r"))]
5065 && TARGET_SOFT_FLOAT
5066 && (GET_CODE (operands[0]) != MEM
5067 || register_operand (operands[1], SFmode))"
5070 ldr%?\\t%0, %1\\t%@ float
5071 str%?\\t%1, %0\\t%@ float"
5072 [(set_attr "length" "4,4,4")
5073 (set_attr "predicable" "yes")
5074 (set_attr "type" "*,load1,store1")
5075 (set_attr "pool_range" "*,4096,*")
5076 (set_attr "neg_pool_range" "*,4084,*")]
5079 ;;; ??? This should have alternatives for constants.
5080 (define_insn "*thumb_movsf_insn"
5081 [(set (match_operand:SF 0 "nonimmediate_operand" "=l,l,>,l, m,*r,*h")
5082 (match_operand:SF 1 "general_operand" "l, >,l,mF,l,*h,*r"))]
5084 && ( register_operand (operands[0], SFmode)
5085 || register_operand (operands[1], SFmode))"
5094 [(set_attr "length" "2")
5095 (set_attr "type" "*,load1,store1,load1,store1,*,*")
5096 (set_attr "pool_range" "*,*,*,1020,*,*,*")]
5099 (define_expand "movdf"
5100 [(set (match_operand:DF 0 "general_operand" "")
5101 (match_operand:DF 1 "general_operand" ""))]
5106 if (GET_CODE (operands[0]) == MEM)
5107 operands[1] = force_reg (DFmode, operands[1]);
5109 else /* TARGET_THUMB */
5111 if (!no_new_pseudos)
5113 if (GET_CODE (operands[0]) != REG)
5114 operands[1] = force_reg (DFmode, operands[1]);
5120 ;; Reloading a df mode value stored in integer regs to memory can require a
5122 (define_expand "reload_outdf"
5123 [(match_operand:DF 0 "arm_reload_memory_operand" "=o")
5124 (match_operand:DF 1 "s_register_operand" "r")
5125 (match_operand:SI 2 "s_register_operand" "=&r")]
5129 enum rtx_code code = GET_CODE (XEXP (operands[0], 0));
5132 operands[2] = XEXP (operands[0], 0);
5133 else if (code == POST_INC || code == PRE_DEC)
5135 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
5136 operands[1] = gen_rtx_SUBREG (DImode, operands[1], 0);
5137 emit_insn (gen_movdi (operands[0], operands[1]));
5140 else if (code == PRE_INC)
5142 rtx reg = XEXP (XEXP (operands[0], 0), 0);
5144 emit_insn (gen_addsi3 (reg, reg, GEN_INT (8)));
5147 else if (code == POST_DEC)
5148 operands[2] = XEXP (XEXP (operands[0], 0), 0);
5150 emit_insn (gen_addsi3 (operands[2], XEXP (XEXP (operands[0], 0), 0),
5151 XEXP (XEXP (operands[0], 0), 1)));
5153 emit_insn (gen_rtx_SET (VOIDmode, gen_rtx_MEM (DFmode, operands[2]),
5156 if (code == POST_DEC)
5157 emit_insn (gen_addsi3 (operands[2], operands[2], GEN_INT (-8)));
5163 (define_insn "*movdf_soft_insn"
5164 [(set (match_operand:DF 0 "nonimmediate_soft_df_operand" "=r,r,m")
5165 (match_operand:DF 1 "soft_df_operand" "r,mF,r"))]
5166 "TARGET_ARM && TARGET_SOFT_FLOAT
5168 "* return output_move_double (operands);"
5169 [(set_attr "length" "8,8,8")
5170 (set_attr "type" "*,load2,store2")
5171 (set_attr "pool_range" "1020")
5172 (set_attr "neg_pool_range" "1008")]
5175 ;;; ??? This should have alternatives for constants.
5176 ;;; ??? This was originally identical to the movdi_insn pattern.
5177 ;;; ??? The 'F' constraint looks funny, but it should always be replaced by
5178 ;;; thumb_reorg with a memory reference.
5179 (define_insn "*thumb_movdf_insn"
5180 [(set (match_operand:DF 0 "nonimmediate_operand" "=l,l,>,l, m,*r")
5181 (match_operand:DF 1 "general_operand" "l, >,l,mF,l,*r"))]
5183 && ( register_operand (operands[0], DFmode)
5184 || register_operand (operands[1], DFmode))"
5186 switch (which_alternative)
5190 if (REGNO (operands[1]) == REGNO (operands[0]) + 1)
5191 return \"add\\t%0, %1, #0\;add\\t%H0, %H1, #0\";
5192 return \"add\\t%H0, %H1, #0\;add\\t%0, %1, #0\";
5194 return \"ldmia\\t%1, {%0, %H0}\";
5196 return \"stmia\\t%0, {%1, %H1}\";
5198 return thumb_load_double_from_address (operands);
5200 operands[2] = gen_rtx_MEM (SImode,
5201 plus_constant (XEXP (operands[0], 0), 4));
5202 output_asm_insn (\"str\\t%1, %0\;str\\t%H1, %2\", operands);
5205 if (REGNO (operands[1]) == REGNO (operands[0]) + 1)
5206 return \"mov\\t%0, %1\;mov\\t%H0, %H1\";
5207 return \"mov\\t%H0, %H1\;mov\\t%0, %1\";
5210 [(set_attr "length" "4,2,2,6,4,4")
5211 (set_attr "type" "*,load2,store2,load2,store2,*")
5212 (set_attr "pool_range" "*,*,*,1020,*,*")]
5216 (define_expand "movv2si"
5217 [(set (match_operand:V2SI 0 "nonimmediate_operand" "")
5218 (match_operand:V2SI 1 "general_operand" ""))]
5219 "TARGET_REALLY_IWMMXT"
5223 (define_expand "movv4hi"
5224 [(set (match_operand:V4HI 0 "nonimmediate_operand" "")
5225 (match_operand:V4HI 1 "general_operand" ""))]
5226 "TARGET_REALLY_IWMMXT"
5230 (define_expand "movv8qi"
5231 [(set (match_operand:V8QI 0 "nonimmediate_operand" "")
5232 (match_operand:V8QI 1 "general_operand" ""))]
5233 "TARGET_REALLY_IWMMXT"
5238 ;; load- and store-multiple insns
5239 ;; The arm can load/store any set of registers, provided that they are in
5240 ;; ascending order; but that is beyond GCC so stick with what it knows.
5242 (define_expand "load_multiple"
5243 [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
5244 (match_operand:SI 1 "" ""))
5245 (use (match_operand:SI 2 "" ""))])]
5248 /* Support only fixed point registers. */
5249 if (GET_CODE (operands[2]) != CONST_INT
5250 || INTVAL (operands[2]) > 14
5251 || INTVAL (operands[2]) < 2
5252 || GET_CODE (operands[1]) != MEM
5253 || GET_CODE (operands[0]) != REG
5254 || REGNO (operands[0]) > (LAST_ARM_REGNUM - 1)
5255 || REGNO (operands[0]) + INTVAL (operands[2]) > LAST_ARM_REGNUM)
5259 = arm_gen_load_multiple (REGNO (operands[0]), INTVAL (operands[2]),
5260 force_reg (SImode, XEXP (operands[1], 0)),
5261 TRUE, FALSE, RTX_UNCHANGING_P(operands[1]),
5262 MEM_IN_STRUCT_P(operands[1]),
5263 MEM_SCALAR_P (operands[1]));
5267 ;; Load multiple with write-back
5269 (define_insn "*ldmsi_postinc4"
5270 [(match_parallel 0 "load_multiple_operation"
5271 [(set (match_operand:SI 1 "s_register_operand" "=r")
5272 (plus:SI (match_operand:SI 2 "s_register_operand" "1")
5274 (set (match_operand:SI 3 "arm_hard_register_operand" "")
5275 (mem:SI (match_dup 2)))
5276 (set (match_operand:SI 4 "arm_hard_register_operand" "")
5277 (mem:SI (plus:SI (match_dup 2) (const_int 4))))
5278 (set (match_operand:SI 5 "arm_hard_register_operand" "")
5279 (mem:SI (plus:SI (match_dup 2) (const_int 8))))
5280 (set (match_operand:SI 6 "arm_hard_register_operand" "")
5281 (mem:SI (plus:SI (match_dup 2) (const_int 12))))])]
5282 "TARGET_ARM && XVECLEN (operands[0], 0) == 5"
5283 "ldm%?ia\\t%1!, {%3, %4, %5, %6}"
5284 [(set_attr "type" "load4")
5285 (set_attr "predicable" "yes")]
5288 (define_insn "*ldmsi_postinc3"
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 "TARGET_ARM && XVECLEN (operands[0], 0) == 4"
5300 "ldm%?ia\\t%1!, {%3, %4, %5}"
5301 [(set_attr "type" "load3")
5302 (set_attr "predicable" "yes")]
5305 (define_insn "*ldmsi_postinc2"
5306 [(match_parallel 0 "load_multiple_operation"
5307 [(set (match_operand:SI 1 "s_register_operand" "=r")
5308 (plus:SI (match_operand:SI 2 "s_register_operand" "1")
5310 (set (match_operand:SI 3 "arm_hard_register_operand" "")
5311 (mem:SI (match_dup 2)))
5312 (set (match_operand:SI 4 "arm_hard_register_operand" "")
5313 (mem:SI (plus:SI (match_dup 2) (const_int 4))))])]
5314 "TARGET_ARM && XVECLEN (operands[0], 0) == 3"
5315 "ldm%?ia\\t%1!, {%3, %4}"
5316 [(set_attr "type" "load2")
5317 (set_attr "predicable" "yes")]
5320 ;; Ordinary load multiple
5322 (define_insn "*ldmsi4"
5323 [(match_parallel 0 "load_multiple_operation"
5324 [(set (match_operand:SI 2 "arm_hard_register_operand" "")
5325 (mem:SI (match_operand:SI 1 "s_register_operand" "r")))
5326 (set (match_operand:SI 3 "arm_hard_register_operand" "")
5327 (mem:SI (plus:SI (match_dup 1) (const_int 4))))
5328 (set (match_operand:SI 4 "arm_hard_register_operand" "")
5329 (mem:SI (plus:SI (match_dup 1) (const_int 8))))
5330 (set (match_operand:SI 5 "arm_hard_register_operand" "")
5331 (mem:SI (plus:SI (match_dup 1) (const_int 12))))])]
5332 "TARGET_ARM && XVECLEN (operands[0], 0) == 4"
5333 "ldm%?ia\\t%1, {%2, %3, %4, %5}"
5334 [(set_attr "type" "load4")
5335 (set_attr "predicable" "yes")]
5338 (define_insn "*ldmsi3"
5339 [(match_parallel 0 "load_multiple_operation"
5340 [(set (match_operand:SI 2 "arm_hard_register_operand" "")
5341 (mem:SI (match_operand:SI 1 "s_register_operand" "r")))
5342 (set (match_operand:SI 3 "arm_hard_register_operand" "")
5343 (mem:SI (plus:SI (match_dup 1) (const_int 4))))
5344 (set (match_operand:SI 4 "arm_hard_register_operand" "")
5345 (mem:SI (plus:SI (match_dup 1) (const_int 8))))])]
5346 "TARGET_ARM && XVECLEN (operands[0], 0) == 3"
5347 "ldm%?ia\\t%1, {%2, %3, %4}"
5348 [(set_attr "type" "load3")
5349 (set_attr "predicable" "yes")]
5352 (define_insn "*ldmsi2"
5353 [(match_parallel 0 "load_multiple_operation"
5354 [(set (match_operand:SI 2 "arm_hard_register_operand" "")
5355 (mem:SI (match_operand:SI 1 "s_register_operand" "r")))
5356 (set (match_operand:SI 3 "arm_hard_register_operand" "")
5357 (mem:SI (plus:SI (match_dup 1) (const_int 4))))])]
5358 "TARGET_ARM && XVECLEN (operands[0], 0) == 2"
5359 "ldm%?ia\\t%1, {%2, %3}"
5360 [(set_attr "type" "load2")
5361 (set_attr "predicable" "yes")]
5364 (define_expand "store_multiple"
5365 [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
5366 (match_operand:SI 1 "" ""))
5367 (use (match_operand:SI 2 "" ""))])]
5370 /* Support only fixed point registers. */
5371 if (GET_CODE (operands[2]) != CONST_INT
5372 || INTVAL (operands[2]) > 14
5373 || INTVAL (operands[2]) < 2
5374 || GET_CODE (operands[1]) != REG
5375 || GET_CODE (operands[0]) != MEM
5376 || REGNO (operands[1]) > (LAST_ARM_REGNUM - 1)
5377 || REGNO (operands[1]) + INTVAL (operands[2]) > LAST_ARM_REGNUM)
5381 = arm_gen_store_multiple (REGNO (operands[1]), INTVAL (operands[2]),
5382 force_reg (SImode, XEXP (operands[0], 0)),
5383 TRUE, FALSE, RTX_UNCHANGING_P (operands[0]),
5384 MEM_IN_STRUCT_P(operands[0]),
5385 MEM_SCALAR_P (operands[0]));
5389 ;; Store multiple with write-back
5391 (define_insn "*stmsi_postinc4"
5392 [(match_parallel 0 "store_multiple_operation"
5393 [(set (match_operand:SI 1 "s_register_operand" "=r")
5394 (plus:SI (match_operand:SI 2 "s_register_operand" "1")
5396 (set (mem:SI (match_dup 2))
5397 (match_operand:SI 3 "arm_hard_register_operand" ""))
5398 (set (mem:SI (plus:SI (match_dup 2) (const_int 4)))
5399 (match_operand:SI 4 "arm_hard_register_operand" ""))
5400 (set (mem:SI (plus:SI (match_dup 2) (const_int 8)))
5401 (match_operand:SI 5 "arm_hard_register_operand" ""))
5402 (set (mem:SI (plus:SI (match_dup 2) (const_int 12)))
5403 (match_operand:SI 6 "arm_hard_register_operand" ""))])]
5404 "TARGET_ARM && XVECLEN (operands[0], 0) == 5"
5405 "stm%?ia\\t%1!, {%3, %4, %5, %6}"
5406 [(set_attr "predicable" "yes")
5407 (set_attr "type" "store4")]
5410 (define_insn "*stmsi_postinc3"
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 "TARGET_ARM && XVECLEN (operands[0], 0) == 4"
5422 "stm%?ia\\t%1!, {%3, %4, %5}"
5423 [(set_attr "predicable" "yes")
5424 (set_attr "type" "store3")]
5427 (define_insn "*stmsi_postinc2"
5428 [(match_parallel 0 "store_multiple_operation"
5429 [(set (match_operand:SI 1 "s_register_operand" "=r")
5430 (plus:SI (match_operand:SI 2 "s_register_operand" "1")
5432 (set (mem:SI (match_dup 2))
5433 (match_operand:SI 3 "arm_hard_register_operand" ""))
5434 (set (mem:SI (plus:SI (match_dup 2) (const_int 4)))
5435 (match_operand:SI 4 "arm_hard_register_operand" ""))])]
5436 "TARGET_ARM && XVECLEN (operands[0], 0) == 3"
5437 "stm%?ia\\t%1!, {%3, %4}"
5438 [(set_attr "predicable" "yes")
5439 (set_attr "type" "store2")]
5442 ;; Ordinary store multiple
5444 (define_insn "*stmsi4"
5445 [(match_parallel 0 "store_multiple_operation"
5446 [(set (mem:SI (match_operand:SI 1 "s_register_operand" "r"))
5447 (match_operand:SI 2 "arm_hard_register_operand" ""))
5448 (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
5449 (match_operand:SI 3 "arm_hard_register_operand" ""))
5450 (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
5451 (match_operand:SI 4 "arm_hard_register_operand" ""))
5452 (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
5453 (match_operand:SI 5 "arm_hard_register_operand" ""))])]
5454 "TARGET_ARM && XVECLEN (operands[0], 0) == 4"
5455 "stm%?ia\\t%1, {%2, %3, %4, %5}"
5456 [(set_attr "predicable" "yes")
5457 (set_attr "type" "store4")]
5460 (define_insn "*stmsi3"
5461 [(match_parallel 0 "store_multiple_operation"
5462 [(set (mem:SI (match_operand:SI 1 "s_register_operand" "r"))
5463 (match_operand:SI 2 "arm_hard_register_operand" ""))
5464 (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
5465 (match_operand:SI 3 "arm_hard_register_operand" ""))
5466 (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
5467 (match_operand:SI 4 "arm_hard_register_operand" ""))])]
5468 "TARGET_ARM && XVECLEN (operands[0], 0) == 3"
5469 "stm%?ia\\t%1, {%2, %3, %4}"
5470 [(set_attr "predicable" "yes")
5471 (set_attr "type" "store3")]
5474 (define_insn "*stmsi2"
5475 [(match_parallel 0 "store_multiple_operation"
5476 [(set (mem:SI (match_operand:SI 1 "s_register_operand" "r"))
5477 (match_operand:SI 2 "arm_hard_register_operand" ""))
5478 (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
5479 (match_operand:SI 3 "arm_hard_register_operand" ""))])]
5480 "TARGET_ARM && XVECLEN (operands[0], 0) == 2"
5481 "stm%?ia\\t%1, {%2, %3}"
5482 [(set_attr "predicable" "yes")
5483 (set_attr "type" "store2")]
5486 ;; Move a block of memory if it is word aligned and MORE than 2 words long.
5487 ;; We could let this apply for blocks of less than this, but it clobbers so
5488 ;; many registers that there is then probably a better way.
5490 (define_expand "movmemqi"
5491 [(match_operand:BLK 0 "general_operand" "")
5492 (match_operand:BLK 1 "general_operand" "")
5493 (match_operand:SI 2 "const_int_operand" "")
5494 (match_operand:SI 3 "const_int_operand" "")]
5499 if (arm_gen_movmemqi (operands))
5503 else /* TARGET_THUMB */
5505 if ( INTVAL (operands[3]) != 4
5506 || INTVAL (operands[2]) > 48)
5509 thumb_expand_movmemqi (operands);
5515 ;; Thumb block-move insns
5517 (define_insn "movmem12b"
5518 [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
5519 (mem:SI (match_operand:SI 3 "register_operand" "1")))
5520 (set (mem:SI (plus:SI (match_dup 2) (const_int 4)))
5521 (mem:SI (plus:SI (match_dup 3) (const_int 4))))
5522 (set (mem:SI (plus:SI (match_dup 2) (const_int 8)))
5523 (mem:SI (plus:SI (match_dup 3) (const_int 8))))
5524 (set (match_operand:SI 0 "register_operand" "=l")
5525 (plus:SI (match_dup 2) (const_int 12)))
5526 (set (match_operand:SI 1 "register_operand" "=l")
5527 (plus:SI (match_dup 3) (const_int 12)))
5528 (clobber (match_scratch:SI 4 "=&l"))
5529 (clobber (match_scratch:SI 5 "=&l"))
5530 (clobber (match_scratch:SI 6 "=&l"))]
5532 "* return thumb_output_move_mem_multiple (3, operands);"
5533 [(set_attr "length" "4")
5534 ; This isn't entirely accurate... It loads as well, but in terms of
5535 ; scheduling the following insn it is better to consider it as a store
5536 (set_attr "type" "store3")]
5539 (define_insn "movmem8b"
5540 [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
5541 (mem:SI (match_operand:SI 3 "register_operand" "1")))
5542 (set (mem:SI (plus:SI (match_dup 2) (const_int 4)))
5543 (mem:SI (plus:SI (match_dup 3) (const_int 4))))
5544 (set (match_operand:SI 0 "register_operand" "=l")
5545 (plus:SI (match_dup 2) (const_int 8)))
5546 (set (match_operand:SI 1 "register_operand" "=l")
5547 (plus:SI (match_dup 3) (const_int 8)))
5548 (clobber (match_scratch:SI 4 "=&l"))
5549 (clobber (match_scratch:SI 5 "=&l"))]
5551 "* return thumb_output_move_mem_multiple (2, 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" "store2")]
5560 ;; Compare & branch insns
5561 ;; The range calculations are based as follows:
5562 ;; For forward branches, the address calculation returns the address of
5563 ;; the next instruction. This is 2 beyond the branch instruction.
5564 ;; For backward branches, the address calculation returns the address of
5565 ;; the first instruction in this pattern (cmp). This is 2 before the branch
5566 ;; instruction for the shortest sequence, and 4 before the branch instruction
5567 ;; if we have to jump around an unconditional branch.
5568 ;; To the basic branch range the PC offset must be added (this is +4).
5569 ;; So for forward branches we have
5570 ;; (pos_range - pos_base_offs + pc_offs) = (pos_range - 2 + 4).
5571 ;; And for backward branches we have
5572 ;; (neg_range - neg_base_offs + pc_offs) = (neg_range - (-2 or -4) + 4).
5574 ;; For a 'b' pos_range = 2046, neg_range = -2048 giving (-2040->2048).
5575 ;; For a 'b<cond>' pos_range = 254, neg_range = -256 giving (-250 ->256).
5577 (define_expand "cbranchsi4"
5578 [(set (pc) (if_then_else
5579 (match_operator 0 "arm_comparison_operator"
5580 [(match_operand:SI 1 "s_register_operand" "")
5581 (match_operand:SI 2 "nonmemory_operand" "")])
5582 (label_ref (match_operand 3 "" ""))
5586 if (thumb_cmpneg_operand (operands[2], SImode))
5588 emit_jump_insn (gen_cbranchsi4_scratch (NULL, operands[1], operands[2],
5589 operands[3], operands[0]));
5592 if (!thumb_cmp_operand (operands[2], SImode))
5593 operands[2] = force_reg (SImode, operands[2]);
5596 (define_insn "*cbranchsi4_insn"
5597 [(set (pc) (if_then_else
5598 (match_operator 0 "arm_comparison_operator"
5599 [(match_operand:SI 1 "s_register_operand" "l,*h")
5600 (match_operand:SI 2 "thumb_cmp_operand" "lI*h,*r")])
5601 (label_ref (match_operand 3 "" ""))
5605 output_asm_insn (\"cmp\\t%1, %2\", operands);
5607 switch (get_attr_length (insn))
5609 case 4: return \"b%d0\\t%l3\";
5610 case 6: return \"b%D0\\t.LCB%=\;b\\t%l3\\t%@long jump\\n.LCB%=:\";
5611 default: return \"b%D0\\t.LCB%=\;bl\\t%l3\\t%@far jump\\n.LCB%=:\";
5614 [(set (attr "far_jump")
5616 (eq_attr "length" "8")
5617 (const_string "yes")
5618 (const_string "no")))
5619 (set (attr "length")
5621 (and (ge (minus (match_dup 3) (pc)) (const_int -250))
5622 (le (minus (match_dup 3) (pc)) (const_int 256)))
5625 (and (ge (minus (match_dup 3) (pc)) (const_int -2040))
5626 (le (minus (match_dup 3) (pc)) (const_int 2048)))
5631 (define_insn "cbranchsi4_scratch"
5632 [(set (pc) (if_then_else
5633 (match_operator 4 "arm_comparison_operator"
5634 [(match_operand:SI 1 "s_register_operand" "l,0")
5635 (match_operand:SI 2 "thumb_cmpneg_operand" "L,J")])
5636 (label_ref (match_operand 3 "" ""))
5638 (clobber (match_scratch:SI 0 "=l,l"))]
5641 output_asm_insn (\"add\\t%0, %1, #%n2\", operands);
5643 switch (get_attr_length (insn))
5645 case 4: return \"b%d4\\t%l3\";
5646 case 6: return \"b%D4\\t.LCB%=\;b\\t%l3\\t%@long jump\\n.LCB%=:\";
5647 default: return \"b%D4\\t.LCB%=\;bl\\t%l3\\t%@far jump\\n.LCB%=:\";
5650 [(set (attr "far_jump")
5652 (eq_attr "length" "8")
5653 (const_string "yes")
5654 (const_string "no")))
5655 (set (attr "length")
5657 (and (ge (minus (match_dup 3) (pc)) (const_int -250))
5658 (le (minus (match_dup 3) (pc)) (const_int 256)))
5661 (and (ge (minus (match_dup 3) (pc)) (const_int -2040))
5662 (le (minus (match_dup 3) (pc)) (const_int 2048)))
5666 (define_insn "*movsi_cbranchsi4"
5669 (match_operator 3 "arm_comparison_operator"
5670 [(match_operand:SI 1 "s_register_operand" "0,l,l,l")
5672 (label_ref (match_operand 2 "" ""))
5674 (set (match_operand:SI 0 "thumb_cbrch_target_operand" "=l,l,*h,*m")
5678 if (which_alternative == 0)
5679 output_asm_insn (\"cmp\t%0, #0\", operands);
5680 else if (which_alternative == 1)
5681 output_asm_insn (\"sub\t%0, %1, #0\", operands);
5684 output_asm_insn (\"cmp\t%1, #0\", operands);
5685 if (which_alternative == 2)
5686 output_asm_insn (\"mov\t%0, %1\", operands);
5688 output_asm_insn (\"str\t%1, %0\", operands);
5690 switch (get_attr_length (insn) - ((which_alternative > 1) ? 2 : 0))
5692 case 4: return \"b%d3\\t%l2\";
5693 case 6: return \"b%D3\\t.LCB%=\;b\\t%l2\\t%@long jump\\n.LCB%=:\";
5694 default: return \"b%D3\\t.LCB%=\;bl\\t%l2\\t%@far jump\\n.LCB%=:\";
5697 [(set (attr "far_jump")
5699 (ior (and (gt (symbol_ref ("which_alternative"))
5701 (eq_attr "length" "8"))
5702 (eq_attr "length" "10"))
5703 (const_string "yes")
5704 (const_string "no")))
5705 (set (attr "length")
5707 (le (symbol_ref ("which_alternative"))
5710 (and (ge (minus (match_dup 2) (pc)) (const_int -250))
5711 (le (minus (match_dup 2) (pc)) (const_int 256)))
5714 (and (ge (minus (match_dup 2) (pc)) (const_int -2040))
5715 (le (minus (match_dup 2) (pc)) (const_int 2048)))
5719 (and (ge (minus (match_dup 2) (pc)) (const_int -248))
5720 (le (minus (match_dup 2) (pc)) (const_int 256)))
5723 (and (ge (minus (match_dup 2) (pc)) (const_int -2038))
5724 (le (minus (match_dup 2) (pc)) (const_int 2048)))
5729 (define_insn "*negated_cbranchsi4"
5732 (match_operator 0 "arm_comparison_operator"
5733 [(match_operand:SI 1 "s_register_operand" "l")
5734 (neg:SI (match_operand:SI 2 "s_register_operand" "l"))])
5735 (label_ref (match_operand 3 "" ""))
5739 output_asm_insn (\"cmn\\t%1, %2\", operands);
5740 switch (get_attr_length (insn))
5742 case 4: return \"b%d0\\t%l3\";
5743 case 6: return \"b%D0\\t.LCB%=\;b\\t%l3\\t%@long jump\\n.LCB%=:\";
5744 default: return \"b%D0\\t.LCB%=\;bl\\t%l3\\t%@far jump\\n.LCB%=:\";
5747 [(set (attr "far_jump")
5749 (eq_attr "length" "8")
5750 (const_string "yes")
5751 (const_string "no")))
5752 (set (attr "length")
5754 (and (ge (minus (match_dup 3) (pc)) (const_int -250))
5755 (le (minus (match_dup 3) (pc)) (const_int 256)))
5758 (and (ge (minus (match_dup 3) (pc)) (const_int -2040))
5759 (le (minus (match_dup 3) (pc)) (const_int 2048)))
5764 (define_insn "*tbit_cbranch"
5767 (match_operator 0 "equality_operator"
5768 [(zero_extract:SI (match_operand:SI 1 "s_register_operand" "l")
5770 (match_operand:SI 2 "const_int_operand" "i"))
5772 (label_ref (match_operand 3 "" ""))
5774 (clobber (match_scratch:SI 4 "=l"))]
5779 op[0] = operands[4];
5780 op[1] = operands[1];
5781 op[2] = GEN_INT (32 - 1 - INTVAL (operands[2]));
5783 output_asm_insn (\"lsl\\t%0, %1, %2\", op);
5784 switch (get_attr_length (insn))
5786 case 4: return \"b%d0\\t%l3\";
5787 case 6: return \"b%D0\\t.LCB%=\;b\\t%l3\\t%@long jump\\n.LCB%=:\";
5788 default: return \"b%D0\\t.LCB%=\;bl\\t%l3\\t%@far jump\\n.LCB%=:\";
5791 [(set (attr "far_jump")
5793 (eq_attr "length" "8")
5794 (const_string "yes")
5795 (const_string "no")))
5796 (set (attr "length")
5798 (and (ge (minus (match_dup 3) (pc)) (const_int -250))
5799 (le (minus (match_dup 3) (pc)) (const_int 256)))
5802 (and (ge (minus (match_dup 3) (pc)) (const_int -2040))
5803 (le (minus (match_dup 3) (pc)) (const_int 2048)))
5808 (define_insn "*tstsi3_cbranch"
5811 (match_operator 3 "equality_operator"
5812 [(and:SI (match_operand:SI 0 "s_register_operand" "%l")
5813 (match_operand:SI 1 "s_register_operand" "l"))
5815 (label_ref (match_operand 2 "" ""))
5820 output_asm_insn (\"tst\\t%0, %1\", operands);
5821 switch (get_attr_length (insn))
5823 case 4: return \"b%d3\\t%l2\";
5824 case 6: return \"b%D3\\t.LCB%=\;b\\t%l2\\t%@long jump\\n.LCB%=:\";
5825 default: return \"b%D3\\t.LCB%=\;bl\\t%l2\\t%@far jump\\n.LCB%=:\";
5828 [(set (attr "far_jump")
5830 (eq_attr "length" "8")
5831 (const_string "yes")
5832 (const_string "no")))
5833 (set (attr "length")
5835 (and (ge (minus (match_dup 2) (pc)) (const_int -250))
5836 (le (minus (match_dup 2) (pc)) (const_int 256)))
5839 (and (ge (minus (match_dup 2) (pc)) (const_int -2040))
5840 (le (minus (match_dup 2) (pc)) (const_int 2048)))
5845 (define_insn "*andsi3_cbranch"
5848 (match_operator 5 "equality_operator"
5849 [(and:SI (match_operand:SI 2 "s_register_operand" "%0,1,1,1")
5850 (match_operand:SI 3 "s_register_operand" "l,l,l,l"))
5852 (label_ref (match_operand 4 "" ""))
5854 (set (match_operand:SI 0 "thumb_cbrch_target_operand" "=l,*?h,*?m,*?m")
5855 (and:SI (match_dup 2) (match_dup 3)))
5856 (clobber (match_scratch:SI 1 "=X,l,&l,&l"))]
5860 if (which_alternative == 0)
5861 output_asm_insn (\"and\\t%0, %3\", operands);
5862 else if (which_alternative == 1)
5864 output_asm_insn (\"and\\t%1, %3\", operands);
5865 output_asm_insn (\"mov\\t%0, %1\", operands);
5869 output_asm_insn (\"and\\t%1, %3\", operands);
5870 output_asm_insn (\"str\\t%1, %0\", operands);
5873 switch (get_attr_length (insn) - (which_alternative ? 2 : 0))
5875 case 4: return \"b%d5\\t%l4\";
5876 case 6: return \"b%D5\\t.LCB%=\;b\\t%l4\\t%@long jump\\n.LCB%=:\";
5877 default: return \"b%D5\\t.LCB%=\;bl\\t%l4\\t%@far jump\\n.LCB%=:\";
5880 [(set (attr "far_jump")
5882 (ior (and (eq (symbol_ref ("which_alternative"))
5884 (eq_attr "length" "8"))
5885 (eq_attr "length" "10"))
5886 (const_string "yes")
5887 (const_string "no")))
5888 (set (attr "length")
5890 (eq (symbol_ref ("which_alternative"))
5893 (and (ge (minus (match_dup 4) (pc)) (const_int -250))
5894 (le (minus (match_dup 4) (pc)) (const_int 256)))
5897 (and (ge (minus (match_dup 4) (pc)) (const_int -2040))
5898 (le (minus (match_dup 4) (pc)) (const_int 2048)))
5902 (and (ge (minus (match_dup 4) (pc)) (const_int -248))
5903 (le (minus (match_dup 4) (pc)) (const_int 256)))
5906 (and (ge (minus (match_dup 4) (pc)) (const_int -2038))
5907 (le (minus (match_dup 4) (pc)) (const_int 2048)))
5912 (define_insn "*orrsi3_cbranch_scratch"
5915 (match_operator 4 "equality_operator"
5916 [(ior:SI (match_operand:SI 1 "s_register_operand" "%0")
5917 (match_operand:SI 2 "s_register_operand" "l"))
5919 (label_ref (match_operand 3 "" ""))
5921 (clobber (match_scratch:SI 0 "=l"))]
5925 output_asm_insn (\"orr\\t%0, %2\", operands);
5926 switch (get_attr_length (insn))
5928 case 4: return \"b%d4\\t%l3\";
5929 case 6: return \"b%D4\\t.LCB%=\;b\\t%l3\\t%@long jump\\n.LCB%=:\";
5930 default: return \"b%D4\\t.LCB%=\;bl\\t%l3\\t%@far jump\\n.LCB%=:\";
5933 [(set (attr "far_jump")
5935 (eq_attr "length" "8")
5936 (const_string "yes")
5937 (const_string "no")))
5938 (set (attr "length")
5940 (and (ge (minus (match_dup 3) (pc)) (const_int -250))
5941 (le (minus (match_dup 3) (pc)) (const_int 256)))
5944 (and (ge (minus (match_dup 3) (pc)) (const_int -2040))
5945 (le (minus (match_dup 3) (pc)) (const_int 2048)))
5950 (define_insn "*orrsi3_cbranch"
5953 (match_operator 5 "equality_operator"
5954 [(ior:SI (match_operand:SI 2 "s_register_operand" "%0,1,1,1")
5955 (match_operand:SI 3 "s_register_operand" "l,l,l,l"))
5957 (label_ref (match_operand 4 "" ""))
5959 (set (match_operand:SI 0 "thumb_cbrch_target_operand" "=l,*?h,*?m,*?m")
5960 (ior:SI (match_dup 2) (match_dup 3)))
5961 (clobber (match_scratch:SI 1 "=X,l,&l,&l"))]
5965 if (which_alternative == 0)
5966 output_asm_insn (\"orr\\t%0, %3\", operands);
5967 else if (which_alternative == 1)
5969 output_asm_insn (\"orr\\t%1, %3\", operands);
5970 output_asm_insn (\"mov\\t%0, %1\", operands);
5974 output_asm_insn (\"orr\\t%1, %3\", operands);
5975 output_asm_insn (\"str\\t%1, %0\", operands);
5978 switch (get_attr_length (insn) - (which_alternative ? 2 : 0))
5980 case 4: return \"b%d5\\t%l4\";
5981 case 6: return \"b%D5\\t.LCB%=\;b\\t%l4\\t%@long jump\\n.LCB%=:\";
5982 default: return \"b%D5\\t.LCB%=\;bl\\t%l4\\t%@far jump\\n.LCB%=:\";
5985 [(set (attr "far_jump")
5987 (ior (and (eq (symbol_ref ("which_alternative"))
5989 (eq_attr "length" "8"))
5990 (eq_attr "length" "10"))
5991 (const_string "yes")
5992 (const_string "no")))
5993 (set (attr "length")
5995 (eq (symbol_ref ("which_alternative"))
5998 (and (ge (minus (match_dup 4) (pc)) (const_int -250))
5999 (le (minus (match_dup 4) (pc)) (const_int 256)))
6002 (and (ge (minus (match_dup 4) (pc)) (const_int -2040))
6003 (le (minus (match_dup 4) (pc)) (const_int 2048)))
6007 (and (ge (minus (match_dup 4) (pc)) (const_int -248))
6008 (le (minus (match_dup 4) (pc)) (const_int 256)))
6011 (and (ge (minus (match_dup 4) (pc)) (const_int -2038))
6012 (le (minus (match_dup 4) (pc)) (const_int 2048)))
6017 (define_insn "*xorsi3_cbranch_scratch"
6020 (match_operator 4 "equality_operator"
6021 [(xor:SI (match_operand:SI 1 "s_register_operand" "%0")
6022 (match_operand:SI 2 "s_register_operand" "l"))
6024 (label_ref (match_operand 3 "" ""))
6026 (clobber (match_scratch:SI 0 "=l"))]
6030 output_asm_insn (\"eor\\t%0, %2\", operands);
6031 switch (get_attr_length (insn))
6033 case 4: return \"b%d4\\t%l3\";
6034 case 6: return \"b%D4\\t.LCB%=\;b\\t%l3\\t%@long jump\\n.LCB%=:\";
6035 default: return \"b%D4\\t.LCB%=\;bl\\t%l3\\t%@far jump\\n.LCB%=:\";
6038 [(set (attr "far_jump")
6040 (eq_attr "length" "8")
6041 (const_string "yes")
6042 (const_string "no")))
6043 (set (attr "length")
6045 (and (ge (minus (match_dup 3) (pc)) (const_int -250))
6046 (le (minus (match_dup 3) (pc)) (const_int 256)))
6049 (and (ge (minus (match_dup 3) (pc)) (const_int -2040))
6050 (le (minus (match_dup 3) (pc)) (const_int 2048)))
6055 (define_insn "*xorsi3_cbranch"
6058 (match_operator 5 "equality_operator"
6059 [(xor:SI (match_operand:SI 2 "s_register_operand" "%0,1,1,1")
6060 (match_operand:SI 3 "s_register_operand" "l,l,l,l"))
6062 (label_ref (match_operand 4 "" ""))
6064 (set (match_operand:SI 0 "thumb_cbrch_target_operand" "=l,*?h,*?m,*?m")
6065 (xor:SI (match_dup 2) (match_dup 3)))
6066 (clobber (match_scratch:SI 1 "=X,l,&l,&l"))]
6070 if (which_alternative == 0)
6071 output_asm_insn (\"eor\\t%0, %3\", operands);
6072 else if (which_alternative == 1)
6074 output_asm_insn (\"eor\\t%1, %3\", operands);
6075 output_asm_insn (\"mov\\t%0, %1\", operands);
6079 output_asm_insn (\"eor\\t%1, %3\", operands);
6080 output_asm_insn (\"str\\t%1, %0\", operands);
6083 switch (get_attr_length (insn) - (which_alternative ? 2 : 0))
6085 case 4: return \"b%d5\\t%l4\";
6086 case 6: return \"b%D5\\t.LCB%=\;b\\t%l4\\t%@long jump\\n.LCB%=:\";
6087 default: return \"b%D5\\t.LCB%=\;bl\\t%l4\\t%@far jump\\n.LCB%=:\";
6090 [(set (attr "far_jump")
6092 (ior (and (eq (symbol_ref ("which_alternative"))
6094 (eq_attr "length" "8"))
6095 (eq_attr "length" "10"))
6096 (const_string "yes")
6097 (const_string "no")))
6098 (set (attr "length")
6100 (eq (symbol_ref ("which_alternative"))
6103 (and (ge (minus (match_dup 4) (pc)) (const_int -250))
6104 (le (minus (match_dup 4) (pc)) (const_int 256)))
6107 (and (ge (minus (match_dup 4) (pc)) (const_int -2040))
6108 (le (minus (match_dup 4) (pc)) (const_int 2048)))
6112 (and (ge (minus (match_dup 4) (pc)) (const_int -248))
6113 (le (minus (match_dup 4) (pc)) (const_int 256)))
6116 (and (ge (minus (match_dup 4) (pc)) (const_int -2038))
6117 (le (minus (match_dup 4) (pc)) (const_int 2048)))
6122 (define_insn "*bicsi3_cbranch_scratch"
6125 (match_operator 4 "equality_operator"
6126 [(and:SI (not:SI (match_operand:SI 2 "s_register_operand" "l"))
6127 (match_operand:SI 1 "s_register_operand" "0"))
6129 (label_ref (match_operand 3 "" ""))
6131 (clobber (match_scratch:SI 0 "=l"))]
6135 output_asm_insn (\"bic\\t%0, %2\", operands);
6136 switch (get_attr_length (insn))
6138 case 4: return \"b%d4\\t%l3\";
6139 case 6: return \"b%D4\\t.LCB%=\;b\\t%l3\\t%@long jump\\n.LCB%=:\";
6140 default: return \"b%D4\\t.LCB%=\;bl\\t%l3\\t%@far jump\\n.LCB%=:\";
6143 [(set (attr "far_jump")
6145 (eq_attr "length" "8")
6146 (const_string "yes")
6147 (const_string "no")))
6148 (set (attr "length")
6150 (and (ge (minus (match_dup 3) (pc)) (const_int -250))
6151 (le (minus (match_dup 3) (pc)) (const_int 256)))
6154 (and (ge (minus (match_dup 3) (pc)) (const_int -2040))
6155 (le (minus (match_dup 3) (pc)) (const_int 2048)))
6160 (define_insn "*bicsi3_cbranch"
6163 (match_operator 5 "equality_operator"
6164 [(and:SI (not:SI (match_operand:SI 3 "s_register_operand" "l,l,l,l,l"))
6165 (match_operand:SI 2 "s_register_operand" "0,1,1,1,1"))
6167 (label_ref (match_operand 4 "" ""))
6169 (set (match_operand:SI 0 "thumb_cbrch_target_operand" "=!l,l,*?h,*?m,*?m")
6170 (and:SI (not:SI (match_dup 3)) (match_dup 2)))
6171 (clobber (match_scratch:SI 1 "=X,l,l,&l,&l"))]
6175 if (which_alternative == 0)
6176 output_asm_insn (\"bic\\t%0, %3\", operands);
6177 else if (which_alternative <= 2)
6179 output_asm_insn (\"bic\\t%1, %3\", operands);
6180 /* It's ok if OP0 is a lo-reg, even though the mov will set the
6181 conditions again, since we're only testing for equality. */
6182 output_asm_insn (\"mov\\t%0, %1\", operands);
6186 output_asm_insn (\"bic\\t%1, %3\", operands);
6187 output_asm_insn (\"str\\t%1, %0\", operands);
6190 switch (get_attr_length (insn) - (which_alternative ? 2 : 0))
6192 case 4: return \"b%d5\\t%l4\";
6193 case 6: return \"b%D5\\t.LCB%=\;b\\t%l4\\t%@long jump\\n.LCB%=:\";
6194 default: return \"b%D5\\t.LCB%=\;bl\\t%l4\\t%@far jump\\n.LCB%=:\";
6197 [(set (attr "far_jump")
6199 (ior (and (eq (symbol_ref ("which_alternative"))
6201 (eq_attr "length" "8"))
6202 (eq_attr "length" "10"))
6203 (const_string "yes")
6204 (const_string "no")))
6205 (set (attr "length")
6207 (eq (symbol_ref ("which_alternative"))
6210 (and (ge (minus (match_dup 4) (pc)) (const_int -250))
6211 (le (minus (match_dup 4) (pc)) (const_int 256)))
6214 (and (ge (minus (match_dup 4) (pc)) (const_int -2040))
6215 (le (minus (match_dup 4) (pc)) (const_int 2048)))
6219 (and (ge (minus (match_dup 4) (pc)) (const_int -248))
6220 (le (minus (match_dup 4) (pc)) (const_int 256)))
6223 (and (ge (minus (match_dup 4) (pc)) (const_int -2038))
6224 (le (minus (match_dup 4) (pc)) (const_int 2048)))
6229 (define_insn "*cbranchne_decr1"
6231 (if_then_else (match_operator 3 "equality_operator"
6232 [(match_operand:SI 2 "s_register_operand" "l,l,1,l")
6234 (label_ref (match_operand 4 "" ""))
6236 (set (match_operand:SI 0 "thumb_cbrch_target_operand" "=l,*?h,*?m,*?m")
6237 (plus:SI (match_dup 2) (const_int -1)))
6238 (clobber (match_scratch:SI 1 "=X,l,&l,&l"))]
6243 cond[0] = gen_rtx_fmt_ee ((GET_CODE (operands[3]) == NE
6245 VOIDmode, operands[2], const1_rtx);
6246 cond[1] = operands[4];
6248 if (which_alternative == 0)
6249 output_asm_insn (\"sub\\t%0, %2, #1\", operands);
6250 else if (which_alternative == 1)
6252 /* We must provide an alternative for a hi reg because reload
6253 cannot handle output reloads on a jump instruction, but we
6254 can't subtract into that. Fortunately a mov from lo to hi
6255 does not clobber the condition codes. */
6256 output_asm_insn (\"sub\\t%1, %2, #1\", operands);
6257 output_asm_insn (\"mov\\t%0, %1\", operands);
6261 /* Similarly, but the target is memory. */
6262 output_asm_insn (\"sub\\t%1, %2, #1\", operands);
6263 output_asm_insn (\"str\\t%1, %0\", operands);
6266 switch (get_attr_length (insn) - (which_alternative ? 2 : 0))
6269 output_asm_insn (\"b%d0\\t%l1\", cond);
6272 output_asm_insn (\"b%D0\\t.LCB%=\", cond);
6273 return \"b\\t%l4\\t%@long jump\\n.LCB%=:\";
6275 output_asm_insn (\"b%D0\\t.LCB%=\", cond);
6276 return \"bl\\t%l4\\t%@far jump\\n.LCB%=:\";
6280 [(set (attr "far_jump")
6282 (ior (and (eq (symbol_ref ("which_alternative"))
6284 (eq_attr "length" "8"))
6285 (eq_attr "length" "10"))
6286 (const_string "yes")
6287 (const_string "no")))
6288 (set_attr_alternative "length"
6292 (and (ge (minus (match_dup 4) (pc)) (const_int -250))
6293 (le (minus (match_dup 4) (pc)) (const_int 256)))
6296 (and (ge (minus (match_dup 4) (pc)) (const_int -2040))
6297 (le (minus (match_dup 4) (pc)) (const_int 2048)))
6302 (and (ge (minus (match_dup 4) (pc)) (const_int -248))
6303 (le (minus (match_dup 4) (pc)) (const_int 256)))
6306 (and (ge (minus (match_dup 4) (pc)) (const_int -2038))
6307 (le (minus (match_dup 4) (pc)) (const_int 2048)))
6312 (and (ge (minus (match_dup 4) (pc)) (const_int -248))
6313 (le (minus (match_dup 4) (pc)) (const_int 256)))
6316 (and (ge (minus (match_dup 4) (pc)) (const_int -2038))
6317 (le (minus (match_dup 4) (pc)) (const_int 2048)))
6322 (and (ge (minus (match_dup 4) (pc)) (const_int -248))
6323 (le (minus (match_dup 4) (pc)) (const_int 256)))
6326 (and (ge (minus (match_dup 4) (pc)) (const_int -2038))
6327 (le (minus (match_dup 4) (pc)) (const_int 2048)))
6332 (define_insn "*addsi3_cbranch"
6335 (match_operator 4 "comparison_operator"
6337 (match_operand:SI 2 "s_register_operand" "%l,0,*0,1,1,1")
6338 (match_operand:SI 3 "reg_or_int_operand" "lL,IJ,*r,lIJ,lIJ,lIJ"))
6340 (label_ref (match_operand 5 "" ""))
6343 (match_operand:SI 0 "thumb_cbrch_target_operand" "=l,l,*!h,*?h,*?m,*?m")
6344 (plus:SI (match_dup 2) (match_dup 3)))
6345 (clobber (match_scratch:SI 1 "=X,X,X,l,&l,&l"))]
6347 && (GET_CODE (operands[4]) == EQ
6348 || GET_CODE (operands[4]) == NE
6349 || GET_CODE (operands[4]) == GE
6350 || GET_CODE (operands[4]) == LT)"
6356 cond[0] = (which_alternative < 3) ? operands[0] : operands[1];
6357 cond[1] = operands[2];
6358 cond[2] = operands[3];
6360 if (GET_CODE (cond[2]) == CONST_INT && INTVAL (cond[2]) < 0)
6361 output_asm_insn (\"sub\\t%0, %1, #%n2\", cond);
6363 output_asm_insn (\"add\\t%0, %1, %2\", cond);
6365 if (which_alternative >= 3
6366 && which_alternative < 4)
6367 output_asm_insn (\"mov\\t%0, %1\", operands);
6368 else if (which_alternative >= 4)
6369 output_asm_insn (\"str\\t%1, %0\", operands);
6371 switch (get_attr_length (insn) - ((which_alternative >= 3) ? 2 : 0))
6374 return \"b%d4\\t%l5\";
6376 return \"b%D4\\t.LCB%=\;b\\t%l5\\t%@long jump\\n.LCB%=:\";
6378 return \"b%D4\\t.LCB%=\;bl\\t%l5\\t%@far jump\\n.LCB%=:\";
6382 [(set (attr "far_jump")
6384 (ior (and (lt (symbol_ref ("which_alternative"))
6386 (eq_attr "length" "8"))
6387 (eq_attr "length" "10"))
6388 (const_string "yes")
6389 (const_string "no")))
6390 (set (attr "length")
6392 (lt (symbol_ref ("which_alternative"))
6395 (and (ge (minus (match_dup 5) (pc)) (const_int -250))
6396 (le (minus (match_dup 5) (pc)) (const_int 256)))
6399 (and (ge (minus (match_dup 5) (pc)) (const_int -2040))
6400 (le (minus (match_dup 5) (pc)) (const_int 2048)))
6404 (and (ge (minus (match_dup 5) (pc)) (const_int -248))
6405 (le (minus (match_dup 5) (pc)) (const_int 256)))
6408 (and (ge (minus (match_dup 5) (pc)) (const_int -2038))
6409 (le (minus (match_dup 5) (pc)) (const_int 2048)))
6414 (define_insn "*addsi3_cbranch_scratch"
6417 (match_operator 3 "comparison_operator"
6419 (match_operand:SI 1 "s_register_operand" "%l,l,l,0")
6420 (match_operand:SI 2 "reg_or_int_operand" "J,l,I,L"))
6422 (label_ref (match_operand 4 "" ""))
6424 (clobber (match_scratch:SI 0 "=X,X,l,l"))]
6426 && (GET_CODE (operands[3]) == EQ
6427 || GET_CODE (operands[3]) == NE
6428 || GET_CODE (operands[3]) == GE
6429 || GET_CODE (operands[3]) == LT)"
6432 switch (which_alternative)
6435 output_asm_insn (\"cmp\t%1, #%n2\", operands);
6438 output_asm_insn (\"cmn\t%1, %2\", operands);
6441 output_asm_insn (\"add\t%0, %1, %2\", operands);
6444 output_asm_insn (\"add\t%0, %0, %2\", operands);
6448 switch (get_attr_length (insn))
6451 return \"b%d3\\t%l4\";
6453 return \"b%D3\\t.LCB%=\;b\\t%l4\\t%@long jump\\n.LCB%=:\";
6455 return \"b%D3\\t.LCB%=\;bl\\t%l4\\t%@far jump\\n.LCB%=:\";
6459 [(set (attr "far_jump")
6461 (eq_attr "length" "8")
6462 (const_string "yes")
6463 (const_string "no")))
6464 (set (attr "length")
6466 (and (ge (minus (match_dup 4) (pc)) (const_int -250))
6467 (le (minus (match_dup 4) (pc)) (const_int 256)))
6470 (and (ge (minus (match_dup 4) (pc)) (const_int -2040))
6471 (le (minus (match_dup 4) (pc)) (const_int 2048)))
6476 (define_insn "*subsi3_cbranch"
6479 (match_operator 4 "comparison_operator"
6481 (match_operand:SI 2 "s_register_operand" "l,l,1,l")
6482 (match_operand:SI 3 "s_register_operand" "l,l,l,l"))
6484 (label_ref (match_operand 5 "" ""))
6486 (set (match_operand:SI 0 "thumb_cbrch_target_operand" "=l,*?h,*?m,*?m")
6487 (minus:SI (match_dup 2) (match_dup 3)))
6488 (clobber (match_scratch:SI 1 "=X,l,&l,&l"))]
6490 && (GET_CODE (operands[4]) == EQ
6491 || GET_CODE (operands[4]) == NE
6492 || GET_CODE (operands[4]) == GE
6493 || GET_CODE (operands[4]) == LT)"
6496 if (which_alternative == 0)
6497 output_asm_insn (\"sub\\t%0, %2, %3\", operands);
6498 else if (which_alternative == 1)
6500 /* We must provide an alternative for a hi reg because reload
6501 cannot handle output reloads on a jump instruction, but we
6502 can't subtract into that. Fortunately a mov from lo to hi
6503 does not clobber the condition codes. */
6504 output_asm_insn (\"sub\\t%1, %2, %3\", operands);
6505 output_asm_insn (\"mov\\t%0, %1\", operands);
6509 /* Similarly, but the target is memory. */
6510 output_asm_insn (\"sub\\t%1, %2, %3\", operands);
6511 output_asm_insn (\"str\\t%1, %0\", operands);
6514 switch (get_attr_length (insn) - ((which_alternative != 0) ? 2 : 0))
6517 return \"b%d4\\t%l5\";
6519 return \"b%D4\\t.LCB%=\;b\\t%l5\\t%@long jump\\n.LCB%=:\";
6521 return \"b%D4\\t.LCB%=\;bl\\t%l5\\t%@far jump\\n.LCB%=:\";
6525 [(set (attr "far_jump")
6527 (ior (and (eq (symbol_ref ("which_alternative"))
6529 (eq_attr "length" "8"))
6530 (eq_attr "length" "10"))
6531 (const_string "yes")
6532 (const_string "no")))
6533 (set (attr "length")
6535 (eq (symbol_ref ("which_alternative"))
6538 (and (ge (minus (match_dup 5) (pc)) (const_int -250))
6539 (le (minus (match_dup 5) (pc)) (const_int 256)))
6542 (and (ge (minus (match_dup 5) (pc)) (const_int -2040))
6543 (le (minus (match_dup 5) (pc)) (const_int 2048)))
6547 (and (ge (minus (match_dup 5) (pc)) (const_int -248))
6548 (le (minus (match_dup 5) (pc)) (const_int 256)))
6551 (and (ge (minus (match_dup 5) (pc)) (const_int -2038))
6552 (le (minus (match_dup 5) (pc)) (const_int 2048)))
6557 (define_insn "*subsi3_cbranch_scratch"
6560 (match_operator 0 "arm_comparison_operator"
6561 [(minus:SI (match_operand:SI 1 "register_operand" "l")
6562 (match_operand:SI 2 "nonmemory_operand" "l"))
6564 (label_ref (match_operand 3 "" ""))
6567 && (GET_CODE (operands[0]) == EQ
6568 || GET_CODE (operands[0]) == NE
6569 || GET_CODE (operands[0]) == GE
6570 || GET_CODE (operands[0]) == LT)"
6572 output_asm_insn (\"cmp\\t%1, %2\", operands);
6573 switch (get_attr_length (insn))
6575 case 4: return \"b%d0\\t%l3\";
6576 case 6: return \"b%D0\\t.LCB%=\;b\\t%l3\\t%@long jump\\n.LCB%=:\";
6577 default: return \"b%D0\\t.LCB%=\;bl\\t%l3\\t%@far jump\\n.LCB%=:\";
6580 [(set (attr "far_jump")
6582 (eq_attr "length" "8")
6583 (const_string "yes")
6584 (const_string "no")))
6585 (set (attr "length")
6587 (and (ge (minus (match_dup 3) (pc)) (const_int -250))
6588 (le (minus (match_dup 3) (pc)) (const_int 256)))
6591 (and (ge (minus (match_dup 3) (pc)) (const_int -2040))
6592 (le (minus (match_dup 3) (pc)) (const_int 2048)))
6597 ;; Comparison and test insns
6599 (define_expand "cmpsi"
6600 [(match_operand:SI 0 "s_register_operand" "")
6601 (match_operand:SI 1 "arm_add_operand" "")]
6604 arm_compare_op0 = operands[0];
6605 arm_compare_op1 = operands[1];
6610 (define_expand "cmpsf"
6611 [(match_operand:SF 0 "s_register_operand" "")
6612 (match_operand:SF 1 "arm_float_compare_operand" "")]
6613 "TARGET_ARM && TARGET_HARD_FLOAT"
6615 arm_compare_op0 = operands[0];
6616 arm_compare_op1 = operands[1];
6621 (define_expand "cmpdf"
6622 [(match_operand:DF 0 "s_register_operand" "")
6623 (match_operand:DF 1 "arm_float_compare_operand" "")]
6624 "TARGET_ARM && TARGET_HARD_FLOAT"
6626 arm_compare_op0 = operands[0];
6627 arm_compare_op1 = operands[1];
6632 (define_insn "*arm_cmpsi_insn"
6633 [(set (reg:CC CC_REGNUM)
6634 (compare:CC (match_operand:SI 0 "s_register_operand" "r,r")
6635 (match_operand:SI 1 "arm_add_operand" "rI,L")))]
6640 [(set_attr "conds" "set")]
6643 (define_insn "*cmpsi_shiftsi"
6644 [(set (reg:CC CC_REGNUM)
6645 (compare:CC (match_operand:SI 0 "s_register_operand" "r")
6646 (match_operator:SI 3 "shift_operator"
6647 [(match_operand:SI 1 "s_register_operand" "r")
6648 (match_operand:SI 2 "arm_rhs_operand" "rM")])))]
6651 [(set_attr "conds" "set")
6652 (set_attr "shift" "1")
6653 (set (attr "type") (if_then_else (match_operand 2 "const_int_operand" "")
6654 (const_string "alu_shift")
6655 (const_string "alu_shift_reg")))]
6658 (define_insn "*cmpsi_shiftsi_swp"
6659 [(set (reg:CC_SWP CC_REGNUM)
6660 (compare:CC_SWP (match_operator:SI 3 "shift_operator"
6661 [(match_operand:SI 1 "s_register_operand" "r")
6662 (match_operand:SI 2 "reg_or_int_operand" "rM")])
6663 (match_operand:SI 0 "s_register_operand" "r")))]
6666 [(set_attr "conds" "set")
6667 (set_attr "shift" "1")
6668 (set (attr "type") (if_then_else (match_operand 2 "const_int_operand" "")
6669 (const_string "alu_shift")
6670 (const_string "alu_shift_reg")))]
6673 (define_insn "*cmpsi_neg_shiftsi"
6674 [(set (reg:CC CC_REGNUM)
6675 (compare:CC (match_operand:SI 0 "s_register_operand" "r")
6676 (neg:SI (match_operator:SI 3 "shift_operator"
6677 [(match_operand:SI 1 "s_register_operand" "r")
6678 (match_operand:SI 2 "arm_rhs_operand" "rM")]))))]
6681 [(set_attr "conds" "set")
6682 (set_attr "shift" "1")
6683 (set (attr "type") (if_then_else (match_operand 2 "const_int_operand" "")
6684 (const_string "alu_shift")
6685 (const_string "alu_shift_reg")))]
6688 ;; Cirrus SF compare instruction
6689 (define_insn "*cirrus_cmpsf"
6690 [(set (reg:CCFP CC_REGNUM)
6691 (compare:CCFP (match_operand:SF 0 "cirrus_fp_register" "v")
6692 (match_operand:SF 1 "cirrus_fp_register" "v")))]
6693 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_MAVERICK"
6694 "cfcmps%?\\tr15, %V0, %V1"
6695 [(set_attr "type" "mav_farith")
6696 (set_attr "cirrus" "compare")]
6699 ;; Cirrus DF compare instruction
6700 (define_insn "*cirrus_cmpdf"
6701 [(set (reg:CCFP CC_REGNUM)
6702 (compare:CCFP (match_operand:DF 0 "cirrus_fp_register" "v")
6703 (match_operand:DF 1 "cirrus_fp_register" "v")))]
6704 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_MAVERICK"
6705 "cfcmpd%?\\tr15, %V0, %V1"
6706 [(set_attr "type" "mav_farith")
6707 (set_attr "cirrus" "compare")]
6710 ;; Cirrus DI compare instruction
6711 (define_expand "cmpdi"
6712 [(match_operand:DI 0 "cirrus_fp_register" "")
6713 (match_operand:DI 1 "cirrus_fp_register" "")]
6714 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_MAVERICK"
6716 arm_compare_op0 = operands[0];
6717 arm_compare_op1 = operands[1];
6721 (define_insn "*cirrus_cmpdi"
6722 [(set (reg:CC CC_REGNUM)
6723 (compare:CC (match_operand:DI 0 "cirrus_fp_register" "v")
6724 (match_operand:DI 1 "cirrus_fp_register" "v")))]
6725 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_MAVERICK"
6726 "cfcmp64%?\\tr15, %V0, %V1"
6727 [(set_attr "type" "mav_farith")
6728 (set_attr "cirrus" "compare")]
6731 ; This insn allows redundant compares to be removed by cse, nothing should
6732 ; ever appear in the output file since (set (reg x) (reg x)) is a no-op that
6733 ; is deleted later on. The match_dup will match the mode here, so that
6734 ; mode changes of the condition codes aren't lost by this even though we don't
6735 ; specify what they are.
6737 (define_insn "*deleted_compare"
6738 [(set (match_operand 0 "cc_register" "") (match_dup 0))]
6740 "\\t%@ deleted compare"
6741 [(set_attr "conds" "set")
6742 (set_attr "length" "0")]
6746 ;; Conditional branch insns
6748 (define_expand "beq"
6750 (if_then_else (eq (match_dup 1) (const_int 0))
6751 (label_ref (match_operand 0 "" ""))
6754 "operands[1] = arm_gen_compare_reg (EQ, arm_compare_op0, arm_compare_op1);"
6757 (define_expand "bne"
6759 (if_then_else (ne (match_dup 1) (const_int 0))
6760 (label_ref (match_operand 0 "" ""))
6763 "operands[1] = arm_gen_compare_reg (NE, arm_compare_op0, arm_compare_op1);"
6766 (define_expand "bgt"
6768 (if_then_else (gt (match_dup 1) (const_int 0))
6769 (label_ref (match_operand 0 "" ""))
6772 "operands[1] = arm_gen_compare_reg (GT, arm_compare_op0, arm_compare_op1);"
6775 (define_expand "ble"
6777 (if_then_else (le (match_dup 1) (const_int 0))
6778 (label_ref (match_operand 0 "" ""))
6781 "operands[1] = arm_gen_compare_reg (LE, arm_compare_op0, arm_compare_op1);"
6784 (define_expand "bge"
6786 (if_then_else (ge (match_dup 1) (const_int 0))
6787 (label_ref (match_operand 0 "" ""))
6790 "operands[1] = arm_gen_compare_reg (GE, arm_compare_op0, arm_compare_op1);"
6793 (define_expand "blt"
6795 (if_then_else (lt (match_dup 1) (const_int 0))
6796 (label_ref (match_operand 0 "" ""))
6799 "operands[1] = arm_gen_compare_reg (LT, arm_compare_op0, arm_compare_op1);"
6802 (define_expand "bgtu"
6804 (if_then_else (gtu (match_dup 1) (const_int 0))
6805 (label_ref (match_operand 0 "" ""))
6808 "operands[1] = arm_gen_compare_reg (GTU, arm_compare_op0, arm_compare_op1);"
6811 (define_expand "bleu"
6813 (if_then_else (leu (match_dup 1) (const_int 0))
6814 (label_ref (match_operand 0 "" ""))
6817 "operands[1] = arm_gen_compare_reg (LEU, arm_compare_op0, arm_compare_op1);"
6820 (define_expand "bgeu"
6822 (if_then_else (geu (match_dup 1) (const_int 0))
6823 (label_ref (match_operand 0 "" ""))
6826 "operands[1] = arm_gen_compare_reg (GEU, arm_compare_op0, arm_compare_op1);"
6829 (define_expand "bltu"
6831 (if_then_else (ltu (match_dup 1) (const_int 0))
6832 (label_ref (match_operand 0 "" ""))
6835 "operands[1] = arm_gen_compare_reg (LTU, arm_compare_op0, arm_compare_op1);"
6838 (define_expand "bunordered"
6840 (if_then_else (unordered (match_dup 1) (const_int 0))
6841 (label_ref (match_operand 0 "" ""))
6843 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
6844 "operands[1] = arm_gen_compare_reg (UNORDERED, arm_compare_op0,
6848 (define_expand "bordered"
6850 (if_then_else (ordered (match_dup 1) (const_int 0))
6851 (label_ref (match_operand 0 "" ""))
6853 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
6854 "operands[1] = arm_gen_compare_reg (ORDERED, arm_compare_op0,
6858 (define_expand "bungt"
6860 (if_then_else (ungt (match_dup 1) (const_int 0))
6861 (label_ref (match_operand 0 "" ""))
6863 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
6864 "operands[1] = arm_gen_compare_reg (UNGT, arm_compare_op0, arm_compare_op1);"
6867 (define_expand "bunlt"
6869 (if_then_else (unlt (match_dup 1) (const_int 0))
6870 (label_ref (match_operand 0 "" ""))
6872 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
6873 "operands[1] = arm_gen_compare_reg (UNLT, arm_compare_op0, arm_compare_op1);"
6876 (define_expand "bunge"
6878 (if_then_else (unge (match_dup 1) (const_int 0))
6879 (label_ref (match_operand 0 "" ""))
6881 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
6882 "operands[1] = arm_gen_compare_reg (UNGE, arm_compare_op0, arm_compare_op1);"
6885 (define_expand "bunle"
6887 (if_then_else (unle (match_dup 1) (const_int 0))
6888 (label_ref (match_operand 0 "" ""))
6890 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
6891 "operands[1] = arm_gen_compare_reg (UNLE, arm_compare_op0, arm_compare_op1);"
6894 ;; The following two patterns need two branch instructions, since there is
6895 ;; no single instruction that will handle all cases.
6896 (define_expand "buneq"
6898 (if_then_else (uneq (match_dup 1) (const_int 0))
6899 (label_ref (match_operand 0 "" ""))
6901 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
6902 "operands[1] = arm_gen_compare_reg (UNEQ, arm_compare_op0, arm_compare_op1);"
6905 (define_expand "bltgt"
6907 (if_then_else (ltgt (match_dup 1) (const_int 0))
6908 (label_ref (match_operand 0 "" ""))
6910 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
6911 "operands[1] = arm_gen_compare_reg (LTGT, arm_compare_op0, arm_compare_op1);"
6915 ;; Patterns to match conditional branch insns.
6918 ; Special pattern to match UNEQ.
6919 (define_insn "*arm_buneq"
6921 (if_then_else (uneq (match_operand 1 "cc_register" "") (const_int 0))
6922 (label_ref (match_operand 0 "" ""))
6924 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
6926 if (arm_ccfsm_state != 0)
6929 return \"bvs\\t%l0\;beq\\t%l0\";
6931 [(set_attr "conds" "jump_clob")
6932 (set_attr "length" "8")]
6935 ; Special pattern to match LTGT.
6936 (define_insn "*arm_bltgt"
6938 (if_then_else (ltgt (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 \"bmi\\t%l0\;bgt\\t%l0\";
6948 [(set_attr "conds" "jump_clob")
6949 (set_attr "length" "8")]
6952 (define_insn "*arm_cond_branch"
6954 (if_then_else (match_operator 1 "arm_comparison_operator"
6955 [(match_operand 2 "cc_register" "") (const_int 0)])
6956 (label_ref (match_operand 0 "" ""))
6960 if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
6962 arm_ccfsm_state += 2;
6965 return \"b%d1\\t%l0\";
6967 [(set_attr "conds" "use")
6968 (set_attr "type" "branch")]
6971 ; Special pattern to match reversed UNEQ.
6972 (define_insn "*arm_buneq_reversed"
6974 (if_then_else (uneq (match_operand 1 "cc_register" "") (const_int 0))
6976 (label_ref (match_operand 0 "" ""))))]
6977 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
6979 if (arm_ccfsm_state != 0)
6982 return \"bmi\\t%l0\;bgt\\t%l0\";
6984 [(set_attr "conds" "jump_clob")
6985 (set_attr "length" "8")]
6988 ; Special pattern to match reversed LTGT.
6989 (define_insn "*arm_bltgt_reversed"
6991 (if_then_else (ltgt (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 \"bvs\\t%l0\;beq\\t%l0\";
7001 [(set_attr "conds" "jump_clob")
7002 (set_attr "length" "8")]
7005 (define_insn "*arm_cond_branch_reversed"
7007 (if_then_else (match_operator 1 "arm_comparison_operator"
7008 [(match_operand 2 "cc_register" "") (const_int 0)])
7010 (label_ref (match_operand 0 "" ""))))]
7013 if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
7015 arm_ccfsm_state += 2;
7018 return \"b%D1\\t%l0\";
7020 [(set_attr "conds" "use")
7021 (set_attr "type" "branch")]
7028 (define_expand "seq"
7029 [(set (match_operand:SI 0 "s_register_operand" "")
7030 (eq:SI (match_dup 1) (const_int 0)))]
7032 "operands[1] = arm_gen_compare_reg (EQ, arm_compare_op0, arm_compare_op1);"
7035 (define_expand "sne"
7036 [(set (match_operand:SI 0 "s_register_operand" "")
7037 (ne:SI (match_dup 1) (const_int 0)))]
7039 "operands[1] = arm_gen_compare_reg (NE, arm_compare_op0, arm_compare_op1);"
7042 (define_expand "sgt"
7043 [(set (match_operand:SI 0 "s_register_operand" "")
7044 (gt:SI (match_dup 1) (const_int 0)))]
7046 "operands[1] = arm_gen_compare_reg (GT, arm_compare_op0, arm_compare_op1);"
7049 (define_expand "sle"
7050 [(set (match_operand:SI 0 "s_register_operand" "")
7051 (le:SI (match_dup 1) (const_int 0)))]
7053 "operands[1] = arm_gen_compare_reg (LE, arm_compare_op0, arm_compare_op1);"
7056 (define_expand "sge"
7057 [(set (match_operand:SI 0 "s_register_operand" "")
7058 (ge:SI (match_dup 1) (const_int 0)))]
7060 "operands[1] = arm_gen_compare_reg (GE, arm_compare_op0, arm_compare_op1);"
7063 (define_expand "slt"
7064 [(set (match_operand:SI 0 "s_register_operand" "")
7065 (lt:SI (match_dup 1) (const_int 0)))]
7067 "operands[1] = arm_gen_compare_reg (LT, arm_compare_op0, arm_compare_op1);"
7070 (define_expand "sgtu"
7071 [(set (match_operand:SI 0 "s_register_operand" "")
7072 (gtu:SI (match_dup 1) (const_int 0)))]
7074 "operands[1] = arm_gen_compare_reg (GTU, arm_compare_op0, arm_compare_op1);"
7077 (define_expand "sleu"
7078 [(set (match_operand:SI 0 "s_register_operand" "")
7079 (leu:SI (match_dup 1) (const_int 0)))]
7081 "operands[1] = arm_gen_compare_reg (LEU, arm_compare_op0, arm_compare_op1);"
7084 (define_expand "sgeu"
7085 [(set (match_operand:SI 0 "s_register_operand" "")
7086 (geu:SI (match_dup 1) (const_int 0)))]
7088 "operands[1] = arm_gen_compare_reg (GEU, arm_compare_op0, arm_compare_op1);"
7091 (define_expand "sltu"
7092 [(set (match_operand:SI 0 "s_register_operand" "")
7093 (ltu:SI (match_dup 1) (const_int 0)))]
7095 "operands[1] = arm_gen_compare_reg (LTU, arm_compare_op0, arm_compare_op1);"
7098 (define_expand "sunordered"
7099 [(set (match_operand:SI 0 "s_register_operand" "")
7100 (unordered:SI (match_dup 1) (const_int 0)))]
7101 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
7102 "operands[1] = arm_gen_compare_reg (UNORDERED, arm_compare_op0,
7106 (define_expand "sordered"
7107 [(set (match_operand:SI 0 "s_register_operand" "")
7108 (ordered:SI (match_dup 1) (const_int 0)))]
7109 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
7110 "operands[1] = arm_gen_compare_reg (ORDERED, arm_compare_op0,
7114 (define_expand "sungt"
7115 [(set (match_operand:SI 0 "s_register_operand" "")
7116 (ungt:SI (match_dup 1) (const_int 0)))]
7117 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
7118 "operands[1] = arm_gen_compare_reg (UNGT, arm_compare_op0,
7122 (define_expand "sunge"
7123 [(set (match_operand:SI 0 "s_register_operand" "")
7124 (unge:SI (match_dup 1) (const_int 0)))]
7125 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
7126 "operands[1] = arm_gen_compare_reg (UNGE, arm_compare_op0,
7130 (define_expand "sunlt"
7131 [(set (match_operand:SI 0 "s_register_operand" "")
7132 (unlt:SI (match_dup 1) (const_int 0)))]
7133 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
7134 "operands[1] = arm_gen_compare_reg (UNLT, arm_compare_op0,
7138 (define_expand "sunle"
7139 [(set (match_operand:SI 0 "s_register_operand" "")
7140 (unle:SI (match_dup 1) (const_int 0)))]
7141 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
7142 "operands[1] = arm_gen_compare_reg (UNLE, arm_compare_op0,
7146 ;;; DO NOT add patterns for SUNEQ or SLTGT, these can't be represented with
7147 ;;; simple ARM instructions.
7149 ; (define_expand "suneq"
7150 ; [(set (match_operand:SI 0 "s_register_operand" "")
7151 ; (uneq:SI (match_dup 1) (const_int 0)))]
7152 ; "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
7156 ; (define_expand "sltgt"
7157 ; [(set (match_operand:SI 0 "s_register_operand" "")
7158 ; (ltgt:SI (match_dup 1) (const_int 0)))]
7159 ; "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
7163 (define_insn "*mov_scc"
7164 [(set (match_operand:SI 0 "s_register_operand" "=r")
7165 (match_operator:SI 1 "arm_comparison_operator"
7166 [(match_operand 2 "cc_register" "") (const_int 0)]))]
7168 "mov%D1\\t%0, #0\;mov%d1\\t%0, #1"
7169 [(set_attr "conds" "use")
7170 (set_attr "length" "8")]
7173 (define_insn "*mov_negscc"
7174 [(set (match_operand:SI 0 "s_register_operand" "=r")
7175 (neg:SI (match_operator:SI 1 "arm_comparison_operator"
7176 [(match_operand 2 "cc_register" "") (const_int 0)])))]
7178 "mov%D1\\t%0, #0\;mvn%d1\\t%0, #0"
7179 [(set_attr "conds" "use")
7180 (set_attr "length" "8")]
7183 (define_insn "*mov_notscc"
7184 [(set (match_operand:SI 0 "s_register_operand" "=r")
7185 (not:SI (match_operator:SI 1 "arm_comparison_operator"
7186 [(match_operand 2 "cc_register" "") (const_int 0)])))]
7188 "mov%D1\\t%0, #0\;mvn%d1\\t%0, #1"
7189 [(set_attr "conds" "use")
7190 (set_attr "length" "8")]
7194 ;; Conditional move insns
7196 (define_expand "movsicc"
7197 [(set (match_operand:SI 0 "s_register_operand" "")
7198 (if_then_else:SI (match_operand 1 "arm_comparison_operator" "")
7199 (match_operand:SI 2 "arm_not_operand" "")
7200 (match_operand:SI 3 "arm_not_operand" "")))]
7204 enum rtx_code code = GET_CODE (operands[1]);
7207 if (code == UNEQ || code == LTGT)
7210 ccreg = arm_gen_compare_reg (code, arm_compare_op0, arm_compare_op1);
7211 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
7215 (define_expand "movsfcc"
7216 [(set (match_operand:SF 0 "s_register_operand" "")
7217 (if_then_else:SF (match_operand 1 "arm_comparison_operator" "")
7218 (match_operand:SF 2 "s_register_operand" "")
7219 (match_operand:SF 3 "nonmemory_operand" "")))]
7223 enum rtx_code code = GET_CODE (operands[1]);
7226 if (code == UNEQ || code == LTGT)
7229 /* When compiling for SOFT_FLOAT, ensure both arms are in registers.
7230 Otherwise, ensure it is a valid FP add operand */
7231 if ((!(TARGET_HARD_FLOAT && TARGET_FPA))
7232 || (!arm_float_add_operand (operands[3], SFmode)))
7233 operands[3] = force_reg (SFmode, operands[3]);
7235 ccreg = arm_gen_compare_reg (code, arm_compare_op0, arm_compare_op1);
7236 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
7240 (define_expand "movdfcc"
7241 [(set (match_operand:DF 0 "s_register_operand" "")
7242 (if_then_else:DF (match_operand 1 "arm_comparison_operator" "")
7243 (match_operand:DF 2 "s_register_operand" "")
7244 (match_operand:DF 3 "arm_float_add_operand" "")))]
7245 "TARGET_ARM && TARGET_HARD_FLOAT && (TARGET_FPA || TARGET_VFP)"
7248 enum rtx_code code = GET_CODE (operands[1]);
7251 if (code == UNEQ || code == LTGT)
7254 ccreg = arm_gen_compare_reg (code, arm_compare_op0, arm_compare_op1);
7255 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
7259 (define_insn "*movsicc_insn"
7260 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r,r,r,r,r")
7262 (match_operator 3 "arm_comparison_operator"
7263 [(match_operand 4 "cc_register" "") (const_int 0)])
7264 (match_operand:SI 1 "arm_not_operand" "0,0,rI,K,rI,rI,K,K")
7265 (match_operand:SI 2 "arm_not_operand" "rI,K,0,0,rI,K,rI,K")))]
7272 mov%d3\\t%0, %1\;mov%D3\\t%0, %2
7273 mov%d3\\t%0, %1\;mvn%D3\\t%0, #%B2
7274 mvn%d3\\t%0, #%B1\;mov%D3\\t%0, %2
7275 mvn%d3\\t%0, #%B1\;mvn%D3\\t%0, #%B2"
7276 [(set_attr "length" "4,4,4,4,8,8,8,8")
7277 (set_attr "conds" "use")]
7280 (define_insn "*movsfcc_soft_insn"
7281 [(set (match_operand:SF 0 "s_register_operand" "=r,r")
7282 (if_then_else:SF (match_operator 3 "arm_comparison_operator"
7283 [(match_operand 4 "cc_register" "") (const_int 0)])
7284 (match_operand:SF 1 "s_register_operand" "0,r")
7285 (match_operand:SF 2 "s_register_operand" "r,0")))]
7286 "TARGET_ARM && TARGET_SOFT_FLOAT"
7290 [(set_attr "conds" "use")]
7294 ;; Jump and linkage insns
7296 (define_expand "jump"
7298 (label_ref (match_operand 0 "" "")))]
7303 (define_insn "*arm_jump"
7305 (label_ref (match_operand 0 "" "")))]
7309 if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
7311 arm_ccfsm_state += 2;
7314 return \"b%?\\t%l0\";
7317 [(set_attr "predicable" "yes")]
7320 (define_insn "*thumb_jump"
7322 (label_ref (match_operand 0 "" "")))]
7325 if (get_attr_length (insn) == 2)
7327 return \"bl\\t%l0\\t%@ far jump\";
7329 [(set (attr "far_jump")
7331 (eq_attr "length" "4")
7332 (const_string "yes")
7333 (const_string "no")))
7334 (set (attr "length")
7336 (and (ge (minus (match_dup 0) (pc)) (const_int -2044))
7337 (le (minus (match_dup 0) (pc)) (const_int 2048)))
7342 (define_expand "call"
7343 [(parallel [(call (match_operand 0 "memory_operand" "")
7344 (match_operand 1 "general_operand" ""))
7345 (use (match_operand 2 "" ""))
7346 (clobber (reg:SI LR_REGNUM))])]
7352 /* In an untyped call, we can get NULL for operand 2. */
7353 if (operands[2] == NULL_RTX)
7354 operands[2] = const0_rtx;
7356 /* This is to decide if we should generate indirect calls by loading the
7357 32 bit address of the callee into a register before performing the
7358 branch and link. operand[2] encodes the long_call/short_call
7359 attribute of the function being called. This attribute is set whenever
7360 __attribute__((long_call/short_call)) or #pragma long_call/no_long_call
7361 is used, and the short_call attribute can also be set if function is
7362 declared as static or if it has already been defined in the current
7363 compilation unit. See arm.c and arm.h for info about this. The third
7364 parameter to arm_is_longcall_p is used to tell it which pattern
7366 callee = XEXP (operands[0], 0);
7368 if (GET_CODE (callee) != REG
7369 && arm_is_longcall_p (operands[0], INTVAL (operands[2]), 0))
7370 XEXP (operands[0], 0) = force_reg (Pmode, callee);
7374 (define_insn "*call_reg_armv5"
7375 [(call (mem:SI (match_operand:SI 0 "s_register_operand" "r"))
7376 (match_operand 1 "" ""))
7377 (use (match_operand 2 "" ""))
7378 (clobber (reg:SI LR_REGNUM))]
7379 "TARGET_ARM && arm_arch5"
7381 [(set_attr "type" "call")]
7384 (define_insn "*call_reg_arm"
7385 [(call (mem:SI (match_operand:SI 0 "s_register_operand" "r"))
7386 (match_operand 1 "" ""))
7387 (use (match_operand 2 "" ""))
7388 (clobber (reg:SI LR_REGNUM))]
7389 "TARGET_ARM && !arm_arch5"
7391 return output_call (operands);
7393 ;; length is worst case, normally it is only two
7394 [(set_attr "length" "12")
7395 (set_attr "type" "call")]
7398 (define_insn "*call_mem"
7399 [(call (mem:SI (match_operand:SI 0 "memory_operand" "m"))
7400 (match_operand 1 "" ""))
7401 (use (match_operand 2 "" ""))
7402 (clobber (reg:SI LR_REGNUM))]
7405 return output_call_mem (operands);
7407 [(set_attr "length" "12")
7408 (set_attr "type" "call")]
7411 (define_insn "*call_reg_thumb_v5"
7412 [(call (mem:SI (match_operand:SI 0 "register_operand" "l*r"))
7413 (match_operand 1 "" ""))
7414 (use (match_operand 2 "" ""))
7415 (clobber (reg:SI LR_REGNUM))]
7416 "TARGET_THUMB && arm_arch5"
7418 [(set_attr "length" "2")
7419 (set_attr "type" "call")]
7422 (define_insn "*call_reg_thumb"
7423 [(call (mem:SI (match_operand:SI 0 "register_operand" "l*r"))
7424 (match_operand 1 "" ""))
7425 (use (match_operand 2 "" ""))
7426 (clobber (reg:SI LR_REGNUM))]
7427 "TARGET_THUMB && !arm_arch5"
7430 if (TARGET_CALLER_INTERWORKING)
7431 return \"bl\\t%__interwork_call_via_%0\";
7433 return \"bl\\t%__call_via_%0\";
7435 [(set_attr "type" "call")]
7438 (define_expand "call_value"
7439 [(parallel [(set (match_operand 0 "" "")
7440 (call (match_operand 1 "memory_operand" "")
7441 (match_operand 2 "general_operand" "")))
7442 (use (match_operand 3 "" ""))
7443 (clobber (reg:SI LR_REGNUM))])]
7447 rtx callee = XEXP (operands[1], 0);
7449 /* In an untyped call, we can get NULL for operand 2. */
7450 if (operands[3] == 0)
7451 operands[3] = const0_rtx;
7453 /* See the comment in define_expand \"call\". */
7454 if (GET_CODE (callee) != REG
7455 && arm_is_longcall_p (operands[1], INTVAL (operands[3]), 0))
7456 XEXP (operands[1], 0) = force_reg (Pmode, callee);
7460 (define_insn "*call_value_reg_armv5"
7461 [(set (match_operand 0 "" "")
7462 (call (mem:SI (match_operand:SI 1 "s_register_operand" "r"))
7463 (match_operand 2 "" "")))
7464 (use (match_operand 3 "" ""))
7465 (clobber (reg:SI LR_REGNUM))]
7466 "TARGET_ARM && arm_arch5"
7468 [(set_attr "type" "call")]
7471 (define_insn "*call_value_reg_arm"
7472 [(set (match_operand 0 "" "")
7473 (call (mem:SI (match_operand:SI 1 "s_register_operand" "r"))
7474 (match_operand 2 "" "")))
7475 (use (match_operand 3 "" ""))
7476 (clobber (reg:SI LR_REGNUM))]
7477 "TARGET_ARM && !arm_arch5"
7479 return output_call (&operands[1]);
7481 [(set_attr "length" "12")
7482 (set_attr "type" "call")]
7485 (define_insn "*call_value_mem"
7486 [(set (match_operand 0 "" "")
7487 (call (mem:SI (match_operand:SI 1 "memory_operand" "m"))
7488 (match_operand 2 "" "")))
7489 (use (match_operand 3 "" ""))
7490 (clobber (reg:SI LR_REGNUM))]
7491 "TARGET_ARM && (!CONSTANT_ADDRESS_P (XEXP (operands[1], 0)))"
7493 return output_call_mem (&operands[1]);
7495 [(set_attr "length" "12")
7496 (set_attr "type" "call")]
7499 (define_insn "*call_value_reg_thumb_v5"
7500 [(set (match_operand 0 "" "")
7501 (call (mem:SI (match_operand:SI 1 "register_operand" "l*r"))
7502 (match_operand 2 "" "")))
7503 (use (match_operand 3 "" ""))
7504 (clobber (reg:SI LR_REGNUM))]
7505 "TARGET_THUMB && arm_arch5"
7507 [(set_attr "length" "2")
7508 (set_attr "type" "call")]
7511 (define_insn "*call_value_reg_thumb"
7512 [(set (match_operand 0 "" "")
7513 (call (mem:SI (match_operand:SI 1 "register_operand" "l*r"))
7514 (match_operand 2 "" "")))
7515 (use (match_operand 3 "" ""))
7516 (clobber (reg:SI LR_REGNUM))]
7517 "TARGET_THUMB && !arm_arch5"
7520 if (TARGET_CALLER_INTERWORKING)
7521 return \"bl\\t%__interwork_call_via_%1\";
7523 return \"bl\\t%__call_via_%1\";
7525 [(set_attr "type" "call")]
7528 ;; Allow calls to SYMBOL_REFs specially as they are not valid general addresses
7529 ;; The 'a' causes the operand to be treated as an address, i.e. no '#' output.
7531 (define_insn "*call_symbol"
7532 [(call (mem:SI (match_operand:SI 0 "" ""))
7533 (match_operand 1 "" ""))
7534 (use (match_operand 2 "" ""))
7535 (clobber (reg:SI LR_REGNUM))]
7537 && (GET_CODE (operands[0]) == SYMBOL_REF)
7538 && !arm_is_longcall_p (operands[0], INTVAL (operands[2]), 1)"
7541 return NEED_PLT_RELOC ? \"bl%?\\t%a0(PLT)\" : \"bl%?\\t%a0\";
7543 [(set_attr "type" "call")]
7546 (define_insn "*call_value_symbol"
7547 [(set (match_operand 0 "s_register_operand" "")
7548 (call (mem:SI (match_operand:SI 1 "" ""))
7549 (match_operand:SI 2 "" "")))
7550 (use (match_operand 3 "" ""))
7551 (clobber (reg:SI LR_REGNUM))]
7553 && (GET_CODE (operands[1]) == SYMBOL_REF)
7554 && !arm_is_longcall_p (operands[1], INTVAL (operands[3]), 1)"
7557 return NEED_PLT_RELOC ? \"bl%?\\t%a1(PLT)\" : \"bl%?\\t%a1\";
7559 [(set_attr "type" "call")]
7562 (define_insn "*call_insn"
7563 [(call (mem:SI (match_operand:SI 0 "" ""))
7564 (match_operand:SI 1 "" ""))
7565 (use (match_operand 2 "" ""))
7566 (clobber (reg:SI LR_REGNUM))]
7568 && GET_CODE (operands[0]) == SYMBOL_REF
7569 && !arm_is_longcall_p (operands[0], INTVAL (operands[2]), 1)"
7571 [(set_attr "length" "4")
7572 (set_attr "type" "call")]
7575 (define_insn "*call_value_insn"
7576 [(set (match_operand 0 "register_operand" "")
7577 (call (mem:SI (match_operand 1 "" ""))
7578 (match_operand 2 "" "")))
7579 (use (match_operand 3 "" ""))
7580 (clobber (reg:SI LR_REGNUM))]
7582 && GET_CODE (operands[1]) == SYMBOL_REF
7583 && !arm_is_longcall_p (operands[1], INTVAL (operands[3]), 1)"
7585 [(set_attr "length" "4")
7586 (set_attr "type" "call")]
7589 ;; We may also be able to do sibcalls for Thumb, but it's much harder...
7590 (define_expand "sibcall"
7591 [(parallel [(call (match_operand 0 "memory_operand" "")
7592 (match_operand 1 "general_operand" ""))
7594 (use (match_operand 2 "" ""))])]
7598 if (operands[2] == NULL_RTX)
7599 operands[2] = const0_rtx;
7603 (define_expand "sibcall_value"
7604 [(parallel [(set (match_operand 0 "register_operand" "")
7605 (call (match_operand 1 "memory_operand" "")
7606 (match_operand 2 "general_operand" "")))
7608 (use (match_operand 3 "" ""))])]
7612 if (operands[3] == NULL_RTX)
7613 operands[3] = const0_rtx;
7617 (define_insn "*sibcall_insn"
7618 [(call (mem:SI (match_operand:SI 0 "" "X"))
7619 (match_operand 1 "" ""))
7621 (use (match_operand 2 "" ""))]
7622 "TARGET_ARM && GET_CODE (operands[0]) == SYMBOL_REF"
7624 return NEED_PLT_RELOC ? \"b%?\\t%a0(PLT)\" : \"b%?\\t%a0\";
7626 [(set_attr "type" "call")]
7629 (define_insn "*sibcall_value_insn"
7630 [(set (match_operand 0 "s_register_operand" "")
7631 (call (mem:SI (match_operand:SI 1 "" "X"))
7632 (match_operand 2 "" "")))
7634 (use (match_operand 3 "" ""))]
7635 "TARGET_ARM && GET_CODE (operands[1]) == SYMBOL_REF"
7637 return NEED_PLT_RELOC ? \"b%?\\t%a1(PLT)\" : \"b%?\\t%a1\";
7639 [(set_attr "type" "call")]
7642 ;; Often the return insn will be the same as loading from memory, so set attr
7643 (define_insn "return"
7645 "TARGET_ARM && USE_RETURN_INSN (FALSE)"
7648 if (arm_ccfsm_state == 2)
7650 arm_ccfsm_state += 2;
7653 return output_return_instruction (const_true_rtx, TRUE, FALSE);
7655 [(set_attr "type" "load1")
7656 (set_attr "length" "12")
7657 (set_attr "predicable" "yes")]
7660 (define_insn "*cond_return"
7662 (if_then_else (match_operator 0 "arm_comparison_operator"
7663 [(match_operand 1 "cc_register" "") (const_int 0)])
7666 "TARGET_ARM && USE_RETURN_INSN (TRUE)"
7669 if (arm_ccfsm_state == 2)
7671 arm_ccfsm_state += 2;
7674 return output_return_instruction (operands[0], TRUE, FALSE);
7676 [(set_attr "conds" "use")
7677 (set_attr "length" "12")
7678 (set_attr "type" "load1")]
7681 (define_insn "*cond_return_inverted"
7683 (if_then_else (match_operator 0 "arm_comparison_operator"
7684 [(match_operand 1 "cc_register" "") (const_int 0)])
7687 "TARGET_ARM && USE_RETURN_INSN (TRUE)"
7690 if (arm_ccfsm_state == 2)
7692 arm_ccfsm_state += 2;
7695 return output_return_instruction (operands[0], TRUE, TRUE);
7697 [(set_attr "conds" "use")
7698 (set_attr "length" "12")
7699 (set_attr "type" "load1")]
7702 ;; Generate a sequence of instructions to determine if the processor is
7703 ;; in 26-bit or 32-bit mode, and return the appropriate return address
7706 (define_expand "return_addr_mask"
7708 (compare:CC_NOOV (unspec [(const_int 0)] UNSPEC_CHECK_ARCH)
7710 (set (match_operand:SI 0 "s_register_operand" "")
7711 (if_then_else:SI (eq (match_dup 1) (const_int 0))
7713 (const_int 67108860)))] ; 0x03fffffc
7716 operands[1] = gen_rtx_REG (CC_NOOVmode, CC_REGNUM);
7719 (define_insn "*check_arch2"
7720 [(set (match_operand:CC_NOOV 0 "cc_register" "")
7721 (compare:CC_NOOV (unspec [(const_int 0)] UNSPEC_CHECK_ARCH)
7724 "teq\\t%|r0, %|r0\;teq\\t%|pc, %|pc"
7725 [(set_attr "length" "8")
7726 (set_attr "conds" "set")]
7729 ;; Call subroutine returning any type.
7731 (define_expand "untyped_call"
7732 [(parallel [(call (match_operand 0 "" "")
7734 (match_operand 1 "" "")
7735 (match_operand 2 "" "")])]
7741 emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, const0_rtx));
7743 for (i = 0; i < XVECLEN (operands[2], 0); i++)
7745 rtx set = XVECEXP (operands[2], 0, i);
7747 emit_move_insn (SET_DEST (set), SET_SRC (set));
7750 /* The optimizer does not know that the call sets the function value
7751 registers we stored in the result block. We avoid problems by
7752 claiming that all hard registers are used and clobbered at this
7754 emit_insn (gen_blockage ());
7760 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
7761 ;; all of memory. This blocks insns from being moved across this point.
7763 (define_insn "blockage"
7764 [(unspec_volatile [(const_int 0)] VUNSPEC_BLOCKAGE)]
7767 [(set_attr "length" "0")
7768 (set_attr "type" "block")]
7771 (define_expand "casesi"
7772 [(match_operand:SI 0 "s_register_operand" "") ; index to jump on
7773 (match_operand:SI 1 "const_int_operand" "") ; lower bound
7774 (match_operand:SI 2 "const_int_operand" "") ; total range
7775 (match_operand:SI 3 "" "") ; table label
7776 (match_operand:SI 4 "" "")] ; Out of range label
7781 if (operands[1] != const0_rtx)
7783 reg = gen_reg_rtx (SImode);
7785 emit_insn (gen_addsi3 (reg, operands[0],
7786 GEN_INT (-INTVAL (operands[1]))));
7790 if (!const_ok_for_arm (INTVAL (operands[2])))
7791 operands[2] = force_reg (SImode, operands[2]);
7793 emit_jump_insn (gen_casesi_internal (operands[0], operands[2], operands[3],
7799 ;; The USE in this pattern is needed to tell flow analysis that this is
7800 ;; a CASESI insn. It has no other purpose.
7801 (define_insn "casesi_internal"
7802 [(parallel [(set (pc)
7804 (leu (match_operand:SI 0 "s_register_operand" "r")
7805 (match_operand:SI 1 "arm_rhs_operand" "rI"))
7806 (mem:SI (plus:SI (mult:SI (match_dup 0) (const_int 4))
7807 (label_ref (match_operand 2 "" ""))))
7808 (label_ref (match_operand 3 "" ""))))
7809 (clobber (reg:CC CC_REGNUM))
7810 (use (label_ref (match_dup 2)))])]
7814 return \"cmp\\t%0, %1\;addls\\t%|pc, %|pc, %0, asl #2\;b\\t%l3\";
7815 return \"cmp\\t%0, %1\;ldrls\\t%|pc, [%|pc, %0, asl #2]\;b\\t%l3\";
7817 [(set_attr "conds" "clob")
7818 (set_attr "length" "12")]
7821 (define_expand "indirect_jump"
7823 (match_operand:SI 0 "s_register_operand" ""))]
7828 ;; NB Never uses BX.
7829 (define_insn "*arm_indirect_jump"
7831 (match_operand:SI 0 "s_register_operand" "r"))]
7833 "mov%?\\t%|pc, %0\\t%@ indirect register jump"
7834 [(set_attr "predicable" "yes")]
7837 (define_insn "*load_indirect_jump"
7839 (match_operand:SI 0 "memory_operand" "m"))]
7841 "ldr%?\\t%|pc, %0\\t%@ indirect memory jump"
7842 [(set_attr "type" "load1")
7843 (set_attr "pool_range" "4096")
7844 (set_attr "neg_pool_range" "4084")
7845 (set_attr "predicable" "yes")]
7848 ;; NB Never uses BX.
7849 (define_insn "*thumb_indirect_jump"
7851 (match_operand:SI 0 "register_operand" "l*r"))]
7854 [(set_attr "conds" "clob")
7855 (set_attr "length" "2")]
7866 return \"mov%?\\t%|r0, %|r0\\t%@ nop\";
7867 return \"mov\\tr8, r8\";
7869 [(set (attr "length")
7870 (if_then_else (eq_attr "is_thumb" "yes")
7876 ;; Patterns to allow combination of arithmetic, cond code and shifts
7878 (define_insn "*arith_shiftsi"
7879 [(set (match_operand:SI 0 "s_register_operand" "=r")
7880 (match_operator:SI 1 "shiftable_operator"
7881 [(match_operator:SI 3 "shift_operator"
7882 [(match_operand:SI 4 "s_register_operand" "r")
7883 (match_operand:SI 5 "reg_or_int_operand" "rI")])
7884 (match_operand:SI 2 "s_register_operand" "r")]))]
7886 "%i1%?\\t%0, %2, %4%S3"
7887 [(set_attr "predicable" "yes")
7888 (set_attr "shift" "4")
7889 (set (attr "type") (if_then_else (match_operand 5 "const_int_operand" "")
7890 (const_string "alu_shift")
7891 (const_string "alu_shift_reg")))]
7895 [(set (match_operand:SI 0 "s_register_operand" "")
7896 (match_operator:SI 1 "shiftable_operator"
7897 [(match_operator:SI 2 "shiftable_operator"
7898 [(match_operator:SI 3 "shift_operator"
7899 [(match_operand:SI 4 "s_register_operand" "")
7900 (match_operand:SI 5 "reg_or_int_operand" "")])
7901 (match_operand:SI 6 "s_register_operand" "")])
7902 (match_operand:SI 7 "arm_rhs_operand" "")]))
7903 (clobber (match_operand:SI 8 "s_register_operand" ""))]
7906 (match_op_dup 2 [(match_op_dup 3 [(match_dup 4) (match_dup 5)])
7909 (match_op_dup 1 [(match_dup 8) (match_dup 7)]))]
7912 (define_insn "*arith_shiftsi_compare0"
7913 [(set (reg:CC_NOOV CC_REGNUM)
7914 (compare:CC_NOOV (match_operator:SI 1 "shiftable_operator"
7915 [(match_operator:SI 3 "shift_operator"
7916 [(match_operand:SI 4 "s_register_operand" "r")
7917 (match_operand:SI 5 "reg_or_int_operand" "rI")])
7918 (match_operand:SI 2 "s_register_operand" "r")])
7920 (set (match_operand:SI 0 "s_register_operand" "=r")
7921 (match_op_dup 1 [(match_op_dup 3 [(match_dup 4) (match_dup 5)])
7924 "%i1%?s\\t%0, %2, %4%S3"
7925 [(set_attr "conds" "set")
7926 (set_attr "shift" "4")
7927 (set (attr "type") (if_then_else (match_operand 5 "const_int_operand" "")
7928 (const_string "alu_shift")
7929 (const_string "alu_shift_reg")))]
7932 (define_insn "*arith_shiftsi_compare0_scratch"
7933 [(set (reg:CC_NOOV CC_REGNUM)
7934 (compare:CC_NOOV (match_operator:SI 1 "shiftable_operator"
7935 [(match_operator:SI 3 "shift_operator"
7936 [(match_operand:SI 4 "s_register_operand" "r")
7937 (match_operand:SI 5 "reg_or_int_operand" "rI")])
7938 (match_operand:SI 2 "s_register_operand" "r")])
7940 (clobber (match_scratch:SI 0 "=r"))]
7942 "%i1%?s\\t%0, %2, %4%S3"
7943 [(set_attr "conds" "set")
7944 (set_attr "shift" "4")
7945 (set (attr "type") (if_then_else (match_operand 5 "const_int_operand" "")
7946 (const_string "alu_shift")
7947 (const_string "alu_shift_reg")))]
7950 (define_insn "*sub_shiftsi"
7951 [(set (match_operand:SI 0 "s_register_operand" "=r")
7952 (minus:SI (match_operand:SI 1 "s_register_operand" "r")
7953 (match_operator:SI 2 "shift_operator"
7954 [(match_operand:SI 3 "s_register_operand" "r")
7955 (match_operand:SI 4 "reg_or_int_operand" "rM")])))]
7957 "sub%?\\t%0, %1, %3%S2"
7958 [(set_attr "predicable" "yes")
7959 (set_attr "shift" "3")
7960 (set (attr "type") (if_then_else (match_operand 4 "const_int_operand" "")
7961 (const_string "alu_shift")
7962 (const_string "alu_shift_reg")))]
7965 (define_insn "*sub_shiftsi_compare0"
7966 [(set (reg:CC_NOOV CC_REGNUM)
7968 (minus:SI (match_operand:SI 1 "s_register_operand" "r")
7969 (match_operator:SI 2 "shift_operator"
7970 [(match_operand:SI 3 "s_register_operand" "r")
7971 (match_operand:SI 4 "reg_or_int_operand" "rM")]))
7973 (set (match_operand:SI 0 "s_register_operand" "=r")
7974 (minus:SI (match_dup 1) (match_op_dup 2 [(match_dup 3)
7977 "sub%?s\\t%0, %1, %3%S2"
7978 [(set_attr "conds" "set")
7979 (set_attr "shift" "3")
7980 (set (attr "type") (if_then_else (match_operand 4 "const_int_operand" "")
7981 (const_string "alu_shift")
7982 (const_string "alu_shift_reg")))]
7985 (define_insn "*sub_shiftsi_compare0_scratch"
7986 [(set (reg:CC_NOOV CC_REGNUM)
7988 (minus:SI (match_operand:SI 1 "s_register_operand" "r")
7989 (match_operator:SI 2 "shift_operator"
7990 [(match_operand:SI 3 "s_register_operand" "r")
7991 (match_operand:SI 4 "reg_or_int_operand" "rM")]))
7993 (clobber (match_scratch:SI 0 "=r"))]
7995 "sub%?s\\t%0, %1, %3%S2"
7996 [(set_attr "conds" "set")
7997 (set_attr "shift" "3")
7998 (set (attr "type") (if_then_else (match_operand 4 "const_int_operand" "")
7999 (const_string "alu_shift")
8000 (const_string "alu_shift_reg")))]
8005 (define_insn "*and_scc"
8006 [(set (match_operand:SI 0 "s_register_operand" "=r")
8007 (and:SI (match_operator:SI 1 "arm_comparison_operator"
8008 [(match_operand 3 "cc_register" "") (const_int 0)])
8009 (match_operand:SI 2 "s_register_operand" "r")))]
8011 "mov%D1\\t%0, #0\;and%d1\\t%0, %2, #1"
8012 [(set_attr "conds" "use")
8013 (set_attr "length" "8")]
8016 (define_insn "*ior_scc"
8017 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8018 (ior:SI (match_operator:SI 2 "arm_comparison_operator"
8019 [(match_operand 3 "cc_register" "") (const_int 0)])
8020 (match_operand:SI 1 "s_register_operand" "0,?r")))]
8024 mov%D2\\t%0, %1\;orr%d2\\t%0, %1, #1"
8025 [(set_attr "conds" "use")
8026 (set_attr "length" "4,8")]
8029 (define_insn "*compare_scc"
8030 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8031 (match_operator:SI 1 "arm_comparison_operator"
8032 [(match_operand:SI 2 "s_register_operand" "r,r")
8033 (match_operand:SI 3 "arm_add_operand" "rI,L")]))
8034 (clobber (reg:CC CC_REGNUM))]
8037 if (operands[3] == const0_rtx)
8039 if (GET_CODE (operands[1]) == LT)
8040 return \"mov\\t%0, %2, lsr #31\";
8042 if (GET_CODE (operands[1]) == GE)
8043 return \"mvn\\t%0, %2\;mov\\t%0, %0, lsr #31\";
8045 if (GET_CODE (operands[1]) == EQ)
8046 return \"rsbs\\t%0, %2, #1\;movcc\\t%0, #0\";
8049 if (GET_CODE (operands[1]) == NE)
8051 if (which_alternative == 1)
8052 return \"adds\\t%0, %2, #%n3\;movne\\t%0, #1\";
8053 return \"subs\\t%0, %2, %3\;movne\\t%0, #1\";
8055 if (which_alternative == 1)
8056 output_asm_insn (\"cmn\\t%2, #%n3\", operands);
8058 output_asm_insn (\"cmp\\t%2, %3\", operands);
8059 return \"mov%D1\\t%0, #0\;mov%d1\\t%0, #1\";
8061 [(set_attr "conds" "clob")
8062 (set_attr "length" "12")]
8065 (define_insn "*cond_move"
8066 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
8067 (if_then_else:SI (match_operator 3 "equality_operator"
8068 [(match_operator 4 "arm_comparison_operator"
8069 [(match_operand 5 "cc_register" "") (const_int 0)])
8071 (match_operand:SI 1 "arm_rhs_operand" "0,rI,?rI")
8072 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))]
8075 if (GET_CODE (operands[3]) == NE)
8077 if (which_alternative != 1)
8078 output_asm_insn (\"mov%D4\\t%0, %2\", operands);
8079 if (which_alternative != 0)
8080 output_asm_insn (\"mov%d4\\t%0, %1\", operands);
8083 if (which_alternative != 0)
8084 output_asm_insn (\"mov%D4\\t%0, %1\", operands);
8085 if (which_alternative != 1)
8086 output_asm_insn (\"mov%d4\\t%0, %2\", operands);
8089 [(set_attr "conds" "use")
8090 (set_attr "length" "4,4,8")]
8093 (define_insn "*cond_arith"
8094 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8095 (match_operator:SI 5 "shiftable_operator"
8096 [(match_operator:SI 4 "arm_comparison_operator"
8097 [(match_operand:SI 2 "s_register_operand" "r,r")
8098 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
8099 (match_operand:SI 1 "s_register_operand" "0,?r")]))
8100 (clobber (reg:CC CC_REGNUM))]
8103 if (GET_CODE (operands[4]) == LT && operands[3] == const0_rtx)
8104 return \"%i5\\t%0, %1, %2, lsr #31\";
8106 output_asm_insn (\"cmp\\t%2, %3\", operands);
8107 if (GET_CODE (operands[5]) == AND)
8108 output_asm_insn (\"mov%D4\\t%0, #0\", operands);
8109 else if (GET_CODE (operands[5]) == MINUS)
8110 output_asm_insn (\"rsb%D4\\t%0, %1, #0\", operands);
8111 else if (which_alternative != 0)
8112 output_asm_insn (\"mov%D4\\t%0, %1\", operands);
8113 return \"%i5%d4\\t%0, %1, #1\";
8115 [(set_attr "conds" "clob")
8116 (set_attr "length" "12")]
8119 (define_insn "*cond_sub"
8120 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8121 (minus:SI (match_operand:SI 1 "s_register_operand" "0,?r")
8122 (match_operator:SI 4 "arm_comparison_operator"
8123 [(match_operand:SI 2 "s_register_operand" "r,r")
8124 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))
8125 (clobber (reg:CC CC_REGNUM))]
8128 output_asm_insn (\"cmp\\t%2, %3\", operands);
8129 if (which_alternative != 0)
8130 output_asm_insn (\"mov%D4\\t%0, %1\", operands);
8131 return \"sub%d4\\t%0, %1, #1\";
8133 [(set_attr "conds" "clob")
8134 (set_attr "length" "8,12")]
8137 (define_insn "*cmp_ite0"
8138 [(set (match_operand 6 "dominant_cc_register" "")
8141 (match_operator 4 "arm_comparison_operator"
8142 [(match_operand:SI 0 "s_register_operand" "r,r,r,r")
8143 (match_operand:SI 1 "arm_add_operand" "rI,L,rI,L")])
8144 (match_operator:SI 5 "arm_comparison_operator"
8145 [(match_operand:SI 2 "s_register_operand" "r,r,r,r")
8146 (match_operand:SI 3 "arm_add_operand" "rI,rI,L,L")])
8152 static const char * const opcodes[4][2] =
8154 {\"cmp\\t%2, %3\;cmp%d5\\t%0, %1\",
8155 \"cmp\\t%0, %1\;cmp%d4\\t%2, %3\"},
8156 {\"cmp\\t%2, %3\;cmn%d5\\t%0, #%n1\",
8157 \"cmn\\t%0, #%n1\;cmp%d4\\t%2, %3\"},
8158 {\"cmn\\t%2, #%n3\;cmp%d5\\t%0, %1\",
8159 \"cmp\\t%0, %1\;cmn%d4\\t%2, #%n3\"},
8160 {\"cmn\\t%2, #%n3\;cmn%d5\\t%0, #%n1\",
8161 \"cmn\\t%0, #%n1\;cmn%d4\\t%2, #%n3\"}
8164 comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4]));
8166 return opcodes[which_alternative][swap];
8168 [(set_attr "conds" "set")
8169 (set_attr "length" "8")]
8172 (define_insn "*cmp_ite1"
8173 [(set (match_operand 6 "dominant_cc_register" "")
8176 (match_operator 4 "arm_comparison_operator"
8177 [(match_operand:SI 0 "s_register_operand" "r,r,r,r")
8178 (match_operand:SI 1 "arm_add_operand" "rI,L,rI,L")])
8179 (match_operator:SI 5 "arm_comparison_operator"
8180 [(match_operand:SI 2 "s_register_operand" "r,r,r,r")
8181 (match_operand:SI 3 "arm_add_operand" "rI,rI,L,L")])
8187 static const char * const opcodes[4][2] =
8189 {\"cmp\\t%0, %1\;cmp%d4\\t%2, %3\",
8190 \"cmp\\t%2, %3\;cmp%D5\\t%0, %1\"},
8191 {\"cmn\\t%0, #%n1\;cmp%d4\\t%2, %3\",
8192 \"cmp\\t%2, %3\;cmn%D5\\t%0, #%n1\"},
8193 {\"cmp\\t%0, %1\;cmn%d4\\t%2, #%n3\",
8194 \"cmn\\t%2, #%n3\;cmp%D5\\t%0, %1\"},
8195 {\"cmn\\t%0, #%n1\;cmn%d4\\t%2, #%n3\",
8196 \"cmn\\t%2, #%n3\;cmn%D5\\t%0, #%n1\"}
8199 comparison_dominates_p (GET_CODE (operands[5]),
8200 reverse_condition (GET_CODE (operands[4])));
8202 return opcodes[which_alternative][swap];
8204 [(set_attr "conds" "set")
8205 (set_attr "length" "8")]
8208 (define_insn "*cmp_and"
8209 [(set (match_operand 6 "dominant_cc_register" "")
8212 (match_operator 4 "arm_comparison_operator"
8213 [(match_operand:SI 0 "s_register_operand" "r,r,r,r")
8214 (match_operand:SI 1 "arm_add_operand" "rI,L,rI,L")])
8215 (match_operator:SI 5 "arm_comparison_operator"
8216 [(match_operand:SI 2 "s_register_operand" "r,r,r,r")
8217 (match_operand:SI 3 "arm_add_operand" "rI,rI,L,L")]))
8222 static const char *const opcodes[4][2] =
8224 {\"cmp\\t%2, %3\;cmp%d5\\t%0, %1\",
8225 \"cmp\\t%0, %1\;cmp%d4\\t%2, %3\"},
8226 {\"cmp\\t%2, %3\;cmn%d5\\t%0, #%n1\",
8227 \"cmn\\t%0, #%n1\;cmp%d4\\t%2, %3\"},
8228 {\"cmn\\t%2, #%n3\;cmp%d5\\t%0, %1\",
8229 \"cmp\\t%0, %1\;cmn%d4\\t%2, #%n3\"},
8230 {\"cmn\\t%2, #%n3\;cmn%d5\\t%0, #%n1\",
8231 \"cmn\\t%0, #%n1\;cmn%d4\\t%2, #%n3\"}
8234 comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4]));
8236 return opcodes[which_alternative][swap];
8238 [(set_attr "conds" "set")
8239 (set_attr "predicable" "no")
8240 (set_attr "length" "8")]
8243 (define_insn "*cmp_ior"
8244 [(set (match_operand 6 "dominant_cc_register" "")
8247 (match_operator 4 "arm_comparison_operator"
8248 [(match_operand:SI 0 "s_register_operand" "r,r,r,r")
8249 (match_operand:SI 1 "arm_add_operand" "rI,L,rI,L")])
8250 (match_operator:SI 5 "arm_comparison_operator"
8251 [(match_operand:SI 2 "s_register_operand" "r,r,r,r")
8252 (match_operand:SI 3 "arm_add_operand" "rI,rI,L,L")]))
8257 static const char *const opcodes[4][2] =
8259 {\"cmp\\t%0, %1\;cmp%D4\\t%2, %3\",
8260 \"cmp\\t%2, %3\;cmp%D5\\t%0, %1\"},
8261 {\"cmn\\t%0, #%n1\;cmp%D4\\t%2, %3\",
8262 \"cmp\\t%2, %3\;cmn%D5\\t%0, #%n1\"},
8263 {\"cmp\\t%0, %1\;cmn%D4\\t%2, #%n3\",
8264 \"cmn\\t%2, #%n3\;cmp%D5\\t%0, %1\"},
8265 {\"cmn\\t%0, #%n1\;cmn%D4\\t%2, #%n3\",
8266 \"cmn\\t%2, #%n3\;cmn%D5\\t%0, #%n1\"}
8269 comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4]));
8271 return opcodes[which_alternative][swap];
8274 [(set_attr "conds" "set")
8275 (set_attr "length" "8")]
8278 (define_insn_and_split "*ior_scc_scc"
8279 [(set (match_operand:SI 0 "s_register_operand" "=r")
8280 (ior:SI (match_operator:SI 3 "arm_comparison_operator"
8281 [(match_operand:SI 1 "s_register_operand" "r")
8282 (match_operand:SI 2 "arm_add_operand" "rIL")])
8283 (match_operator:SI 6 "arm_comparison_operator"
8284 [(match_operand:SI 4 "s_register_operand" "r")
8285 (match_operand:SI 5 "arm_add_operand" "rIL")])))
8286 (clobber (reg:CC CC_REGNUM))]
8288 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_OR_Y)
8291 "TARGET_ARM && reload_completed"
8295 (match_op_dup 3 [(match_dup 1) (match_dup 2)])
8296 (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
8298 (set (match_dup 0) (ne:SI (match_dup 7) (const_int 0)))]
8300 = gen_rtx_REG (arm_select_dominance_cc_mode (operands[3], operands[6],
8303 [(set_attr "conds" "clob")
8304 (set_attr "length" "16")])
8306 ; If the above pattern is followed by a CMP insn, then the compare is
8307 ; redundant, since we can rework the conditional instruction that follows.
8308 (define_insn_and_split "*ior_scc_scc_cmp"
8309 [(set (match_operand 0 "dominant_cc_register" "")
8310 (compare (ior:SI (match_operator:SI 3 "arm_comparison_operator"
8311 [(match_operand:SI 1 "s_register_operand" "r")
8312 (match_operand:SI 2 "arm_add_operand" "rIL")])
8313 (match_operator:SI 6 "arm_comparison_operator"
8314 [(match_operand:SI 4 "s_register_operand" "r")
8315 (match_operand:SI 5 "arm_add_operand" "rIL")]))
8317 (set (match_operand:SI 7 "s_register_operand" "=r")
8318 (ior:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)])
8319 (match_op_dup 6 [(match_dup 4) (match_dup 5)])))]
8322 "TARGET_ARM && reload_completed"
8326 (match_op_dup 3 [(match_dup 1) (match_dup 2)])
8327 (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
8329 (set (match_dup 7) (ne:SI (match_dup 0) (const_int 0)))]
8331 [(set_attr "conds" "set")
8332 (set_attr "length" "16")])
8334 (define_insn_and_split "*and_scc_scc"
8335 [(set (match_operand:SI 0 "s_register_operand" "=r")
8336 (and:SI (match_operator:SI 3 "arm_comparison_operator"
8337 [(match_operand:SI 1 "s_register_operand" "r")
8338 (match_operand:SI 2 "arm_add_operand" "rIL")])
8339 (match_operator:SI 6 "arm_comparison_operator"
8340 [(match_operand:SI 4 "s_register_operand" "r")
8341 (match_operand:SI 5 "arm_add_operand" "rIL")])))
8342 (clobber (reg:CC CC_REGNUM))]
8344 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y)
8347 "TARGET_ARM && reload_completed
8348 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y)
8353 (match_op_dup 3 [(match_dup 1) (match_dup 2)])
8354 (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
8356 (set (match_dup 0) (ne:SI (match_dup 7) (const_int 0)))]
8358 = gen_rtx_REG (arm_select_dominance_cc_mode (operands[3], operands[6],
8361 [(set_attr "conds" "clob")
8362 (set_attr "length" "16")])
8364 ; If the above pattern is followed by a CMP insn, then the compare is
8365 ; redundant, since we can rework the conditional instruction that follows.
8366 (define_insn_and_split "*and_scc_scc_cmp"
8367 [(set (match_operand 0 "dominant_cc_register" "")
8368 (compare (and:SI (match_operator:SI 3 "arm_comparison_operator"
8369 [(match_operand:SI 1 "s_register_operand" "r")
8370 (match_operand:SI 2 "arm_add_operand" "rIL")])
8371 (match_operator:SI 6 "arm_comparison_operator"
8372 [(match_operand:SI 4 "s_register_operand" "r")
8373 (match_operand:SI 5 "arm_add_operand" "rIL")]))
8375 (set (match_operand:SI 7 "s_register_operand" "=r")
8376 (and:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)])
8377 (match_op_dup 6 [(match_dup 4) (match_dup 5)])))]
8380 "TARGET_ARM && reload_completed"
8384 (match_op_dup 3 [(match_dup 1) (match_dup 2)])
8385 (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
8387 (set (match_dup 7) (ne:SI (match_dup 0) (const_int 0)))]
8389 [(set_attr "conds" "set")
8390 (set_attr "length" "16")])
8392 ;; If there is no dominance in the comparison, then we can still save an
8393 ;; instruction in the AND case, since we can know that the second compare
8394 ;; need only zero the value if false (if true, then the value is already
8396 (define_insn_and_split "*and_scc_scc_nodom"
8397 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r")
8398 (and:SI (match_operator:SI 3 "arm_comparison_operator"
8399 [(match_operand:SI 1 "s_register_operand" "r,r,0")
8400 (match_operand:SI 2 "arm_add_operand" "rIL,0,rIL")])
8401 (match_operator:SI 6 "arm_comparison_operator"
8402 [(match_operand:SI 4 "s_register_operand" "r,r,r")
8403 (match_operand:SI 5 "arm_add_operand" "rIL,rIL,rIL")])))
8404 (clobber (reg:CC CC_REGNUM))]
8406 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y)
8409 "TARGET_ARM && reload_completed"
8410 [(parallel [(set (match_dup 0)
8411 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
8412 (clobber (reg:CC CC_REGNUM))])
8413 (set (match_dup 7) (match_op_dup 8 [(match_dup 4) (match_dup 5)]))
8415 (if_then_else:SI (match_op_dup 6 [(match_dup 7) (const_int 0)])
8418 "operands[7] = gen_rtx_REG (SELECT_CC_MODE (GET_CODE (operands[6]),
8419 operands[4], operands[5]),
8421 operands[8] = gen_rtx_COMPARE (GET_MODE (operands[7]), operands[4],
8423 [(set_attr "conds" "clob")
8424 (set_attr "length" "20")])
8427 [(set (reg:CC_NOOV CC_REGNUM)
8428 (compare:CC_NOOV (ior:SI
8429 (and:SI (match_operand:SI 0 "s_register_operand" "")
8431 (match_operator:SI 1 "comparison_operator"
8432 [(match_operand:SI 2 "s_register_operand" "")
8433 (match_operand:SI 3 "arm_add_operand" "")]))
8435 (clobber (match_operand:SI 4 "s_register_operand" ""))]
8438 (ior:SI (match_op_dup 1 [(match_dup 2) (match_dup 3)])
8440 (set (reg:CC_NOOV CC_REGNUM)
8441 (compare:CC_NOOV (and:SI (match_dup 4) (const_int 1))
8446 [(set (reg:CC_NOOV CC_REGNUM)
8447 (compare:CC_NOOV (ior:SI
8448 (match_operator:SI 1 "comparison_operator"
8449 [(match_operand:SI 2 "s_register_operand" "")
8450 (match_operand:SI 3 "arm_add_operand" "")])
8451 (and:SI (match_operand:SI 0 "s_register_operand" "")
8454 (clobber (match_operand:SI 4 "s_register_operand" ""))]
8457 (ior:SI (match_op_dup 1 [(match_dup 2) (match_dup 3)])
8459 (set (reg:CC_NOOV CC_REGNUM)
8460 (compare:CC_NOOV (and:SI (match_dup 4) (const_int 1))
8464 (define_insn "*negscc"
8465 [(set (match_operand:SI 0 "s_register_operand" "=r")
8466 (neg:SI (match_operator 3 "arm_comparison_operator"
8467 [(match_operand:SI 1 "s_register_operand" "r")
8468 (match_operand:SI 2 "arm_rhs_operand" "rI")])))
8469 (clobber (reg:CC CC_REGNUM))]
8472 if (GET_CODE (operands[3]) == LT && operands[3] == const0_rtx)
8473 return \"mov\\t%0, %1, asr #31\";
8475 if (GET_CODE (operands[3]) == NE)
8476 return \"subs\\t%0, %1, %2\;mvnne\\t%0, #0\";
8478 if (GET_CODE (operands[3]) == GT)
8479 return \"subs\\t%0, %1, %2\;mvnne\\t%0, %0, asr #31\";
8481 output_asm_insn (\"cmp\\t%1, %2\", operands);
8482 output_asm_insn (\"mov%D3\\t%0, #0\", operands);
8483 return \"mvn%d3\\t%0, #0\";
8485 [(set_attr "conds" "clob")
8486 (set_attr "length" "12")]
8489 (define_insn "movcond"
8490 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
8492 (match_operator 5 "arm_comparison_operator"
8493 [(match_operand:SI 3 "s_register_operand" "r,r,r")
8494 (match_operand:SI 4 "arm_add_operand" "rIL,rIL,rIL")])
8495 (match_operand:SI 1 "arm_rhs_operand" "0,rI,?rI")
8496 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
8497 (clobber (reg:CC CC_REGNUM))]
8500 if (GET_CODE (operands[5]) == LT
8501 && (operands[4] == const0_rtx))
8503 if (which_alternative != 1 && GET_CODE (operands[1]) == REG)
8505 if (operands[2] == const0_rtx)
8506 return \"and\\t%0, %1, %3, asr #31\";
8507 return \"ands\\t%0, %1, %3, asr #32\;movcc\\t%0, %2\";
8509 else if (which_alternative != 0 && GET_CODE (operands[2]) == REG)
8511 if (operands[1] == const0_rtx)
8512 return \"bic\\t%0, %2, %3, asr #31\";
8513 return \"bics\\t%0, %2, %3, asr #32\;movcs\\t%0, %1\";
8515 /* The only case that falls through to here is when both ops 1 & 2
8519 if (GET_CODE (operands[5]) == GE
8520 && (operands[4] == const0_rtx))
8522 if (which_alternative != 1 && GET_CODE (operands[1]) == REG)
8524 if (operands[2] == const0_rtx)
8525 return \"bic\\t%0, %1, %3, asr #31\";
8526 return \"bics\\t%0, %1, %3, asr #32\;movcs\\t%0, %2\";
8528 else if (which_alternative != 0 && GET_CODE (operands[2]) == REG)
8530 if (operands[1] == const0_rtx)
8531 return \"and\\t%0, %2, %3, asr #31\";
8532 return \"ands\\t%0, %2, %3, asr #32\;movcc\\t%0, %1\";
8534 /* The only case that falls through to here is when both ops 1 & 2
8537 if (GET_CODE (operands[4]) == CONST_INT
8538 && !const_ok_for_arm (INTVAL (operands[4])))
8539 output_asm_insn (\"cmn\\t%3, #%n4\", operands);
8541 output_asm_insn (\"cmp\\t%3, %4\", operands);
8542 if (which_alternative != 0)
8543 output_asm_insn (\"mov%d5\\t%0, %1\", operands);
8544 if (which_alternative != 1)
8545 output_asm_insn (\"mov%D5\\t%0, %2\", operands);
8548 [(set_attr "conds" "clob")
8549 (set_attr "length" "8,8,12")]
8552 (define_insn "*ifcompare_plus_move"
8553 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8554 (if_then_else:SI (match_operator 6 "arm_comparison_operator"
8555 [(match_operand:SI 4 "s_register_operand" "r,r")
8556 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
8558 (match_operand:SI 2 "s_register_operand" "r,r")
8559 (match_operand:SI 3 "arm_add_operand" "rIL,rIL"))
8560 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))
8561 (clobber (reg:CC CC_REGNUM))]
8564 [(set_attr "conds" "clob")
8565 (set_attr "length" "8,12")]
8568 (define_insn "*if_plus_move"
8569 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r")
8571 (match_operator 4 "arm_comparison_operator"
8572 [(match_operand 5 "cc_register" "") (const_int 0)])
8574 (match_operand:SI 2 "s_register_operand" "r,r,r,r")
8575 (match_operand:SI 3 "arm_add_operand" "rI,L,rI,L"))
8576 (match_operand:SI 1 "arm_rhs_operand" "0,0,?rI,?rI")))]
8580 sub%d4\\t%0, %2, #%n3
8581 add%d4\\t%0, %2, %3\;mov%D4\\t%0, %1
8582 sub%d4\\t%0, %2, #%n3\;mov%D4\\t%0, %1"
8583 [(set_attr "conds" "use")
8584 (set_attr "length" "4,4,8,8")
8585 (set_attr "type" "*,*,*,*")]
8588 (define_insn "*ifcompare_move_plus"
8589 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8590 (if_then_else:SI (match_operator 6 "arm_comparison_operator"
8591 [(match_operand:SI 4 "s_register_operand" "r,r")
8592 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
8593 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
8595 (match_operand:SI 2 "s_register_operand" "r,r")
8596 (match_operand:SI 3 "arm_add_operand" "rIL,rIL"))))
8597 (clobber (reg:CC CC_REGNUM))]
8600 [(set_attr "conds" "clob")
8601 (set_attr "length" "8,12")]
8604 (define_insn "*if_move_plus"
8605 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r")
8607 (match_operator 4 "arm_comparison_operator"
8608 [(match_operand 5 "cc_register" "") (const_int 0)])
8609 (match_operand:SI 1 "arm_rhs_operand" "0,0,?rI,?rI")
8611 (match_operand:SI 2 "s_register_operand" "r,r,r,r")
8612 (match_operand:SI 3 "arm_add_operand" "rI,L,rI,L"))))]
8616 sub%D4\\t%0, %2, #%n3
8617 add%D4\\t%0, %2, %3\;mov%d4\\t%0, %1
8618 sub%D4\\t%0, %2, #%n3\;mov%d4\\t%0, %1"
8619 [(set_attr "conds" "use")
8620 (set_attr "length" "4,4,8,8")
8621 (set_attr "type" "*,*,*,*")]
8624 (define_insn "*ifcompare_arith_arith"
8625 [(set (match_operand:SI 0 "s_register_operand" "=r")
8626 (if_then_else:SI (match_operator 9 "arm_comparison_operator"
8627 [(match_operand:SI 5 "s_register_operand" "r")
8628 (match_operand:SI 6 "arm_add_operand" "rIL")])
8629 (match_operator:SI 8 "shiftable_operator"
8630 [(match_operand:SI 1 "s_register_operand" "r")
8631 (match_operand:SI 2 "arm_rhs_operand" "rI")])
8632 (match_operator:SI 7 "shiftable_operator"
8633 [(match_operand:SI 3 "s_register_operand" "r")
8634 (match_operand:SI 4 "arm_rhs_operand" "rI")])))
8635 (clobber (reg:CC CC_REGNUM))]
8638 [(set_attr "conds" "clob")
8639 (set_attr "length" "12")]
8642 (define_insn "*if_arith_arith"
8643 [(set (match_operand:SI 0 "s_register_operand" "=r")
8644 (if_then_else:SI (match_operator 5 "arm_comparison_operator"
8645 [(match_operand 8 "cc_register" "") (const_int 0)])
8646 (match_operator:SI 6 "shiftable_operator"
8647 [(match_operand:SI 1 "s_register_operand" "r")
8648 (match_operand:SI 2 "arm_rhs_operand" "rI")])
8649 (match_operator:SI 7 "shiftable_operator"
8650 [(match_operand:SI 3 "s_register_operand" "r")
8651 (match_operand:SI 4 "arm_rhs_operand" "rI")])))]
8653 "%I6%d5\\t%0, %1, %2\;%I7%D5\\t%0, %3, %4"
8654 [(set_attr "conds" "use")
8655 (set_attr "length" "8")]
8658 (define_insn "*ifcompare_arith_move"
8659 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8660 (if_then_else:SI (match_operator 6 "arm_comparison_operator"
8661 [(match_operand:SI 2 "s_register_operand" "r,r")
8662 (match_operand:SI 3 "arm_add_operand" "rIL,rIL")])
8663 (match_operator:SI 7 "shiftable_operator"
8664 [(match_operand:SI 4 "s_register_operand" "r,r")
8665 (match_operand:SI 5 "arm_rhs_operand" "rI,rI")])
8666 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))
8667 (clobber (reg:CC CC_REGNUM))]
8670 /* If we have an operation where (op x 0) is the identity operation and
8671 the conditional operator is LT or GE and we are comparing against zero and
8672 everything is in registers then we can do this in two instructions. */
8673 if (operands[3] == const0_rtx
8674 && GET_CODE (operands[7]) != AND
8675 && GET_CODE (operands[5]) == REG
8676 && GET_CODE (operands[1]) == REG
8677 && REGNO (operands[1]) == REGNO (operands[4])
8678 && REGNO (operands[4]) != REGNO (operands[0]))
8680 if (GET_CODE (operands[6]) == LT)
8681 return \"and\\t%0, %5, %2, asr #31\;%I7\\t%0, %4, %0\";
8682 else if (GET_CODE (operands[6]) == GE)
8683 return \"bic\\t%0, %5, %2, asr #31\;%I7\\t%0, %4, %0\";
8685 if (GET_CODE (operands[3]) == CONST_INT
8686 && !const_ok_for_arm (INTVAL (operands[3])))
8687 output_asm_insn (\"cmn\\t%2, #%n3\", operands);
8689 output_asm_insn (\"cmp\\t%2, %3\", operands);
8690 output_asm_insn (\"%I7%d6\\t%0, %4, %5\", operands);
8691 if (which_alternative != 0)
8692 return \"mov%D6\\t%0, %1\";
8695 [(set_attr "conds" "clob")
8696 (set_attr "length" "8,12")]
8699 (define_insn "*if_arith_move"
8700 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8701 (if_then_else:SI (match_operator 4 "arm_comparison_operator"
8702 [(match_operand 6 "cc_register" "") (const_int 0)])
8703 (match_operator:SI 5 "shiftable_operator"
8704 [(match_operand:SI 2 "s_register_operand" "r,r")
8705 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
8706 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))]
8710 %I5%d4\\t%0, %2, %3\;mov%D4\\t%0, %1"
8711 [(set_attr "conds" "use")
8712 (set_attr "length" "4,8")
8713 (set_attr "type" "*,*")]
8716 (define_insn "*ifcompare_move_arith"
8717 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8718 (if_then_else:SI (match_operator 6 "arm_comparison_operator"
8719 [(match_operand:SI 4 "s_register_operand" "r,r")
8720 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
8721 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
8722 (match_operator:SI 7 "shiftable_operator"
8723 [(match_operand:SI 2 "s_register_operand" "r,r")
8724 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))
8725 (clobber (reg:CC CC_REGNUM))]
8728 /* If we have an operation where (op x 0) is the identity operation and
8729 the conditional operator is LT or GE and we are comparing against zero and
8730 everything is in registers then we can do this in two instructions */
8731 if (operands[5] == const0_rtx
8732 && GET_CODE (operands[7]) != AND
8733 && GET_CODE (operands[3]) == REG
8734 && GET_CODE (operands[1]) == REG
8735 && REGNO (operands[1]) == REGNO (operands[2])
8736 && REGNO (operands[2]) != REGNO (operands[0]))
8738 if (GET_CODE (operands[6]) == GE)
8739 return \"and\\t%0, %3, %4, asr #31\;%I7\\t%0, %2, %0\";
8740 else if (GET_CODE (operands[6]) == LT)
8741 return \"bic\\t%0, %3, %4, asr #31\;%I7\\t%0, %2, %0\";
8744 if (GET_CODE (operands[5]) == CONST_INT
8745 && !const_ok_for_arm (INTVAL (operands[5])))
8746 output_asm_insn (\"cmn\\t%4, #%n5\", operands);
8748 output_asm_insn (\"cmp\\t%4, %5\", operands);
8750 if (which_alternative != 0)
8751 output_asm_insn (\"mov%d6\\t%0, %1\", operands);
8752 return \"%I7%D6\\t%0, %2, %3\";
8754 [(set_attr "conds" "clob")
8755 (set_attr "length" "8,12")]
8758 (define_insn "*if_move_arith"
8759 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8761 (match_operator 4 "arm_comparison_operator"
8762 [(match_operand 6 "cc_register" "") (const_int 0)])
8763 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
8764 (match_operator:SI 5 "shiftable_operator"
8765 [(match_operand:SI 2 "s_register_operand" "r,r")
8766 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))]
8770 %I5%D4\\t%0, %2, %3\;mov%d4\\t%0, %1"
8771 [(set_attr "conds" "use")
8772 (set_attr "length" "4,8")
8773 (set_attr "type" "*,*")]
8776 (define_insn "*ifcompare_move_not"
8777 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8779 (match_operator 5 "arm_comparison_operator"
8780 [(match_operand:SI 3 "s_register_operand" "r,r")
8781 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
8782 (match_operand:SI 1 "arm_not_operand" "0,?rIK")
8784 (match_operand:SI 2 "s_register_operand" "r,r"))))
8785 (clobber (reg:CC CC_REGNUM))]
8788 [(set_attr "conds" "clob")
8789 (set_attr "length" "8,12")]
8792 (define_insn "*if_move_not"
8793 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
8795 (match_operator 4 "arm_comparison_operator"
8796 [(match_operand 3 "cc_register" "") (const_int 0)])
8797 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")
8798 (not:SI (match_operand:SI 2 "s_register_operand" "r,r,r"))))]
8802 mov%d4\\t%0, %1\;mvn%D4\\t%0, %2
8803 mvn%d4\\t%0, #%B1\;mvn%D4\\t%0, %2"
8804 [(set_attr "conds" "use")
8805 (set_attr "length" "4,8,8")]
8808 (define_insn "*ifcompare_not_move"
8809 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8811 (match_operator 5 "arm_comparison_operator"
8812 [(match_operand:SI 3 "s_register_operand" "r,r")
8813 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
8815 (match_operand:SI 2 "s_register_operand" "r,r"))
8816 (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
8817 (clobber (reg:CC CC_REGNUM))]
8820 [(set_attr "conds" "clob")
8821 (set_attr "length" "8,12")]
8824 (define_insn "*if_not_move"
8825 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
8827 (match_operator 4 "arm_comparison_operator"
8828 [(match_operand 3 "cc_register" "") (const_int 0)])
8829 (not:SI (match_operand:SI 2 "s_register_operand" "r,r,r"))
8830 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")))]
8834 mov%D4\\t%0, %1\;mvn%d4\\t%0, %2
8835 mvn%D4\\t%0, #%B1\;mvn%d4\\t%0, %2"
8836 [(set_attr "conds" "use")
8837 (set_attr "length" "4,8,8")]
8840 (define_insn "*ifcompare_shift_move"
8841 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8843 (match_operator 6 "arm_comparison_operator"
8844 [(match_operand:SI 4 "s_register_operand" "r,r")
8845 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
8846 (match_operator:SI 7 "shift_operator"
8847 [(match_operand:SI 2 "s_register_operand" "r,r")
8848 (match_operand:SI 3 "arm_rhs_operand" "rM,rM")])
8849 (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
8850 (clobber (reg:CC CC_REGNUM))]
8853 [(set_attr "conds" "clob")
8854 (set_attr "length" "8,12")]
8857 (define_insn "*if_shift_move"
8858 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
8860 (match_operator 5 "arm_comparison_operator"
8861 [(match_operand 6 "cc_register" "") (const_int 0)])
8862 (match_operator:SI 4 "shift_operator"
8863 [(match_operand:SI 2 "s_register_operand" "r,r,r")
8864 (match_operand:SI 3 "arm_rhs_operand" "rM,rM,rM")])
8865 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")))]
8869 mov%D5\\t%0, %1\;mov%d5\\t%0, %2%S4
8870 mvn%D5\\t%0, #%B1\;mov%d5\\t%0, %2%S4"
8871 [(set_attr "conds" "use")
8872 (set_attr "shift" "2")
8873 (set_attr "length" "4,8,8")
8874 (set (attr "type") (if_then_else (match_operand 3 "const_int_operand" "")
8875 (const_string "alu_shift")
8876 (const_string "alu_shift_reg")))]
8879 (define_insn "*ifcompare_move_shift"
8880 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8882 (match_operator 6 "arm_comparison_operator"
8883 [(match_operand:SI 4 "s_register_operand" "r,r")
8884 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
8885 (match_operand:SI 1 "arm_not_operand" "0,?rIK")
8886 (match_operator:SI 7 "shift_operator"
8887 [(match_operand:SI 2 "s_register_operand" "r,r")
8888 (match_operand:SI 3 "arm_rhs_operand" "rM,rM")])))
8889 (clobber (reg:CC CC_REGNUM))]
8892 [(set_attr "conds" "clob")
8893 (set_attr "length" "8,12")]
8896 (define_insn "*if_move_shift"
8897 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
8899 (match_operator 5 "arm_comparison_operator"
8900 [(match_operand 6 "cc_register" "") (const_int 0)])
8901 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")
8902 (match_operator:SI 4 "shift_operator"
8903 [(match_operand:SI 2 "s_register_operand" "r,r,r")
8904 (match_operand:SI 3 "arm_rhs_operand" "rM,rM,rM")])))]
8908 mov%d5\\t%0, %1\;mov%D5\\t%0, %2%S4
8909 mvn%d5\\t%0, #%B1\;mov%D5\\t%0, %2%S4"
8910 [(set_attr "conds" "use")
8911 (set_attr "shift" "2")
8912 (set_attr "length" "4,8,8")
8913 (set (attr "type") (if_then_else (match_operand 3 "const_int_operand" "")
8914 (const_string "alu_shift")
8915 (const_string "alu_shift_reg")))]
8918 (define_insn "*ifcompare_shift_shift"
8919 [(set (match_operand:SI 0 "s_register_operand" "=r")
8921 (match_operator 7 "arm_comparison_operator"
8922 [(match_operand:SI 5 "s_register_operand" "r")
8923 (match_operand:SI 6 "arm_add_operand" "rIL")])
8924 (match_operator:SI 8 "shift_operator"
8925 [(match_operand:SI 1 "s_register_operand" "r")
8926 (match_operand:SI 2 "arm_rhs_operand" "rM")])
8927 (match_operator:SI 9 "shift_operator"
8928 [(match_operand:SI 3 "s_register_operand" "r")
8929 (match_operand:SI 4 "arm_rhs_operand" "rM")])))
8930 (clobber (reg:CC CC_REGNUM))]
8933 [(set_attr "conds" "clob")
8934 (set_attr "length" "12")]
8937 (define_insn "*if_shift_shift"
8938 [(set (match_operand:SI 0 "s_register_operand" "=r")
8940 (match_operator 5 "arm_comparison_operator"
8941 [(match_operand 8 "cc_register" "") (const_int 0)])
8942 (match_operator:SI 6 "shift_operator"
8943 [(match_operand:SI 1 "s_register_operand" "r")
8944 (match_operand:SI 2 "arm_rhs_operand" "rM")])
8945 (match_operator:SI 7 "shift_operator"
8946 [(match_operand:SI 3 "s_register_operand" "r")
8947 (match_operand:SI 4 "arm_rhs_operand" "rM")])))]
8949 "mov%d5\\t%0, %1%S6\;mov%D5\\t%0, %3%S7"
8950 [(set_attr "conds" "use")
8951 (set_attr "shift" "1")
8952 (set_attr "length" "8")
8953 (set (attr "type") (if_then_else
8954 (and (match_operand 2 "const_int_operand" "")
8955 (match_operand 4 "const_int_operand" ""))
8956 (const_string "alu_shift")
8957 (const_string "alu_shift_reg")))]
8960 (define_insn "*ifcompare_not_arith"
8961 [(set (match_operand:SI 0 "s_register_operand" "=r")
8963 (match_operator 6 "arm_comparison_operator"
8964 [(match_operand:SI 4 "s_register_operand" "r")
8965 (match_operand:SI 5 "arm_add_operand" "rIL")])
8966 (not:SI (match_operand:SI 1 "s_register_operand" "r"))
8967 (match_operator:SI 7 "shiftable_operator"
8968 [(match_operand:SI 2 "s_register_operand" "r")
8969 (match_operand:SI 3 "arm_rhs_operand" "rI")])))
8970 (clobber (reg:CC CC_REGNUM))]
8973 [(set_attr "conds" "clob")
8974 (set_attr "length" "12")]
8977 (define_insn "*if_not_arith"
8978 [(set (match_operand:SI 0 "s_register_operand" "=r")
8980 (match_operator 5 "arm_comparison_operator"
8981 [(match_operand 4 "cc_register" "") (const_int 0)])
8982 (not:SI (match_operand:SI 1 "s_register_operand" "r"))
8983 (match_operator:SI 6 "shiftable_operator"
8984 [(match_operand:SI 2 "s_register_operand" "r")
8985 (match_operand:SI 3 "arm_rhs_operand" "rI")])))]
8987 "mvn%d5\\t%0, %1\;%I6%D5\\t%0, %2, %3"
8988 [(set_attr "conds" "use")
8989 (set_attr "length" "8")]
8992 (define_insn "*ifcompare_arith_not"
8993 [(set (match_operand:SI 0 "s_register_operand" "=r")
8995 (match_operator 6 "arm_comparison_operator"
8996 [(match_operand:SI 4 "s_register_operand" "r")
8997 (match_operand:SI 5 "arm_add_operand" "rIL")])
8998 (match_operator:SI 7 "shiftable_operator"
8999 [(match_operand:SI 2 "s_register_operand" "r")
9000 (match_operand:SI 3 "arm_rhs_operand" "rI")])
9001 (not:SI (match_operand:SI 1 "s_register_operand" "r"))))
9002 (clobber (reg:CC CC_REGNUM))]
9005 [(set_attr "conds" "clob")
9006 (set_attr "length" "12")]
9009 (define_insn "*if_arith_not"
9010 [(set (match_operand:SI 0 "s_register_operand" "=r")
9012 (match_operator 5 "arm_comparison_operator"
9013 [(match_operand 4 "cc_register" "") (const_int 0)])
9014 (match_operator:SI 6 "shiftable_operator"
9015 [(match_operand:SI 2 "s_register_operand" "r")
9016 (match_operand:SI 3 "arm_rhs_operand" "rI")])
9017 (not:SI (match_operand:SI 1 "s_register_operand" "r"))))]
9019 "mvn%D5\\t%0, %1\;%I6%d5\\t%0, %2, %3"
9020 [(set_attr "conds" "use")
9021 (set_attr "length" "8")]
9024 (define_insn "*ifcompare_neg_move"
9025 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9027 (match_operator 5 "arm_comparison_operator"
9028 [(match_operand:SI 3 "s_register_operand" "r,r")
9029 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
9030 (neg:SI (match_operand:SI 2 "s_register_operand" "r,r"))
9031 (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
9032 (clobber (reg:CC CC_REGNUM))]
9035 [(set_attr "conds" "clob")
9036 (set_attr "length" "8,12")]
9039 (define_insn "*if_neg_move"
9040 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9042 (match_operator 4 "arm_comparison_operator"
9043 [(match_operand 3 "cc_register" "") (const_int 0)])
9044 (neg:SI (match_operand:SI 2 "s_register_operand" "r,r,r"))
9045 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")))]
9049 mov%D4\\t%0, %1\;rsb%d4\\t%0, %2, #0
9050 mvn%D4\\t%0, #%B1\;rsb%d4\\t%0, %2, #0"
9051 [(set_attr "conds" "use")
9052 (set_attr "length" "4,8,8")]
9055 (define_insn "*ifcompare_move_neg"
9056 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9058 (match_operator 5 "arm_comparison_operator"
9059 [(match_operand:SI 3 "s_register_operand" "r,r")
9060 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
9061 (match_operand:SI 1 "arm_not_operand" "0,?rIK")
9062 (neg:SI (match_operand:SI 2 "s_register_operand" "r,r"))))
9063 (clobber (reg:CC CC_REGNUM))]
9066 [(set_attr "conds" "clob")
9067 (set_attr "length" "8,12")]
9070 (define_insn "*if_move_neg"
9071 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9073 (match_operator 4 "arm_comparison_operator"
9074 [(match_operand 3 "cc_register" "") (const_int 0)])
9075 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")
9076 (neg:SI (match_operand:SI 2 "s_register_operand" "r,r,r"))))]
9080 mov%d4\\t%0, %1\;rsb%D4\\t%0, %2, #0
9081 mvn%d4\\t%0, #%B1\;rsb%D4\\t%0, %2, #0"
9082 [(set_attr "conds" "use")
9083 (set_attr "length" "4,8,8")]
9086 (define_insn "*arith_adjacentmem"
9087 [(set (match_operand:SI 0 "s_register_operand" "=r")
9088 (match_operator:SI 1 "shiftable_operator"
9089 [(match_operand:SI 2 "memory_operand" "m")
9090 (match_operand:SI 3 "memory_operand" "m")]))
9091 (clobber (match_scratch:SI 4 "=r"))]
9092 "TARGET_ARM && adjacent_mem_locations (operands[2], operands[3])"
9097 int val1 = 0, val2 = 0;
9099 if (REGNO (operands[0]) > REGNO (operands[4]))
9101 ldm[1] = operands[4];
9102 ldm[2] = operands[0];
9106 ldm[1] = operands[0];
9107 ldm[2] = operands[4];
9109 if (GET_CODE (XEXP (operands[2], 0)) != REG)
9110 val1 = INTVAL (XEXP (XEXP (operands[2], 0), 1));
9111 if (GET_CODE (XEXP (operands[3], 0)) != REG)
9112 val2 = INTVAL (XEXP (XEXP (operands[3], 0), 1));
9113 arith[0] = operands[0];
9114 arith[3] = operands[1];
9128 ldm[0] = ops[0] = operands[4];
9129 ops[1] = XEXP (XEXP (operands[2], 0), 0);
9130 ops[2] = XEXP (XEXP (operands[2], 0), 1);
9131 output_add_immediate (ops);
9133 output_asm_insn (\"ldm%?ia\\t%0, {%1, %2}\", ldm);
9135 output_asm_insn (\"ldm%?da\\t%0, {%1, %2}\", ldm);
9139 ldm[0] = XEXP (operands[3], 0);
9141 output_asm_insn (\"ldm%?da\\t%0, {%1, %2}\", ldm);
9143 output_asm_insn (\"ldm%?ia\\t%0, {%1, %2}\", ldm);
9147 ldm[0] = XEXP (operands[2], 0);
9149 output_asm_insn (\"ldm%?ia\\t%0, {%1, %2}\", ldm);
9151 output_asm_insn (\"ldm%?da\\t%0, {%1, %2}\", ldm);
9153 output_asm_insn (\"%I3%?\\t%0, %1, %2\", arith);
9156 [(set_attr "length" "12")
9157 (set_attr "predicable" "yes")
9158 (set_attr "type" "load1")]
9161 ;; the arm can support extended pre-inc instructions
9163 ;; In all these cases, we use operands 0 and 1 for the register being
9164 ;; incremented because those are the operands that local-alloc will
9165 ;; tie and these are the pair most likely to be tieable (and the ones
9166 ;; that will benefit the most).
9168 ;; We reject the frame pointer if it occurs anywhere in these patterns since
9169 ;; elimination will cause too many headaches.
9171 (define_insn "*strqi_preinc"
9172 [(set (mem:QI (plus:SI (match_operand:SI 1 "s_register_operand" "%0")
9173 (match_operand:SI 2 "index_operand" "rJ")))
9174 (match_operand:QI 3 "s_register_operand" "r"))
9175 (set (match_operand:SI 0 "s_register_operand" "=r")
9176 (plus:SI (match_dup 1) (match_dup 2)))]
9178 && REGNO (operands[0]) != FRAME_POINTER_REGNUM
9179 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
9180 && (GET_CODE (operands[2]) != REG
9181 || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
9182 "str%?b\\t%3, [%0, %2]!"
9183 [(set_attr "type" "store1")
9184 (set_attr "predicable" "yes")]
9187 (define_insn "*strqi_predec"
9188 [(set (mem:QI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
9189 (match_operand:SI 2 "s_register_operand" "r")))
9190 (match_operand:QI 3 "s_register_operand" "r"))
9191 (set (match_operand:SI 0 "s_register_operand" "=r")
9192 (minus:SI (match_dup 1) (match_dup 2)))]
9194 && REGNO (operands[0]) != FRAME_POINTER_REGNUM
9195 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
9196 && (GET_CODE (operands[2]) != REG
9197 || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
9198 "str%?b\\t%3, [%0, -%2]!"
9199 [(set_attr "type" "store1")
9200 (set_attr "predicable" "yes")]
9203 (define_insn "*loadqi_preinc"
9204 [(set (match_operand:QI 3 "s_register_operand" "=r")
9205 (mem:QI (plus:SI (match_operand:SI 1 "s_register_operand" "%0")
9206 (match_operand:SI 2 "index_operand" "rJ"))))
9207 (set (match_operand:SI 0 "s_register_operand" "=r")
9208 (plus:SI (match_dup 1) (match_dup 2)))]
9210 && REGNO (operands[0]) != FRAME_POINTER_REGNUM
9211 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
9212 && (GET_CODE (operands[2]) != REG
9213 || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
9214 "ldr%?b\\t%3, [%0, %2]!"
9215 [(set_attr "type" "load_byte")
9216 (set_attr "predicable" "yes")]
9219 (define_insn "*loadqi_predec"
9220 [(set (match_operand:QI 3 "s_register_operand" "=r")
9221 (mem:QI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
9222 (match_operand:SI 2 "s_register_operand" "r"))))
9223 (set (match_operand:SI 0 "s_register_operand" "=r")
9224 (minus:SI (match_dup 1) (match_dup 2)))]
9226 && REGNO (operands[0]) != FRAME_POINTER_REGNUM
9227 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
9228 && (GET_CODE (operands[2]) != REG
9229 || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
9230 "ldr%?b\\t%3, [%0, -%2]!"
9231 [(set_attr "type" "load_byte")
9232 (set_attr "predicable" "yes")]
9235 (define_insn "*loadqisi_preinc"
9236 [(set (match_operand:SI 3 "s_register_operand" "=r")
9238 (mem:QI (plus:SI (match_operand:SI 1 "s_register_operand" "%0")
9239 (match_operand:SI 2 "index_operand" "rJ")))))
9240 (set (match_operand:SI 0 "s_register_operand" "=r")
9241 (plus:SI (match_dup 1) (match_dup 2)))]
9243 && REGNO (operands[0]) != FRAME_POINTER_REGNUM
9244 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
9245 && (GET_CODE (operands[2]) != REG
9246 || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
9247 "ldr%?b\\t%3, [%0, %2]!\\t%@ z_extendqisi"
9248 [(set_attr "type" "load_byte")
9249 (set_attr "predicable" "yes")]
9252 (define_insn "*loadqisi_predec"
9253 [(set (match_operand:SI 3 "s_register_operand" "=r")
9255 (mem:QI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
9256 (match_operand:SI 2 "s_register_operand" "r")))))
9257 (set (match_operand:SI 0 "s_register_operand" "=r")
9258 (minus:SI (match_dup 1) (match_dup 2)))]
9260 && REGNO (operands[0]) != FRAME_POINTER_REGNUM
9261 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
9262 && (GET_CODE (operands[2]) != REG
9263 || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
9264 "ldr%?b\\t%3, [%0, -%2]!\\t%@ z_extendqisi"
9265 [(set_attr "type" "load_byte")
9266 (set_attr "predicable" "yes")]
9269 (define_insn "*strsi_preinc"
9270 [(set (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "%0")
9271 (match_operand:SI 2 "index_operand" "rJ")))
9272 (match_operand:SI 3 "s_register_operand" "r"))
9273 (set (match_operand:SI 0 "s_register_operand" "=r")
9274 (plus:SI (match_dup 1) (match_dup 2)))]
9276 && REGNO (operands[0]) != FRAME_POINTER_REGNUM
9277 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
9278 && (GET_CODE (operands[2]) != REG
9279 || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
9280 "str%?\\t%3, [%0, %2]!"
9281 [(set_attr "type" "store1")
9282 (set_attr "predicable" "yes")]
9285 (define_insn "*strsi_predec"
9286 [(set (mem:SI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
9287 (match_operand:SI 2 "s_register_operand" "r")))
9288 (match_operand:SI 3 "s_register_operand" "r"))
9289 (set (match_operand:SI 0 "s_register_operand" "=r")
9290 (minus:SI (match_dup 1) (match_dup 2)))]
9292 && REGNO (operands[0]) != FRAME_POINTER_REGNUM
9293 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
9294 && (GET_CODE (operands[2]) != REG
9295 || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
9296 "str%?\\t%3, [%0, -%2]!"
9297 [(set_attr "type" "store1")
9298 (set_attr "predicable" "yes")]
9301 (define_insn "*loadsi_preinc"
9302 [(set (match_operand:SI 3 "s_register_operand" "=r")
9303 (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "%0")
9304 (match_operand:SI 2 "index_operand" "rJ"))))
9305 (set (match_operand:SI 0 "s_register_operand" "=r")
9306 (plus:SI (match_dup 1) (match_dup 2)))]
9308 && REGNO (operands[0]) != FRAME_POINTER_REGNUM
9309 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
9310 && (GET_CODE (operands[2]) != REG
9311 || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
9312 "ldr%?\\t%3, [%0, %2]!"
9313 [(set_attr "type" "load1")
9314 (set_attr "predicable" "yes")]
9317 (define_insn "*loadsi_predec"
9318 [(set (match_operand:SI 3 "s_register_operand" "=r")
9319 (mem:SI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
9320 (match_operand:SI 2 "s_register_operand" "r"))))
9321 (set (match_operand:SI 0 "s_register_operand" "=r")
9322 (minus:SI (match_dup 1) (match_dup 2)))]
9324 && REGNO (operands[0]) != FRAME_POINTER_REGNUM
9325 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
9326 && (GET_CODE (operands[2]) != REG
9327 || REGNO (operands[2]) != FRAME_POINTER_REGNUM)"
9328 "ldr%?\\t%3, [%0, -%2]!"
9329 [(set_attr "type" "load1")
9330 (set_attr "predicable" "yes")]
9333 (define_insn "*strqi_shiftpreinc"
9334 [(set (mem:QI (plus:SI (match_operator:SI 2 "shift_operator"
9335 [(match_operand:SI 3 "s_register_operand" "r")
9336 (match_operand:SI 4 "const_shift_operand" "n")])
9337 (match_operand:SI 1 "s_register_operand" "0")))
9338 (match_operand:QI 5 "s_register_operand" "r"))
9339 (set (match_operand:SI 0 "s_register_operand" "=r")
9340 (plus:SI (match_op_dup 2 [(match_dup 3) (match_dup 4)])
9343 && REGNO (operands[0]) != FRAME_POINTER_REGNUM
9344 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
9345 && REGNO (operands[3]) != FRAME_POINTER_REGNUM"
9346 "str%?b\\t%5, [%0, %3%S2]!"
9347 [(set_attr "type" "store1")
9348 (set_attr "predicable" "yes")]
9351 (define_insn "*strqi_shiftpredec"
9352 [(set (mem:QI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
9353 (match_operator:SI 2 "shift_operator"
9354 [(match_operand:SI 3 "s_register_operand" "r")
9355 (match_operand:SI 4 "const_shift_operand" "n")])))
9356 (match_operand:QI 5 "s_register_operand" "r"))
9357 (set (match_operand:SI 0 "s_register_operand" "=r")
9358 (minus:SI (match_dup 1) (match_op_dup 2 [(match_dup 3)
9361 && REGNO (operands[0]) != FRAME_POINTER_REGNUM
9362 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
9363 && REGNO (operands[3]) != FRAME_POINTER_REGNUM"
9364 "str%?b\\t%5, [%0, -%3%S2]!"
9365 [(set_attr "type" "store1")
9366 (set_attr "predicable" "yes")]
9369 (define_insn "*loadqi_shiftpreinc"
9370 [(set (match_operand:QI 5 "s_register_operand" "=r")
9371 (mem:QI (plus:SI (match_operator:SI 2 "shift_operator"
9372 [(match_operand:SI 3 "s_register_operand" "r")
9373 (match_operand:SI 4 "const_shift_operand" "n")])
9374 (match_operand:SI 1 "s_register_operand" "0"))))
9375 (set (match_operand:SI 0 "s_register_operand" "=r")
9376 (plus:SI (match_op_dup 2 [(match_dup 3) (match_dup 4)])
9379 && REGNO (operands[0]) != FRAME_POINTER_REGNUM
9380 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
9381 && REGNO (operands[3]) != FRAME_POINTER_REGNUM"
9382 "ldr%?b\\t%5, [%0, %3%S2]!"
9383 [(set_attr "type" "load_byte")
9384 (set_attr "predicable" "yes")]
9387 (define_insn "*loadqi_shiftpredec"
9388 [(set (match_operand:QI 5 "s_register_operand" "=r")
9389 (mem:QI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
9390 (match_operator:SI 2 "shift_operator"
9391 [(match_operand:SI 3 "s_register_operand" "r")
9392 (match_operand:SI 4 "const_shift_operand" "n")]))))
9393 (set (match_operand:SI 0 "s_register_operand" "=r")
9394 (minus:SI (match_dup 1) (match_op_dup 2 [(match_dup 3)
9397 && REGNO (operands[0]) != FRAME_POINTER_REGNUM
9398 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
9399 && REGNO (operands[3]) != FRAME_POINTER_REGNUM"
9400 "ldr%?b\\t%5, [%0, -%3%S2]!"
9401 [(set_attr "type" "load_byte")
9402 (set_attr "predicable" "yes")]
9405 (define_insn "*strsi_shiftpreinc"
9406 [(set (mem:SI (plus:SI (match_operator:SI 2 "shift_operator"
9407 [(match_operand:SI 3 "s_register_operand" "r")
9408 (match_operand:SI 4 "const_shift_operand" "n")])
9409 (match_operand:SI 1 "s_register_operand" "0")))
9410 (match_operand:SI 5 "s_register_operand" "r"))
9411 (set (match_operand:SI 0 "s_register_operand" "=r")
9412 (plus:SI (match_op_dup 2 [(match_dup 3) (match_dup 4)])
9415 && REGNO (operands[0]) != FRAME_POINTER_REGNUM
9416 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
9417 && REGNO (operands[3]) != FRAME_POINTER_REGNUM"
9418 "str%?\\t%5, [%0, %3%S2]!"
9419 [(set_attr "type" "store1")
9420 (set_attr "predicable" "yes")]
9423 (define_insn "*strsi_shiftpredec"
9424 [(set (mem:SI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
9425 (match_operator:SI 2 "shift_operator"
9426 [(match_operand:SI 3 "s_register_operand" "r")
9427 (match_operand:SI 4 "const_shift_operand" "n")])))
9428 (match_operand:SI 5 "s_register_operand" "r"))
9429 (set (match_operand:SI 0 "s_register_operand" "=r")
9430 (minus:SI (match_dup 1) (match_op_dup 2 [(match_dup 3)
9433 && REGNO (operands[0]) != FRAME_POINTER_REGNUM
9434 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
9435 && REGNO (operands[3]) != FRAME_POINTER_REGNUM"
9436 "str%?\\t%5, [%0, -%3%S2]!"
9437 [(set_attr "type" "store1")
9438 (set_attr "predicable" "yes")]
9441 (define_insn "*loadsi_shiftpreinc"
9442 [(set (match_operand:SI 5 "s_register_operand" "=r")
9443 (mem:SI (plus:SI (match_operator:SI 2 "shift_operator"
9444 [(match_operand:SI 3 "s_register_operand" "r")
9445 (match_operand:SI 4 "const_shift_operand" "n")])
9446 (match_operand:SI 1 "s_register_operand" "0"))))
9447 (set (match_operand:SI 0 "s_register_operand" "=r")
9448 (plus:SI (match_op_dup 2 [(match_dup 3) (match_dup 4)])
9451 && REGNO (operands[0]) != FRAME_POINTER_REGNUM
9452 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
9453 && REGNO (operands[3]) != FRAME_POINTER_REGNUM"
9454 "ldr%?\\t%5, [%0, %3%S2]!"
9455 [(set_attr "type" "load1")
9456 (set_attr "predicable" "yes")]
9459 (define_insn "*loadsi_shiftpredec"
9460 [(set (match_operand:SI 5 "s_register_operand" "=r")
9461 (mem:SI (minus:SI (match_operand:SI 1 "s_register_operand" "0")
9462 (match_operator:SI 2 "shift_operator"
9463 [(match_operand:SI 3 "s_register_operand" "r")
9464 (match_operand:SI 4 "const_shift_operand" "n")]))))
9465 (set (match_operand:SI 0 "s_register_operand" "=r")
9466 (minus:SI (match_dup 1) (match_op_dup 2 [(match_dup 3)
9469 && REGNO (operands[0]) != FRAME_POINTER_REGNUM
9470 && REGNO (operands[1]) != FRAME_POINTER_REGNUM
9471 && REGNO (operands[3]) != FRAME_POINTER_REGNUM"
9472 "ldr%?\\t%5, [%0, -%3%S2]!"
9473 [(set_attr "type" "load1")
9474 (set_attr "predicable" "yes")])
9476 ; It can also support extended post-inc expressions, but combine doesn't
9478 ; It doesn't seem worth adding peepholes for anything but the most common
9479 ; cases since, unlike combine, the increment must immediately follow the load
9480 ; for this pattern to match.
9481 ; We must watch to see that the source/destination register isn't also the
9482 ; same as the base address register, and that if the index is a register,
9483 ; that it is not the same as the base address register. In such cases the
9484 ; instruction that we would generate would have UNPREDICTABLE behavior so
9488 [(set (mem:QI (match_operand:SI 0 "s_register_operand" "+r"))
9489 (match_operand:QI 2 "s_register_operand" "r"))
9491 (plus:SI (match_dup 0) (match_operand:SI 1 "index_operand" "rJ")))]
9493 && (REGNO (operands[2]) != REGNO (operands[0]))
9494 && (GET_CODE (operands[1]) != REG
9495 || (REGNO (operands[1]) != REGNO (operands[0])))"
9496 "str%?b\\t%2, [%0], %1"
9500 [(set (match_operand:QI 0 "s_register_operand" "=r")
9501 (mem:QI (match_operand:SI 1 "s_register_operand" "+r")))
9503 (plus:SI (match_dup 1) (match_operand:SI 2 "index_operand" "rJ")))]
9505 && REGNO (operands[0]) != REGNO(operands[1])
9506 && (GET_CODE (operands[2]) != REG
9507 || REGNO(operands[0]) != REGNO (operands[2]))"
9508 "ldr%?b\\t%0, [%1], %2"
9512 [(set (mem:SI (match_operand:SI 0 "s_register_operand" "+r"))
9513 (match_operand:SI 2 "s_register_operand" "r"))
9515 (plus:SI (match_dup 0) (match_operand:SI 1 "index_operand" "rJ")))]
9517 && (REGNO (operands[2]) != REGNO (operands[0]))
9518 && (GET_CODE (operands[1]) != REG
9519 || (REGNO (operands[1]) != REGNO (operands[0])))"
9520 "str%?\\t%2, [%0], %1"
9524 [(set (match_operand:SI 0 "s_register_operand" "=r")
9525 (mem:SI (match_operand:SI 1 "s_register_operand" "+r")))
9527 (plus:SI (match_dup 1) (match_operand:SI 2 "index_operand" "rJ")))]
9529 && REGNO (operands[0]) != REGNO(operands[1])
9530 && (GET_CODE (operands[2]) != REG
9531 || REGNO(operands[0]) != REGNO (operands[2]))"
9532 "ldr%?\\t%0, [%1], %2"
9536 [(set (mem:QI (plus:SI (match_operand:SI 0 "s_register_operand" "+r")
9537 (match_operand:SI 1 "index_operand" "rJ")))
9538 (match_operand:QI 2 "s_register_operand" "r"))
9539 (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))]
9541 && (REGNO (operands[2]) != REGNO (operands[0]))
9542 && (GET_CODE (operands[1]) != REG
9543 || (REGNO (operands[1]) != REGNO (operands[0])))"
9544 "str%?b\\t%2, [%0, %1]!"
9548 [(set (mem:QI (plus:SI (match_operator:SI 4 "shift_operator"
9549 [(match_operand:SI 0 "s_register_operand" "r")
9550 (match_operand:SI 1 "const_int_operand" "n")])
9551 (match_operand:SI 2 "s_register_operand" "+r")))
9552 (match_operand:QI 3 "s_register_operand" "r"))
9553 (set (match_dup 2) (plus:SI (match_op_dup 4 [(match_dup 0) (match_dup 1)])
9556 && (REGNO (operands[3]) != REGNO (operands[2]))
9557 && (REGNO (operands[0]) != REGNO (operands[2]))"
9558 "str%?b\\t%3, [%2, %0%S4]!"
9561 ; This pattern is never tried by combine, so do it as a peephole
9564 [(set (match_operand:SI 0 "arm_general_register_operand" "")
9565 (match_operand:SI 1 "arm_general_register_operand" ""))
9566 (set (reg:CC CC_REGNUM)
9567 (compare:CC (match_dup 1) (const_int 0)))]
9569 [(parallel [(set (reg:CC CC_REGNUM) (compare:CC (match_dup 1) (const_int 0)))
9570 (set (match_dup 0) (match_dup 1))])]
9574 ; Peepholes to spot possible load- and store-multiples, if the ordering is
9575 ; reversed, check that the memory references aren't volatile.
9578 [(set (match_operand:SI 0 "s_register_operand" "=r")
9579 (match_operand:SI 4 "memory_operand" "m"))
9580 (set (match_operand:SI 1 "s_register_operand" "=r")
9581 (match_operand:SI 5 "memory_operand" "m"))
9582 (set (match_operand:SI 2 "s_register_operand" "=r")
9583 (match_operand:SI 6 "memory_operand" "m"))
9584 (set (match_operand:SI 3 "s_register_operand" "=r")
9585 (match_operand:SI 7 "memory_operand" "m"))]
9586 "TARGET_ARM && load_multiple_sequence (operands, 4, NULL, NULL, NULL)"
9588 return emit_ldm_seq (operands, 4);
9593 [(set (match_operand:SI 0 "s_register_operand" "=r")
9594 (match_operand:SI 3 "memory_operand" "m"))
9595 (set (match_operand:SI 1 "s_register_operand" "=r")
9596 (match_operand:SI 4 "memory_operand" "m"))
9597 (set (match_operand:SI 2 "s_register_operand" "=r")
9598 (match_operand:SI 5 "memory_operand" "m"))]
9599 "TARGET_ARM && load_multiple_sequence (operands, 3, NULL, NULL, NULL)"
9601 return emit_ldm_seq (operands, 3);
9606 [(set (match_operand:SI 0 "s_register_operand" "=r")
9607 (match_operand:SI 2 "memory_operand" "m"))
9608 (set (match_operand:SI 1 "s_register_operand" "=r")
9609 (match_operand:SI 3 "memory_operand" "m"))]
9610 "TARGET_ARM && load_multiple_sequence (operands, 2, NULL, NULL, NULL)"
9612 return emit_ldm_seq (operands, 2);
9617 [(set (match_operand:SI 4 "memory_operand" "=m")
9618 (match_operand:SI 0 "s_register_operand" "r"))
9619 (set (match_operand:SI 5 "memory_operand" "=m")
9620 (match_operand:SI 1 "s_register_operand" "r"))
9621 (set (match_operand:SI 6 "memory_operand" "=m")
9622 (match_operand:SI 2 "s_register_operand" "r"))
9623 (set (match_operand:SI 7 "memory_operand" "=m")
9624 (match_operand:SI 3 "s_register_operand" "r"))]
9625 "TARGET_ARM && store_multiple_sequence (operands, 4, NULL, NULL, NULL)"
9627 return emit_stm_seq (operands, 4);
9632 [(set (match_operand:SI 3 "memory_operand" "=m")
9633 (match_operand:SI 0 "s_register_operand" "r"))
9634 (set (match_operand:SI 4 "memory_operand" "=m")
9635 (match_operand:SI 1 "s_register_operand" "r"))
9636 (set (match_operand:SI 5 "memory_operand" "=m")
9637 (match_operand:SI 2 "s_register_operand" "r"))]
9638 "TARGET_ARM && store_multiple_sequence (operands, 3, NULL, NULL, NULL)"
9640 return emit_stm_seq (operands, 3);
9645 [(set (match_operand:SI 2 "memory_operand" "=m")
9646 (match_operand:SI 0 "s_register_operand" "r"))
9647 (set (match_operand:SI 3 "memory_operand" "=m")
9648 (match_operand:SI 1 "s_register_operand" "r"))]
9649 "TARGET_ARM && store_multiple_sequence (operands, 2, NULL, NULL, NULL)"
9651 return emit_stm_seq (operands, 2);
9656 [(set (match_operand:SI 0 "s_register_operand" "")
9657 (and:SI (ge:SI (match_operand:SI 1 "s_register_operand" "")
9659 (neg:SI (match_operator:SI 2 "arm_comparison_operator"
9660 [(match_operand:SI 3 "s_register_operand" "")
9661 (match_operand:SI 4 "arm_rhs_operand" "")]))))
9662 (clobber (match_operand:SI 5 "s_register_operand" ""))]
9664 [(set (match_dup 5) (not:SI (ashiftrt:SI (match_dup 1) (const_int 31))))
9665 (set (match_dup 0) (and:SI (match_op_dup 2 [(match_dup 3) (match_dup 4)])
9670 ;; This split can be used because CC_Z mode implies that the following
9671 ;; branch will be an equality, or an unsigned inequality, so the sign
9672 ;; extension is not needed.
9675 [(set (reg:CC_Z CC_REGNUM)
9677 (ashift:SI (subreg:SI (match_operand:QI 0 "memory_operand" "") 0)
9679 (match_operand 1 "const_int_operand" "")))
9680 (clobber (match_scratch:SI 2 ""))]
9682 && (((unsigned HOST_WIDE_INT) INTVAL (operands[1]))
9683 == (((unsigned HOST_WIDE_INT) INTVAL (operands[1])) >> 24) << 24)"
9684 [(set (match_dup 2) (zero_extend:SI (match_dup 0)))
9685 (set (reg:CC CC_REGNUM) (compare:CC (match_dup 2) (match_dup 1)))]
9687 operands[1] = GEN_INT (((unsigned long) INTVAL (operands[1])) >> 24);
9691 (define_expand "prologue"
9692 [(clobber (const_int 0))]
9695 arm_expand_prologue ();
9697 thumb_expand_prologue ();
9702 (define_expand "epilogue"
9703 [(clobber (const_int 0))]
9706 if (current_function_calls_eh_return)
9707 emit_insn (gen_prologue_use (gen_rtx_REG (Pmode, 2)));
9709 thumb_expand_epilogue ();
9710 else if (USE_RETURN_INSN (FALSE))
9712 emit_jump_insn (gen_return ());
9715 emit_jump_insn (gen_rtx_UNSPEC_VOLATILE (VOIDmode,
9717 gen_rtx_RETURN (VOIDmode)),
9723 ;; Note - although unspec_volatile's USE all hard registers,
9724 ;; USEs are ignored after relaod has completed. Thus we need
9725 ;; to add an unspec of the link register to ensure that flow
9726 ;; does not think that it is unused by the sibcall branch that
9727 ;; will replace the standard function epilogue.
9728 (define_insn "sibcall_epilogue"
9729 [(parallel [(unspec:SI [(reg:SI LR_REGNUM)] UNSPEC_PROLOGUE_USE)
9730 (unspec_volatile [(return)] VUNSPEC_EPILOGUE)])]
9733 if (use_return_insn (FALSE, next_nonnote_insn (insn)))
9734 return output_return_instruction (const_true_rtx, FALSE, FALSE);
9735 return arm_output_epilogue (next_nonnote_insn (insn));
9737 ;; Length is absolute worst case
9738 [(set_attr "length" "44")
9739 (set_attr "type" "block")
9740 ;; We don't clobber the conditions, but the potential length of this
9741 ;; operation is sufficient to make conditionalizing the sequence
9742 ;; unlikely to be profitable.
9743 (set_attr "conds" "clob")]
9746 (define_insn "*epilogue_insns"
9747 [(unspec_volatile [(return)] VUNSPEC_EPILOGUE)]
9751 return arm_output_epilogue (NULL);
9752 else /* TARGET_THUMB */
9753 return thumb_unexpanded_epilogue ();
9755 ; Length is absolute worst case
9756 [(set_attr "length" "44")
9757 (set_attr "type" "block")
9758 ;; We don't clobber the conditions, but the potential length of this
9759 ;; operation is sufficient to make conditionalizing the sequence
9760 ;; unlikely to be profitable.
9761 (set_attr "conds" "clob")]
9764 (define_expand "eh_epilogue"
9765 [(use (match_operand:SI 0 "register_operand" ""))
9766 (use (match_operand:SI 1 "register_operand" ""))
9767 (use (match_operand:SI 2 "register_operand" ""))]
9771 cfun->machine->eh_epilogue_sp_ofs = operands[1];
9772 if (GET_CODE (operands[2]) != REG || REGNO (operands[2]) != 2)
9774 rtx ra = gen_rtx_REG (Pmode, 2);
9776 emit_move_insn (ra, operands[2]);
9779 /* This is a hack -- we may have crystalized the function type too
9781 cfun->machine->func_type = 0;
9785 ;; This split is only used during output to reduce the number of patterns
9786 ;; that need assembler instructions adding to them. We allowed the setting
9787 ;; of the conditions to be implicit during rtl generation so that
9788 ;; the conditional compare patterns would work. However this conflicts to
9789 ;; some extent with the conditional data operations, so we have to split them
9793 [(set (match_operand:SI 0 "s_register_operand" "")
9794 (if_then_else:SI (match_operator 1 "arm_comparison_operator"
9795 [(match_operand 2 "" "") (match_operand 3 "" "")])
9797 (match_operand 4 "" "")))
9798 (clobber (reg:CC CC_REGNUM))]
9799 "TARGET_ARM && reload_completed"
9800 [(set (match_dup 5) (match_dup 6))
9801 (cond_exec (match_dup 7)
9802 (set (match_dup 0) (match_dup 4)))]
9805 enum machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
9806 operands[2], operands[3]);
9807 enum rtx_code rc = GET_CODE (operands[1]);
9809 operands[5] = gen_rtx_REG (mode, CC_REGNUM);
9810 operands[6] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
9811 if (mode == CCFPmode || mode == CCFPEmode)
9812 rc = reverse_condition_maybe_unordered (rc);
9814 rc = reverse_condition (rc);
9816 operands[7] = gen_rtx_fmt_ee (rc, VOIDmode, operands[5], const0_rtx);
9821 [(set (match_operand:SI 0 "s_register_operand" "")
9822 (if_then_else:SI (match_operator 1 "arm_comparison_operator"
9823 [(match_operand 2 "" "") (match_operand 3 "" "")])
9824 (match_operand 4 "" "")
9826 (clobber (reg:CC CC_REGNUM))]
9827 "TARGET_ARM && reload_completed"
9828 [(set (match_dup 5) (match_dup 6))
9829 (cond_exec (match_op_dup 1 [(match_dup 5) (const_int 0)])
9830 (set (match_dup 0) (match_dup 4)))]
9833 enum machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
9834 operands[2], operands[3]);
9836 operands[5] = gen_rtx_REG (mode, CC_REGNUM);
9837 operands[6] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
9842 [(set (match_operand:SI 0 "s_register_operand" "")
9843 (if_then_else:SI (match_operator 1 "arm_comparison_operator"
9844 [(match_operand 2 "" "") (match_operand 3 "" "")])
9845 (match_operand 4 "" "")
9846 (match_operand 5 "" "")))
9847 (clobber (reg:CC CC_REGNUM))]
9848 "TARGET_ARM && reload_completed"
9849 [(set (match_dup 6) (match_dup 7))
9850 (cond_exec (match_op_dup 1 [(match_dup 6) (const_int 0)])
9851 (set (match_dup 0) (match_dup 4)))
9852 (cond_exec (match_dup 8)
9853 (set (match_dup 0) (match_dup 5)))]
9856 enum machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
9857 operands[2], operands[3]);
9858 enum rtx_code rc = GET_CODE (operands[1]);
9860 operands[6] = gen_rtx_REG (mode, CC_REGNUM);
9861 operands[7] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
9862 if (mode == CCFPmode || mode == CCFPEmode)
9863 rc = reverse_condition_maybe_unordered (rc);
9865 rc = reverse_condition (rc);
9867 operands[8] = gen_rtx_fmt_ee (rc, VOIDmode, operands[6], const0_rtx);
9872 [(set (match_operand:SI 0 "s_register_operand" "")
9873 (if_then_else:SI (match_operator 1 "arm_comparison_operator"
9874 [(match_operand:SI 2 "s_register_operand" "")
9875 (match_operand:SI 3 "arm_add_operand" "")])
9876 (match_operand:SI 4 "arm_rhs_operand" "")
9878 (match_operand:SI 5 "s_register_operand" ""))))
9879 (clobber (reg:CC CC_REGNUM))]
9880 "TARGET_ARM && reload_completed"
9881 [(set (match_dup 6) (match_dup 7))
9882 (cond_exec (match_op_dup 1 [(match_dup 6) (const_int 0)])
9883 (set (match_dup 0) (match_dup 4)))
9884 (cond_exec (match_dup 8)
9885 (set (match_dup 0) (not:SI (match_dup 5))))]
9888 enum machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
9889 operands[2], operands[3]);
9890 enum rtx_code rc = GET_CODE (operands[1]);
9892 operands[6] = gen_rtx_REG (mode, CC_REGNUM);
9893 operands[7] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
9894 if (mode == CCFPmode || mode == CCFPEmode)
9895 rc = reverse_condition_maybe_unordered (rc);
9897 rc = reverse_condition (rc);
9899 operands[8] = gen_rtx_fmt_ee (rc, VOIDmode, operands[6], const0_rtx);
9903 (define_insn "*cond_move_not"
9904 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9905 (if_then_else:SI (match_operator 4 "arm_comparison_operator"
9906 [(match_operand 3 "cc_register" "") (const_int 0)])
9907 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
9909 (match_operand:SI 2 "s_register_operand" "r,r"))))]
9913 mov%d4\\t%0, %1\;mvn%D4\\t%0, %2"
9914 [(set_attr "conds" "use")
9915 (set_attr "length" "4,8")]
9918 ;; The next two patterns occur when an AND operation is followed by a
9919 ;; scc insn sequence
9921 (define_insn "*sign_extract_onebit"
9922 [(set (match_operand:SI 0 "s_register_operand" "=r")
9923 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
9925 (match_operand:SI 2 "const_int_operand" "n")))
9926 (clobber (reg:CC CC_REGNUM))]
9929 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
9930 output_asm_insn (\"ands\\t%0, %1, %2\", operands);
9931 return \"mvnne\\t%0, #0\";
9933 [(set_attr "conds" "clob")
9934 (set_attr "length" "8")]
9937 (define_insn "*not_signextract_onebit"
9938 [(set (match_operand:SI 0 "s_register_operand" "=r")
9940 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
9942 (match_operand:SI 2 "const_int_operand" "n"))))
9943 (clobber (reg:CC CC_REGNUM))]
9946 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
9947 output_asm_insn (\"tst\\t%1, %2\", operands);
9948 output_asm_insn (\"mvneq\\t%0, #0\", operands);
9949 return \"movne\\t%0, #0\";
9951 [(set_attr "conds" "clob")
9952 (set_attr "length" "12")]
9955 ;; Push multiple registers to the stack. Registers are in parallel (use ...)
9956 ;; expressions. For simplicity, the first register is also in the unspec
9958 (define_insn "*push_multi"
9959 [(match_parallel 2 "multi_register_push"
9960 [(set (match_operand:BLK 0 "memory_operand" "=m")
9961 (unspec:BLK [(match_operand:SI 1 "s_register_operand" "r")]
9962 UNSPEC_PUSH_MULT))])]
9966 int num_saves = XVECLEN (operands[2], 0);
9968 /* For the StrongARM at least it is faster to
9969 use STR to store only a single register. */
9971 output_asm_insn (\"str\\t%1, [%m0, #-4]!\", operands);
9977 strcpy (pattern, \"stmfd\\t%m0!, {%1\");
9979 for (i = 1; i < num_saves; i++)
9981 strcat (pattern, \", %|\");
9983 reg_names[REGNO (XEXP (XVECEXP (operands[2], 0, i), 0))]);
9986 strcat (pattern, \"}\");
9987 output_asm_insn (pattern, operands);
9992 [(set_attr "type" "store4")]
9995 (define_insn "stack_tie"
9996 [(set (mem:BLK (scratch))
9997 (unspec:BLK [(match_operand:SI 0 "s_register_operand" "r")
9998 (match_operand:SI 1 "s_register_operand" "r")]
10002 [(set_attr "length" "0")]
10005 ;; Similarly for the floating point registers
10006 (define_insn "*push_fp_multi"
10007 [(match_parallel 2 "multi_register_push"
10008 [(set (match_operand:BLK 0 "memory_operand" "=m")
10009 (unspec:BLK [(match_operand:XF 1 "f_register_operand" "f")]
10010 UNSPEC_PUSH_MULT))])]
10011 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
10016 sprintf (pattern, \"sfmfd\\t%%1, %d, [%%m0]!\", XVECLEN (operands[2], 0));
10017 output_asm_insn (pattern, operands);
10020 [(set_attr "type" "f_store")]
10023 ;; Special patterns for dealing with the constant pool
10025 (define_insn "align_4"
10026 [(unspec_volatile [(const_int 0)] VUNSPEC_ALIGN)]
10029 assemble_align (32);
10034 (define_insn "align_8"
10035 [(unspec_volatile [(const_int 0)] VUNSPEC_ALIGN8)]
10038 assemble_align (64);
10043 (define_insn "consttable_end"
10044 [(unspec_volatile [(const_int 0)] VUNSPEC_POOL_END)]
10047 making_const_table = FALSE;
10052 (define_insn "consttable_1"
10053 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_1)]
10056 making_const_table = TRUE;
10057 assemble_integer (operands[0], 1, BITS_PER_WORD, 1);
10058 assemble_zeros (3);
10061 [(set_attr "length" "4")]
10064 (define_insn "consttable_2"
10065 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_2)]
10068 making_const_table = TRUE;
10069 assemble_integer (operands[0], 2, BITS_PER_WORD, 1);
10070 assemble_zeros (2);
10073 [(set_attr "length" "4")]
10076 (define_insn "consttable_4"
10077 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_4)]
10081 making_const_table = TRUE;
10082 switch (GET_MODE_CLASS (GET_MODE (operands[0])))
10087 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[0]);
10088 assemble_real (r, GET_MODE (operands[0]), BITS_PER_WORD);
10092 assemble_integer (operands[0], 4, BITS_PER_WORD, 1);
10097 [(set_attr "length" "4")]
10100 (define_insn "consttable_8"
10101 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_8)]
10105 making_const_table = TRUE;
10106 switch (GET_MODE_CLASS (GET_MODE (operands[0])))
10111 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[0]);
10112 assemble_real (r, GET_MODE (operands[0]), BITS_PER_WORD);
10116 assemble_integer (operands[0], 8, BITS_PER_WORD, 1);
10121 [(set_attr "length" "8")]
10124 ;; Miscellaneous Thumb patterns
10126 (define_expand "tablejump"
10127 [(parallel [(set (pc) (match_operand:SI 0 "register_operand" ""))
10128 (use (label_ref (match_operand 1 "" "")))])]
10133 /* Hopefully, CSE will eliminate this copy. */
10134 rtx reg1 = copy_addr_to_reg (gen_rtx_LABEL_REF (Pmode, operands[1]));
10135 rtx reg2 = gen_reg_rtx (SImode);
10137 emit_insn (gen_addsi3 (reg2, operands[0], reg1));
10138 operands[0] = reg2;
10143 ;; NB never uses BX.
10144 (define_insn "*thumb_tablejump"
10145 [(set (pc) (match_operand:SI 0 "register_operand" "l*r"))
10146 (use (label_ref (match_operand 1 "" "")))]
10149 [(set_attr "length" "2")]
10152 ;; V5 Instructions,
10154 (define_insn "clzsi2"
10155 [(set (match_operand:SI 0 "s_register_operand" "=r")
10156 (clz:SI (match_operand:SI 1 "s_register_operand" "r")))]
10157 "TARGET_ARM && arm_arch5"
10159 [(set_attr "predicable" "yes")])
10161 (define_expand "ffssi2"
10162 [(set (match_operand:SI 0 "s_register_operand" "")
10163 (ffs:SI (match_operand:SI 1 "s_register_operand" "")))]
10164 "TARGET_ARM && arm_arch5"
10169 t1 = gen_reg_rtx (SImode);
10170 t2 = gen_reg_rtx (SImode);
10171 t3 = gen_reg_rtx (SImode);
10173 emit_insn (gen_negsi2 (t1, operands[1]));
10174 emit_insn (gen_andsi3 (t2, operands[1], t1));
10175 emit_insn (gen_clzsi2 (t3, t2));
10176 emit_insn (gen_subsi3 (operands[0], GEN_INT (32), t3));
10181 (define_expand "ctzsi2"
10182 [(set (match_operand:SI 0 "s_register_operand" "")
10183 (ctz:SI (match_operand:SI 1 "s_register_operand" "")))]
10184 "TARGET_ARM && arm_arch5"
10189 t1 = gen_reg_rtx (SImode);
10190 t2 = gen_reg_rtx (SImode);
10191 t3 = gen_reg_rtx (SImode);
10193 emit_insn (gen_negsi2 (t1, operands[1]));
10194 emit_insn (gen_andsi3 (t2, operands[1], t1));
10195 emit_insn (gen_clzsi2 (t3, t2));
10196 emit_insn (gen_subsi3 (operands[0], GEN_INT (31), t3));
10201 ;; V5E instructions.
10203 (define_insn "prefetch"
10204 [(prefetch (match_operand:SI 0 "address_operand" "p")
10205 (match_operand:SI 1 "" "")
10206 (match_operand:SI 2 "" ""))]
10207 "TARGET_ARM && arm_arch5e"
10210 ;; General predication pattern
10213 [(match_operator 0 "arm_comparison_operator"
10214 [(match_operand 1 "cc_register" "")
10220 (define_insn "prologue_use"
10221 [(unspec:SI [(match_operand:SI 0 "register_operand" "")] UNSPEC_PROLOGUE_USE)]
10223 "%@ %0 needed for prologue"
10227 ;; Patterns for exception handling
10229 (define_expand "eh_return"
10230 [(use (match_operand 0 "general_operand" ""))]
10235 emit_insn (gen_arm_eh_return (operands[0]));
10237 emit_insn (gen_thumb_eh_return (operands[0]));
10242 ;; We can't expand this before we know where the link register is stored.
10243 (define_insn_and_split "arm_eh_return"
10244 [(unspec_volatile [(match_operand:SI 0 "s_register_operand" "r")]
10246 (clobber (match_scratch:SI 1 "=&r"))]
10249 "&& reload_completed"
10253 arm_set_return_address (operands[0], operands[1]);
10258 (define_insn_and_split "thumb_eh_return"
10259 [(unspec_volatile [(match_operand:SI 0 "s_register_operand" "l")]
10261 (clobber (match_scratch:SI 1 "=&l"))]
10264 "&& reload_completed"
10268 thumb_set_return_address (operands[0], operands[1]);
10273 ;; Load the FPA co-processor patterns
10275 ;; Load the Maverick co-processor patterns
10276 (include "cirrus.md")
10277 ;; Load the Intel Wireless Multimedia Extension patterns
10278 (include "iwmmxt.md")
10279 ;; Load the VFP co-processor patterns