1 ;;- Machine description for ARM for GNU compiler
2 ;; Copyright 1991, 1993, 1994, 1995, 1996, 1996, 1997, 1998, 1999, 2000,
3 ;; 2001, 2002, 2003, 2004, 2005, 2006 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, 51 Franklin Street, Fifth Floor,
23 ;; Boston, MA 02110-1301, USA.
25 ;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
28 ;;---------------------------------------------------------------------------
33 [(R0_REGNUM 0) ; First CORE register
34 (IP_REGNUM 12) ; Scratch register
35 (SP_REGNUM 13) ; Stack pointer
36 (LR_REGNUM 14) ; Return address register
37 (PC_REGNUM 15) ; Program counter
38 (CC_REGNUM 24) ; Condition code pseudo register
39 (LAST_ARM_REGNUM 15) ;
40 (FPA_F0_REGNUM 16) ; FIRST_FPA_REGNUM
41 (FPA_F7_REGNUM 23) ; LAST_FPA_REGNUM
44 ;; 3rd operand to select_dominance_cc_mode
53 ;; Note: sin and cos are no-longer used.
56 [(UNSPEC_SIN 0) ; `sin' operation (MODE_FLOAT):
57 ; operand 0 is the result,
58 ; operand 1 the parameter.
59 (UNPSEC_COS 1) ; `cos' operation (MODE_FLOAT):
60 ; operand 0 is the result,
61 ; operand 1 the parameter.
62 (UNSPEC_PUSH_MULT 2) ; `push multiple' operation:
63 ; operand 0 is the first register,
64 ; subsequent registers are in parallel (use ...)
66 (UNSPEC_PIC_SYM 3) ; A symbol that has been treated properly for pic
67 ; usage, that is, we will add the pic_register
68 ; value to it before trying to dereference it.
69 (UNSPEC_PIC_BASE 4) ; Adding the PC value to the offset to the
70 ; GLOBAL_OFFSET_TABLE. The operation is fully
71 ; described by the RTL but must be wrapped to
72 ; prevent combine from trying to rip it apart.
73 (UNSPEC_PRLG_STK 5) ; A special barrier that prevents frame accesses
74 ; being scheduled before the stack adjustment insn.
75 (UNSPEC_PROLOGUE_USE 6) ; As USE insns are not meaningful after reload,
76 ; this unspec is used to prevent the deletion of
77 ; instructions setting registers for EH handling
78 ; and stack frame generation. Operand 0 is the
80 (UNSPEC_CHECK_ARCH 7); Set CCs to indicate 26-bit or 32-bit mode.
81 (UNSPEC_WSHUFH 8) ; Used by the intrinsic form of the iWMMXt WSHUFH instruction.
82 (UNSPEC_WACC 9) ; Used by the intrinsic form of the iWMMXt WACC instruction.
83 (UNSPEC_TMOVMSK 10) ; Used by the intrinsic form of the iWMMXt TMOVMSK instruction.
84 (UNSPEC_WSAD 11) ; Used by the intrinsic form of the iWMMXt WSAD instruction.
85 (UNSPEC_WSADZ 12) ; Used by the intrinsic form of the iWMMXt WSADZ instruction.
86 (UNSPEC_WMACS 13) ; Used by the intrinsic form of the iWMMXt WMACS instruction.
87 (UNSPEC_WMACU 14) ; Used by the intrinsic form of the iWMMXt WMACU instruction.
88 (UNSPEC_WMACSZ 15) ; Used by the intrinsic form of the iWMMXt WMACSZ instruction.
89 (UNSPEC_WMACUZ 16) ; Used by the intrinsic form of the iWMMXt WMACUZ instruction.
90 (UNSPEC_CLRDI 17) ; Used by the intrinsic form of the iWMMXt CLRDI instruction.
91 (UNSPEC_WMADDS 18) ; Used by the intrinsic form of the iWMMXt WMADDS instruction.
92 (UNSPEC_WMADDU 19) ; Used by the intrinsic form of the iWMMXt WMADDU instruction.
93 (UNSPEC_TLS 20) ; A symbol that has been treated properly for TLS usage.
94 (UNSPEC_PIC_LABEL 21) ; A label used for PIC access that does not appear in the
99 ;; UNSPEC_VOLATILE Usage:
102 [(VUNSPEC_BLOCKAGE 0) ; `blockage' insn to prevent scheduling across an
104 (VUNSPEC_EPILOGUE 1) ; `epilogue' insn, used to represent any part of the
105 ; instruction epilogue sequence that isn't expanded
106 ; into normal RTL. Used for both normal and sibcall
108 (VUNSPEC_ALIGN 2) ; `align' insn. Used at the head of a minipool table
109 ; for inlined constants.
110 (VUNSPEC_POOL_END 3) ; `end-of-table'. Used to mark the end of a minipool
112 (VUNSPEC_POOL_1 4) ; `pool-entry(1)'. An entry in the constant pool for
114 (VUNSPEC_POOL_2 5) ; `pool-entry(2)'. An entry in the constant pool for
116 (VUNSPEC_POOL_4 6) ; `pool-entry(4)'. An entry in the constant pool for
118 (VUNSPEC_POOL_8 7) ; `pool-entry(8)'. An entry in the constant pool for
120 (VUNSPEC_TMRC 8) ; Used by the iWMMXt TMRC instruction.
121 (VUNSPEC_TMCR 9) ; Used by the iWMMXt TMCR instruction.
122 (VUNSPEC_ALIGN8 10) ; 8-byte alignment version of VUNSPEC_ALIGN
123 (VUNSPEC_WCMP_EQ 11) ; Used by the iWMMXt WCMPEQ instructions
124 (VUNSPEC_WCMP_GTU 12) ; Used by the iWMMXt WCMPGTU instructions
125 (VUNSPEC_WCMP_GT 13) ; Used by the iwMMXT WCMPGT instructions
126 (VUNSPEC_EH_RETURN 20); Use to override the return address for exception
131 ;;---------------------------------------------------------------------------
134 ; IS_THUMB is set to 'yes' when we are generating Thumb code, and 'no' when
135 ; generating ARM code. This is used to control the length of some insn
136 ; patterns that share the same RTL in both ARM and Thumb code.
137 (define_attr "is_thumb" "no,yes" (const (symbol_ref "thumb_code")))
139 ; IS_STRONGARM is set to 'yes' when compiling for StrongARM, it affects
140 ; scheduling decisions for the load unit and the multiplier.
141 (define_attr "is_strongarm" "no,yes" (const (symbol_ref "arm_tune_strongarm")))
143 ; IS_XSCALE is set to 'yes' when compiling for XScale.
144 (define_attr "is_xscale" "no,yes" (const (symbol_ref "arm_tune_xscale")))
146 ;; Operand number of an input operand that is shifted. Zero if the
147 ;; given instruction does not shift one of its input operands.
148 (define_attr "shift" "" (const_int 0))
150 ; Floating Point Unit. If we only have floating point emulation, then there
151 ; is no point in scheduling the floating point insns. (Well, for best
152 ; performance we should try and group them together).
153 (define_attr "fpu" "none,fpa,fpe2,fpe3,maverick,vfp"
154 (const (symbol_ref "arm_fpu_attr")))
156 ; LENGTH of an instruction (in bytes)
157 (define_attr "length" "" (const_int 4))
159 ; POOL_RANGE is how far away from a constant pool entry that this insn
160 ; can be placed. If the distance is zero, then this insn will never
161 ; reference the pool.
162 ; NEG_POOL_RANGE is nonzero for insns that can reference a constant pool entry
163 ; before its address.
164 (define_attr "pool_range" "" (const_int 0))
165 (define_attr "neg_pool_range" "" (const_int 0))
167 ; An assembler sequence may clobber the condition codes without us knowing.
168 ; If such an insn references the pool, then we have no way of knowing how,
169 ; so use the most conservative value for pool_range.
170 (define_asm_attributes
171 [(set_attr "conds" "clob")
172 (set_attr "length" "4")
173 (set_attr "pool_range" "250")])
175 ;; The instruction used to implement a particular pattern. This
176 ;; information is used by pipeline descriptions to provide accurate
177 ;; scheduling information.
180 "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"
181 (const_string "other"))
183 ; TYPE attribute is used to detect floating point instructions which, if
184 ; running on a co-processor can run in parallel with other, basic instructions
185 ; If write-buffer scheduling is enabled then it can also be used in the
186 ; scheduling of writes.
188 ; Classification of each insn
189 ; alu any alu instruction that doesn't hit memory or fp
190 ; regs or have a shifted source operand
191 ; alu_shift any data instruction that doesn't hit memory or fp
192 ; regs, but has a source operand shifted by a constant
193 ; alu_shift_reg any data instruction that doesn't hit memory or fp
194 ; regs, but has a source operand shifted by a register value
195 ; mult a multiply instruction
196 ; block blockage insn, this blocks all functional units
197 ; float a floating point arithmetic operation (subject to expansion)
198 ; fdivd DFmode floating point division
199 ; fdivs SFmode floating point division
200 ; fmul Floating point multiply
201 ; ffmul Fast floating point multiply
202 ; farith Floating point arithmetic (4 cycle)
203 ; ffarith Fast floating point arithmetic (2 cycle)
204 ; float_em a floating point arithmetic operation that is normally emulated
205 ; even on a machine with an fpa.
206 ; f_load a floating point load from memory
207 ; f_store a floating point store to memory
208 ; f_load[sd] single/double load from memory
209 ; f_store[sd] single/double store to memory
210 ; f_flag a transfer of co-processor flags to the CPSR
211 ; f_mem_r a transfer of a floating point register to a real reg via mem
212 ; r_mem_f the reverse of f_mem_r
213 ; f_2_r fast transfer float to arm (no memory needed)
214 ; r_2_f fast transfer arm to float
215 ; f_cvt convert floating<->integral
217 ; call a subroutine call
218 ; load_byte load byte(s) from memory to arm registers
219 ; load1 load 1 word from memory to arm registers
220 ; load2 load 2 words from memory to arm registers
221 ; load3 load 3 words from memory to arm registers
222 ; load4 load 4 words from memory to arm registers
223 ; store store 1 word to memory from arm registers
224 ; store2 store 2 words
225 ; store3 store 3 words
226 ; store4 store 4 (or more) words
227 ; Additions for Cirrus Maverick co-processor:
228 ; mav_farith Floating point arithmetic (4 cycle)
229 ; mav_dmult Double multiplies (7 cycle)
232 "alu,alu_shift,alu_shift_reg,mult,block,float,fdivx,fdivd,fdivs,fmul,ffmul,farith,ffarith,f_flag,float_em,f_load,f_store,f_loads,f_loadd,f_stores,f_stored,f_mem_r,r_mem_f,f_2_r,r_2_f,f_cvt,branch,call,load_byte,load1,load2,load3,load4,store1,store2,store3,store4,mav_farith,mav_dmult"
234 (eq_attr "insn" "smulxy,smlaxy,smlalxy,smulwy,smlawx,mul,muls,mla,mlas,umull,umulls,umlal,umlals,smull,smulls,smlal,smlals")
235 (const_string "mult")
236 (const_string "alu")))
238 ; Load scheduling, set from the arm_ld_sched variable
239 ; initialized by arm_override_options()
240 (define_attr "ldsched" "no,yes" (const (symbol_ref "arm_ld_sched")))
242 ; condition codes: this one is used by final_prescan_insn to speed up
243 ; conditionalizing instructions. It saves having to scan the rtl to see if
244 ; it uses or alters the condition codes.
246 ; USE means that the condition codes are used by the insn in the process of
247 ; outputting code, this means (at present) that we can't use the insn in
250 ; SET means that the purpose of the insn is to set the condition codes in a
251 ; well defined manner.
253 ; CLOB means that the condition codes are altered in an undefined manner, if
254 ; they are altered at all
256 ; JUMP_CLOB is used when the condition cannot be represented by a single
257 ; instruction (UNEQ and LTGT). These cannot be predicated.
259 ; NOCOND means that the condition codes are neither altered nor affect the
260 ; output of this insn
262 (define_attr "conds" "use,set,clob,jump_clob,nocond"
263 (if_then_else (eq_attr "type" "call")
264 (const_string "clob")
265 (const_string "nocond")))
267 ; Predicable means that the insn can be conditionally executed based on
268 ; an automatically added predicate (additional patterns are generated by
269 ; gen...). We default to 'no' because no Thumb patterns match this rule
270 ; and not all ARM patterns do.
271 (define_attr "predicable" "no,yes" (const_string "no"))
273 ; Only model the write buffer for ARM6 and ARM7. Earlier processors don't
274 ; have one. Later ones, such as StrongARM, have write-back caches, so don't
275 ; suffer blockages enough to warrant modelling this (and it can adversely
276 ; affect the schedule).
277 (define_attr "model_wbuf" "no,yes" (const (symbol_ref "arm_tune_wbuf")))
279 ; WRITE_CONFLICT implies that a read following an unrelated write is likely
280 ; to stall the processor. Used with model_wbuf above.
281 (define_attr "write_conflict" "no,yes"
282 (if_then_else (eq_attr "type"
283 "block,float_em,f_load,f_store,f_mem_r,r_mem_f,call,load1")
285 (const_string "no")))
287 ; Classify the insns into those that take one cycle and those that take more
288 ; than one on the main cpu execution unit.
289 (define_attr "core_cycles" "single,multi"
290 (if_then_else (eq_attr "type"
291 "alu,alu_shift,float,fdivx,fdivd,fdivs,fmul,ffmul,farith,ffarith")
292 (const_string "single")
293 (const_string "multi")))
295 ;; FAR_JUMP is "yes" if a BL instruction is used to generate a branch to a
296 ;; distant label. Only applicable to Thumb code.
297 (define_attr "far_jump" "yes,no" (const_string "no"))
300 ;;---------------------------------------------------------------------------
303 ; A list of modes that are exactly 64 bits in size. We use this to expand
304 ; some splits that are the same for all modes when operating on ARM
306 (define_mode_macro ANY64 [DI DF V8QI V4HI V2SI V2SF])
308 ;;---------------------------------------------------------------------------
311 (include "predicates.md")
312 (include "constraints.md")
314 ;;---------------------------------------------------------------------------
315 ;; Pipeline descriptions
317 ;; Processor type. This is created automatically from arm-cores.def.
318 (include "arm-tune.md")
320 ;; True if the generic scheduling description should be used.
322 (define_attr "generic_sched" "yes,no"
324 (eq_attr "tune" "arm926ejs,arm1020e,arm1026ejs,arm1136js,arm1136jfs")
326 (const_string "yes"))))
328 (define_attr "generic_vfp" "yes,no"
330 (and (eq_attr "fpu" "vfp")
331 (eq_attr "tune" "!arm1020e,arm1022e"))
333 (const_string "no"))))
335 (include "arm-generic.md")
336 (include "arm926ejs.md")
337 (include "arm1020e.md")
338 (include "arm1026ejs.md")
339 (include "arm1136jfs.md")
342 ;;---------------------------------------------------------------------------
347 ;; Note: For DImode insns, there is normally no reason why operands should
348 ;; not be in the same register, what we don't want is for something being
349 ;; written to partially overlap something that is an input.
350 ;; Cirrus 64bit additions should not be split because we have a native
351 ;; 64bit addition instructions.
353 (define_expand "adddi3"
355 [(set (match_operand:DI 0 "s_register_operand" "")
356 (plus:DI (match_operand:DI 1 "s_register_operand" "")
357 (match_operand:DI 2 "s_register_operand" "")))
358 (clobber (reg:CC CC_REGNUM))])]
361 if (TARGET_HARD_FLOAT && TARGET_MAVERICK)
363 if (!cirrus_fp_register (operands[0], DImode))
364 operands[0] = force_reg (DImode, operands[0]);
365 if (!cirrus_fp_register (operands[1], DImode))
366 operands[1] = force_reg (DImode, operands[1]);
367 emit_insn (gen_cirrus_adddi3 (operands[0], operands[1], operands[2]));
373 if (GET_CODE (operands[1]) != REG)
374 operands[1] = force_reg (SImode, operands[1]);
375 if (GET_CODE (operands[2]) != REG)
376 operands[2] = force_reg (SImode, operands[2]);
381 (define_insn "*thumb_adddi3"
382 [(set (match_operand:DI 0 "register_operand" "=l")
383 (plus:DI (match_operand:DI 1 "register_operand" "%0")
384 (match_operand:DI 2 "register_operand" "l")))
385 (clobber (reg:CC CC_REGNUM))
388 "add\\t%Q0, %Q0, %Q2\;adc\\t%R0, %R0, %R2"
389 [(set_attr "length" "4")]
392 (define_insn_and_split "*arm_adddi3"
393 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
394 (plus:DI (match_operand:DI 1 "s_register_operand" "%0, 0")
395 (match_operand:DI 2 "s_register_operand" "r, 0")))
396 (clobber (reg:CC CC_REGNUM))]
397 "TARGET_ARM && !(TARGET_HARD_FLOAT && TARGET_MAVERICK)"
399 "TARGET_ARM && reload_completed"
400 [(parallel [(set (reg:CC_C CC_REGNUM)
401 (compare:CC_C (plus:SI (match_dup 1) (match_dup 2))
403 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
404 (set (match_dup 3) (plus:SI (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))
405 (plus:SI (match_dup 4) (match_dup 5))))]
408 operands[3] = gen_highpart (SImode, operands[0]);
409 operands[0] = gen_lowpart (SImode, operands[0]);
410 operands[4] = gen_highpart (SImode, operands[1]);
411 operands[1] = gen_lowpart (SImode, operands[1]);
412 operands[5] = gen_highpart (SImode, operands[2]);
413 operands[2] = gen_lowpart (SImode, operands[2]);
415 [(set_attr "conds" "clob")
416 (set_attr "length" "8")]
419 (define_insn_and_split "*adddi_sesidi_di"
420 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
421 (plus:DI (sign_extend:DI
422 (match_operand:SI 2 "s_register_operand" "r,r"))
423 (match_operand:DI 1 "s_register_operand" "r,0")))
424 (clobber (reg:CC CC_REGNUM))]
425 "TARGET_ARM && !(TARGET_HARD_FLOAT && TARGET_MAVERICK)"
427 "TARGET_ARM && reload_completed"
428 [(parallel [(set (reg:CC_C CC_REGNUM)
429 (compare:CC_C (plus:SI (match_dup 1) (match_dup 2))
431 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
432 (set (match_dup 3) (plus:SI (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))
433 (plus:SI (ashiftrt:SI (match_dup 2)
438 operands[3] = gen_highpart (SImode, operands[0]);
439 operands[0] = gen_lowpart (SImode, operands[0]);
440 operands[4] = gen_highpart (SImode, operands[1]);
441 operands[1] = gen_lowpart (SImode, operands[1]);
442 operands[2] = gen_lowpart (SImode, operands[2]);
444 [(set_attr "conds" "clob")
445 (set_attr "length" "8")]
448 (define_insn_and_split "*adddi_zesidi_di"
449 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
450 (plus:DI (zero_extend:DI
451 (match_operand:SI 2 "s_register_operand" "r,r"))
452 (match_operand:DI 1 "s_register_operand" "r,0")))
453 (clobber (reg:CC CC_REGNUM))]
454 "TARGET_ARM && !(TARGET_HARD_FLOAT && TARGET_MAVERICK)"
456 "TARGET_ARM && reload_completed"
457 [(parallel [(set (reg:CC_C CC_REGNUM)
458 (compare:CC_C (plus:SI (match_dup 1) (match_dup 2))
460 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
461 (set (match_dup 3) (plus:SI (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))
462 (plus:SI (match_dup 4) (const_int 0))))]
465 operands[3] = gen_highpart (SImode, operands[0]);
466 operands[0] = gen_lowpart (SImode, operands[0]);
467 operands[4] = gen_highpart (SImode, operands[1]);
468 operands[1] = gen_lowpart (SImode, operands[1]);
469 operands[2] = gen_lowpart (SImode, operands[2]);
471 [(set_attr "conds" "clob")
472 (set_attr "length" "8")]
475 (define_expand "addsi3"
476 [(set (match_operand:SI 0 "s_register_operand" "")
477 (plus:SI (match_operand:SI 1 "s_register_operand" "")
478 (match_operand:SI 2 "reg_or_int_operand" "")))]
481 if (TARGET_ARM && GET_CODE (operands[2]) == CONST_INT)
483 arm_split_constant (PLUS, SImode, NULL_RTX,
484 INTVAL (operands[2]), operands[0], operands[1],
485 optimize && !no_new_pseudos);
491 ; If there is a scratch available, this will be faster than synthesizing the
494 [(match_scratch:SI 3 "r")
495 (set (match_operand:SI 0 "arm_general_register_operand" "")
496 (plus:SI (match_operand:SI 1 "arm_general_register_operand" "")
497 (match_operand:SI 2 "const_int_operand" "")))]
499 !(const_ok_for_arm (INTVAL (operands[2]))
500 || const_ok_for_arm (-INTVAL (operands[2])))
501 && const_ok_for_arm (~INTVAL (operands[2]))"
502 [(set (match_dup 3) (match_dup 2))
503 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 3)))]
507 (define_insn_and_split "*arm_addsi3"
508 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
509 (plus:SI (match_operand:SI 1 "s_register_operand" "%r,r,r")
510 (match_operand:SI 2 "reg_or_int_operand" "rI,L,?n")))]
517 GET_CODE (operands[2]) == CONST_INT
518 && !(const_ok_for_arm (INTVAL (operands[2]))
519 || const_ok_for_arm (-INTVAL (operands[2])))"
520 [(clobber (const_int 0))]
522 arm_split_constant (PLUS, SImode, curr_insn,
523 INTVAL (operands[2]), operands[0],
527 [(set_attr "length" "4,4,16")
528 (set_attr "predicable" "yes")]
531 ;; Register group 'k' is a single register group containing only the stack
532 ;; register. Trying to reload it will always fail catastrophically,
533 ;; so never allow those alternatives to match if reloading is needed.
535 (define_insn "*thumb_addsi3"
536 [(set (match_operand:SI 0 "register_operand" "=l,l,l,*r,*h,l,!k")
537 (plus:SI (match_operand:SI 1 "register_operand" "%0,0,l,*0,*0,!k,!k")
538 (match_operand:SI 2 "nonmemory_operand" "I,J,lL,*h,*r,!M,!O")))]
541 static const char * const asms[] =
543 \"add\\t%0, %0, %2\",
544 \"sub\\t%0, %0, #%n2\",
545 \"add\\t%0, %1, %2\",
546 \"add\\t%0, %0, %2\",
547 \"add\\t%0, %0, %2\",
548 \"add\\t%0, %1, %2\",
551 if ((which_alternative == 2 || which_alternative == 6)
552 && GET_CODE (operands[2]) == CONST_INT
553 && INTVAL (operands[2]) < 0)
554 return \"sub\\t%0, %1, #%n2\";
555 return asms[which_alternative];
557 [(set_attr "length" "2")]
560 ;; Reloading and elimination of the frame pointer can
561 ;; sometimes cause this optimization to be missed.
563 [(set (match_operand:SI 0 "arm_general_register_operand" "")
564 (match_operand:SI 1 "const_int_operand" ""))
566 (plus:SI (match_dup 0) (reg:SI SP_REGNUM)))]
568 && (unsigned HOST_WIDE_INT) (INTVAL (operands[1])) < 1024
569 && (INTVAL (operands[1]) & 3) == 0"
570 [(set (match_dup 0) (plus:SI (reg:SI SP_REGNUM) (match_dup 1)))]
574 (define_insn "*addsi3_compare0"
575 [(set (reg:CC_NOOV CC_REGNUM)
577 (plus:SI (match_operand:SI 1 "s_register_operand" "r, r")
578 (match_operand:SI 2 "arm_add_operand" "rI,L"))
580 (set (match_operand:SI 0 "s_register_operand" "=r,r")
581 (plus:SI (match_dup 1) (match_dup 2)))]
585 sub%?s\\t%0, %1, #%n2"
586 [(set_attr "conds" "set")]
589 (define_insn "*addsi3_compare0_scratch"
590 [(set (reg:CC_NOOV CC_REGNUM)
592 (plus:SI (match_operand:SI 0 "s_register_operand" "r, r")
593 (match_operand:SI 1 "arm_add_operand" "rI,L"))
599 [(set_attr "conds" "set")]
602 (define_insn "*compare_negsi_si"
603 [(set (reg:CC_Z CC_REGNUM)
605 (neg:SI (match_operand:SI 0 "s_register_operand" "r"))
606 (match_operand:SI 1 "s_register_operand" "r")))]
609 [(set_attr "conds" "set")]
612 ;; This is the canonicalization of addsi3_compare0_for_combiner when the
613 ;; addend is a constant.
614 (define_insn "*cmpsi2_addneg"
615 [(set (reg:CC CC_REGNUM)
617 (match_operand:SI 1 "s_register_operand" "r,r")
618 (match_operand:SI 2 "arm_addimm_operand" "I,L")))
619 (set (match_operand:SI 0 "s_register_operand" "=r,r")
620 (plus:SI (match_dup 1)
621 (match_operand:SI 3 "arm_addimm_operand" "L,I")))]
622 "TARGET_ARM && INTVAL (operands[2]) == -INTVAL (operands[3])"
625 add%?s\\t%0, %1, #%n2"
626 [(set_attr "conds" "set")]
629 ;; Convert the sequence
631 ;; cmn rd, #1 (equivalent to cmp rd, #-1)
635 ;; bcs dest ((unsigned)rn >= 1)
636 ;; similarly for the beq variant using bcc.
637 ;; This is a common looping idiom (while (n--))
639 [(set (match_operand:SI 0 "arm_general_register_operand" "")
640 (plus:SI (match_operand:SI 1 "arm_general_register_operand" "")
642 (set (match_operand 2 "cc_register" "")
643 (compare (match_dup 0) (const_int -1)))
645 (if_then_else (match_operator 3 "equality_operator"
646 [(match_dup 2) (const_int 0)])
647 (match_operand 4 "" "")
648 (match_operand 5 "" "")))]
649 "TARGET_ARM && peep2_reg_dead_p (3, operands[2])"
653 (match_dup 1) (const_int 1)))
654 (set (match_dup 0) (plus:SI (match_dup 1) (const_int -1)))])
656 (if_then_else (match_op_dup 3 [(match_dup 2) (const_int 0)])
659 "operands[2] = gen_rtx_REG (CCmode, CC_REGNUM);
660 operands[3] = gen_rtx_fmt_ee ((GET_CODE (operands[3]) == NE
663 operands[2], const0_rtx);"
666 ;; The next four insns work because they compare the result with one of
667 ;; the operands, and we know that the use of the condition code is
668 ;; either GEU or LTU, so we can use the carry flag from the addition
669 ;; instead of doing the compare a second time.
670 (define_insn "*addsi3_compare_op1"
671 [(set (reg:CC_C CC_REGNUM)
673 (plus:SI (match_operand:SI 1 "s_register_operand" "r,r")
674 (match_operand:SI 2 "arm_add_operand" "rI,L"))
676 (set (match_operand:SI 0 "s_register_operand" "=r,r")
677 (plus:SI (match_dup 1) (match_dup 2)))]
681 sub%?s\\t%0, %1, #%n2"
682 [(set_attr "conds" "set")]
685 (define_insn "*addsi3_compare_op2"
686 [(set (reg:CC_C CC_REGNUM)
688 (plus:SI (match_operand:SI 1 "s_register_operand" "r,r")
689 (match_operand:SI 2 "arm_add_operand" "rI,L"))
691 (set (match_operand:SI 0 "s_register_operand" "=r,r")
692 (plus:SI (match_dup 1) (match_dup 2)))]
696 sub%?s\\t%0, %1, #%n2"
697 [(set_attr "conds" "set")]
700 (define_insn "*compare_addsi2_op0"
701 [(set (reg:CC_C CC_REGNUM)
703 (plus:SI (match_operand:SI 0 "s_register_operand" "r,r")
704 (match_operand:SI 1 "arm_add_operand" "rI,L"))
710 [(set_attr "conds" "set")]
713 (define_insn "*compare_addsi2_op1"
714 [(set (reg:CC_C CC_REGNUM)
716 (plus:SI (match_operand:SI 0 "s_register_operand" "r,r")
717 (match_operand:SI 1 "arm_add_operand" "rI,L"))
723 [(set_attr "conds" "set")]
726 (define_insn "*addsi3_carryin"
727 [(set (match_operand:SI 0 "s_register_operand" "=r")
728 (plus:SI (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))
729 (plus:SI (match_operand:SI 1 "s_register_operand" "r")
730 (match_operand:SI 2 "arm_rhs_operand" "rI"))))]
733 [(set_attr "conds" "use")]
736 (define_insn "*addsi3_carryin_shift"
737 [(set (match_operand:SI 0 "s_register_operand" "=r")
738 (plus:SI (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))
740 (match_operator:SI 2 "shift_operator"
741 [(match_operand:SI 3 "s_register_operand" "r")
742 (match_operand:SI 4 "reg_or_int_operand" "rM")])
743 (match_operand:SI 1 "s_register_operand" "r"))))]
745 "adc%?\\t%0, %1, %3%S2"
746 [(set_attr "conds" "use")
747 (set (attr "type") (if_then_else (match_operand 4 "const_int_operand" "")
748 (const_string "alu_shift")
749 (const_string "alu_shift_reg")))]
752 (define_insn "*addsi3_carryin_alt1"
753 [(set (match_operand:SI 0 "s_register_operand" "=r")
754 (plus:SI (plus:SI (match_operand:SI 1 "s_register_operand" "r")
755 (match_operand:SI 2 "arm_rhs_operand" "rI"))
756 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
759 [(set_attr "conds" "use")]
762 (define_insn "*addsi3_carryin_alt2"
763 [(set (match_operand:SI 0 "s_register_operand" "=r")
764 (plus:SI (plus:SI (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))
765 (match_operand:SI 1 "s_register_operand" "r"))
766 (match_operand:SI 2 "arm_rhs_operand" "rI")))]
769 [(set_attr "conds" "use")]
772 (define_insn "*addsi3_carryin_alt3"
773 [(set (match_operand:SI 0 "s_register_operand" "=r")
774 (plus:SI (plus:SI (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))
775 (match_operand:SI 2 "arm_rhs_operand" "rI"))
776 (match_operand:SI 1 "s_register_operand" "r")))]
779 [(set_attr "conds" "use")]
782 (define_insn "incscc"
783 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
784 (plus:SI (match_operator:SI 2 "arm_comparison_operator"
785 [(match_operand:CC 3 "cc_register" "") (const_int 0)])
786 (match_operand:SI 1 "s_register_operand" "0,?r")))]
790 mov%D2\\t%0, %1\;add%d2\\t%0, %1, #1"
791 [(set_attr "conds" "use")
792 (set_attr "length" "4,8")]
795 ; transform ((x << y) - 1) to ~(~(x-1) << y) Where X is a constant.
797 [(set (match_operand:SI 0 "s_register_operand" "")
798 (plus:SI (ashift:SI (match_operand:SI 1 "const_int_operand" "")
799 (match_operand:SI 2 "s_register_operand" ""))
801 (clobber (match_operand:SI 3 "s_register_operand" ""))]
803 [(set (match_dup 3) (match_dup 1))
804 (set (match_dup 0) (not:SI (ashift:SI (match_dup 3) (match_dup 2))))]
806 operands[1] = GEN_INT (~(INTVAL (operands[1]) - 1));
809 (define_expand "addsf3"
810 [(set (match_operand:SF 0 "s_register_operand" "")
811 (plus:SF (match_operand:SF 1 "s_register_operand" "")
812 (match_operand:SF 2 "arm_float_add_operand" "")))]
813 "TARGET_ARM && TARGET_HARD_FLOAT"
816 && !cirrus_fp_register (operands[2], SFmode))
817 operands[2] = force_reg (SFmode, operands[2]);
820 (define_expand "adddf3"
821 [(set (match_operand:DF 0 "s_register_operand" "")
822 (plus:DF (match_operand:DF 1 "s_register_operand" "")
823 (match_operand:DF 2 "arm_float_add_operand" "")))]
824 "TARGET_ARM && TARGET_HARD_FLOAT"
827 && !cirrus_fp_register (operands[2], DFmode))
828 operands[2] = force_reg (DFmode, operands[2]);
831 (define_expand "subdi3"
833 [(set (match_operand:DI 0 "s_register_operand" "")
834 (minus:DI (match_operand:DI 1 "s_register_operand" "")
835 (match_operand:DI 2 "s_register_operand" "")))
836 (clobber (reg:CC CC_REGNUM))])]
839 if (TARGET_HARD_FLOAT && TARGET_MAVERICK
841 && cirrus_fp_register (operands[0], DImode)
842 && cirrus_fp_register (operands[1], DImode))
844 emit_insn (gen_cirrus_subdi3 (operands[0], operands[1], operands[2]));
850 if (GET_CODE (operands[1]) != REG)
851 operands[1] = force_reg (SImode, operands[1]);
852 if (GET_CODE (operands[2]) != REG)
853 operands[2] = force_reg (SImode, operands[2]);
858 (define_insn "*arm_subdi3"
859 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r,&r")
860 (minus:DI (match_operand:DI 1 "s_register_operand" "0,r,0")
861 (match_operand:DI 2 "s_register_operand" "r,0,0")))
862 (clobber (reg:CC CC_REGNUM))]
864 "subs\\t%Q0, %Q1, %Q2\;sbc\\t%R0, %R1, %R2"
865 [(set_attr "conds" "clob")
866 (set_attr "length" "8")]
869 (define_insn "*thumb_subdi3"
870 [(set (match_operand:DI 0 "register_operand" "=l")
871 (minus:DI (match_operand:DI 1 "register_operand" "0")
872 (match_operand:DI 2 "register_operand" "l")))
873 (clobber (reg:CC CC_REGNUM))]
875 "sub\\t%Q0, %Q0, %Q2\;sbc\\t%R0, %R0, %R2"
876 [(set_attr "length" "4")]
879 (define_insn "*subdi_di_zesidi"
880 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
881 (minus:DI (match_operand:DI 1 "s_register_operand" "?r,0")
883 (match_operand:SI 2 "s_register_operand" "r,r"))))
884 (clobber (reg:CC CC_REGNUM))]
886 "subs\\t%Q0, %Q1, %2\;sbc\\t%R0, %R1, #0"
887 [(set_attr "conds" "clob")
888 (set_attr "length" "8")]
891 (define_insn "*subdi_di_sesidi"
892 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
893 (minus:DI (match_operand:DI 1 "s_register_operand" "r,0")
895 (match_operand:SI 2 "s_register_operand" "r,r"))))
896 (clobber (reg:CC CC_REGNUM))]
898 "subs\\t%Q0, %Q1, %2\;sbc\\t%R0, %R1, %2, asr #31"
899 [(set_attr "conds" "clob")
900 (set_attr "length" "8")]
903 (define_insn "*subdi_zesidi_di"
904 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
905 (minus:DI (zero_extend:DI
906 (match_operand:SI 2 "s_register_operand" "r,r"))
907 (match_operand:DI 1 "s_register_operand" "?r,0")))
908 (clobber (reg:CC CC_REGNUM))]
910 "rsbs\\t%Q0, %Q1, %2\;rsc\\t%R0, %R1, #0"
911 [(set_attr "conds" "clob")
912 (set_attr "length" "8")]
915 (define_insn "*subdi_sesidi_di"
916 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
917 (minus:DI (sign_extend:DI
918 (match_operand:SI 2 "s_register_operand" "r,r"))
919 (match_operand:DI 1 "s_register_operand" "?r,0")))
920 (clobber (reg:CC CC_REGNUM))]
922 "rsbs\\t%Q0, %Q1, %2\;rsc\\t%R0, %R1, %2, asr #31"
923 [(set_attr "conds" "clob")
924 (set_attr "length" "8")]
927 (define_insn "*subdi_zesidi_zesidi"
928 [(set (match_operand:DI 0 "s_register_operand" "=r")
929 (minus:DI (zero_extend:DI
930 (match_operand:SI 1 "s_register_operand" "r"))
932 (match_operand:SI 2 "s_register_operand" "r"))))
933 (clobber (reg:CC CC_REGNUM))]
935 "subs\\t%Q0, %1, %2\;rsc\\t%R0, %1, %1"
936 [(set_attr "conds" "clob")
937 (set_attr "length" "8")]
940 (define_expand "subsi3"
941 [(set (match_operand:SI 0 "s_register_operand" "")
942 (minus:SI (match_operand:SI 1 "reg_or_int_operand" "")
943 (match_operand:SI 2 "s_register_operand" "")))]
946 if (GET_CODE (operands[1]) == CONST_INT)
950 arm_split_constant (MINUS, SImode, NULL_RTX,
951 INTVAL (operands[1]), operands[0],
952 operands[2], optimize && !no_new_pseudos);
955 else /* TARGET_THUMB */
956 operands[1] = force_reg (SImode, operands[1]);
961 (define_insn "*thumb_subsi3_insn"
962 [(set (match_operand:SI 0 "register_operand" "=l")
963 (minus:SI (match_operand:SI 1 "register_operand" "l")
964 (match_operand:SI 2 "register_operand" "l")))]
967 [(set_attr "length" "2")]
970 (define_insn_and_split "*arm_subsi3_insn"
971 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
972 (minus:SI (match_operand:SI 1 "reg_or_int_operand" "rI,?n")
973 (match_operand:SI 2 "s_register_operand" "r,r")))]
979 && GET_CODE (operands[1]) == CONST_INT
980 && !const_ok_for_arm (INTVAL (operands[1]))"
981 [(clobber (const_int 0))]
983 arm_split_constant (MINUS, SImode, curr_insn,
984 INTVAL (operands[1]), operands[0], operands[2], 0);
987 [(set_attr "length" "4,16")
988 (set_attr "predicable" "yes")]
992 [(match_scratch:SI 3 "r")
993 (set (match_operand:SI 0 "arm_general_register_operand" "")
994 (minus:SI (match_operand:SI 1 "const_int_operand" "")
995 (match_operand:SI 2 "arm_general_register_operand" "")))]
997 && !const_ok_for_arm (INTVAL (operands[1]))
998 && const_ok_for_arm (~INTVAL (operands[1]))"
999 [(set (match_dup 3) (match_dup 1))
1000 (set (match_dup 0) (minus:SI (match_dup 3) (match_dup 2)))]
1004 (define_insn "*subsi3_compare0"
1005 [(set (reg:CC_NOOV CC_REGNUM)
1007 (minus:SI (match_operand:SI 1 "arm_rhs_operand" "r,I")
1008 (match_operand:SI 2 "arm_rhs_operand" "rI,r"))
1010 (set (match_operand:SI 0 "s_register_operand" "=r,r")
1011 (minus:SI (match_dup 1) (match_dup 2)))]
1015 rsb%?s\\t%0, %2, %1"
1016 [(set_attr "conds" "set")]
1019 (define_insn "decscc"
1020 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
1021 (minus:SI (match_operand:SI 1 "s_register_operand" "0,?r")
1022 (match_operator:SI 2 "arm_comparison_operator"
1023 [(match_operand 3 "cc_register" "") (const_int 0)])))]
1027 mov%D2\\t%0, %1\;sub%d2\\t%0, %1, #1"
1028 [(set_attr "conds" "use")
1029 (set_attr "length" "*,8")]
1032 (define_expand "subsf3"
1033 [(set (match_operand:SF 0 "s_register_operand" "")
1034 (minus:SF (match_operand:SF 1 "arm_float_rhs_operand" "")
1035 (match_operand:SF 2 "arm_float_rhs_operand" "")))]
1036 "TARGET_ARM && TARGET_HARD_FLOAT"
1038 if (TARGET_MAVERICK)
1040 if (!cirrus_fp_register (operands[1], SFmode))
1041 operands[1] = force_reg (SFmode, operands[1]);
1042 if (!cirrus_fp_register (operands[2], SFmode))
1043 operands[2] = force_reg (SFmode, operands[2]);
1047 (define_expand "subdf3"
1048 [(set (match_operand:DF 0 "s_register_operand" "")
1049 (minus:DF (match_operand:DF 1 "arm_float_rhs_operand" "")
1050 (match_operand:DF 2 "arm_float_rhs_operand" "")))]
1051 "TARGET_ARM && TARGET_HARD_FLOAT"
1053 if (TARGET_MAVERICK)
1055 if (!cirrus_fp_register (operands[1], DFmode))
1056 operands[1] = force_reg (DFmode, operands[1]);
1057 if (!cirrus_fp_register (operands[2], DFmode))
1058 operands[2] = force_reg (DFmode, operands[2]);
1063 ;; Multiplication insns
1065 (define_expand "mulsi3"
1066 [(set (match_operand:SI 0 "s_register_operand" "")
1067 (mult:SI (match_operand:SI 2 "s_register_operand" "")
1068 (match_operand:SI 1 "s_register_operand" "")))]
1073 ;; Use `&' and then `0' to prevent the operands 0 and 1 being the same
1074 (define_insn "*arm_mulsi3"
1075 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r")
1076 (mult:SI (match_operand:SI 2 "s_register_operand" "r,r")
1077 (match_operand:SI 1 "s_register_operand" "%?r,0")))]
1079 "mul%?\\t%0, %2, %1"
1080 [(set_attr "insn" "mul")
1081 (set_attr "predicable" "yes")]
1084 ; Unfortunately with the Thumb the '&'/'0' trick can fails when operands
1085 ; 1 and 2; are the same, because reload will make operand 0 match
1086 ; operand 1 without realizing that this conflicts with operand 2. We fix
1087 ; this by adding another alternative to match this case, and then `reload'
1088 ; it ourselves. This alternative must come first.
1089 (define_insn "*thumb_mulsi3"
1090 [(set (match_operand:SI 0 "register_operand" "=&l,&l,&l")
1091 (mult:SI (match_operand:SI 1 "register_operand" "%l,*h,0")
1092 (match_operand:SI 2 "register_operand" "l,l,l")))]
1095 if (which_alternative < 2)
1096 return \"mov\\t%0, %1\;mul\\t%0, %2\";
1098 return \"mul\\t%0, %2\";
1100 [(set_attr "length" "4,4,2")
1101 (set_attr "insn" "mul")]
1104 (define_insn "*mulsi3_compare0"
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 (set (match_operand:SI 0 "s_register_operand" "=&r,&r")
1111 (mult:SI (match_dup 2) (match_dup 1)))]
1113 "mul%?s\\t%0, %2, %1"
1114 [(set_attr "conds" "set")
1115 (set_attr "insn" "muls")]
1118 (define_insn "*mulsi_compare0_scratch"
1119 [(set (reg:CC_NOOV CC_REGNUM)
1120 (compare:CC_NOOV (mult:SI
1121 (match_operand:SI 2 "s_register_operand" "r,r")
1122 (match_operand:SI 1 "s_register_operand" "%?r,0"))
1124 (clobber (match_scratch:SI 0 "=&r,&r"))]
1126 "mul%?s\\t%0, %2, %1"
1127 [(set_attr "conds" "set")
1128 (set_attr "insn" "muls")]
1131 ;; Unnamed templates to match MLA instruction.
1133 (define_insn "*mulsi3addsi"
1134 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r,&r")
1136 (mult:SI (match_operand:SI 2 "s_register_operand" "r,r,r,r")
1137 (match_operand:SI 1 "s_register_operand" "%r,0,r,0"))
1138 (match_operand:SI 3 "s_register_operand" "?r,r,0,0")))]
1140 "mla%?\\t%0, %2, %1, %3"
1141 [(set_attr "insn" "mla")
1142 (set_attr "predicable" "yes")]
1145 (define_insn "*mulsi3addsi_compare0"
1146 [(set (reg:CC_NOOV CC_REGNUM)
1149 (match_operand:SI 2 "s_register_operand" "r,r,r,r")
1150 (match_operand:SI 1 "s_register_operand" "%r,0,r,0"))
1151 (match_operand:SI 3 "s_register_operand" "?r,r,0,0"))
1153 (set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r,&r")
1154 (plus:SI (mult:SI (match_dup 2) (match_dup 1))
1157 "mla%?s\\t%0, %2, %1, %3"
1158 [(set_attr "conds" "set")
1159 (set_attr "insn" "mlas")]
1162 (define_insn "*mulsi3addsi_compare0_scratch"
1163 [(set (reg:CC_NOOV CC_REGNUM)
1166 (match_operand:SI 2 "s_register_operand" "r,r,r,r")
1167 (match_operand:SI 1 "s_register_operand" "%r,0,r,0"))
1168 (match_operand:SI 3 "s_register_operand" "?r,r,0,0"))
1170 (clobber (match_scratch:SI 0 "=&r,&r,&r,&r"))]
1172 "mla%?s\\t%0, %2, %1, %3"
1173 [(set_attr "conds" "set")
1174 (set_attr "insn" "mlas")]
1177 ;; Unnamed template to match long long multiply-accumulate (smlal)
1179 (define_insn "*mulsidi3adddi"
1180 [(set (match_operand:DI 0 "s_register_operand" "=&r")
1183 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "%r"))
1184 (sign_extend:DI (match_operand:SI 3 "s_register_operand" "r")))
1185 (match_operand:DI 1 "s_register_operand" "0")))]
1186 "TARGET_ARM && arm_arch3m"
1187 "smlal%?\\t%Q0, %R0, %3, %2"
1188 [(set_attr "insn" "smlal")
1189 (set_attr "predicable" "yes")]
1192 (define_insn "mulsidi3"
1193 [(set (match_operand:DI 0 "s_register_operand" "=&r")
1195 (sign_extend:DI (match_operand:SI 1 "s_register_operand" "%r"))
1196 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))]
1197 "TARGET_ARM && arm_arch3m"
1198 "smull%?\\t%Q0, %R0, %1, %2"
1199 [(set_attr "insn" "smull")
1200 (set_attr "predicable" "yes")]
1203 (define_insn "umulsidi3"
1204 [(set (match_operand:DI 0 "s_register_operand" "=&r")
1206 (zero_extend:DI (match_operand:SI 1 "s_register_operand" "%r"))
1207 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))]
1208 "TARGET_ARM && arm_arch3m"
1209 "umull%?\\t%Q0, %R0, %1, %2"
1210 [(set_attr "insn" "umull")
1211 (set_attr "predicable" "yes")]
1214 ;; Unnamed template to match long long unsigned multiply-accumulate (umlal)
1216 (define_insn "*umulsidi3adddi"
1217 [(set (match_operand:DI 0 "s_register_operand" "=&r")
1220 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "%r"))
1221 (zero_extend:DI (match_operand:SI 3 "s_register_operand" "r")))
1222 (match_operand:DI 1 "s_register_operand" "0")))]
1223 "TARGET_ARM && arm_arch3m"
1224 "umlal%?\\t%Q0, %R0, %3, %2"
1225 [(set_attr "insn" "umlal")
1226 (set_attr "predicable" "yes")]
1229 (define_insn "smulsi3_highpart"
1230 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r")
1234 (sign_extend:DI (match_operand:SI 1 "s_register_operand" "%r,0"))
1235 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r,r")))
1237 (clobber (match_scratch:SI 3 "=&r,&r"))]
1238 "TARGET_ARM && arm_arch3m"
1239 "smull%?\\t%3, %0, %2, %1"
1240 [(set_attr "insn" "smull")
1241 (set_attr "predicable" "yes")]
1244 (define_insn "umulsi3_highpart"
1245 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r")
1249 (zero_extend:DI (match_operand:SI 1 "s_register_operand" "%r,0"))
1250 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r,r")))
1252 (clobber (match_scratch:SI 3 "=&r,&r"))]
1253 "TARGET_ARM && arm_arch3m"
1254 "umull%?\\t%3, %0, %2, %1"
1255 [(set_attr "insn" "umull")
1256 (set_attr "predicable" "yes")]
1259 (define_insn "mulhisi3"
1260 [(set (match_operand:SI 0 "s_register_operand" "=r")
1261 (mult:SI (sign_extend:SI
1262 (match_operand:HI 1 "s_register_operand" "%r"))
1264 (match_operand:HI 2 "s_register_operand" "r"))))]
1265 "TARGET_ARM && arm_arch5e"
1266 "smulbb%?\\t%0, %1, %2"
1267 [(set_attr "insn" "smulxy")
1268 (set_attr "predicable" "yes")]
1271 (define_insn "*mulhisi3tb"
1272 [(set (match_operand:SI 0 "s_register_operand" "=r")
1273 (mult:SI (ashiftrt:SI
1274 (match_operand:SI 1 "s_register_operand" "r")
1277 (match_operand:HI 2 "s_register_operand" "r"))))]
1278 "TARGET_ARM && arm_arch5e"
1279 "smultb%?\\t%0, %1, %2"
1280 [(set_attr "insn" "smulxy")
1281 (set_attr "predicable" "yes")]
1284 (define_insn "*mulhisi3bt"
1285 [(set (match_operand:SI 0 "s_register_operand" "=r")
1286 (mult:SI (sign_extend:SI
1287 (match_operand:HI 1 "s_register_operand" "r"))
1289 (match_operand:SI 2 "s_register_operand" "r")
1291 "TARGET_ARM && arm_arch5e"
1292 "smulbt%?\\t%0, %1, %2"
1293 [(set_attr "insn" "smulxy")
1294 (set_attr "predicable" "yes")]
1297 (define_insn "*mulhisi3tt"
1298 [(set (match_operand:SI 0 "s_register_operand" "=r")
1299 (mult:SI (ashiftrt:SI
1300 (match_operand:SI 1 "s_register_operand" "r")
1303 (match_operand:SI 2 "s_register_operand" "r")
1305 "TARGET_ARM && arm_arch5e"
1306 "smultt%?\\t%0, %1, %2"
1307 [(set_attr "insn" "smulxy")
1308 (set_attr "predicable" "yes")]
1311 (define_insn "*mulhisi3addsi"
1312 [(set (match_operand:SI 0 "s_register_operand" "=r")
1313 (plus:SI (match_operand:SI 1 "s_register_operand" "r")
1314 (mult:SI (sign_extend:SI
1315 (match_operand:HI 2 "s_register_operand" "%r"))
1317 (match_operand:HI 3 "s_register_operand" "r")))))]
1318 "TARGET_ARM && arm_arch5e"
1319 "smlabb%?\\t%0, %2, %3, %1"
1320 [(set_attr "insn" "smlaxy")
1321 (set_attr "predicable" "yes")]
1324 (define_insn "*mulhidi3adddi"
1325 [(set (match_operand:DI 0 "s_register_operand" "=r")
1327 (match_operand:DI 1 "s_register_operand" "0")
1328 (mult:DI (sign_extend:DI
1329 (match_operand:HI 2 "s_register_operand" "%r"))
1331 (match_operand:HI 3 "s_register_operand" "r")))))]
1332 "TARGET_ARM && arm_arch5e"
1333 "smlalbb%?\\t%Q0, %R0, %2, %3"
1334 [(set_attr "insn" "smlalxy")
1335 (set_attr "predicable" "yes")])
1337 (define_expand "mulsf3"
1338 [(set (match_operand:SF 0 "s_register_operand" "")
1339 (mult:SF (match_operand:SF 1 "s_register_operand" "")
1340 (match_operand:SF 2 "arm_float_rhs_operand" "")))]
1341 "TARGET_ARM && TARGET_HARD_FLOAT"
1344 && !cirrus_fp_register (operands[2], SFmode))
1345 operands[2] = force_reg (SFmode, operands[2]);
1348 (define_expand "muldf3"
1349 [(set (match_operand:DF 0 "s_register_operand" "")
1350 (mult:DF (match_operand:DF 1 "s_register_operand" "")
1351 (match_operand:DF 2 "arm_float_rhs_operand" "")))]
1352 "TARGET_ARM && TARGET_HARD_FLOAT"
1355 && !cirrus_fp_register (operands[2], DFmode))
1356 operands[2] = force_reg (DFmode, operands[2]);
1361 (define_expand "divsf3"
1362 [(set (match_operand:SF 0 "s_register_operand" "")
1363 (div:SF (match_operand:SF 1 "arm_float_rhs_operand" "")
1364 (match_operand:SF 2 "arm_float_rhs_operand" "")))]
1365 "TARGET_ARM && TARGET_HARD_FLOAT && (TARGET_FPA || TARGET_VFP)"
1368 (define_expand "divdf3"
1369 [(set (match_operand:DF 0 "s_register_operand" "")
1370 (div:DF (match_operand:DF 1 "arm_float_rhs_operand" "")
1371 (match_operand:DF 2 "arm_float_rhs_operand" "")))]
1372 "TARGET_ARM && TARGET_HARD_FLOAT && (TARGET_FPA || TARGET_VFP)"
1377 (define_expand "modsf3"
1378 [(set (match_operand:SF 0 "s_register_operand" "")
1379 (mod:SF (match_operand:SF 1 "s_register_operand" "")
1380 (match_operand:SF 2 "arm_float_rhs_operand" "")))]
1381 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
1384 (define_expand "moddf3"
1385 [(set (match_operand:DF 0 "s_register_operand" "")
1386 (mod:DF (match_operand:DF 1 "s_register_operand" "")
1387 (match_operand:DF 2 "arm_float_rhs_operand" "")))]
1388 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
1391 ;; Boolean and,ior,xor insns
1393 ;; Split up double word logical operations
1395 ;; Split up simple DImode logical operations. Simply perform the logical
1396 ;; operation on the upper and lower halves of the registers.
1398 [(set (match_operand:DI 0 "s_register_operand" "")
1399 (match_operator:DI 6 "logical_binary_operator"
1400 [(match_operand:DI 1 "s_register_operand" "")
1401 (match_operand:DI 2 "s_register_operand" "")]))]
1402 "TARGET_ARM && reload_completed && ! IS_IWMMXT_REGNUM (REGNO (operands[0]))"
1403 [(set (match_dup 0) (match_op_dup:SI 6 [(match_dup 1) (match_dup 2)]))
1404 (set (match_dup 3) (match_op_dup:SI 6 [(match_dup 4) (match_dup 5)]))]
1407 operands[3] = gen_highpart (SImode, operands[0]);
1408 operands[0] = gen_lowpart (SImode, operands[0]);
1409 operands[4] = gen_highpart (SImode, operands[1]);
1410 operands[1] = gen_lowpart (SImode, operands[1]);
1411 operands[5] = gen_highpart (SImode, operands[2]);
1412 operands[2] = gen_lowpart (SImode, operands[2]);
1417 [(set (match_operand:DI 0 "s_register_operand" "")
1418 (match_operator:DI 6 "logical_binary_operator"
1419 [(sign_extend:DI (match_operand:SI 2 "s_register_operand" ""))
1420 (match_operand:DI 1 "s_register_operand" "")]))]
1421 "TARGET_ARM && reload_completed"
1422 [(set (match_dup 0) (match_op_dup:SI 6 [(match_dup 1) (match_dup 2)]))
1423 (set (match_dup 3) (match_op_dup:SI 6
1424 [(ashiftrt:SI (match_dup 2) (const_int 31))
1428 operands[3] = gen_highpart (SImode, operands[0]);
1429 operands[0] = gen_lowpart (SImode, operands[0]);
1430 operands[4] = gen_highpart (SImode, operands[1]);
1431 operands[1] = gen_lowpart (SImode, operands[1]);
1432 operands[5] = gen_highpart (SImode, operands[2]);
1433 operands[2] = gen_lowpart (SImode, operands[2]);
1437 ;; The zero extend of operand 2 means we can just copy the high part of
1438 ;; operand1 into operand0.
1440 [(set (match_operand:DI 0 "s_register_operand" "")
1442 (zero_extend:DI (match_operand:SI 2 "s_register_operand" ""))
1443 (match_operand:DI 1 "s_register_operand" "")))]
1444 "TARGET_ARM && operands[0] != operands[1] && reload_completed"
1445 [(set (match_dup 0) (ior:SI (match_dup 1) (match_dup 2)))
1446 (set (match_dup 3) (match_dup 4))]
1449 operands[4] = gen_highpart (SImode, operands[1]);
1450 operands[3] = gen_highpart (SImode, operands[0]);
1451 operands[0] = gen_lowpart (SImode, operands[0]);
1452 operands[1] = gen_lowpart (SImode, operands[1]);
1456 ;; The zero extend of operand 2 means we can just copy the high part of
1457 ;; operand1 into operand0.
1459 [(set (match_operand:DI 0 "s_register_operand" "")
1461 (zero_extend:DI (match_operand:SI 2 "s_register_operand" ""))
1462 (match_operand:DI 1 "s_register_operand" "")))]
1463 "TARGET_ARM && operands[0] != operands[1] && reload_completed"
1464 [(set (match_dup 0) (xor:SI (match_dup 1) (match_dup 2)))
1465 (set (match_dup 3) (match_dup 4))]
1468 operands[4] = gen_highpart (SImode, operands[1]);
1469 operands[3] = gen_highpart (SImode, operands[0]);
1470 operands[0] = gen_lowpart (SImode, operands[0]);
1471 operands[1] = gen_lowpart (SImode, operands[1]);
1475 (define_insn "anddi3"
1476 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1477 (and:DI (match_operand:DI 1 "s_register_operand" "%0,r")
1478 (match_operand:DI 2 "s_register_operand" "r,r")))]
1479 "TARGET_ARM && ! TARGET_IWMMXT"
1481 [(set_attr "length" "8")]
1484 (define_insn_and_split "*anddi_zesidi_di"
1485 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1486 (and:DI (zero_extend:DI
1487 (match_operand:SI 2 "s_register_operand" "r,r"))
1488 (match_operand:DI 1 "s_register_operand" "?r,0")))]
1491 "TARGET_ARM && reload_completed"
1492 ; The zero extend of operand 2 clears the high word of the output
1494 [(set (match_dup 0) (and:SI (match_dup 1) (match_dup 2)))
1495 (set (match_dup 3) (const_int 0))]
1498 operands[3] = gen_highpart (SImode, operands[0]);
1499 operands[0] = gen_lowpart (SImode, operands[0]);
1500 operands[1] = gen_lowpart (SImode, operands[1]);
1502 [(set_attr "length" "8")]
1505 (define_insn "*anddi_sesdi_di"
1506 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1507 (and:DI (sign_extend:DI
1508 (match_operand:SI 2 "s_register_operand" "r,r"))
1509 (match_operand:DI 1 "s_register_operand" "?r,0")))]
1512 [(set_attr "length" "8")]
1515 (define_expand "andsi3"
1516 [(set (match_operand:SI 0 "s_register_operand" "")
1517 (and:SI (match_operand:SI 1 "s_register_operand" "")
1518 (match_operand:SI 2 "reg_or_int_operand" "")))]
1523 if (GET_CODE (operands[2]) == CONST_INT)
1525 arm_split_constant (AND, SImode, NULL_RTX,
1526 INTVAL (operands[2]), operands[0],
1527 operands[1], optimize && !no_new_pseudos);
1532 else /* TARGET_THUMB */
1534 if (GET_CODE (operands[2]) != CONST_INT)
1535 operands[2] = force_reg (SImode, operands[2]);
1540 if (((unsigned HOST_WIDE_INT) ~INTVAL (operands[2])) < 256)
1542 operands[2] = force_reg (SImode,
1543 GEN_INT (~INTVAL (operands[2])));
1545 emit_insn (gen_bicsi3 (operands[0], operands[2], operands[1]));
1550 for (i = 9; i <= 31; i++)
1552 if ((((HOST_WIDE_INT) 1) << i) - 1 == INTVAL (operands[2]))
1554 emit_insn (gen_extzv (operands[0], operands[1], GEN_INT (i),
1558 else if ((((HOST_WIDE_INT) 1) << i) - 1
1559 == ~INTVAL (operands[2]))
1561 rtx shift = GEN_INT (i);
1562 rtx reg = gen_reg_rtx (SImode);
1564 emit_insn (gen_lshrsi3 (reg, operands[1], shift));
1565 emit_insn (gen_ashlsi3 (operands[0], reg, shift));
1571 operands[2] = force_reg (SImode, operands[2]);
1577 (define_insn_and_split "*arm_andsi3_insn"
1578 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
1579 (and:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
1580 (match_operand:SI 2 "reg_or_int_operand" "rI,K,?n")))]
1584 bic%?\\t%0, %1, #%B2
1587 && GET_CODE (operands[2]) == CONST_INT
1588 && !(const_ok_for_arm (INTVAL (operands[2]))
1589 || const_ok_for_arm (~INTVAL (operands[2])))"
1590 [(clobber (const_int 0))]
1592 arm_split_constant (AND, SImode, curr_insn,
1593 INTVAL (operands[2]), operands[0], operands[1], 0);
1596 [(set_attr "length" "4,4,16")
1597 (set_attr "predicable" "yes")]
1600 (define_insn "*thumb_andsi3_insn"
1601 [(set (match_operand:SI 0 "register_operand" "=l")
1602 (and:SI (match_operand:SI 1 "register_operand" "%0")
1603 (match_operand:SI 2 "register_operand" "l")))]
1606 [(set_attr "length" "2")]
1609 (define_insn "*andsi3_compare0"
1610 [(set (reg:CC_NOOV CC_REGNUM)
1612 (and:SI (match_operand:SI 1 "s_register_operand" "r,r")
1613 (match_operand:SI 2 "arm_not_operand" "rI,K"))
1615 (set (match_operand:SI 0 "s_register_operand" "=r,r")
1616 (and:SI (match_dup 1) (match_dup 2)))]
1620 bic%?s\\t%0, %1, #%B2"
1621 [(set_attr "conds" "set")]
1624 (define_insn "*andsi3_compare0_scratch"
1625 [(set (reg:CC_NOOV CC_REGNUM)
1627 (and:SI (match_operand:SI 0 "s_register_operand" "r,r")
1628 (match_operand:SI 1 "arm_not_operand" "rI,K"))
1630 (clobber (match_scratch:SI 2 "=X,r"))]
1634 bic%?s\\t%2, %0, #%B1"
1635 [(set_attr "conds" "set")]
1638 (define_insn "*zeroextractsi_compare0_scratch"
1639 [(set (reg:CC_NOOV CC_REGNUM)
1640 (compare:CC_NOOV (zero_extract:SI
1641 (match_operand:SI 0 "s_register_operand" "r")
1642 (match_operand 1 "const_int_operand" "n")
1643 (match_operand 2 "const_int_operand" "n"))
1646 && (INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) < 32
1647 && INTVAL (operands[1]) > 0
1648 && INTVAL (operands[1]) + (INTVAL (operands[2]) & 1) <= 8
1649 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32)"
1651 operands[1] = GEN_INT (((1 << INTVAL (operands[1])) - 1)
1652 << INTVAL (operands[2]));
1653 output_asm_insn (\"tst%?\\t%0, %1\", operands);
1656 [(set_attr "conds" "set")]
1659 (define_insn_and_split "*ne_zeroextractsi"
1660 [(set (match_operand:SI 0 "s_register_operand" "=r")
1661 (ne:SI (zero_extract:SI
1662 (match_operand:SI 1 "s_register_operand" "r")
1663 (match_operand:SI 2 "const_int_operand" "n")
1664 (match_operand:SI 3 "const_int_operand" "n"))
1666 (clobber (reg:CC CC_REGNUM))]
1668 && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
1669 && INTVAL (operands[2]) > 0
1670 && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
1671 && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)"
1674 && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
1675 && INTVAL (operands[2]) > 0
1676 && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
1677 && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)"
1678 [(parallel [(set (reg:CC_NOOV CC_REGNUM)
1679 (compare:CC_NOOV (and:SI (match_dup 1) (match_dup 2))
1681 (set (match_dup 0) (and:SI (match_dup 1) (match_dup 2)))])
1683 (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
1684 (match_dup 0) (const_int 1)))]
1686 operands[2] = GEN_INT (((1 << INTVAL (operands[2])) - 1)
1687 << INTVAL (operands[3]));
1689 [(set_attr "conds" "clob")
1690 (set_attr "length" "8")]
1693 (define_insn_and_split "*ne_zeroextractsi_shifted"
1694 [(set (match_operand:SI 0 "s_register_operand" "=r")
1695 (ne:SI (zero_extract:SI
1696 (match_operand:SI 1 "s_register_operand" "r")
1697 (match_operand:SI 2 "const_int_operand" "n")
1700 (clobber (reg:CC CC_REGNUM))]
1704 [(parallel [(set (reg:CC_NOOV CC_REGNUM)
1705 (compare:CC_NOOV (ashift:SI (match_dup 1) (match_dup 2))
1707 (set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 2)))])
1709 (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
1710 (match_dup 0) (const_int 1)))]
1712 operands[2] = GEN_INT (32 - INTVAL (operands[2]));
1714 [(set_attr "conds" "clob")
1715 (set_attr "length" "8")]
1718 (define_insn_and_split "*ite_ne_zeroextractsi"
1719 [(set (match_operand:SI 0 "s_register_operand" "=r")
1720 (if_then_else:SI (ne (zero_extract:SI
1721 (match_operand:SI 1 "s_register_operand" "r")
1722 (match_operand:SI 2 "const_int_operand" "n")
1723 (match_operand:SI 3 "const_int_operand" "n"))
1725 (match_operand:SI 4 "arm_not_operand" "rIK")
1727 (clobber (reg:CC CC_REGNUM))]
1729 && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
1730 && INTVAL (operands[2]) > 0
1731 && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
1732 && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)
1733 && !reg_overlap_mentioned_p (operands[0], operands[4])"
1736 && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
1737 && INTVAL (operands[2]) > 0
1738 && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
1739 && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)
1740 && !reg_overlap_mentioned_p (operands[0], operands[4])"
1741 [(parallel [(set (reg:CC_NOOV CC_REGNUM)
1742 (compare:CC_NOOV (and:SI (match_dup 1) (match_dup 2))
1744 (set (match_dup 0) (and:SI (match_dup 1) (match_dup 2)))])
1746 (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
1747 (match_dup 0) (match_dup 4)))]
1749 operands[2] = GEN_INT (((1 << INTVAL (operands[2])) - 1)
1750 << INTVAL (operands[3]));
1752 [(set_attr "conds" "clob")
1753 (set_attr "length" "8")]
1756 (define_insn_and_split "*ite_ne_zeroextractsi_shifted"
1757 [(set (match_operand:SI 0 "s_register_operand" "=r")
1758 (if_then_else:SI (ne (zero_extract:SI
1759 (match_operand:SI 1 "s_register_operand" "r")
1760 (match_operand:SI 2 "const_int_operand" "n")
1763 (match_operand:SI 3 "arm_not_operand" "rIK")
1765 (clobber (reg:CC CC_REGNUM))]
1766 "TARGET_ARM && !reg_overlap_mentioned_p (operands[0], operands[3])"
1768 "TARGET_ARM && !reg_overlap_mentioned_p (operands[0], operands[3])"
1769 [(parallel [(set (reg:CC_NOOV CC_REGNUM)
1770 (compare:CC_NOOV (ashift:SI (match_dup 1) (match_dup 2))
1772 (set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 2)))])
1774 (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
1775 (match_dup 0) (match_dup 3)))]
1777 operands[2] = GEN_INT (32 - INTVAL (operands[2]));
1779 [(set_attr "conds" "clob")
1780 (set_attr "length" "8")]
1784 [(set (match_operand:SI 0 "s_register_operand" "")
1785 (zero_extract:SI (match_operand:SI 1 "s_register_operand" "")
1786 (match_operand:SI 2 "const_int_operand" "")
1787 (match_operand:SI 3 "const_int_operand" "")))
1788 (clobber (match_operand:SI 4 "s_register_operand" ""))]
1790 [(set (match_dup 4) (ashift:SI (match_dup 1) (match_dup 2)))
1791 (set (match_dup 0) (lshiftrt:SI (match_dup 4) (match_dup 3)))]
1793 HOST_WIDE_INT temp = INTVAL (operands[2]);
1795 operands[2] = GEN_INT (32 - temp - INTVAL (operands[3]));
1796 operands[3] = GEN_INT (32 - temp);
1801 [(set (match_operand:SI 0 "s_register_operand" "")
1802 (match_operator:SI 1 "shiftable_operator"
1803 [(zero_extract:SI (match_operand:SI 2 "s_register_operand" "")
1804 (match_operand:SI 3 "const_int_operand" "")
1805 (match_operand:SI 4 "const_int_operand" ""))
1806 (match_operand:SI 5 "s_register_operand" "")]))
1807 (clobber (match_operand:SI 6 "s_register_operand" ""))]
1809 [(set (match_dup 6) (ashift:SI (match_dup 2) (match_dup 3)))
1812 [(lshiftrt:SI (match_dup 6) (match_dup 4))
1815 HOST_WIDE_INT temp = INTVAL (operands[3]);
1817 operands[3] = GEN_INT (32 - temp - INTVAL (operands[4]));
1818 operands[4] = GEN_INT (32 - temp);
1823 [(set (match_operand:SI 0 "s_register_operand" "")
1824 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "")
1825 (match_operand:SI 2 "const_int_operand" "")
1826 (match_operand:SI 3 "const_int_operand" "")))]
1828 [(set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 2)))
1829 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (match_dup 3)))]
1831 HOST_WIDE_INT temp = INTVAL (operands[2]);
1833 operands[2] = GEN_INT (32 - temp - INTVAL (operands[3]));
1834 operands[3] = GEN_INT (32 - temp);
1839 [(set (match_operand:SI 0 "s_register_operand" "")
1840 (match_operator:SI 1 "shiftable_operator"
1841 [(sign_extract:SI (match_operand:SI 2 "s_register_operand" "")
1842 (match_operand:SI 3 "const_int_operand" "")
1843 (match_operand:SI 4 "const_int_operand" ""))
1844 (match_operand:SI 5 "s_register_operand" "")]))
1845 (clobber (match_operand:SI 6 "s_register_operand" ""))]
1847 [(set (match_dup 6) (ashift:SI (match_dup 2) (match_dup 3)))
1850 [(ashiftrt:SI (match_dup 6) (match_dup 4))
1853 HOST_WIDE_INT temp = INTVAL (operands[3]);
1855 operands[3] = GEN_INT (32 - temp - INTVAL (operands[4]));
1856 operands[4] = GEN_INT (32 - temp);
1860 ;;; ??? This pattern is bogus. If operand3 has bits outside the range
1861 ;;; represented by the bitfield, then this will produce incorrect results.
1862 ;;; Somewhere, the value needs to be truncated. On targets like the m68k,
1863 ;;; which have a real bit-field insert instruction, the truncation happens
1864 ;;; in the bit-field insert instruction itself. Since arm does not have a
1865 ;;; bit-field insert instruction, we would have to emit code here to truncate
1866 ;;; the value before we insert. This loses some of the advantage of having
1867 ;;; this insv pattern, so this pattern needs to be reevalutated.
1869 (define_expand "insv"
1870 [(set (zero_extract:SI (match_operand:SI 0 "s_register_operand" "")
1871 (match_operand:SI 1 "general_operand" "")
1872 (match_operand:SI 2 "general_operand" ""))
1873 (match_operand:SI 3 "reg_or_int_operand" ""))]
1877 int start_bit = INTVAL (operands[2]);
1878 int width = INTVAL (operands[1]);
1879 HOST_WIDE_INT mask = (((HOST_WIDE_INT)1) << width) - 1;
1880 rtx target, subtarget;
1882 target = operands[0];
1883 /* Avoid using a subreg as a subtarget, and avoid writing a paradoxical
1884 subreg as the final target. */
1885 if (GET_CODE (target) == SUBREG)
1887 subtarget = gen_reg_rtx (SImode);
1888 if (GET_MODE_SIZE (GET_MODE (SUBREG_REG (target)))
1889 < GET_MODE_SIZE (SImode))
1890 target = SUBREG_REG (target);
1895 if (GET_CODE (operands[3]) == CONST_INT)
1897 /* Since we are inserting a known constant, we may be able to
1898 reduce the number of bits that we have to clear so that
1899 the mask becomes simple. */
1900 /* ??? This code does not check to see if the new mask is actually
1901 simpler. It may not be. */
1902 rtx op1 = gen_reg_rtx (SImode);
1903 /* ??? Truncate operand3 to fit in the bitfield. See comment before
1904 start of this pattern. */
1905 HOST_WIDE_INT op3_value = mask & INTVAL (operands[3]);
1906 HOST_WIDE_INT mask2 = ((mask & ~op3_value) << start_bit);
1908 emit_insn (gen_andsi3 (op1, operands[0],
1909 gen_int_mode (~mask2, SImode)));
1910 emit_insn (gen_iorsi3 (subtarget, op1,
1911 gen_int_mode (op3_value << start_bit, SImode)));
1913 else if (start_bit == 0
1914 && !(const_ok_for_arm (mask)
1915 || const_ok_for_arm (~mask)))
1917 /* A Trick, since we are setting the bottom bits in the word,
1918 we can shift operand[3] up, operand[0] down, OR them together
1919 and rotate the result back again. This takes 3 insns, and
1920 the third might be mergeable into another op. */
1921 /* The shift up copes with the possibility that operand[3] is
1922 wider than the bitfield. */
1923 rtx op0 = gen_reg_rtx (SImode);
1924 rtx op1 = gen_reg_rtx (SImode);
1926 emit_insn (gen_ashlsi3 (op0, operands[3], GEN_INT (32 - width)));
1927 emit_insn (gen_lshrsi3 (op1, operands[0], operands[1]));
1928 emit_insn (gen_iorsi3 (op1, op1, op0));
1929 emit_insn (gen_rotlsi3 (subtarget, op1, operands[1]));
1931 else if ((width + start_bit == 32)
1932 && !(const_ok_for_arm (mask)
1933 || const_ok_for_arm (~mask)))
1935 /* Similar trick, but slightly less efficient. */
1937 rtx op0 = gen_reg_rtx (SImode);
1938 rtx op1 = gen_reg_rtx (SImode);
1940 emit_insn (gen_ashlsi3 (op0, operands[3], GEN_INT (32 - width)));
1941 emit_insn (gen_ashlsi3 (op1, operands[0], operands[1]));
1942 emit_insn (gen_lshrsi3 (op1, op1, operands[1]));
1943 emit_insn (gen_iorsi3 (subtarget, op1, op0));
1947 rtx op0 = gen_int_mode (mask, SImode);
1948 rtx op1 = gen_reg_rtx (SImode);
1949 rtx op2 = gen_reg_rtx (SImode);
1951 if (!(const_ok_for_arm (mask) || const_ok_for_arm (~mask)))
1953 rtx tmp = gen_reg_rtx (SImode);
1955 emit_insn (gen_movsi (tmp, op0));
1959 /* Mask out any bits in operand[3] that are not needed. */
1960 emit_insn (gen_andsi3 (op1, operands[3], op0));
1962 if (GET_CODE (op0) == CONST_INT
1963 && (const_ok_for_arm (mask << start_bit)
1964 || const_ok_for_arm (~(mask << start_bit))))
1966 op0 = gen_int_mode (~(mask << start_bit), SImode);
1967 emit_insn (gen_andsi3 (op2, operands[0], op0));
1971 if (GET_CODE (op0) == CONST_INT)
1973 rtx tmp = gen_reg_rtx (SImode);
1975 emit_insn (gen_movsi (tmp, op0));
1980 emit_insn (gen_ashlsi3 (op0, op0, operands[2]));
1982 emit_insn (gen_andsi_notsi_si (op2, operands[0], op0));
1986 emit_insn (gen_ashlsi3 (op1, op1, operands[2]));
1988 emit_insn (gen_iorsi3 (subtarget, op1, op2));
1991 if (subtarget != target)
1993 /* If TARGET is still a SUBREG, then it must be wider than a word,
1994 so we must be careful only to set the subword we were asked to. */
1995 if (GET_CODE (target) == SUBREG)
1996 emit_move_insn (target, subtarget);
1998 emit_move_insn (target, gen_lowpart (GET_MODE (target), subtarget));
2005 ; constants for op 2 will never be given to these patterns.
2006 (define_insn_and_split "*anddi_notdi_di"
2007 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2008 (and:DI (not:DI (match_operand:DI 1 "s_register_operand" "r,0"))
2009 (match_operand:DI 2 "s_register_operand" "0,r")))]
2012 "TARGET_ARM && reload_completed && ! IS_IWMMXT_REGNUM (REGNO (operands[0]))"
2013 [(set (match_dup 0) (and:SI (not:SI (match_dup 1)) (match_dup 2)))
2014 (set (match_dup 3) (and:SI (not:SI (match_dup 4)) (match_dup 5)))]
2017 operands[3] = gen_highpart (SImode, operands[0]);
2018 operands[0] = gen_lowpart (SImode, operands[0]);
2019 operands[4] = gen_highpart (SImode, operands[1]);
2020 operands[1] = gen_lowpart (SImode, operands[1]);
2021 operands[5] = gen_highpart (SImode, operands[2]);
2022 operands[2] = gen_lowpart (SImode, operands[2]);
2024 [(set_attr "length" "8")
2025 (set_attr "predicable" "yes")]
2028 (define_insn_and_split "*anddi_notzesidi_di"
2029 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2030 (and:DI (not:DI (zero_extend:DI
2031 (match_operand:SI 2 "s_register_operand" "r,r")))
2032 (match_operand:DI 1 "s_register_operand" "0,?r")))]
2035 bic%?\\t%Q0, %Q1, %2
2037 ; (not (zero_extend ...)) allows us to just copy the high word from
2038 ; operand1 to operand0.
2041 && operands[0] != operands[1]"
2042 [(set (match_dup 0) (and:SI (not:SI (match_dup 2)) (match_dup 1)))
2043 (set (match_dup 3) (match_dup 4))]
2046 operands[3] = gen_highpart (SImode, operands[0]);
2047 operands[0] = gen_lowpart (SImode, operands[0]);
2048 operands[4] = gen_highpart (SImode, operands[1]);
2049 operands[1] = gen_lowpart (SImode, operands[1]);
2051 [(set_attr "length" "4,8")
2052 (set_attr "predicable" "yes")]
2055 (define_insn_and_split "*anddi_notsesidi_di"
2056 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2057 (and:DI (not:DI (sign_extend:DI
2058 (match_operand:SI 2 "s_register_operand" "r,r")))
2059 (match_operand:DI 1 "s_register_operand" "0,r")))]
2062 "TARGET_ARM && reload_completed"
2063 [(set (match_dup 0) (and:SI (not:SI (match_dup 2)) (match_dup 1)))
2064 (set (match_dup 3) (and:SI (not:SI
2065 (ashiftrt:SI (match_dup 2) (const_int 31)))
2069 operands[3] = gen_highpart (SImode, operands[0]);
2070 operands[0] = gen_lowpart (SImode, operands[0]);
2071 operands[4] = gen_highpart (SImode, operands[1]);
2072 operands[1] = gen_lowpart (SImode, operands[1]);
2074 [(set_attr "length" "8")
2075 (set_attr "predicable" "yes")]
2078 (define_insn "andsi_notsi_si"
2079 [(set (match_operand:SI 0 "s_register_operand" "=r")
2080 (and:SI (not:SI (match_operand:SI 2 "s_register_operand" "r"))
2081 (match_operand:SI 1 "s_register_operand" "r")))]
2083 "bic%?\\t%0, %1, %2"
2084 [(set_attr "predicable" "yes")]
2087 (define_insn "bicsi3"
2088 [(set (match_operand:SI 0 "register_operand" "=l")
2089 (and:SI (not:SI (match_operand:SI 1 "register_operand" "l"))
2090 (match_operand:SI 2 "register_operand" "0")))]
2093 [(set_attr "length" "2")]
2096 (define_insn "andsi_not_shiftsi_si"
2097 [(set (match_operand:SI 0 "s_register_operand" "=r")
2098 (and:SI (not:SI (match_operator:SI 4 "shift_operator"
2099 [(match_operand:SI 2 "s_register_operand" "r")
2100 (match_operand:SI 3 "arm_rhs_operand" "rM")]))
2101 (match_operand:SI 1 "s_register_operand" "r")))]
2103 "bic%?\\t%0, %1, %2%S4"
2104 [(set_attr "predicable" "yes")
2105 (set_attr "shift" "2")
2106 (set (attr "type") (if_then_else (match_operand 3 "const_int_operand" "")
2107 (const_string "alu_shift")
2108 (const_string "alu_shift_reg")))]
2111 (define_insn "*andsi_notsi_si_compare0"
2112 [(set (reg:CC_NOOV CC_REGNUM)
2114 (and:SI (not:SI (match_operand:SI 2 "s_register_operand" "r"))
2115 (match_operand:SI 1 "s_register_operand" "r"))
2117 (set (match_operand:SI 0 "s_register_operand" "=r")
2118 (and:SI (not:SI (match_dup 2)) (match_dup 1)))]
2120 "bic%?s\\t%0, %1, %2"
2121 [(set_attr "conds" "set")]
2124 (define_insn "*andsi_notsi_si_compare0_scratch"
2125 [(set (reg:CC_NOOV CC_REGNUM)
2127 (and:SI (not:SI (match_operand:SI 2 "s_register_operand" "r"))
2128 (match_operand:SI 1 "s_register_operand" "r"))
2130 (clobber (match_scratch:SI 0 "=r"))]
2132 "bic%?s\\t%0, %1, %2"
2133 [(set_attr "conds" "set")]
2136 (define_insn "iordi3"
2137 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2138 (ior:DI (match_operand:DI 1 "s_register_operand" "%0,r")
2139 (match_operand:DI 2 "s_register_operand" "r,r")))]
2140 "TARGET_ARM && ! TARGET_IWMMXT"
2142 [(set_attr "length" "8")
2143 (set_attr "predicable" "yes")]
2146 (define_insn "*iordi_zesidi_di"
2147 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2148 (ior:DI (zero_extend:DI
2149 (match_operand:SI 2 "s_register_operand" "r,r"))
2150 (match_operand:DI 1 "s_register_operand" "0,?r")))]
2153 orr%?\\t%Q0, %Q1, %2
2155 [(set_attr "length" "4,8")
2156 (set_attr "predicable" "yes")]
2159 (define_insn "*iordi_sesidi_di"
2160 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2161 (ior:DI (sign_extend:DI
2162 (match_operand:SI 2 "s_register_operand" "r,r"))
2163 (match_operand:DI 1 "s_register_operand" "?r,0")))]
2166 [(set_attr "length" "8")
2167 (set_attr "predicable" "yes")]
2170 (define_expand "iorsi3"
2171 [(set (match_operand:SI 0 "s_register_operand" "")
2172 (ior:SI (match_operand:SI 1 "s_register_operand" "")
2173 (match_operand:SI 2 "reg_or_int_operand" "")))]
2176 if (GET_CODE (operands[2]) == CONST_INT)
2180 arm_split_constant (IOR, SImode, NULL_RTX,
2181 INTVAL (operands[2]), operands[0], operands[1],
2182 optimize && !no_new_pseudos);
2185 else /* TARGET_THUMB */
2186 operands [2] = force_reg (SImode, operands [2]);
2191 (define_insn_and_split "*arm_iorsi3"
2192 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
2193 (ior:SI (match_operand:SI 1 "s_register_operand" "r,r")
2194 (match_operand:SI 2 "reg_or_int_operand" "rI,?n")))]
2200 && GET_CODE (operands[2]) == CONST_INT
2201 && !const_ok_for_arm (INTVAL (operands[2]))"
2202 [(clobber (const_int 0))]
2204 arm_split_constant (IOR, SImode, curr_insn,
2205 INTVAL (operands[2]), operands[0], operands[1], 0);
2208 [(set_attr "length" "4,16")
2209 (set_attr "predicable" "yes")]
2212 (define_insn "*thumb_iorsi3"
2213 [(set (match_operand:SI 0 "register_operand" "=l")
2214 (ior:SI (match_operand:SI 1 "register_operand" "%0")
2215 (match_operand:SI 2 "register_operand" "l")))]
2218 [(set_attr "length" "2")]
2222 [(match_scratch:SI 3 "r")
2223 (set (match_operand:SI 0 "arm_general_register_operand" "")
2224 (ior:SI (match_operand:SI 1 "arm_general_register_operand" "")
2225 (match_operand:SI 2 "const_int_operand" "")))]
2227 && !const_ok_for_arm (INTVAL (operands[2]))
2228 && const_ok_for_arm (~INTVAL (operands[2]))"
2229 [(set (match_dup 3) (match_dup 2))
2230 (set (match_dup 0) (ior:SI (match_dup 1) (match_dup 3)))]
2234 (define_insn "*iorsi3_compare0"
2235 [(set (reg:CC_NOOV CC_REGNUM)
2236 (compare:CC_NOOV (ior:SI (match_operand:SI 1 "s_register_operand" "%r")
2237 (match_operand:SI 2 "arm_rhs_operand" "rI"))
2239 (set (match_operand:SI 0 "s_register_operand" "=r")
2240 (ior:SI (match_dup 1) (match_dup 2)))]
2242 "orr%?s\\t%0, %1, %2"
2243 [(set_attr "conds" "set")]
2246 (define_insn "*iorsi3_compare0_scratch"
2247 [(set (reg:CC_NOOV CC_REGNUM)
2248 (compare:CC_NOOV (ior:SI (match_operand:SI 1 "s_register_operand" "%r")
2249 (match_operand:SI 2 "arm_rhs_operand" "rI"))
2251 (clobber (match_scratch:SI 0 "=r"))]
2253 "orr%?s\\t%0, %1, %2"
2254 [(set_attr "conds" "set")]
2257 (define_insn "xordi3"
2258 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2259 (xor:DI (match_operand:DI 1 "s_register_operand" "%0,r")
2260 (match_operand:DI 2 "s_register_operand" "r,r")))]
2261 "TARGET_ARM && !TARGET_IWMMXT"
2263 [(set_attr "length" "8")
2264 (set_attr "predicable" "yes")]
2267 (define_insn "*xordi_zesidi_di"
2268 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2269 (xor:DI (zero_extend:DI
2270 (match_operand:SI 2 "s_register_operand" "r,r"))
2271 (match_operand:DI 1 "s_register_operand" "0,?r")))]
2274 eor%?\\t%Q0, %Q1, %2
2276 [(set_attr "length" "4,8")
2277 (set_attr "predicable" "yes")]
2280 (define_insn "*xordi_sesidi_di"
2281 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2282 (xor:DI (sign_extend:DI
2283 (match_operand:SI 2 "s_register_operand" "r,r"))
2284 (match_operand:DI 1 "s_register_operand" "?r,0")))]
2287 [(set_attr "length" "8")
2288 (set_attr "predicable" "yes")]
2291 (define_expand "xorsi3"
2292 [(set (match_operand:SI 0 "s_register_operand" "")
2293 (xor:SI (match_operand:SI 1 "s_register_operand" "")
2294 (match_operand:SI 2 "arm_rhs_operand" "")))]
2297 if (GET_CODE (operands[2]) == CONST_INT)
2298 operands[2] = force_reg (SImode, operands[2]);
2302 (define_insn "*arm_xorsi3"
2303 [(set (match_operand:SI 0 "s_register_operand" "=r")
2304 (xor:SI (match_operand:SI 1 "s_register_operand" "r")
2305 (match_operand:SI 2 "arm_rhs_operand" "rI")))]
2307 "eor%?\\t%0, %1, %2"
2308 [(set_attr "predicable" "yes")]
2311 (define_insn "*thumb_xorsi3"
2312 [(set (match_operand:SI 0 "register_operand" "=l")
2313 (xor:SI (match_operand:SI 1 "register_operand" "%0")
2314 (match_operand:SI 2 "register_operand" "l")))]
2317 [(set_attr "length" "2")]
2320 (define_insn "*xorsi3_compare0"
2321 [(set (reg:CC_NOOV CC_REGNUM)
2322 (compare:CC_NOOV (xor:SI (match_operand:SI 1 "s_register_operand" "r")
2323 (match_operand:SI 2 "arm_rhs_operand" "rI"))
2325 (set (match_operand:SI 0 "s_register_operand" "=r")
2326 (xor:SI (match_dup 1) (match_dup 2)))]
2328 "eor%?s\\t%0, %1, %2"
2329 [(set_attr "conds" "set")]
2332 (define_insn "*xorsi3_compare0_scratch"
2333 [(set (reg:CC_NOOV CC_REGNUM)
2334 (compare:CC_NOOV (xor:SI (match_operand:SI 0 "s_register_operand" "r")
2335 (match_operand:SI 1 "arm_rhs_operand" "rI"))
2339 [(set_attr "conds" "set")]
2342 ; By splitting (IOR (AND (NOT A) (NOT B)) C) as D = AND (IOR A B) (NOT C),
2343 ; (NOT D) we can sometimes merge the final NOT into one of the following
2347 [(set (match_operand:SI 0 "s_register_operand" "")
2348 (ior:SI (and:SI (not:SI (match_operand:SI 1 "s_register_operand" ""))
2349 (not:SI (match_operand:SI 2 "arm_rhs_operand" "")))
2350 (match_operand:SI 3 "arm_rhs_operand" "")))
2351 (clobber (match_operand:SI 4 "s_register_operand" ""))]
2353 [(set (match_dup 4) (and:SI (ior:SI (match_dup 1) (match_dup 2))
2354 (not:SI (match_dup 3))))
2355 (set (match_dup 0) (not:SI (match_dup 4)))]
2359 (define_insn "*andsi_iorsi3_notsi"
2360 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r")
2361 (and:SI (ior:SI (match_operand:SI 1 "s_register_operand" "r,r,0")
2362 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI"))
2363 (not:SI (match_operand:SI 3 "arm_rhs_operand" "rI,rI,rI"))))]
2365 "orr%?\\t%0, %1, %2\;bic%?\\t%0, %0, %3"
2366 [(set_attr "length" "8")
2367 (set_attr "predicable" "yes")]
2371 [(set (match_operand:SI 0 "s_register_operand" "")
2372 (match_operator:SI 1 "logical_binary_operator"
2373 [(zero_extract:SI (match_operand:SI 2 "s_register_operand" "")
2374 (match_operand:SI 3 "const_int_operand" "")
2375 (match_operand:SI 4 "const_int_operand" ""))
2376 (match_operator:SI 9 "logical_binary_operator"
2377 [(lshiftrt:SI (match_operand:SI 5 "s_register_operand" "")
2378 (match_operand:SI 6 "const_int_operand" ""))
2379 (match_operand:SI 7 "s_register_operand" "")])]))
2380 (clobber (match_operand:SI 8 "s_register_operand" ""))]
2382 && GET_CODE (operands[1]) == GET_CODE (operands[9])
2383 && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
2386 [(ashift:SI (match_dup 2) (match_dup 4))
2390 [(lshiftrt:SI (match_dup 8) (match_dup 6))
2393 operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
2397 [(set (match_operand:SI 0 "s_register_operand" "")
2398 (match_operator:SI 1 "logical_binary_operator"
2399 [(match_operator:SI 9 "logical_binary_operator"
2400 [(lshiftrt:SI (match_operand:SI 5 "s_register_operand" "")
2401 (match_operand:SI 6 "const_int_operand" ""))
2402 (match_operand:SI 7 "s_register_operand" "")])
2403 (zero_extract:SI (match_operand:SI 2 "s_register_operand" "")
2404 (match_operand:SI 3 "const_int_operand" "")
2405 (match_operand:SI 4 "const_int_operand" ""))]))
2406 (clobber (match_operand:SI 8 "s_register_operand" ""))]
2408 && GET_CODE (operands[1]) == GET_CODE (operands[9])
2409 && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
2412 [(ashift:SI (match_dup 2) (match_dup 4))
2416 [(lshiftrt:SI (match_dup 8) (match_dup 6))
2419 operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
2423 [(set (match_operand:SI 0 "s_register_operand" "")
2424 (match_operator:SI 1 "logical_binary_operator"
2425 [(sign_extract:SI (match_operand:SI 2 "s_register_operand" "")
2426 (match_operand:SI 3 "const_int_operand" "")
2427 (match_operand:SI 4 "const_int_operand" ""))
2428 (match_operator:SI 9 "logical_binary_operator"
2429 [(ashiftrt:SI (match_operand:SI 5 "s_register_operand" "")
2430 (match_operand:SI 6 "const_int_operand" ""))
2431 (match_operand:SI 7 "s_register_operand" "")])]))
2432 (clobber (match_operand:SI 8 "s_register_operand" ""))]
2434 && GET_CODE (operands[1]) == GET_CODE (operands[9])
2435 && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
2438 [(ashift:SI (match_dup 2) (match_dup 4))
2442 [(ashiftrt:SI (match_dup 8) (match_dup 6))
2445 operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
2449 [(set (match_operand:SI 0 "s_register_operand" "")
2450 (match_operator:SI 1 "logical_binary_operator"
2451 [(match_operator:SI 9 "logical_binary_operator"
2452 [(ashiftrt:SI (match_operand:SI 5 "s_register_operand" "")
2453 (match_operand:SI 6 "const_int_operand" ""))
2454 (match_operand:SI 7 "s_register_operand" "")])
2455 (sign_extract:SI (match_operand:SI 2 "s_register_operand" "")
2456 (match_operand:SI 3 "const_int_operand" "")
2457 (match_operand:SI 4 "const_int_operand" ""))]))
2458 (clobber (match_operand:SI 8 "s_register_operand" ""))]
2460 && GET_CODE (operands[1]) == GET_CODE (operands[9])
2461 && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
2464 [(ashift:SI (match_dup 2) (match_dup 4))
2468 [(ashiftrt:SI (match_dup 8) (match_dup 6))
2471 operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
2475 ;; Minimum and maximum insns
2477 (define_expand "smaxsi3"
2479 (set (match_operand:SI 0 "s_register_operand" "")
2480 (smax:SI (match_operand:SI 1 "s_register_operand" "")
2481 (match_operand:SI 2 "arm_rhs_operand" "")))
2482 (clobber (reg:CC CC_REGNUM))])]
2485 if (operands[2] == const0_rtx || operands[2] == constm1_rtx)
2487 /* No need for a clobber of the condition code register here. */
2488 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
2489 gen_rtx_SMAX (SImode, operands[1],
2495 (define_insn "*smax_0"
2496 [(set (match_operand:SI 0 "s_register_operand" "=r")
2497 (smax:SI (match_operand:SI 1 "s_register_operand" "r")
2500 "bic%?\\t%0, %1, %1, asr #31"
2501 [(set_attr "predicable" "yes")]
2504 (define_insn "*smax_m1"
2505 [(set (match_operand:SI 0 "s_register_operand" "=r")
2506 (smax:SI (match_operand:SI 1 "s_register_operand" "r")
2509 "orr%?\\t%0, %1, %1, asr #31"
2510 [(set_attr "predicable" "yes")]
2513 (define_insn "*smax_insn"
2514 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
2515 (smax:SI (match_operand:SI 1 "s_register_operand" "%0,?r")
2516 (match_operand:SI 2 "arm_rhs_operand" "rI,rI")))
2517 (clobber (reg:CC CC_REGNUM))]
2520 cmp\\t%1, %2\;movlt\\t%0, %2
2521 cmp\\t%1, %2\;movge\\t%0, %1\;movlt\\t%0, %2"
2522 [(set_attr "conds" "clob")
2523 (set_attr "length" "8,12")]
2526 (define_expand "sminsi3"
2528 (set (match_operand:SI 0 "s_register_operand" "")
2529 (smin:SI (match_operand:SI 1 "s_register_operand" "")
2530 (match_operand:SI 2 "arm_rhs_operand" "")))
2531 (clobber (reg:CC CC_REGNUM))])]
2534 if (operands[2] == const0_rtx)
2536 /* No need for a clobber of the condition code register here. */
2537 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
2538 gen_rtx_SMIN (SImode, operands[1],
2544 (define_insn "*smin_0"
2545 [(set (match_operand:SI 0 "s_register_operand" "=r")
2546 (smin:SI (match_operand:SI 1 "s_register_operand" "r")
2549 "and%?\\t%0, %1, %1, asr #31"
2550 [(set_attr "predicable" "yes")]
2553 (define_insn "*smin_insn"
2554 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
2555 (smin:SI (match_operand:SI 1 "s_register_operand" "%0,?r")
2556 (match_operand:SI 2 "arm_rhs_operand" "rI,rI")))
2557 (clobber (reg:CC CC_REGNUM))]
2560 cmp\\t%1, %2\;movge\\t%0, %2
2561 cmp\\t%1, %2\;movlt\\t%0, %1\;movge\\t%0, %2"
2562 [(set_attr "conds" "clob")
2563 (set_attr "length" "8,12")]
2566 (define_insn "umaxsi3"
2567 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
2568 (umax:SI (match_operand:SI 1 "s_register_operand" "0,r,?r")
2569 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
2570 (clobber (reg:CC CC_REGNUM))]
2573 cmp\\t%1, %2\;movcc\\t%0, %2
2574 cmp\\t%1, %2\;movcs\\t%0, %1
2575 cmp\\t%1, %2\;movcs\\t%0, %1\;movcc\\t%0, %2"
2576 [(set_attr "conds" "clob")
2577 (set_attr "length" "8,8,12")]
2580 (define_insn "uminsi3"
2581 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
2582 (umin:SI (match_operand:SI 1 "s_register_operand" "0,r,?r")
2583 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
2584 (clobber (reg:CC CC_REGNUM))]
2587 cmp\\t%1, %2\;movcs\\t%0, %2
2588 cmp\\t%1, %2\;movcc\\t%0, %1
2589 cmp\\t%1, %2\;movcc\\t%0, %1\;movcs\\t%0, %2"
2590 [(set_attr "conds" "clob")
2591 (set_attr "length" "8,8,12")]
2594 (define_insn "*store_minmaxsi"
2595 [(set (match_operand:SI 0 "memory_operand" "=m")
2596 (match_operator:SI 3 "minmax_operator"
2597 [(match_operand:SI 1 "s_register_operand" "r")
2598 (match_operand:SI 2 "s_register_operand" "r")]))
2599 (clobber (reg:CC CC_REGNUM))]
2602 operands[3] = gen_rtx_fmt_ee (minmax_code (operands[3]), SImode,
2603 operands[1], operands[2]);
2604 output_asm_insn (\"cmp\\t%1, %2\", operands);
2605 output_asm_insn (\"str%d3\\t%1, %0\", operands);
2606 output_asm_insn (\"str%D3\\t%2, %0\", operands);
2609 [(set_attr "conds" "clob")
2610 (set_attr "length" "12")
2611 (set_attr "type" "store1")]
2614 ; Reject the frame pointer in operand[1], since reloading this after
2615 ; it has been eliminated can cause carnage.
2616 (define_insn "*minmax_arithsi"
2617 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
2618 (match_operator:SI 4 "shiftable_operator"
2619 [(match_operator:SI 5 "minmax_operator"
2620 [(match_operand:SI 2 "s_register_operand" "r,r")
2621 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
2622 (match_operand:SI 1 "s_register_operand" "0,?r")]))
2623 (clobber (reg:CC CC_REGNUM))]
2624 "TARGET_ARM && !arm_eliminable_register (operands[1])"
2627 enum rtx_code code = GET_CODE (operands[4]);
2629 operands[5] = gen_rtx_fmt_ee (minmax_code (operands[5]), SImode,
2630 operands[2], operands[3]);
2631 output_asm_insn (\"cmp\\t%2, %3\", operands);
2632 output_asm_insn (\"%i4%d5\\t%0, %1, %2\", operands);
2633 if (which_alternative != 0 || operands[3] != const0_rtx
2634 || (code != PLUS && code != MINUS && code != IOR && code != XOR))
2635 output_asm_insn (\"%i4%D5\\t%0, %1, %3\", operands);
2638 [(set_attr "conds" "clob")
2639 (set_attr "length" "12")]
2643 ;; Shift and rotation insns
2645 (define_expand "ashldi3"
2646 [(set (match_operand:DI 0 "s_register_operand" "")
2647 (ashift:DI (match_operand:DI 1 "s_register_operand" "")
2648 (match_operand:SI 2 "reg_or_int_operand" "")))]
2651 if (GET_CODE (operands[2]) == CONST_INT)
2653 if ((HOST_WIDE_INT) INTVAL (operands[2]) == 1)
2655 emit_insn (gen_arm_ashldi3_1bit (operands[0], operands[1]));
2658 /* Ideally we shouldn't fail here if we could know that operands[1]
2659 ends up already living in an iwmmxt register. Otherwise it's
2660 cheaper to have the alternate code being generated than moving
2661 values to iwmmxt regs and back. */
2664 else if (!TARGET_REALLY_IWMMXT && !(TARGET_HARD_FLOAT && TARGET_MAVERICK))
2669 (define_insn "arm_ashldi3_1bit"
2670 [(set (match_operand:DI 0 "s_register_operand" "=&r,r")
2671 (ashift:DI (match_operand:DI 1 "s_register_operand" "?r,0")
2673 (clobber (reg:CC CC_REGNUM))]
2675 "movs\\t%Q0, %Q1, asl #1\;adc\\t%R0, %R1, %R1"
2676 [(set_attr "conds" "clob")
2677 (set_attr "length" "8")]
2680 (define_expand "ashlsi3"
2681 [(set (match_operand:SI 0 "s_register_operand" "")
2682 (ashift:SI (match_operand:SI 1 "s_register_operand" "")
2683 (match_operand:SI 2 "arm_rhs_operand" "")))]
2686 if (GET_CODE (operands[2]) == CONST_INT
2687 && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) > 31)
2689 emit_insn (gen_movsi (operands[0], const0_rtx));
2695 (define_insn "*thumb_ashlsi3"
2696 [(set (match_operand:SI 0 "register_operand" "=l,l")
2697 (ashift:SI (match_operand:SI 1 "register_operand" "l,0")
2698 (match_operand:SI 2 "nonmemory_operand" "N,l")))]
2701 [(set_attr "length" "2")]
2704 (define_expand "ashrdi3"
2705 [(set (match_operand:DI 0 "s_register_operand" "")
2706 (ashiftrt:DI (match_operand:DI 1 "s_register_operand" "")
2707 (match_operand:SI 2 "reg_or_int_operand" "")))]
2710 if (GET_CODE (operands[2]) == CONST_INT)
2712 if ((HOST_WIDE_INT) INTVAL (operands[2]) == 1)
2714 emit_insn (gen_arm_ashrdi3_1bit (operands[0], operands[1]));
2717 /* Ideally we shouldn't fail here if we could know that operands[1]
2718 ends up already living in an iwmmxt register. Otherwise it's
2719 cheaper to have the alternate code being generated than moving
2720 values to iwmmxt regs and back. */
2723 else if (!TARGET_REALLY_IWMMXT)
2728 (define_insn "arm_ashrdi3_1bit"
2729 [(set (match_operand:DI 0 "s_register_operand" "=&r,r")
2730 (ashiftrt:DI (match_operand:DI 1 "s_register_operand" "?r,0")
2732 (clobber (reg:CC CC_REGNUM))]
2734 "movs\\t%R0, %R1, asr #1\;mov\\t%Q0, %Q1, rrx"
2735 [(set_attr "conds" "clob")
2736 (set_attr "length" "8")]
2739 (define_expand "ashrsi3"
2740 [(set (match_operand:SI 0 "s_register_operand" "")
2741 (ashiftrt:SI (match_operand:SI 1 "s_register_operand" "")
2742 (match_operand:SI 2 "arm_rhs_operand" "")))]
2745 if (GET_CODE (operands[2]) == CONST_INT
2746 && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) > 31)
2747 operands[2] = GEN_INT (31);
2751 (define_insn "*thumb_ashrsi3"
2752 [(set (match_operand:SI 0 "register_operand" "=l,l")
2753 (ashiftrt:SI (match_operand:SI 1 "register_operand" "l,0")
2754 (match_operand:SI 2 "nonmemory_operand" "N,l")))]
2757 [(set_attr "length" "2")]
2760 (define_expand "lshrdi3"
2761 [(set (match_operand:DI 0 "s_register_operand" "")
2762 (lshiftrt:DI (match_operand:DI 1 "s_register_operand" "")
2763 (match_operand:SI 2 "reg_or_int_operand" "")))]
2766 if (GET_CODE (operands[2]) == CONST_INT)
2768 if ((HOST_WIDE_INT) INTVAL (operands[2]) == 1)
2770 emit_insn (gen_arm_lshrdi3_1bit (operands[0], operands[1]));
2773 /* Ideally we shouldn't fail here if we could know that operands[1]
2774 ends up already living in an iwmmxt register. Otherwise it's
2775 cheaper to have the alternate code being generated than moving
2776 values to iwmmxt regs and back. */
2779 else if (!TARGET_REALLY_IWMMXT)
2784 (define_insn "arm_lshrdi3_1bit"
2785 [(set (match_operand:DI 0 "s_register_operand" "=&r,r")
2786 (lshiftrt:DI (match_operand:DI 1 "s_register_operand" "?r,0")
2788 (clobber (reg:CC CC_REGNUM))]
2790 "movs\\t%R0, %R1, lsr #1\;mov\\t%Q0, %Q1, rrx"
2791 [(set_attr "conds" "clob")
2792 (set_attr "length" "8")]
2795 (define_expand "lshrsi3"
2796 [(set (match_operand:SI 0 "s_register_operand" "")
2797 (lshiftrt:SI (match_operand:SI 1 "s_register_operand" "")
2798 (match_operand:SI 2 "arm_rhs_operand" "")))]
2801 if (GET_CODE (operands[2]) == CONST_INT
2802 && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) > 31)
2804 emit_insn (gen_movsi (operands[0], const0_rtx));
2810 (define_insn "*thumb_lshrsi3"
2811 [(set (match_operand:SI 0 "register_operand" "=l,l")
2812 (lshiftrt:SI (match_operand:SI 1 "register_operand" "l,0")
2813 (match_operand:SI 2 "nonmemory_operand" "N,l")))]
2816 [(set_attr "length" "2")]
2819 (define_expand "rotlsi3"
2820 [(set (match_operand:SI 0 "s_register_operand" "")
2821 (rotatert:SI (match_operand:SI 1 "s_register_operand" "")
2822 (match_operand:SI 2 "reg_or_int_operand" "")))]
2825 if (GET_CODE (operands[2]) == CONST_INT)
2826 operands[2] = GEN_INT ((32 - INTVAL (operands[2])) % 32);
2829 rtx reg = gen_reg_rtx (SImode);
2830 emit_insn (gen_subsi3 (reg, GEN_INT (32), operands[2]));
2836 (define_expand "rotrsi3"
2837 [(set (match_operand:SI 0 "s_register_operand" "")
2838 (rotatert:SI (match_operand:SI 1 "s_register_operand" "")
2839 (match_operand:SI 2 "arm_rhs_operand" "")))]
2844 if (GET_CODE (operands[2]) == CONST_INT
2845 && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) > 31)
2846 operands[2] = GEN_INT (INTVAL (operands[2]) % 32);
2848 else /* TARGET_THUMB */
2850 if (GET_CODE (operands [2]) == CONST_INT)
2851 operands [2] = force_reg (SImode, operands[2]);
2856 (define_insn "*thumb_rotrsi3"
2857 [(set (match_operand:SI 0 "register_operand" "=l")
2858 (rotatert:SI (match_operand:SI 1 "register_operand" "0")
2859 (match_operand:SI 2 "register_operand" "l")))]
2862 [(set_attr "length" "2")]
2865 (define_insn "*arm_shiftsi3"
2866 [(set (match_operand:SI 0 "s_register_operand" "=r")
2867 (match_operator:SI 3 "shift_operator"
2868 [(match_operand:SI 1 "s_register_operand" "r")
2869 (match_operand:SI 2 "reg_or_int_operand" "rM")]))]
2872 [(set_attr "predicable" "yes")
2873 (set_attr "shift" "1")
2874 (set (attr "type") (if_then_else (match_operand 2 "const_int_operand" "")
2875 (const_string "alu_shift")
2876 (const_string "alu_shift_reg")))]
2879 (define_insn "*shiftsi3_compare0"
2880 [(set (reg:CC_NOOV CC_REGNUM)
2881 (compare:CC_NOOV (match_operator:SI 3 "shift_operator"
2882 [(match_operand:SI 1 "s_register_operand" "r")
2883 (match_operand:SI 2 "arm_rhs_operand" "rM")])
2885 (set (match_operand:SI 0 "s_register_operand" "=r")
2886 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))]
2888 "mov%?s\\t%0, %1%S3"
2889 [(set_attr "conds" "set")
2890 (set_attr "shift" "1")
2891 (set (attr "type") (if_then_else (match_operand 2 "const_int_operand" "")
2892 (const_string "alu_shift")
2893 (const_string "alu_shift_reg")))]
2896 (define_insn "*shiftsi3_compare0_scratch"
2897 [(set (reg:CC_NOOV CC_REGNUM)
2898 (compare:CC_NOOV (match_operator:SI 3 "shift_operator"
2899 [(match_operand:SI 1 "s_register_operand" "r")
2900 (match_operand:SI 2 "arm_rhs_operand" "rM")])
2902 (clobber (match_scratch:SI 0 "=r"))]
2904 "mov%?s\\t%0, %1%S3"
2905 [(set_attr "conds" "set")
2906 (set_attr "shift" "1")]
2909 (define_insn "*notsi_shiftsi"
2910 [(set (match_operand:SI 0 "s_register_operand" "=r")
2911 (not:SI (match_operator:SI 3 "shift_operator"
2912 [(match_operand:SI 1 "s_register_operand" "r")
2913 (match_operand:SI 2 "arm_rhs_operand" "rM")])))]
2916 [(set_attr "predicable" "yes")
2917 (set_attr "shift" "1")
2918 (set (attr "type") (if_then_else (match_operand 2 "const_int_operand" "")
2919 (const_string "alu_shift")
2920 (const_string "alu_shift_reg")))]
2923 (define_insn "*notsi_shiftsi_compare0"
2924 [(set (reg:CC_NOOV CC_REGNUM)
2925 (compare:CC_NOOV (not:SI (match_operator:SI 3 "shift_operator"
2926 [(match_operand:SI 1 "s_register_operand" "r")
2927 (match_operand:SI 2 "arm_rhs_operand" "rM")]))
2929 (set (match_operand:SI 0 "s_register_operand" "=r")
2930 (not:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)])))]
2932 "mvn%?s\\t%0, %1%S3"
2933 [(set_attr "conds" "set")
2934 (set_attr "shift" "1")
2935 (set (attr "type") (if_then_else (match_operand 2 "const_int_operand" "")
2936 (const_string "alu_shift")
2937 (const_string "alu_shift_reg")))]
2940 (define_insn "*not_shiftsi_compare0_scratch"
2941 [(set (reg:CC_NOOV CC_REGNUM)
2942 (compare:CC_NOOV (not:SI (match_operator:SI 3 "shift_operator"
2943 [(match_operand:SI 1 "s_register_operand" "r")
2944 (match_operand:SI 2 "arm_rhs_operand" "rM")]))
2946 (clobber (match_scratch:SI 0 "=r"))]
2948 "mvn%?s\\t%0, %1%S3"
2949 [(set_attr "conds" "set")
2950 (set_attr "shift" "1")
2951 (set (attr "type") (if_then_else (match_operand 2 "const_int_operand" "")
2952 (const_string "alu_shift")
2953 (const_string "alu_shift_reg")))]
2956 ;; We don't really have extzv, but defining this using shifts helps
2957 ;; to reduce register pressure later on.
2959 (define_expand "extzv"
2961 (ashift:SI (match_operand:SI 1 "register_operand" "")
2962 (match_operand:SI 2 "const_int_operand" "")))
2963 (set (match_operand:SI 0 "register_operand" "")
2964 (lshiftrt:SI (match_dup 4)
2965 (match_operand:SI 3 "const_int_operand" "")))]
2969 HOST_WIDE_INT lshift = 32 - INTVAL (operands[2]) - INTVAL (operands[3]);
2970 HOST_WIDE_INT rshift = 32 - INTVAL (operands[2]);
2972 operands[3] = GEN_INT (rshift);
2976 emit_insn (gen_lshrsi3 (operands[0], operands[1], operands[3]));
2980 operands[2] = GEN_INT (lshift);
2981 operands[4] = gen_reg_rtx (SImode);
2986 ;; Unary arithmetic insns
2988 (define_expand "negdi2"
2990 [(set (match_operand:DI 0 "s_register_operand" "")
2991 (neg:DI (match_operand:DI 1 "s_register_operand" "")))
2992 (clobber (reg:CC CC_REGNUM))])]
2997 if (GET_CODE (operands[1]) != REG)
2998 operands[1] = force_reg (SImode, operands[1]);
3003 ;; The constraints here are to prevent a *partial* overlap (where %Q0 == %R1).
3004 ;; The second alternative is to allow the common case of a *full* overlap.
3005 (define_insn "*arm_negdi2"
3006 [(set (match_operand:DI 0 "s_register_operand" "=&r,r")
3007 (neg:DI (match_operand:DI 1 "s_register_operand" "?r,0")))
3008 (clobber (reg:CC CC_REGNUM))]
3010 "rsbs\\t%Q0, %Q1, #0\;rsc\\t%R0, %R1, #0"
3011 [(set_attr "conds" "clob")
3012 (set_attr "length" "8")]
3015 (define_insn "*thumb_negdi2"
3016 [(set (match_operand:DI 0 "register_operand" "=&l")
3017 (neg:DI (match_operand:DI 1 "register_operand" "l")))
3018 (clobber (reg:CC CC_REGNUM))]
3020 "mov\\t%R0, #0\;neg\\t%Q0, %Q1\;sbc\\t%R0, %R1"
3021 [(set_attr "length" "6")]
3024 (define_expand "negsi2"
3025 [(set (match_operand:SI 0 "s_register_operand" "")
3026 (neg:SI (match_operand:SI 1 "s_register_operand" "")))]
3031 (define_insn "*arm_negsi2"
3032 [(set (match_operand:SI 0 "s_register_operand" "=r")
3033 (neg:SI (match_operand:SI 1 "s_register_operand" "r")))]
3035 "rsb%?\\t%0, %1, #0"
3036 [(set_attr "predicable" "yes")]
3039 (define_insn "*thumb_negsi2"
3040 [(set (match_operand:SI 0 "register_operand" "=l")
3041 (neg:SI (match_operand:SI 1 "register_operand" "l")))]
3044 [(set_attr "length" "2")]
3047 (define_expand "negsf2"
3048 [(set (match_operand:SF 0 "s_register_operand" "")
3049 (neg:SF (match_operand:SF 1 "s_register_operand" "")))]
3050 "TARGET_ARM && TARGET_HARD_FLOAT && (TARGET_FPA || TARGET_VFP)"
3054 (define_expand "negdf2"
3055 [(set (match_operand:DF 0 "s_register_operand" "")
3056 (neg:DF (match_operand:DF 1 "s_register_operand" "")))]
3057 "TARGET_ARM && TARGET_HARD_FLOAT && (TARGET_FPA || TARGET_VFP)"
3060 ;; abssi2 doesn't really clobber the condition codes if a different register
3061 ;; is being set. To keep things simple, assume during rtl manipulations that
3062 ;; it does, but tell the final scan operator the truth. Similarly for
3065 (define_expand "abssi2"
3067 [(set (match_operand:SI 0 "s_register_operand" "")
3068 (abs:SI (match_operand:SI 1 "s_register_operand" "")))
3069 (clobber (reg:CC CC_REGNUM))])]
3073 (define_insn "*arm_abssi2"
3074 [(set (match_operand:SI 0 "s_register_operand" "=r,&r")
3075 (abs:SI (match_operand:SI 1 "s_register_operand" "0,r")))
3076 (clobber (reg:CC CC_REGNUM))]
3079 cmp\\t%0, #0\;rsblt\\t%0, %0, #0
3080 eor%?\\t%0, %1, %1, asr #31\;sub%?\\t%0, %0, %1, asr #31"
3081 [(set_attr "conds" "clob,*")
3082 (set_attr "shift" "1")
3083 ;; predicable can't be set based on the variant, so left as no
3084 (set_attr "length" "8")]
3087 (define_insn "*neg_abssi2"
3088 [(set (match_operand:SI 0 "s_register_operand" "=r,&r")
3089 (neg:SI (abs:SI (match_operand:SI 1 "s_register_operand" "0,r"))))
3090 (clobber (reg:CC CC_REGNUM))]
3093 cmp\\t%0, #0\;rsbgt\\t%0, %0, #0
3094 eor%?\\t%0, %1, %1, asr #31\;rsb%?\\t%0, %0, %1, asr #31"
3095 [(set_attr "conds" "clob,*")
3096 (set_attr "shift" "1")
3097 ;; predicable can't be set based on the variant, so left as no
3098 (set_attr "length" "8")]
3101 (define_expand "abssf2"
3102 [(set (match_operand:SF 0 "s_register_operand" "")
3103 (abs:SF (match_operand:SF 1 "s_register_operand" "")))]
3104 "TARGET_ARM && TARGET_HARD_FLOAT"
3107 (define_expand "absdf2"
3108 [(set (match_operand:DF 0 "s_register_operand" "")
3109 (abs:DF (match_operand:DF 1 "s_register_operand" "")))]
3110 "TARGET_ARM && TARGET_HARD_FLOAT"
3113 (define_expand "sqrtsf2"
3114 [(set (match_operand:SF 0 "s_register_operand" "")
3115 (sqrt:SF (match_operand:SF 1 "s_register_operand" "")))]
3116 "TARGET_ARM && TARGET_HARD_FLOAT && (TARGET_FPA || TARGET_VFP)"
3119 (define_expand "sqrtdf2"
3120 [(set (match_operand:DF 0 "s_register_operand" "")
3121 (sqrt:DF (match_operand:DF 1 "s_register_operand" "")))]
3122 "TARGET_ARM && TARGET_HARD_FLOAT && (TARGET_FPA || TARGET_VFP)"
3125 (define_insn_and_split "one_cmpldi2"
3126 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
3127 (not:DI (match_operand:DI 1 "s_register_operand" "?r,0")))]
3130 "TARGET_ARM && reload_completed"
3131 [(set (match_dup 0) (not:SI (match_dup 1)))
3132 (set (match_dup 2) (not:SI (match_dup 3)))]
3135 operands[2] = gen_highpart (SImode, operands[0]);
3136 operands[0] = gen_lowpart (SImode, operands[0]);
3137 operands[3] = gen_highpart (SImode, operands[1]);
3138 operands[1] = gen_lowpart (SImode, operands[1]);
3140 [(set_attr "length" "8")
3141 (set_attr "predicable" "yes")]
3144 (define_expand "one_cmplsi2"
3145 [(set (match_operand:SI 0 "s_register_operand" "")
3146 (not:SI (match_operand:SI 1 "s_register_operand" "")))]
3151 (define_insn "*arm_one_cmplsi2"
3152 [(set (match_operand:SI 0 "s_register_operand" "=r")
3153 (not:SI (match_operand:SI 1 "s_register_operand" "r")))]
3156 [(set_attr "predicable" "yes")]
3159 (define_insn "*thumb_one_cmplsi2"
3160 [(set (match_operand:SI 0 "register_operand" "=l")
3161 (not:SI (match_operand:SI 1 "register_operand" "l")))]
3164 [(set_attr "length" "2")]
3167 (define_insn "*notsi_compare0"
3168 [(set (reg:CC_NOOV CC_REGNUM)
3169 (compare:CC_NOOV (not:SI (match_operand:SI 1 "s_register_operand" "r"))
3171 (set (match_operand:SI 0 "s_register_operand" "=r")
3172 (not:SI (match_dup 1)))]
3175 [(set_attr "conds" "set")]
3178 (define_insn "*notsi_compare0_scratch"
3179 [(set (reg:CC_NOOV CC_REGNUM)
3180 (compare:CC_NOOV (not:SI (match_operand:SI 1 "s_register_operand" "r"))
3182 (clobber (match_scratch:SI 0 "=r"))]
3185 [(set_attr "conds" "set")]
3188 ;; Fixed <--> Floating conversion insns
3190 (define_expand "floatsisf2"
3191 [(set (match_operand:SF 0 "s_register_operand" "")
3192 (float:SF (match_operand:SI 1 "s_register_operand" "")))]
3193 "TARGET_ARM && TARGET_HARD_FLOAT"
3195 if (TARGET_MAVERICK)
3197 emit_insn (gen_cirrus_floatsisf2 (operands[0], operands[1]));
3202 (define_expand "floatsidf2"
3203 [(set (match_operand:DF 0 "s_register_operand" "")
3204 (float:DF (match_operand:SI 1 "s_register_operand" "")))]
3205 "TARGET_ARM && TARGET_HARD_FLOAT"
3207 if (TARGET_MAVERICK)
3209 emit_insn (gen_cirrus_floatsidf2 (operands[0], operands[1]));
3214 (define_expand "fix_truncsfsi2"
3215 [(set (match_operand:SI 0 "s_register_operand" "")
3216 (fix:SI (fix:SF (match_operand:SF 1 "s_register_operand" ""))))]
3217 "TARGET_ARM && TARGET_HARD_FLOAT"
3219 if (TARGET_MAVERICK)
3221 if (!cirrus_fp_register (operands[0], SImode))
3222 operands[0] = force_reg (SImode, operands[0]);
3223 if (!cirrus_fp_register (operands[1], SFmode))
3224 operands[1] = force_reg (SFmode, operands[0]);
3225 emit_insn (gen_cirrus_truncsfsi2 (operands[0], operands[1]));
3230 (define_expand "fix_truncdfsi2"
3231 [(set (match_operand:SI 0 "s_register_operand" "")
3232 (fix:SI (fix:DF (match_operand:DF 1 "s_register_operand" ""))))]
3233 "TARGET_ARM && TARGET_HARD_FLOAT"
3235 if (TARGET_MAVERICK)
3237 if (!cirrus_fp_register (operands[1], DFmode))
3238 operands[1] = force_reg (DFmode, operands[0]);
3239 emit_insn (gen_cirrus_truncdfsi2 (operands[0], operands[1]));
3246 (define_expand "truncdfsf2"
3247 [(set (match_operand:SF 0 "s_register_operand" "")
3249 (match_operand:DF 1 "s_register_operand" "")))]
3250 "TARGET_ARM && TARGET_HARD_FLOAT"
3254 ;; Zero and sign extension instructions.
3256 (define_insn "zero_extendsidi2"
3257 [(set (match_operand:DI 0 "s_register_operand" "=r")
3258 (zero_extend:DI (match_operand:SI 1 "s_register_operand" "r")))]
3261 if (REGNO (operands[1])
3262 != REGNO (operands[0]) + (WORDS_BIG_ENDIAN ? 1 : 0))
3263 output_asm_insn (\"mov%?\\t%Q0, %1\", operands);
3264 return \"mov%?\\t%R0, #0\";
3266 [(set_attr "length" "8")
3267 (set_attr "predicable" "yes")]
3270 (define_insn "zero_extendqidi2"
3271 [(set (match_operand:DI 0 "s_register_operand" "=r,r")
3272 (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
3275 and%?\\t%Q0, %1, #255\;mov%?\\t%R0, #0
3276 ldr%?b\\t%Q0, %1\;mov%?\\t%R0, #0"
3277 [(set_attr "length" "8")
3278 (set_attr "predicable" "yes")
3279 (set_attr "type" "*,load_byte")
3280 (set_attr "pool_range" "*,4092")
3281 (set_attr "neg_pool_range" "*,4084")]
3284 (define_insn "extendsidi2"
3285 [(set (match_operand:DI 0 "s_register_operand" "=r")
3286 (sign_extend:DI (match_operand:SI 1 "s_register_operand" "r")))]
3289 if (REGNO (operands[1])
3290 != REGNO (operands[0]) + (WORDS_BIG_ENDIAN ? 1 : 0))
3291 output_asm_insn (\"mov%?\\t%Q0, %1\", operands);
3292 return \"mov%?\\t%R0, %Q0, asr #31\";
3294 [(set_attr "length" "8")
3295 (set_attr "shift" "1")
3296 (set_attr "predicable" "yes")]
3299 (define_expand "zero_extendhisi2"
3301 (ashift:SI (match_operand:HI 1 "nonimmediate_operand" "")
3303 (set (match_operand:SI 0 "s_register_operand" "")
3304 (lshiftrt:SI (match_dup 2) (const_int 16)))]
3308 if ((TARGET_THUMB || arm_arch4) && GET_CODE (operands[1]) == MEM)
3310 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
3311 gen_rtx_ZERO_EXTEND (SImode, operands[1])));
3315 if (TARGET_ARM && GET_CODE (operands[1]) == MEM)
3317 emit_insn (gen_movhi_bytes (operands[0], operands[1]));
3321 if (!s_register_operand (operands[1], HImode))
3322 operands[1] = copy_to_mode_reg (HImode, operands[1]);
3326 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
3327 gen_rtx_ZERO_EXTEND (SImode, operands[1])));
3331 operands[1] = gen_lowpart (SImode, operands[1]);
3332 operands[2] = gen_reg_rtx (SImode);
3336 (define_insn "*thumb_zero_extendhisi2"
3337 [(set (match_operand:SI 0 "register_operand" "=l")
3338 (zero_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
3339 "TARGET_THUMB && !arm_arch6"
3341 rtx mem = XEXP (operands[1], 0);
3343 if (GET_CODE (mem) == CONST)
3344 mem = XEXP (mem, 0);
3346 if (GET_CODE (mem) == LABEL_REF)
3347 return \"ldr\\t%0, %1\";
3349 if (GET_CODE (mem) == PLUS)
3351 rtx a = XEXP (mem, 0);
3352 rtx b = XEXP (mem, 1);
3354 /* This can happen due to bugs in reload. */
3355 if (GET_CODE (a) == REG && REGNO (a) == SP_REGNUM)
3358 ops[0] = operands[0];
3361 output_asm_insn (\"mov %0, %1\", ops);
3363 XEXP (mem, 0) = operands[0];
3366 else if ( GET_CODE (a) == LABEL_REF
3367 && GET_CODE (b) == CONST_INT)
3368 return \"ldr\\t%0, %1\";