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, 2007, 2008, 2009, 2010, 2011, 2012
4 ;; Free Software Foundation, Inc.
5 ;; Contributed by Pieter `Tiggr' Schoenmakers (rcpieter@win.tue.nl)
6 ;; and Martin Simmons (@harleqn.co.uk).
7 ;; More major hacks by Richard Earnshaw (rearnsha@arm.com).
9 ;; This file is part of GCC.
11 ;; GCC is free software; you can redistribute it and/or modify it
12 ;; under the terms of the GNU General Public License as published
13 ;; by the Free Software Foundation; either version 3, or (at your
14 ;; option) any later version.
16 ;; GCC is distributed in the hope that it will be useful, but WITHOUT
17 ;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
18 ;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
19 ;; License for more details.
21 ;; You should have received a copy of the GNU General Public License
22 ;; along with GCC; see the file COPYING3. If not see
23 ;; <http://www.gnu.org/licenses/>.
25 ;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
28 ;;---------------------------------------------------------------------------
33 [(R0_REGNUM 0) ; First CORE register
34 (R1_REGNUM 1) ; Second CORE register
35 (IP_REGNUM 12) ; Scratch register
36 (SP_REGNUM 13) ; Stack pointer
37 (LR_REGNUM 14) ; Return address register
38 (PC_REGNUM 15) ; Program counter
39 (CC_REGNUM 24) ; Condition code pseudo register
40 (LAST_ARM_REGNUM 15) ;
41 (FPA_F0_REGNUM 16) ; FIRST_FPA_REGNUM
42 (FPA_F7_REGNUM 23) ; LAST_FPA_REGNUM
45 ;; 3rd operand to select_dominance_cc_mode
52 ;; conditional compare combination
63 ;; Note: sin and cos are no-longer used.
64 ;; Unspec enumerators for Neon are defined in neon.md.
66 (define_c_enum "unspec" [
67 UNSPEC_SIN ; `sin' operation (MODE_FLOAT):
68 ; operand 0 is the result,
69 ; operand 1 the parameter.
70 UNPSEC_COS ; `cos' operation (MODE_FLOAT):
71 ; operand 0 is the result,
72 ; operand 1 the parameter.
73 UNSPEC_PUSH_MULT ; `push multiple' operation:
74 ; operand 0 is the first register,
75 ; subsequent registers are in parallel (use ...)
77 UNSPEC_PIC_SYM ; A symbol that has been treated properly for pic
78 ; usage, that is, we will add the pic_register
79 ; value to it before trying to dereference it.
80 UNSPEC_PIC_BASE ; Add PC and all but the last operand together,
81 ; The last operand is the number of a PIC_LABEL
82 ; that points at the containing instruction.
83 UNSPEC_PRLG_STK ; A special barrier that prevents frame accesses
84 ; being scheduled before the stack adjustment insn.
85 UNSPEC_PROLOGUE_USE ; As USE insns are not meaningful after reload,
86 ; this unspec is used to prevent the deletion of
87 ; instructions setting registers for EH handling
88 ; and stack frame generation. Operand 0 is the
90 UNSPEC_CHECK_ARCH ; Set CCs to indicate 26-bit or 32-bit mode.
91 UNSPEC_WSHUFH ; Used by the intrinsic form of the iWMMXt WSHUFH instruction.
92 UNSPEC_WACC ; Used by the intrinsic form of the iWMMXt WACC instruction.
93 UNSPEC_TMOVMSK ; Used by the intrinsic form of the iWMMXt TMOVMSK instruction.
94 UNSPEC_WSAD ; Used by the intrinsic form of the iWMMXt WSAD instruction.
95 UNSPEC_WSADZ ; Used by the intrinsic form of the iWMMXt WSADZ instruction.
96 UNSPEC_WMACS ; Used by the intrinsic form of the iWMMXt WMACS instruction.
97 UNSPEC_WMACU ; Used by the intrinsic form of the iWMMXt WMACU instruction.
98 UNSPEC_WMACSZ ; Used by the intrinsic form of the iWMMXt WMACSZ instruction.
99 UNSPEC_WMACUZ ; Used by the intrinsic form of the iWMMXt WMACUZ instruction.
100 UNSPEC_CLRDI ; Used by the intrinsic form of the iWMMXt CLRDI instruction.
101 UNSPEC_WMADDS ; Used by the intrinsic form of the iWMMXt WMADDS instruction.
102 UNSPEC_WMADDU ; Used by the intrinsic form of the iWMMXt WMADDU instruction.
103 UNSPEC_TLS ; A symbol that has been treated properly for TLS usage.
104 UNSPEC_PIC_LABEL ; A label used for PIC access that does not appear in the
105 ; instruction stream.
106 UNSPEC_PIC_OFFSET ; A symbolic 12-bit OFFSET that has been treated
107 ; correctly for PIC usage.
108 UNSPEC_GOTSYM_OFF ; The offset of the start of the GOT from a
109 ; a given symbolic address.
110 UNSPEC_THUMB1_CASESI ; A Thumb1 compressed dispatch-table call.
111 UNSPEC_RBIT ; rbit operation.
112 UNSPEC_SYMBOL_OFFSET ; The offset of the start of the symbol from
113 ; another symbolic address.
114 UNSPEC_MEMORY_BARRIER ; Represent a memory barrier.
115 UNSPEC_UNALIGNED_LOAD ; Used to represent ldr/ldrh instructions that access
116 ; unaligned locations, on architectures which support
118 UNSPEC_UNALIGNED_STORE ; Same for str/strh.
119 UNSPEC_PIC_UNIFIED ; Create a common pic addressing form.
122 ;; UNSPEC_VOLATILE Usage:
124 (define_c_enum "unspecv" [
125 VUNSPEC_BLOCKAGE ; `blockage' insn to prevent scheduling across an
127 VUNSPEC_EPILOGUE ; `epilogue' insn, used to represent any part of the
128 ; instruction epilogue sequence that isn't expanded
129 ; into normal RTL. Used for both normal and sibcall
131 VUNSPEC_THUMB1_INTERWORK ; `prologue_thumb1_interwork' insn, used to swap
132 ; modes from arm to thumb.
133 VUNSPEC_ALIGN ; `align' insn. Used at the head of a minipool table
134 ; for inlined constants.
135 VUNSPEC_POOL_END ; `end-of-table'. Used to mark the end of a minipool
137 VUNSPEC_POOL_1 ; `pool-entry(1)'. An entry in the constant pool for
139 VUNSPEC_POOL_2 ; `pool-entry(2)'. An entry in the constant pool for
141 VUNSPEC_POOL_4 ; `pool-entry(4)'. An entry in the constant pool for
143 VUNSPEC_POOL_8 ; `pool-entry(8)'. An entry in the constant pool for
145 VUNSPEC_POOL_16 ; `pool-entry(16)'. An entry in the constant pool for
147 VUNSPEC_TMRC ; Used by the iWMMXt TMRC instruction.
148 VUNSPEC_TMCR ; Used by the iWMMXt TMCR instruction.
149 VUNSPEC_ALIGN8 ; 8-byte alignment version of VUNSPEC_ALIGN
150 VUNSPEC_WCMP_EQ ; Used by the iWMMXt WCMPEQ instructions
151 VUNSPEC_WCMP_GTU ; Used by the iWMMXt WCMPGTU instructions
152 VUNSPEC_WCMP_GT ; Used by the iwMMXT WCMPGT instructions
153 VUNSPEC_EH_RETURN ; Use to override the return address for exception
155 VUNSPEC_ATOMIC_CAS ; Represent an atomic compare swap.
156 VUNSPEC_ATOMIC_XCHG ; Represent an atomic exchange.
157 VUNSPEC_ATOMIC_OP ; Represent an atomic operation.
158 VUNSPEC_LL ; Represent a load-register-exclusive.
159 VUNSPEC_SC ; Represent a store-register-exclusive.
162 ;;---------------------------------------------------------------------------
165 ;; Processor type. This is created automatically from arm-cores.def.
166 (include "arm-tune.md")
168 ; IS_THUMB is set to 'yes' when we are generating Thumb code, and 'no' when
169 ; generating ARM code. This is used to control the length of some insn
170 ; patterns that share the same RTL in both ARM and Thumb code.
171 (define_attr "is_thumb" "no,yes" (const (symbol_ref "thumb_code")))
173 ; IS_ARCH6 is set to 'yes' when we are generating code form ARMv6.
174 (define_attr "is_arch6" "no,yes" (const (symbol_ref "arm_arch6")))
176 ; IS_THUMB1 is set to 'yes' iff we are generating Thumb-1 code.
177 (define_attr "is_thumb1" "no,yes" (const (symbol_ref "thumb1_code")))
179 ;; Operand number of an input operand that is shifted. Zero if the
180 ;; given instruction does not shift one of its input operands.
181 (define_attr "shift" "" (const_int 0))
183 ; Floating Point Unit. If we only have floating point emulation, then there
184 ; is no point in scheduling the floating point insns. (Well, for best
185 ; performance we should try and group them together).
186 (define_attr "fpu" "none,fpa,fpe2,fpe3,maverick,vfp"
187 (const (symbol_ref "arm_fpu_attr")))
189 ; LENGTH of an instruction (in bytes)
190 (define_attr "length" ""
193 ; The architecture which supports the instruction (or alternative).
194 ; This can be "a" for ARM, "t" for either of the Thumbs, "32" for
195 ; TARGET_32BIT, "t1" or "t2" to specify a specific Thumb mode. "v6"
196 ; for ARM or Thumb-2 with arm_arch6, and nov6 for ARM without
197 ; arm_arch6. This attribute is used to compute attribute "enabled",
198 ; use type "any" to enable an alternative in all cases.
199 (define_attr "arch" "any,a,t,32,t1,t2,v6,nov6,onlya8,nota8"
200 (const_string "any"))
202 (define_attr "arch_enabled" "no,yes"
203 (cond [(eq_attr "arch" "any")
206 (and (eq_attr "arch" "a")
207 (match_test "TARGET_ARM"))
210 (and (eq_attr "arch" "t")
211 (match_test "TARGET_THUMB"))
214 (and (eq_attr "arch" "t1")
215 (match_test "TARGET_THUMB1"))
218 (and (eq_attr "arch" "t2")
219 (match_test "TARGET_THUMB2"))
222 (and (eq_attr "arch" "32")
223 (match_test "TARGET_32BIT"))
226 (and (eq_attr "arch" "v6")
227 (match_test "TARGET_32BIT && arm_arch6"))
230 (and (eq_attr "arch" "nov6")
231 (match_test "TARGET_32BIT && !arm_arch6"))
234 (and (eq_attr "arch" "onlya8")
235 (eq_attr "tune" "cortexa8"))
238 (and (eq_attr "arch" "nota8")
239 (not (eq_attr "tune" "cortexa8")))
240 (const_string "yes")]
241 (const_string "no")))
243 ; Allows an insn to disable certain alternatives for reasons other than
245 (define_attr "insn_enabled" "no,yes"
246 (const_string "yes"))
248 ; Enable all alternatives that are both arch_enabled and insn_enabled.
249 (define_attr "enabled" "no,yes"
250 (if_then_else (eq_attr "insn_enabled" "yes")
251 (if_then_else (eq_attr "arch_enabled" "yes")
254 (const_string "no")))
256 ; POOL_RANGE is how far away from a constant pool entry that this insn
257 ; can be placed. If the distance is zero, then this insn will never
258 ; reference the pool.
259 ; NEG_POOL_RANGE is nonzero for insns that can reference a constant pool entry
260 ; before its address. It is set to <max_range> - (8 + <data_size>).
261 (define_attr "arm_pool_range" "" (const_int 0))
262 (define_attr "thumb2_pool_range" "" (const_int 0))
263 (define_attr "arm_neg_pool_range" "" (const_int 0))
264 (define_attr "thumb2_neg_pool_range" "" (const_int 0))
266 (define_attr "pool_range" ""
267 (cond [(eq_attr "is_thumb" "yes") (attr "thumb2_pool_range")]
268 (attr "arm_pool_range")))
269 (define_attr "neg_pool_range" ""
270 (cond [(eq_attr "is_thumb" "yes") (attr "thumb2_neg_pool_range")]
271 (attr "arm_neg_pool_range")))
273 ; An assembler sequence may clobber the condition codes without us knowing.
274 ; If such an insn references the pool, then we have no way of knowing how,
275 ; so use the most conservative value for pool_range.
276 (define_asm_attributes
277 [(set_attr "conds" "clob")
278 (set_attr "length" "4")
279 (set_attr "pool_range" "250")])
281 ;; The instruction used to implement a particular pattern. This
282 ;; information is used by pipeline descriptions to provide accurate
283 ;; scheduling information.
286 "mov,mvn,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,smmla,umaal,smlald,smlsld,clz,mrs,msr,xtab,sdiv,udiv,other"
287 (const_string "other"))
289 ; TYPE attribute is used to detect floating point instructions which, if
290 ; running on a co-processor can run in parallel with other, basic instructions
291 ; If write-buffer scheduling is enabled then it can also be used in the
292 ; scheduling of writes.
294 ; Classification of each insn
295 ; Note: vfp.md has different meanings for some of these, and some further
296 ; types as well. See that file for details.
297 ; alu any alu instruction that doesn't hit memory or fp
298 ; regs or have a shifted source operand
299 ; alu_shift any data instruction that doesn't hit memory or fp
300 ; regs, but has a source operand shifted by a constant
301 ; alu_shift_reg any data instruction that doesn't hit memory or fp
302 ; regs, but has a source operand shifted by a register value
303 ; mult a multiply instruction
304 ; block blockage insn, this blocks all functional units
305 ; float a floating point arithmetic operation (subject to expansion)
306 ; fdivd DFmode floating point division
307 ; fdivs SFmode floating point division
308 ; fmul Floating point multiply
309 ; ffmul Fast floating point multiply
310 ; farith Floating point arithmetic (4 cycle)
311 ; ffarith Fast floating point arithmetic (2 cycle)
312 ; float_em a floating point arithmetic operation that is normally emulated
313 ; even on a machine with an fpa.
314 ; f_fpa_load a floating point load from memory. Only for the FPA.
315 ; f_fpa_store a floating point store to memory. Only for the FPA.
316 ; f_load[sd] A single/double load from memory. Used for VFP unit.
317 ; f_store[sd] A single/double store to memory. Used for VFP unit.
318 ; f_flag a transfer of co-processor flags to the CPSR
319 ; f_mem_r a transfer of a floating point register to a real reg via mem
320 ; r_mem_f the reverse of f_mem_r
321 ; f_2_r fast transfer float to arm (no memory needed)
322 ; r_2_f fast transfer arm to float
323 ; f_cvt convert floating<->integral
325 ; call a subroutine call
326 ; load_byte load byte(s) from memory to arm registers
327 ; load1 load 1 word from memory to arm registers
328 ; load2 load 2 words from memory to arm registers
329 ; load3 load 3 words from memory to arm registers
330 ; load4 load 4 words from memory to arm registers
331 ; store store 1 word to memory from arm registers
332 ; store2 store 2 words
333 ; store3 store 3 words
334 ; store4 store 4 (or more) words
335 ; Additions for Cirrus Maverick co-processor:
336 ; mav_farith Floating point arithmetic (4 cycle)
337 ; mav_dmult Double multiplies (7 cycle)
341 "alu,alu_shift,alu_shift_reg,mult,block,float,fdivx,fdivd,fdivs,fmul,fmuls,fmuld,fmacs,fmacd,ffmul,farith,ffarith,f_flag,float_em,f_fpa_load,f_fpa_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,fconsts,fconstd,fadds,faddd,ffariths,ffarithd,fcmps,fcmpd,fcpys"
343 (eq_attr "insn" "smulxy,smlaxy,smlalxy,smulwy,smlawx,mul,muls,mla,mlas,umull,umulls,umlal,umlals,smull,smulls,smlal,smlals")
344 (const_string "mult")
345 (const_string "alu")))
347 ; Is this an (integer side) multiply with a 64-bit result?
348 (define_attr "mul64" "no,yes"
350 (eq_attr "insn" "smlalxy,umull,umulls,umlal,umlals,smull,smulls,smlal,smlals")
352 (const_string "no")))
354 ; Load scheduling, set from the arm_ld_sched variable
355 ; initialized by arm_option_override()
356 (define_attr "ldsched" "no,yes" (const (symbol_ref "arm_ld_sched")))
358 ;; Classification of NEON instructions for scheduling purposes.
359 ;; Do not set this attribute and the "type" attribute together in
360 ;; any one instruction pattern.
361 (define_attr "neon_type"
372 neon_mul_ddd_8_16_qdd_16_8_long_32_16_long,\
373 neon_mul_qqq_8_16_32_ddd_32,\
374 neon_mul_qdd_64_32_long_qqd_16_ddd_32_scalar_64_32_long_scalar,\
375 neon_mla_ddd_8_16_qdd_16_8_long_32_16_long,\
377 neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long,\
378 neon_mla_qqq_32_qqd_32_scalar,\
379 neon_mul_ddd_16_scalar_32_16_long_scalar,\
380 neon_mul_qqd_32_scalar,\
381 neon_mla_ddd_16_scalar_qdd_32_16_long_scalar,\
386 neon_vqshl_vrshl_vqrshl_qqq,\
388 neon_fp_vadd_ddd_vabs_dd,\
389 neon_fp_vadd_qqq_vabs_qq,\
395 neon_fp_vmla_ddd_scalar,\
396 neon_fp_vmla_qqq_scalar,\
397 neon_fp_vrecps_vrsqrts_ddd,\
398 neon_fp_vrecps_vrsqrts_qqq,\
406 neon_vld2_2_regs_vld1_vld2_all_lanes,\
409 neon_vst1_1_2_regs_vst2_2_regs,\
411 neon_vst2_4_regs_vst3_vst4,\
413 neon_vld1_vld2_lane,\
414 neon_vld3_vld4_lane,\
415 neon_vst1_vst2_lane,\
416 neon_vst3_vst4_lane,\
417 neon_vld3_vld4_all_lanes,\
425 (const_string "none"))
427 ; condition codes: this one is used by final_prescan_insn to speed up
428 ; conditionalizing instructions. It saves having to scan the rtl to see if
429 ; it uses or alters the condition codes.
431 ; USE means that the condition codes are used by the insn in the process of
432 ; outputting code, this means (at present) that we can't use the insn in
435 ; SET means that the purpose of the insn is to set the condition codes in a
436 ; well defined manner.
438 ; CLOB means that the condition codes are altered in an undefined manner, if
439 ; they are altered at all
441 ; UNCONDITIONAL means the instruction can not be conditionally executed and
442 ; that the instruction does not use or alter the condition codes.
444 ; NOCOND means that the instruction does not use or alter the condition
445 ; codes but can be converted into a conditionally exectuted instruction.
447 (define_attr "conds" "use,set,clob,unconditional,nocond"
449 (ior (eq_attr "is_thumb1" "yes")
450 (eq_attr "type" "call"))
451 (const_string "clob")
452 (if_then_else (eq_attr "neon_type" "none")
453 (const_string "nocond")
454 (const_string "unconditional"))))
456 ; Predicable means that the insn can be conditionally executed based on
457 ; an automatically added predicate (additional patterns are generated by
458 ; gen...). We default to 'no' because no Thumb patterns match this rule
459 ; and not all ARM patterns do.
460 (define_attr "predicable" "no,yes" (const_string "no"))
462 ; Only model the write buffer for ARM6 and ARM7. Earlier processors don't
463 ; have one. Later ones, such as StrongARM, have write-back caches, so don't
464 ; suffer blockages enough to warrant modelling this (and it can adversely
465 ; affect the schedule).
466 (define_attr "model_wbuf" "no,yes" (const (symbol_ref "arm_tune_wbuf")))
468 ; WRITE_CONFLICT implies that a read following an unrelated write is likely
469 ; to stall the processor. Used with model_wbuf above.
470 (define_attr "write_conflict" "no,yes"
471 (if_then_else (eq_attr "type"
472 "block,float_em,f_fpa_load,f_fpa_store,f_mem_r,r_mem_f,call,load1")
474 (const_string "no")))
476 ; Classify the insns into those that take one cycle and those that take more
477 ; than one on the main cpu execution unit.
478 (define_attr "core_cycles" "single,multi"
479 (if_then_else (eq_attr "type"
480 "alu,alu_shift,float,fdivx,fdivd,fdivs,fmul,ffmul,farith,ffarith")
481 (const_string "single")
482 (const_string "multi")))
484 ;; FAR_JUMP is "yes" if a BL instruction is used to generate a branch to a
485 ;; distant label. Only applicable to Thumb code.
486 (define_attr "far_jump" "yes,no" (const_string "no"))
489 ;; The number of machine instructions this pattern expands to.
490 ;; Used for Thumb-2 conditional execution.
491 (define_attr "ce_count" "" (const_int 1))
493 ;;---------------------------------------------------------------------------
496 (include "iterators.md")
498 ;;---------------------------------------------------------------------------
501 (include "predicates.md")
502 (include "constraints.md")
504 ;;---------------------------------------------------------------------------
505 ;; Pipeline descriptions
507 (define_attr "tune_cortexr4" "yes,no"
509 (eq_attr "tune" "cortexr4,cortexr4f,cortexr5")
511 (const_string "no"))))
513 ;; True if the generic scheduling description should be used.
515 (define_attr "generic_sched" "yes,no"
517 (ior (eq_attr "tune" "fa526,fa626,fa606te,fa626te,fmp626,fa726te,arm926ejs,arm1020e,arm1026ejs,arm1136js,arm1136jfs,cortexa5,cortexa8,cortexa9,cortexa15,cortexm4")
518 (eq_attr "tune_cortexr4" "yes"))
520 (const_string "yes"))))
522 (define_attr "generic_vfp" "yes,no"
524 (and (eq_attr "fpu" "vfp")
525 (eq_attr "tune" "!arm1020e,arm1022e,cortexa5,cortexa8,cortexa9,cortexm4")
526 (eq_attr "tune_cortexr4" "no"))
528 (const_string "no"))))
530 (include "arm-generic.md")
531 (include "arm926ejs.md")
532 (include "arm1020e.md")
533 (include "arm1026ejs.md")
534 (include "arm1136jfs.md")
536 (include "fa606te.md")
537 (include "fa626te.md")
538 (include "fmp626.md")
539 (include "fa726te.md")
540 (include "cortex-a5.md")
541 (include "cortex-a8.md")
542 (include "cortex-a9.md")
543 (include "cortex-a15.md")
544 (include "cortex-r4.md")
545 (include "cortex-r4f.md")
546 (include "cortex-m4.md")
547 (include "cortex-m4-fpu.md")
551 ;;---------------------------------------------------------------------------
556 ;; Note: For DImode insns, there is normally no reason why operands should
557 ;; not be in the same register, what we don't want is for something being
558 ;; written to partially overlap something that is an input.
559 ;; Cirrus 64bit additions should not be split because we have a native
560 ;; 64bit addition instructions.
562 (define_expand "adddi3"
564 [(set (match_operand:DI 0 "s_register_operand" "")
565 (plus:DI (match_operand:DI 1 "s_register_operand" "")
566 (match_operand:DI 2 "s_register_operand" "")))
567 (clobber (reg:CC CC_REGNUM))])]
570 if (TARGET_HARD_FLOAT && TARGET_MAVERICK)
572 if (!cirrus_fp_register (operands[0], DImode))
573 operands[0] = force_reg (DImode, operands[0]);
574 if (!cirrus_fp_register (operands[1], DImode))
575 operands[1] = force_reg (DImode, operands[1]);
576 emit_insn (gen_cirrus_adddi3 (operands[0], operands[1], operands[2]));
582 if (GET_CODE (operands[1]) != REG)
583 operands[1] = force_reg (DImode, operands[1]);
584 if (GET_CODE (operands[2]) != REG)
585 operands[2] = force_reg (DImode, operands[2]);
590 (define_insn "*thumb1_adddi3"
591 [(set (match_operand:DI 0 "register_operand" "=l")
592 (plus:DI (match_operand:DI 1 "register_operand" "%0")
593 (match_operand:DI 2 "register_operand" "l")))
594 (clobber (reg:CC CC_REGNUM))
597 "add\\t%Q0, %Q0, %Q2\;adc\\t%R0, %R0, %R2"
598 [(set_attr "length" "4")]
601 (define_insn_and_split "*arm_adddi3"
602 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
603 (plus:DI (match_operand:DI 1 "s_register_operand" "%0, 0")
604 (match_operand:DI 2 "s_register_operand" "r, 0")))
605 (clobber (reg:CC CC_REGNUM))]
606 "TARGET_32BIT && !(TARGET_HARD_FLOAT && TARGET_MAVERICK) && !TARGET_NEON"
608 "TARGET_32BIT && reload_completed
609 && ! (TARGET_NEON && IS_VFP_REGNUM (REGNO (operands[0])))"
610 [(parallel [(set (reg:CC_C CC_REGNUM)
611 (compare:CC_C (plus:SI (match_dup 1) (match_dup 2))
613 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
614 (set (match_dup 3) (plus:SI (plus:SI (match_dup 4) (match_dup 5))
615 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
618 operands[3] = gen_highpart (SImode, operands[0]);
619 operands[0] = gen_lowpart (SImode, operands[0]);
620 operands[4] = gen_highpart (SImode, operands[1]);
621 operands[1] = gen_lowpart (SImode, operands[1]);
622 operands[5] = gen_highpart (SImode, operands[2]);
623 operands[2] = gen_lowpart (SImode, operands[2]);
625 [(set_attr "conds" "clob")
626 (set_attr "length" "8")]
629 (define_insn_and_split "*adddi_sesidi_di"
630 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
631 (plus:DI (sign_extend:DI
632 (match_operand:SI 2 "s_register_operand" "r,r"))
633 (match_operand:DI 1 "s_register_operand" "0,r")))
634 (clobber (reg:CC CC_REGNUM))]
635 "TARGET_32BIT && !(TARGET_HARD_FLOAT && TARGET_MAVERICK)"
637 "TARGET_32BIT && reload_completed"
638 [(parallel [(set (reg:CC_C CC_REGNUM)
639 (compare:CC_C (plus:SI (match_dup 1) (match_dup 2))
641 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
642 (set (match_dup 3) (plus:SI (plus:SI (ashiftrt:SI (match_dup 2)
645 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
648 operands[3] = gen_highpart (SImode, operands[0]);
649 operands[0] = gen_lowpart (SImode, operands[0]);
650 operands[4] = gen_highpart (SImode, operands[1]);
651 operands[1] = gen_lowpart (SImode, operands[1]);
652 operands[2] = gen_lowpart (SImode, operands[2]);
654 [(set_attr "conds" "clob")
655 (set_attr "length" "8")]
658 (define_insn_and_split "*adddi_zesidi_di"
659 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
660 (plus:DI (zero_extend:DI
661 (match_operand:SI 2 "s_register_operand" "r,r"))
662 (match_operand:DI 1 "s_register_operand" "0,r")))
663 (clobber (reg:CC CC_REGNUM))]
664 "TARGET_32BIT && !(TARGET_HARD_FLOAT && TARGET_MAVERICK)"
666 "TARGET_32BIT && reload_completed"
667 [(parallel [(set (reg:CC_C CC_REGNUM)
668 (compare:CC_C (plus:SI (match_dup 1) (match_dup 2))
670 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
671 (set (match_dup 3) (plus:SI (plus:SI (match_dup 4) (const_int 0))
672 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
675 operands[3] = gen_highpart (SImode, operands[0]);
676 operands[0] = gen_lowpart (SImode, operands[0]);
677 operands[4] = gen_highpart (SImode, operands[1]);
678 operands[1] = gen_lowpart (SImode, operands[1]);
679 operands[2] = gen_lowpart (SImode, operands[2]);
681 [(set_attr "conds" "clob")
682 (set_attr "length" "8")]
685 (define_expand "addsi3"
686 [(set (match_operand:SI 0 "s_register_operand" "")
687 (plus:SI (match_operand:SI 1 "s_register_operand" "")
688 (match_operand:SI 2 "reg_or_int_operand" "")))]
691 if (TARGET_32BIT && GET_CODE (operands[2]) == CONST_INT)
693 arm_split_constant (PLUS, SImode, NULL_RTX,
694 INTVAL (operands[2]), operands[0], operands[1],
695 optimize && can_create_pseudo_p ());
701 ; If there is a scratch available, this will be faster than synthesizing the
704 [(match_scratch:SI 3 "r")
705 (set (match_operand:SI 0 "arm_general_register_operand" "")
706 (plus:SI (match_operand:SI 1 "arm_general_register_operand" "")
707 (match_operand:SI 2 "const_int_operand" "")))]
709 !(const_ok_for_arm (INTVAL (operands[2]))
710 || const_ok_for_arm (-INTVAL (operands[2])))
711 && const_ok_for_arm (~INTVAL (operands[2]))"
712 [(set (match_dup 3) (match_dup 2))
713 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 3)))]
717 ;; The r/r/k alternative is required when reloading the address
718 ;; (plus (reg rN) (reg sp)) into (reg rN). In this case reload will
719 ;; put the duplicated register first, and not try the commutative version.
720 (define_insn_and_split "*arm_addsi3"
721 [(set (match_operand:SI 0 "s_register_operand" "=r, k,r,r, k, r, k,r, k, r")
722 (plus:SI (match_operand:SI 1 "s_register_operand" "%rk,k,r,rk,k, rk,k,rk,k, rk")
723 (match_operand:SI 2 "reg_or_int_operand" "rI,rI,k,Pj,Pj,L, L,PJ,PJ,?n")))]
733 subw%?\\t%0, %1, #%n2
734 subw%?\\t%0, %1, #%n2
737 && GET_CODE (operands[2]) == CONST_INT
738 && !const_ok_for_op (INTVAL (operands[2]), PLUS)
739 && (reload_completed || !arm_eliminable_register (operands[1]))"
740 [(clobber (const_int 0))]
742 arm_split_constant (PLUS, SImode, curr_insn,
743 INTVAL (operands[2]), operands[0],
747 [(set_attr "length" "4,4,4,4,4,4,4,4,4,16")
748 (set_attr "predicable" "yes")
749 (set_attr "arch" "*,*,*,t2,t2,*,*,t2,t2,*")]
752 (define_insn_and_split "*thumb1_addsi3"
753 [(set (match_operand:SI 0 "register_operand" "=l,l,l,*rk,*hk,l,k,l,l,l")
754 (plus:SI (match_operand:SI 1 "register_operand" "%0,0,l,*0,*0,k,k,0,l,k")
755 (match_operand:SI 2 "nonmemory_operand" "I,J,lL,*hk,*rk,M,O,Pa,Pb,Pc")))]
758 static const char * const asms[] =
760 \"add\\t%0, %0, %2\",
761 \"sub\\t%0, %0, #%n2\",
762 \"add\\t%0, %1, %2\",
763 \"add\\t%0, %0, %2\",
764 \"add\\t%0, %0, %2\",
765 \"add\\t%0, %1, %2\",
766 \"add\\t%0, %1, %2\",
771 if ((which_alternative == 2 || which_alternative == 6)
772 && GET_CODE (operands[2]) == CONST_INT
773 && INTVAL (operands[2]) < 0)
774 return \"sub\\t%0, %1, #%n2\";
775 return asms[which_alternative];
777 "&& reload_completed && CONST_INT_P (operands[2])
778 && ((operands[1] != stack_pointer_rtx
779 && (INTVAL (operands[2]) > 255 || INTVAL (operands[2]) < -255))
780 || (operands[1] == stack_pointer_rtx
781 && INTVAL (operands[2]) > 1020))"
782 [(set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))
783 (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 3)))]
785 HOST_WIDE_INT offset = INTVAL (operands[2]);
786 if (operands[1] == stack_pointer_rtx)
792 else if (offset < -255)
795 operands[3] = GEN_INT (offset);
796 operands[2] = GEN_INT (INTVAL (operands[2]) - offset);
798 [(set_attr "length" "2,2,2,2,2,2,2,4,4,4")]
801 ;; Reloading and elimination of the frame pointer can
802 ;; sometimes cause this optimization to be missed.
804 [(set (match_operand:SI 0 "arm_general_register_operand" "")
805 (match_operand:SI 1 "const_int_operand" ""))
807 (plus:SI (match_dup 0) (reg:SI SP_REGNUM)))]
809 && (unsigned HOST_WIDE_INT) (INTVAL (operands[1])) < 1024
810 && (INTVAL (operands[1]) & 3) == 0"
811 [(set (match_dup 0) (plus:SI (reg:SI SP_REGNUM) (match_dup 1)))]
815 (define_insn "addsi3_compare0"
816 [(set (reg:CC_NOOV CC_REGNUM)
818 (plus:SI (match_operand:SI 1 "s_register_operand" "r, r")
819 (match_operand:SI 2 "arm_add_operand" "rI,L"))
821 (set (match_operand:SI 0 "s_register_operand" "=r,r")
822 (plus:SI (match_dup 1) (match_dup 2)))]
826 sub%.\\t%0, %1, #%n2"
827 [(set_attr "conds" "set")]
830 (define_insn "*addsi3_compare0_scratch"
831 [(set (reg:CC_NOOV CC_REGNUM)
833 (plus:SI (match_operand:SI 0 "s_register_operand" "r, r")
834 (match_operand:SI 1 "arm_add_operand" "rI,L"))
840 [(set_attr "conds" "set")
841 (set_attr "predicable" "yes")]
844 (define_insn "*compare_negsi_si"
845 [(set (reg:CC_Z CC_REGNUM)
847 (neg:SI (match_operand:SI 0 "s_register_operand" "r"))
848 (match_operand:SI 1 "s_register_operand" "r")))]
851 [(set_attr "conds" "set")
852 (set_attr "predicable" "yes")]
855 ;; This is the canonicalization of addsi3_compare0_for_combiner when the
856 ;; addend is a constant.
857 (define_insn "*cmpsi2_addneg"
858 [(set (reg:CC CC_REGNUM)
860 (match_operand:SI 1 "s_register_operand" "r,r")
861 (match_operand:SI 2 "arm_addimm_operand" "L,I")))
862 (set (match_operand:SI 0 "s_register_operand" "=r,r")
863 (plus:SI (match_dup 1)
864 (match_operand:SI 3 "arm_addimm_operand" "I,L")))]
865 "TARGET_32BIT && INTVAL (operands[2]) == -INTVAL (operands[3])"
868 sub%.\\t%0, %1, #%n3"
869 [(set_attr "conds" "set")]
872 ;; Convert the sequence
874 ;; cmn rd, #1 (equivalent to cmp rd, #-1)
878 ;; bcs dest ((unsigned)rn >= 1)
879 ;; similarly for the beq variant using bcc.
880 ;; This is a common looping idiom (while (n--))
882 [(set (match_operand:SI 0 "arm_general_register_operand" "")
883 (plus:SI (match_operand:SI 1 "arm_general_register_operand" "")
885 (set (match_operand 2 "cc_register" "")
886 (compare (match_dup 0) (const_int -1)))
888 (if_then_else (match_operator 3 "equality_operator"
889 [(match_dup 2) (const_int 0)])
890 (match_operand 4 "" "")
891 (match_operand 5 "" "")))]
892 "TARGET_32BIT && peep2_reg_dead_p (3, operands[2])"
896 (match_dup 1) (const_int 1)))
897 (set (match_dup 0) (plus:SI (match_dup 1) (const_int -1)))])
899 (if_then_else (match_op_dup 3 [(match_dup 2) (const_int 0)])
902 "operands[2] = gen_rtx_REG (CCmode, CC_REGNUM);
903 operands[3] = gen_rtx_fmt_ee ((GET_CODE (operands[3]) == NE
906 operands[2], const0_rtx);"
909 ;; The next four insns work because they compare the result with one of
910 ;; the operands, and we know that the use of the condition code is
911 ;; either GEU or LTU, so we can use the carry flag from the addition
912 ;; instead of doing the compare a second time.
913 (define_insn "*addsi3_compare_op1"
914 [(set (reg:CC_C CC_REGNUM)
916 (plus:SI (match_operand:SI 1 "s_register_operand" "r,r")
917 (match_operand:SI 2 "arm_add_operand" "rI,L"))
919 (set (match_operand:SI 0 "s_register_operand" "=r,r")
920 (plus:SI (match_dup 1) (match_dup 2)))]
924 sub%.\\t%0, %1, #%n2"
925 [(set_attr "conds" "set")]
928 (define_insn "*addsi3_compare_op2"
929 [(set (reg:CC_C CC_REGNUM)
931 (plus:SI (match_operand:SI 1 "s_register_operand" "r,r")
932 (match_operand:SI 2 "arm_add_operand" "rI,L"))
934 (set (match_operand:SI 0 "s_register_operand" "=r,r")
935 (plus:SI (match_dup 1) (match_dup 2)))]
939 sub%.\\t%0, %1, #%n2"
940 [(set_attr "conds" "set")]
943 (define_insn "*compare_addsi2_op0"
944 [(set (reg:CC_C CC_REGNUM)
946 (plus:SI (match_operand:SI 0 "s_register_operand" "r,r")
947 (match_operand:SI 1 "arm_add_operand" "rI,L"))
953 [(set_attr "conds" "set")
954 (set_attr "predicable" "yes")]
957 (define_insn "*compare_addsi2_op1"
958 [(set (reg:CC_C CC_REGNUM)
960 (plus:SI (match_operand:SI 0 "s_register_operand" "r,r")
961 (match_operand:SI 1 "arm_add_operand" "rI,L"))
967 [(set_attr "conds" "set")
968 (set_attr "predicable" "yes")]
971 (define_insn "*addsi3_carryin_<optab>"
972 [(set (match_operand:SI 0 "s_register_operand" "=r")
973 (plus:SI (plus:SI (match_operand:SI 1 "s_register_operand" "%r")
974 (match_operand:SI 2 "arm_rhs_operand" "rI"))
975 (LTUGEU:SI (reg:<cnb> CC_REGNUM) (const_int 0))))]
978 [(set_attr "conds" "use")]
981 (define_insn "*addsi3_carryin_alt2_<optab>"
982 [(set (match_operand:SI 0 "s_register_operand" "=r")
983 (plus:SI (plus:SI (LTUGEU:SI (reg:<cnb> CC_REGNUM) (const_int 0))
984 (match_operand:SI 1 "s_register_operand" "%r"))
985 (match_operand:SI 2 "arm_rhs_operand" "rI")))]
988 [(set_attr "conds" "use")]
991 (define_insn "*addsi3_carryin_shift_<optab>"
992 [(set (match_operand:SI 0 "s_register_operand" "=r")
994 (match_operator:SI 2 "shift_operator"
995 [(match_operand:SI 3 "s_register_operand" "r")
996 (match_operand:SI 4 "reg_or_int_operand" "rM")])
997 (match_operand:SI 1 "s_register_operand" "r"))
998 (LTUGEU:SI (reg:<cnb> CC_REGNUM) (const_int 0))))]
1000 "adc%?\\t%0, %1, %3%S2"
1001 [(set_attr "conds" "use")
1002 (set (attr "type") (if_then_else (match_operand 4 "const_int_operand" "")
1003 (const_string "alu_shift")
1004 (const_string "alu_shift_reg")))]
1007 (define_insn "*addsi3_carryin_clobercc_<optab>"
1008 [(set (match_operand:SI 0 "s_register_operand" "=r")
1009 (plus:SI (plus:SI (match_operand:SI 1 "s_register_operand" "%r")
1010 (match_operand:SI 2 "arm_rhs_operand" "rI"))
1011 (LTUGEU:SI (reg:<cnb> CC_REGNUM) (const_int 0))))
1012 (clobber (reg:CC CC_REGNUM))]
1014 "adc%.\\t%0, %1, %2"
1015 [(set_attr "conds" "set")]
1018 (define_expand "incscc"
1019 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
1020 (plus:SI (match_operator:SI 2 "arm_comparison_operator"
1021 [(match_operand:CC 3 "cc_register" "") (const_int 0)])
1022 (match_operand:SI 1 "s_register_operand" "0,?r")))]
1027 (define_insn "*arm_incscc"
1028 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
1029 (plus:SI (match_operator:SI 2 "arm_comparison_operator"
1030 [(match_operand:CC 3 "cc_register" "") (const_int 0)])
1031 (match_operand:SI 1 "s_register_operand" "0,?r")))]
1035 mov%D2\\t%0, %1\;add%d2\\t%0, %1, #1"
1036 [(set_attr "conds" "use")
1037 (set_attr "length" "4,8")]
1040 ; transform ((x << y) - 1) to ~(~(x-1) << y) Where X is a constant.
1042 [(set (match_operand:SI 0 "s_register_operand" "")
1043 (plus:SI (ashift:SI (match_operand:SI 1 "const_int_operand" "")
1044 (match_operand:SI 2 "s_register_operand" ""))
1046 (clobber (match_operand:SI 3 "s_register_operand" ""))]
1048 [(set (match_dup 3) (match_dup 1))
1049 (set (match_dup 0) (not:SI (ashift:SI (match_dup 3) (match_dup 2))))]
1051 operands[1] = GEN_INT (~(INTVAL (operands[1]) - 1));
1054 (define_expand "addsf3"
1055 [(set (match_operand:SF 0 "s_register_operand" "")
1056 (plus:SF (match_operand:SF 1 "s_register_operand" "")
1057 (match_operand:SF 2 "arm_float_add_operand" "")))]
1058 "TARGET_32BIT && TARGET_HARD_FLOAT"
1061 && !cirrus_fp_register (operands[2], SFmode))
1062 operands[2] = force_reg (SFmode, operands[2]);
1065 (define_expand "adddf3"
1066 [(set (match_operand:DF 0 "s_register_operand" "")
1067 (plus:DF (match_operand:DF 1 "s_register_operand" "")
1068 (match_operand:DF 2 "arm_float_add_operand" "")))]
1069 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
1072 && !cirrus_fp_register (operands[2], DFmode))
1073 operands[2] = force_reg (DFmode, operands[2]);
1076 (define_expand "subdi3"
1078 [(set (match_operand:DI 0 "s_register_operand" "")
1079 (minus:DI (match_operand:DI 1 "s_register_operand" "")
1080 (match_operand:DI 2 "s_register_operand" "")))
1081 (clobber (reg:CC CC_REGNUM))])]
1084 if (TARGET_HARD_FLOAT && TARGET_MAVERICK
1086 && cirrus_fp_register (operands[0], DImode)
1087 && cirrus_fp_register (operands[1], DImode))
1089 emit_insn (gen_cirrus_subdi3 (operands[0], operands[1], operands[2]));
1095 if (GET_CODE (operands[1]) != REG)
1096 operands[1] = force_reg (DImode, operands[1]);
1097 if (GET_CODE (operands[2]) != REG)
1098 operands[2] = force_reg (DImode, operands[2]);
1103 (define_insn "*arm_subdi3"
1104 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r,&r")
1105 (minus:DI (match_operand:DI 1 "s_register_operand" "0,r,0")
1106 (match_operand:DI 2 "s_register_operand" "r,0,0")))
1107 (clobber (reg:CC CC_REGNUM))]
1108 "TARGET_32BIT && !TARGET_NEON"
1109 "subs\\t%Q0, %Q1, %Q2\;sbc\\t%R0, %R1, %R2"
1110 [(set_attr "conds" "clob")
1111 (set_attr "length" "8")]
1114 (define_insn "*thumb_subdi3"
1115 [(set (match_operand:DI 0 "register_operand" "=l")
1116 (minus:DI (match_operand:DI 1 "register_operand" "0")
1117 (match_operand:DI 2 "register_operand" "l")))
1118 (clobber (reg:CC CC_REGNUM))]
1120 "sub\\t%Q0, %Q0, %Q2\;sbc\\t%R0, %R0, %R2"
1121 [(set_attr "length" "4")]
1124 (define_insn "*subdi_di_zesidi"
1125 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1126 (minus:DI (match_operand:DI 1 "s_register_operand" "0,r")
1128 (match_operand:SI 2 "s_register_operand" "r,r"))))
1129 (clobber (reg:CC CC_REGNUM))]
1131 "subs\\t%Q0, %Q1, %2\;sbc\\t%R0, %R1, #0"
1132 [(set_attr "conds" "clob")
1133 (set_attr "length" "8")]
1136 (define_insn "*subdi_di_sesidi"
1137 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1138 (minus:DI (match_operand:DI 1 "s_register_operand" "0,r")
1140 (match_operand:SI 2 "s_register_operand" "r,r"))))
1141 (clobber (reg:CC CC_REGNUM))]
1143 "subs\\t%Q0, %Q1, %2\;sbc\\t%R0, %R1, %2, asr #31"
1144 [(set_attr "conds" "clob")
1145 (set_attr "length" "8")]
1148 (define_insn "*subdi_zesidi_di"
1149 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1150 (minus:DI (zero_extend:DI
1151 (match_operand:SI 2 "s_register_operand" "r,r"))
1152 (match_operand:DI 1 "s_register_operand" "0,r")))
1153 (clobber (reg:CC CC_REGNUM))]
1155 "rsbs\\t%Q0, %Q1, %2\;rsc\\t%R0, %R1, #0"
1156 [(set_attr "conds" "clob")
1157 (set_attr "length" "8")]
1160 (define_insn "*subdi_sesidi_di"
1161 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1162 (minus:DI (sign_extend:DI
1163 (match_operand:SI 2 "s_register_operand" "r,r"))
1164 (match_operand:DI 1 "s_register_operand" "0,r")))
1165 (clobber (reg:CC CC_REGNUM))]
1167 "rsbs\\t%Q0, %Q1, %2\;rsc\\t%R0, %R1, %2, asr #31"
1168 [(set_attr "conds" "clob")
1169 (set_attr "length" "8")]
1172 (define_insn "*subdi_zesidi_zesidi"
1173 [(set (match_operand:DI 0 "s_register_operand" "=r")
1174 (minus:DI (zero_extend:DI
1175 (match_operand:SI 1 "s_register_operand" "r"))
1177 (match_operand:SI 2 "s_register_operand" "r"))))
1178 (clobber (reg:CC CC_REGNUM))]
1180 "subs\\t%Q0, %1, %2\;sbc\\t%R0, %1, %1"
1181 [(set_attr "conds" "clob")
1182 (set_attr "length" "8")]
1185 (define_expand "subsi3"
1186 [(set (match_operand:SI 0 "s_register_operand" "")
1187 (minus:SI (match_operand:SI 1 "reg_or_int_operand" "")
1188 (match_operand:SI 2 "s_register_operand" "")))]
1191 if (GET_CODE (operands[1]) == CONST_INT)
1195 arm_split_constant (MINUS, SImode, NULL_RTX,
1196 INTVAL (operands[1]), operands[0],
1197 operands[2], optimize && can_create_pseudo_p ());
1200 else /* TARGET_THUMB1 */
1201 operands[1] = force_reg (SImode, operands[1]);
1206 (define_insn "thumb1_subsi3_insn"
1207 [(set (match_operand:SI 0 "register_operand" "=l")
1208 (minus:SI (match_operand:SI 1 "register_operand" "l")
1209 (match_operand:SI 2 "reg_or_int_operand" "lPd")))]
1212 [(set_attr "length" "2")
1213 (set_attr "conds" "set")])
1215 ; ??? Check Thumb-2 split length
1216 (define_insn_and_split "*arm_subsi3_insn"
1217 [(set (match_operand:SI 0 "s_register_operand" "=r,r,rk,r")
1218 (minus:SI (match_operand:SI 1 "reg_or_int_operand" "rI,r,k,?n")
1219 (match_operand:SI 2 "reg_or_int_operand" "r,rI,r, r")))]
1226 "&& (GET_CODE (operands[1]) == CONST_INT
1227 && !const_ok_for_arm (INTVAL (operands[1])))"
1228 [(clobber (const_int 0))]
1230 arm_split_constant (MINUS, SImode, curr_insn,
1231 INTVAL (operands[1]), operands[0], operands[2], 0);
1234 [(set_attr "length" "4,4,4,16")
1235 (set_attr "predicable" "yes")]
1239 [(match_scratch:SI 3 "r")
1240 (set (match_operand:SI 0 "arm_general_register_operand" "")
1241 (minus:SI (match_operand:SI 1 "const_int_operand" "")
1242 (match_operand:SI 2 "arm_general_register_operand" "")))]
1244 && !const_ok_for_arm (INTVAL (operands[1]))
1245 && const_ok_for_arm (~INTVAL (operands[1]))"
1246 [(set (match_dup 3) (match_dup 1))
1247 (set (match_dup 0) (minus:SI (match_dup 3) (match_dup 2)))]
1251 (define_insn "*subsi3_compare0"
1252 [(set (reg:CC_NOOV CC_REGNUM)
1254 (minus:SI (match_operand:SI 1 "arm_rhs_operand" "r,I")
1255 (match_operand:SI 2 "arm_rhs_operand" "rI,r"))
1257 (set (match_operand:SI 0 "s_register_operand" "=r,r")
1258 (minus:SI (match_dup 1) (match_dup 2)))]
1263 [(set_attr "conds" "set")]
1266 (define_insn "*subsi3_compare"
1267 [(set (reg:CC CC_REGNUM)
1268 (compare:CC (match_operand:SI 1 "arm_rhs_operand" "r,I")
1269 (match_operand:SI 2 "arm_rhs_operand" "rI,r")))
1270 (set (match_operand:SI 0 "s_register_operand" "=r,r")
1271 (minus:SI (match_dup 1) (match_dup 2)))]
1276 [(set_attr "conds" "set")]
1279 (define_expand "decscc"
1280 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
1281 (minus:SI (match_operand:SI 1 "s_register_operand" "0,?r")
1282 (match_operator:SI 2 "arm_comparison_operator"
1283 [(match_operand 3 "cc_register" "") (const_int 0)])))]
1288 (define_insn "*arm_decscc"
1289 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
1290 (minus:SI (match_operand:SI 1 "s_register_operand" "0,?r")
1291 (match_operator:SI 2 "arm_comparison_operator"
1292 [(match_operand 3 "cc_register" "") (const_int 0)])))]
1296 mov%D2\\t%0, %1\;sub%d2\\t%0, %1, #1"
1297 [(set_attr "conds" "use")
1298 (set_attr "length" "*,8")]
1301 (define_expand "subsf3"
1302 [(set (match_operand:SF 0 "s_register_operand" "")
1303 (minus:SF (match_operand:SF 1 "arm_float_rhs_operand" "")
1304 (match_operand:SF 2 "arm_float_rhs_operand" "")))]
1305 "TARGET_32BIT && TARGET_HARD_FLOAT"
1307 if (TARGET_MAVERICK)
1309 if (!cirrus_fp_register (operands[1], SFmode))
1310 operands[1] = force_reg (SFmode, operands[1]);
1311 if (!cirrus_fp_register (operands[2], SFmode))
1312 operands[2] = force_reg (SFmode, operands[2]);
1316 (define_expand "subdf3"
1317 [(set (match_operand:DF 0 "s_register_operand" "")
1318 (minus:DF (match_operand:DF 1 "arm_float_rhs_operand" "")
1319 (match_operand:DF 2 "arm_float_rhs_operand" "")))]
1320 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
1322 if (TARGET_MAVERICK)
1324 if (!cirrus_fp_register (operands[1], DFmode))
1325 operands[1] = force_reg (DFmode, operands[1]);
1326 if (!cirrus_fp_register (operands[2], DFmode))
1327 operands[2] = force_reg (DFmode, operands[2]);
1332 ;; Multiplication insns
1334 (define_expand "mulsi3"
1335 [(set (match_operand:SI 0 "s_register_operand" "")
1336 (mult:SI (match_operand:SI 2 "s_register_operand" "")
1337 (match_operand:SI 1 "s_register_operand" "")))]
1342 ;; Use `&' and then `0' to prevent the operands 0 and 1 being the same
1343 (define_insn "*arm_mulsi3"
1344 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r")
1345 (mult:SI (match_operand:SI 2 "s_register_operand" "r,r")
1346 (match_operand:SI 1 "s_register_operand" "%0,r")))]
1347 "TARGET_32BIT && !arm_arch6"
1348 "mul%?\\t%0, %2, %1"
1349 [(set_attr "insn" "mul")
1350 (set_attr "predicable" "yes")]
1353 (define_insn "*arm_mulsi3_v6"
1354 [(set (match_operand:SI 0 "s_register_operand" "=r")
1355 (mult:SI (match_operand:SI 1 "s_register_operand" "r")
1356 (match_operand:SI 2 "s_register_operand" "r")))]
1357 "TARGET_32BIT && arm_arch6"
1358 "mul%?\\t%0, %1, %2"
1359 [(set_attr "insn" "mul")
1360 (set_attr "predicable" "yes")]
1363 ; Unfortunately with the Thumb the '&'/'0' trick can fails when operands
1364 ; 1 and 2; are the same, because reload will make operand 0 match
1365 ; operand 1 without realizing that this conflicts with operand 2. We fix
1366 ; this by adding another alternative to match this case, and then `reload'
1367 ; it ourselves. This alternative must come first.
1368 (define_insn "*thumb_mulsi3"
1369 [(set (match_operand:SI 0 "register_operand" "=&l,&l,&l")
1370 (mult:SI (match_operand:SI 1 "register_operand" "%l,*h,0")
1371 (match_operand:SI 2 "register_operand" "l,l,l")))]
1372 "TARGET_THUMB1 && !arm_arch6"
1374 if (which_alternative < 2)
1375 return \"mov\\t%0, %1\;mul\\t%0, %2\";
1377 return \"mul\\t%0, %2\";
1379 [(set_attr "length" "4,4,2")
1380 (set_attr "insn" "mul")]
1383 (define_insn "*thumb_mulsi3_v6"
1384 [(set (match_operand:SI 0 "register_operand" "=l,l,l")
1385 (mult:SI (match_operand:SI 1 "register_operand" "0,l,0")
1386 (match_operand:SI 2 "register_operand" "l,0,0")))]
1387 "TARGET_THUMB1 && arm_arch6"
1392 [(set_attr "length" "2")
1393 (set_attr "insn" "mul")]
1396 (define_insn "*mulsi3_compare0"
1397 [(set (reg:CC_NOOV CC_REGNUM)
1398 (compare:CC_NOOV (mult:SI
1399 (match_operand:SI 2 "s_register_operand" "r,r")
1400 (match_operand:SI 1 "s_register_operand" "%0,r"))
1402 (set (match_operand:SI 0 "s_register_operand" "=&r,&r")
1403 (mult:SI (match_dup 2) (match_dup 1)))]
1404 "TARGET_ARM && !arm_arch6"
1405 "mul%.\\t%0, %2, %1"
1406 [(set_attr "conds" "set")
1407 (set_attr "insn" "muls")]
1410 (define_insn "*mulsi3_compare0_v6"
1411 [(set (reg:CC_NOOV CC_REGNUM)
1412 (compare:CC_NOOV (mult:SI
1413 (match_operand:SI 2 "s_register_operand" "r")
1414 (match_operand:SI 1 "s_register_operand" "r"))
1416 (set (match_operand:SI 0 "s_register_operand" "=r")
1417 (mult:SI (match_dup 2) (match_dup 1)))]
1418 "TARGET_ARM && arm_arch6 && optimize_size"
1419 "mul%.\\t%0, %2, %1"
1420 [(set_attr "conds" "set")
1421 (set_attr "insn" "muls")]
1424 (define_insn "*mulsi_compare0_scratch"
1425 [(set (reg:CC_NOOV CC_REGNUM)
1426 (compare:CC_NOOV (mult:SI
1427 (match_operand:SI 2 "s_register_operand" "r,r")
1428 (match_operand:SI 1 "s_register_operand" "%0,r"))
1430 (clobber (match_scratch:SI 0 "=&r,&r"))]
1431 "TARGET_ARM && !arm_arch6"
1432 "mul%.\\t%0, %2, %1"
1433 [(set_attr "conds" "set")
1434 (set_attr "insn" "muls")]
1437 (define_insn "*mulsi_compare0_scratch_v6"
1438 [(set (reg:CC_NOOV CC_REGNUM)
1439 (compare:CC_NOOV (mult:SI
1440 (match_operand:SI 2 "s_register_operand" "r")
1441 (match_operand:SI 1 "s_register_operand" "r"))
1443 (clobber (match_scratch:SI 0 "=r"))]
1444 "TARGET_ARM && arm_arch6 && optimize_size"
1445 "mul%.\\t%0, %2, %1"
1446 [(set_attr "conds" "set")
1447 (set_attr "insn" "muls")]
1450 ;; Unnamed templates to match MLA instruction.
1452 (define_insn "*mulsi3addsi"
1453 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r,&r")
1455 (mult:SI (match_operand:SI 2 "s_register_operand" "r,r,r,r")
1456 (match_operand:SI 1 "s_register_operand" "%0,r,0,r"))
1457 (match_operand:SI 3 "s_register_operand" "r,r,0,0")))]
1458 "TARGET_32BIT && !arm_arch6"
1459 "mla%?\\t%0, %2, %1, %3"
1460 [(set_attr "insn" "mla")
1461 (set_attr "predicable" "yes")]
1464 (define_insn "*mulsi3addsi_v6"
1465 [(set (match_operand:SI 0 "s_register_operand" "=r")
1467 (mult:SI (match_operand:SI 2 "s_register_operand" "r")
1468 (match_operand:SI 1 "s_register_operand" "r"))
1469 (match_operand:SI 3 "s_register_operand" "r")))]
1470 "TARGET_32BIT && arm_arch6"
1471 "mla%?\\t%0, %2, %1, %3"
1472 [(set_attr "insn" "mla")
1473 (set_attr "predicable" "yes")]
1476 (define_insn "*mulsi3addsi_compare0"
1477 [(set (reg:CC_NOOV CC_REGNUM)
1480 (match_operand:SI 2 "s_register_operand" "r,r,r,r")
1481 (match_operand:SI 1 "s_register_operand" "%0,r,0,r"))
1482 (match_operand:SI 3 "s_register_operand" "r,r,0,0"))
1484 (set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r,&r")
1485 (plus:SI (mult:SI (match_dup 2) (match_dup 1))
1487 "TARGET_ARM && arm_arch6"
1488 "mla%.\\t%0, %2, %1, %3"
1489 [(set_attr "conds" "set")
1490 (set_attr "insn" "mlas")]
1493 (define_insn "*mulsi3addsi_compare0_v6"
1494 [(set (reg:CC_NOOV CC_REGNUM)
1497 (match_operand:SI 2 "s_register_operand" "r")
1498 (match_operand:SI 1 "s_register_operand" "r"))
1499 (match_operand:SI 3 "s_register_operand" "r"))
1501 (set (match_operand:SI 0 "s_register_operand" "=r")
1502 (plus:SI (mult:SI (match_dup 2) (match_dup 1))
1504 "TARGET_ARM && arm_arch6 && optimize_size"
1505 "mla%.\\t%0, %2, %1, %3"
1506 [(set_attr "conds" "set")
1507 (set_attr "insn" "mlas")]
1510 (define_insn "*mulsi3addsi_compare0_scratch"
1511 [(set (reg:CC_NOOV CC_REGNUM)
1514 (match_operand:SI 2 "s_register_operand" "r,r,r,r")
1515 (match_operand:SI 1 "s_register_operand" "%0,r,0,r"))
1516 (match_operand:SI 3 "s_register_operand" "?r,r,0,0"))
1518 (clobber (match_scratch:SI 0 "=&r,&r,&r,&r"))]
1519 "TARGET_ARM && !arm_arch6"
1520 "mla%.\\t%0, %2, %1, %3"
1521 [(set_attr "conds" "set")
1522 (set_attr "insn" "mlas")]
1525 (define_insn "*mulsi3addsi_compare0_scratch_v6"
1526 [(set (reg:CC_NOOV CC_REGNUM)
1529 (match_operand:SI 2 "s_register_operand" "r")
1530 (match_operand:SI 1 "s_register_operand" "r"))
1531 (match_operand:SI 3 "s_register_operand" "r"))
1533 (clobber (match_scratch:SI 0 "=r"))]
1534 "TARGET_ARM && arm_arch6 && optimize_size"
1535 "mla%.\\t%0, %2, %1, %3"
1536 [(set_attr "conds" "set")
1537 (set_attr "insn" "mlas")]
1540 (define_insn "*mulsi3subsi"
1541 [(set (match_operand:SI 0 "s_register_operand" "=r")
1543 (match_operand:SI 3 "s_register_operand" "r")
1544 (mult:SI (match_operand:SI 2 "s_register_operand" "r")
1545 (match_operand:SI 1 "s_register_operand" "r"))))]
1546 "TARGET_32BIT && arm_arch_thumb2"
1547 "mls%?\\t%0, %2, %1, %3"
1548 [(set_attr "insn" "mla")
1549 (set_attr "predicable" "yes")]
1552 (define_expand "maddsidi4"
1553 [(set (match_operand:DI 0 "s_register_operand" "")
1556 (sign_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1557 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "")))
1558 (match_operand:DI 3 "s_register_operand" "")))]
1559 "TARGET_32BIT && arm_arch3m"
1562 (define_insn "*mulsidi3adddi"
1563 [(set (match_operand:DI 0 "s_register_operand" "=&r")
1566 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "%r"))
1567 (sign_extend:DI (match_operand:SI 3 "s_register_operand" "r")))
1568 (match_operand:DI 1 "s_register_operand" "0")))]
1569 "TARGET_32BIT && arm_arch3m && !arm_arch6"
1570 "smlal%?\\t%Q0, %R0, %3, %2"
1571 [(set_attr "insn" "smlal")
1572 (set_attr "predicable" "yes")]
1575 (define_insn "*mulsidi3adddi_v6"
1576 [(set (match_operand:DI 0 "s_register_operand" "=r")
1579 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r"))
1580 (sign_extend:DI (match_operand:SI 3 "s_register_operand" "r")))
1581 (match_operand:DI 1 "s_register_operand" "0")))]
1582 "TARGET_32BIT && arm_arch6"
1583 "smlal%?\\t%Q0, %R0, %3, %2"
1584 [(set_attr "insn" "smlal")
1585 (set_attr "predicable" "yes")]
1588 ;; 32x32->64 widening multiply.
1589 ;; As with mulsi3, the only difference between the v3-5 and v6+
1590 ;; versions of these patterns is the requirement that the output not
1591 ;; overlap the inputs, but that still means we have to have a named
1592 ;; expander and two different starred insns.
1594 (define_expand "mulsidi3"
1595 [(set (match_operand:DI 0 "s_register_operand" "")
1597 (sign_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1598 (sign_extend:DI (match_operand:SI 2 "s_register_operand" ""))))]
1599 "TARGET_32BIT && arm_arch3m"
1603 (define_insn "*mulsidi3_nov6"
1604 [(set (match_operand:DI 0 "s_register_operand" "=&r")
1606 (sign_extend:DI (match_operand:SI 1 "s_register_operand" "%r"))
1607 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))]
1608 "TARGET_32BIT && arm_arch3m && !arm_arch6"
1609 "smull%?\\t%Q0, %R0, %1, %2"
1610 [(set_attr "insn" "smull")
1611 (set_attr "predicable" "yes")]
1614 (define_insn "*mulsidi3_v6"
1615 [(set (match_operand:DI 0 "s_register_operand" "=r")
1617 (sign_extend:DI (match_operand:SI 1 "s_register_operand" "r"))
1618 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))]
1619 "TARGET_32BIT && arm_arch6"
1620 "smull%?\\t%Q0, %R0, %1, %2"
1621 [(set_attr "insn" "smull")
1622 (set_attr "predicable" "yes")]
1625 (define_expand "umulsidi3"
1626 [(set (match_operand:DI 0 "s_register_operand" "")
1628 (zero_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1629 (zero_extend:DI (match_operand:SI 2 "s_register_operand" ""))))]
1630 "TARGET_32BIT && arm_arch3m"
1634 (define_insn "*umulsidi3_nov6"
1635 [(set (match_operand:DI 0 "s_register_operand" "=&r")
1637 (zero_extend:DI (match_operand:SI 1 "s_register_operand" "%r"))
1638 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))]
1639 "TARGET_32BIT && arm_arch3m && !arm_arch6"
1640 "umull%?\\t%Q0, %R0, %1, %2"
1641 [(set_attr "insn" "umull")
1642 (set_attr "predicable" "yes")]
1645 (define_insn "*umulsidi3_v6"
1646 [(set (match_operand:DI 0 "s_register_operand" "=r")
1648 (zero_extend:DI (match_operand:SI 1 "s_register_operand" "r"))
1649 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))]
1650 "TARGET_32BIT && arm_arch6"
1651 "umull%?\\t%Q0, %R0, %1, %2"
1652 [(set_attr "insn" "umull")
1653 (set_attr "predicable" "yes")]
1656 (define_expand "umaddsidi4"
1657 [(set (match_operand:DI 0 "s_register_operand" "")
1660 (zero_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1661 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "")))
1662 (match_operand:DI 3 "s_register_operand" "")))]
1663 "TARGET_32BIT && arm_arch3m"
1666 (define_insn "*umulsidi3adddi"
1667 [(set (match_operand:DI 0 "s_register_operand" "=&r")
1670 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "%r"))
1671 (zero_extend:DI (match_operand:SI 3 "s_register_operand" "r")))
1672 (match_operand:DI 1 "s_register_operand" "0")))]
1673 "TARGET_32BIT && arm_arch3m && !arm_arch6"
1674 "umlal%?\\t%Q0, %R0, %3, %2"
1675 [(set_attr "insn" "umlal")
1676 (set_attr "predicable" "yes")]
1679 (define_insn "*umulsidi3adddi_v6"
1680 [(set (match_operand:DI 0 "s_register_operand" "=r")
1683 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r"))
1684 (zero_extend:DI (match_operand:SI 3 "s_register_operand" "r")))
1685 (match_operand:DI 1 "s_register_operand" "0")))]
1686 "TARGET_32BIT && arm_arch6"
1687 "umlal%?\\t%Q0, %R0, %3, %2"
1688 [(set_attr "insn" "umlal")
1689 (set_attr "predicable" "yes")]
1692 (define_expand "smulsi3_highpart"
1694 [(set (match_operand:SI 0 "s_register_operand" "")
1698 (sign_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1699 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "")))
1701 (clobber (match_scratch:SI 3 ""))])]
1702 "TARGET_32BIT && arm_arch3m"
1706 (define_insn "*smulsi3_highpart_nov6"
1707 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r")
1711 (sign_extend:DI (match_operand:SI 1 "s_register_operand" "%0,r"))
1712 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r,r")))
1714 (clobber (match_scratch:SI 3 "=&r,&r"))]
1715 "TARGET_32BIT && arm_arch3m && !arm_arch6"
1716 "smull%?\\t%3, %0, %2, %1"
1717 [(set_attr "insn" "smull")
1718 (set_attr "predicable" "yes")]
1721 (define_insn "*smulsi3_highpart_v6"
1722 [(set (match_operand:SI 0 "s_register_operand" "=r")
1726 (sign_extend:DI (match_operand:SI 1 "s_register_operand" "r"))
1727 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r")))
1729 (clobber (match_scratch:SI 3 "=r"))]
1730 "TARGET_32BIT && arm_arch6"
1731 "smull%?\\t%3, %0, %2, %1"
1732 [(set_attr "insn" "smull")
1733 (set_attr "predicable" "yes")]
1736 (define_expand "umulsi3_highpart"
1738 [(set (match_operand:SI 0 "s_register_operand" "")
1742 (zero_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1743 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "")))
1745 (clobber (match_scratch:SI 3 ""))])]
1746 "TARGET_32BIT && arm_arch3m"
1750 (define_insn "*umulsi3_highpart_nov6"
1751 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r")
1755 (zero_extend:DI (match_operand:SI 1 "s_register_operand" "%0,r"))
1756 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r,r")))
1758 (clobber (match_scratch:SI 3 "=&r,&r"))]
1759 "TARGET_32BIT && arm_arch3m && !arm_arch6"
1760 "umull%?\\t%3, %0, %2, %1"
1761 [(set_attr "insn" "umull")
1762 (set_attr "predicable" "yes")]
1765 (define_insn "*umulsi3_highpart_v6"
1766 [(set (match_operand:SI 0 "s_register_operand" "=r")
1770 (zero_extend:DI (match_operand:SI 1 "s_register_operand" "r"))
1771 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r")))
1773 (clobber (match_scratch:SI 3 "=r"))]
1774 "TARGET_32BIT && arm_arch6"
1775 "umull%?\\t%3, %0, %2, %1"
1776 [(set_attr "insn" "umull")
1777 (set_attr "predicable" "yes")]
1780 (define_insn "mulhisi3"
1781 [(set (match_operand:SI 0 "s_register_operand" "=r")
1782 (mult:SI (sign_extend:SI
1783 (match_operand:HI 1 "s_register_operand" "%r"))
1785 (match_operand:HI 2 "s_register_operand" "r"))))]
1786 "TARGET_DSP_MULTIPLY"
1787 "smulbb%?\\t%0, %1, %2"
1788 [(set_attr "insn" "smulxy")
1789 (set_attr "predicable" "yes")]
1792 (define_insn "*mulhisi3tb"
1793 [(set (match_operand:SI 0 "s_register_operand" "=r")
1794 (mult:SI (ashiftrt:SI
1795 (match_operand:SI 1 "s_register_operand" "r")
1798 (match_operand:HI 2 "s_register_operand" "r"))))]
1799 "TARGET_DSP_MULTIPLY"
1800 "smultb%?\\t%0, %1, %2"
1801 [(set_attr "insn" "smulxy")
1802 (set_attr "predicable" "yes")]
1805 (define_insn "*mulhisi3bt"
1806 [(set (match_operand:SI 0 "s_register_operand" "=r")
1807 (mult:SI (sign_extend:SI
1808 (match_operand:HI 1 "s_register_operand" "r"))
1810 (match_operand:SI 2 "s_register_operand" "r")
1812 "TARGET_DSP_MULTIPLY"
1813 "smulbt%?\\t%0, %1, %2"
1814 [(set_attr "insn" "smulxy")
1815 (set_attr "predicable" "yes")]
1818 (define_insn "*mulhisi3tt"
1819 [(set (match_operand:SI 0 "s_register_operand" "=r")
1820 (mult:SI (ashiftrt:SI
1821 (match_operand:SI 1 "s_register_operand" "r")
1824 (match_operand:SI 2 "s_register_operand" "r")
1826 "TARGET_DSP_MULTIPLY"
1827 "smultt%?\\t%0, %1, %2"
1828 [(set_attr "insn" "smulxy")
1829 (set_attr "predicable" "yes")]
1832 (define_insn "maddhisi4"
1833 [(set (match_operand:SI 0 "s_register_operand" "=r")
1834 (plus:SI (mult:SI (sign_extend:SI
1835 (match_operand:HI 1 "s_register_operand" "r"))
1837 (match_operand:HI 2 "s_register_operand" "r")))
1838 (match_operand:SI 3 "s_register_operand" "r")))]
1839 "TARGET_DSP_MULTIPLY"
1840 "smlabb%?\\t%0, %1, %2, %3"
1841 [(set_attr "insn" "smlaxy")
1842 (set_attr "predicable" "yes")]
1845 ;; Note: there is no maddhisi4ibt because this one is canonical form
1846 (define_insn "*maddhisi4tb"
1847 [(set (match_operand:SI 0 "s_register_operand" "=r")
1848 (plus:SI (mult:SI (ashiftrt:SI
1849 (match_operand:SI 1 "s_register_operand" "r")
1852 (match_operand:HI 2 "s_register_operand" "r")))
1853 (match_operand:SI 3 "s_register_operand" "r")))]
1854 "TARGET_DSP_MULTIPLY"
1855 "smlatb%?\\t%0, %1, %2, %3"
1856 [(set_attr "insn" "smlaxy")
1857 (set_attr "predicable" "yes")]
1860 (define_insn "*maddhisi4tt"
1861 [(set (match_operand:SI 0 "s_register_operand" "=r")
1862 (plus:SI (mult:SI (ashiftrt:SI
1863 (match_operand:SI 1 "s_register_operand" "r")
1866 (match_operand:SI 2 "s_register_operand" "r")
1868 (match_operand:SI 3 "s_register_operand" "r")))]
1869 "TARGET_DSP_MULTIPLY"
1870 "smlatt%?\\t%0, %1, %2, %3"
1871 [(set_attr "insn" "smlaxy")
1872 (set_attr "predicable" "yes")]
1875 (define_insn "maddhidi4"
1876 [(set (match_operand:DI 0 "s_register_operand" "=r")
1878 (mult:DI (sign_extend:DI
1879 (match_operand:HI 1 "s_register_operand" "r"))
1881 (match_operand:HI 2 "s_register_operand" "r")))
1882 (match_operand:DI 3 "s_register_operand" "0")))]
1883 "TARGET_DSP_MULTIPLY"
1884 "smlalbb%?\\t%Q0, %R0, %1, %2"
1885 [(set_attr "insn" "smlalxy")
1886 (set_attr "predicable" "yes")])
1888 ;; Note: there is no maddhidi4ibt because this one is canonical form
1889 (define_insn "*maddhidi4tb"
1890 [(set (match_operand:DI 0 "s_register_operand" "=r")
1892 (mult:DI (sign_extend:DI
1894 (match_operand:SI 1 "s_register_operand" "r")
1897 (match_operand:HI 2 "s_register_operand" "r")))
1898 (match_operand:DI 3 "s_register_operand" "0")))]
1899 "TARGET_DSP_MULTIPLY"
1900 "smlaltb%?\\t%Q0, %R0, %1, %2"
1901 [(set_attr "insn" "smlalxy")
1902 (set_attr "predicable" "yes")])
1904 (define_insn "*maddhidi4tt"
1905 [(set (match_operand:DI 0 "s_register_operand" "=r")
1907 (mult:DI (sign_extend:DI
1909 (match_operand:SI 1 "s_register_operand" "r")
1913 (match_operand:SI 2 "s_register_operand" "r")
1915 (match_operand:DI 3 "s_register_operand" "0")))]
1916 "TARGET_DSP_MULTIPLY"
1917 "smlaltt%?\\t%Q0, %R0, %1, %2"
1918 [(set_attr "insn" "smlalxy")
1919 (set_attr "predicable" "yes")])
1921 (define_expand "mulsf3"
1922 [(set (match_operand:SF 0 "s_register_operand" "")
1923 (mult:SF (match_operand:SF 1 "s_register_operand" "")
1924 (match_operand:SF 2 "arm_float_rhs_operand" "")))]
1925 "TARGET_32BIT && TARGET_HARD_FLOAT"
1928 && !cirrus_fp_register (operands[2], SFmode))
1929 operands[2] = force_reg (SFmode, operands[2]);
1932 (define_expand "muldf3"
1933 [(set (match_operand:DF 0 "s_register_operand" "")
1934 (mult:DF (match_operand:DF 1 "s_register_operand" "")
1935 (match_operand:DF 2 "arm_float_rhs_operand" "")))]
1936 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
1939 && !cirrus_fp_register (operands[2], DFmode))
1940 operands[2] = force_reg (DFmode, operands[2]);
1945 (define_expand "divsf3"
1946 [(set (match_operand:SF 0 "s_register_operand" "")
1947 (div:SF (match_operand:SF 1 "arm_float_rhs_operand" "")
1948 (match_operand:SF 2 "arm_float_rhs_operand" "")))]
1949 "TARGET_32BIT && TARGET_HARD_FLOAT && (TARGET_FPA || TARGET_VFP)"
1952 (define_expand "divdf3"
1953 [(set (match_operand:DF 0 "s_register_operand" "")
1954 (div:DF (match_operand:DF 1 "arm_float_rhs_operand" "")
1955 (match_operand:DF 2 "arm_float_rhs_operand" "")))]
1956 "TARGET_32BIT && TARGET_HARD_FLOAT && (TARGET_FPA || TARGET_VFP_DOUBLE)"
1961 (define_expand "modsf3"
1962 [(set (match_operand:SF 0 "s_register_operand" "")
1963 (mod:SF (match_operand:SF 1 "s_register_operand" "")
1964 (match_operand:SF 2 "arm_float_rhs_operand" "")))]
1965 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_FPA"
1968 (define_expand "moddf3"
1969 [(set (match_operand:DF 0 "s_register_operand" "")
1970 (mod:DF (match_operand:DF 1 "s_register_operand" "")
1971 (match_operand:DF 2 "arm_float_rhs_operand" "")))]
1972 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_FPA"
1975 ;; Boolean and,ior,xor insns
1977 ;; Split up double word logical operations
1979 ;; Split up simple DImode logical operations. Simply perform the logical
1980 ;; operation on the upper and lower halves of the registers.
1982 [(set (match_operand:DI 0 "s_register_operand" "")
1983 (match_operator:DI 6 "logical_binary_operator"
1984 [(match_operand:DI 1 "s_register_operand" "")
1985 (match_operand:DI 2 "s_register_operand" "")]))]
1986 "TARGET_32BIT && reload_completed
1987 && ! (TARGET_NEON && IS_VFP_REGNUM (REGNO (operands[0])))
1988 && ! IS_IWMMXT_REGNUM (REGNO (operands[0]))"
1989 [(set (match_dup 0) (match_op_dup:SI 6 [(match_dup 1) (match_dup 2)]))
1990 (set (match_dup 3) (match_op_dup:SI 6 [(match_dup 4) (match_dup 5)]))]
1993 operands[3] = gen_highpart (SImode, operands[0]);
1994 operands[0] = gen_lowpart (SImode, operands[0]);
1995 operands[4] = gen_highpart (SImode, operands[1]);
1996 operands[1] = gen_lowpart (SImode, operands[1]);
1997 operands[5] = gen_highpart (SImode, operands[2]);
1998 operands[2] = gen_lowpart (SImode, operands[2]);
2003 [(set (match_operand:DI 0 "s_register_operand" "")
2004 (match_operator:DI 6 "logical_binary_operator"
2005 [(sign_extend:DI (match_operand:SI 2 "s_register_operand" ""))
2006 (match_operand:DI 1 "s_register_operand" "")]))]
2007 "TARGET_32BIT && reload_completed"
2008 [(set (match_dup 0) (match_op_dup:SI 6 [(match_dup 1) (match_dup 2)]))
2009 (set (match_dup 3) (match_op_dup:SI 6
2010 [(ashiftrt:SI (match_dup 2) (const_int 31))
2014 operands[3] = gen_highpart (SImode, operands[0]);
2015 operands[0] = gen_lowpart (SImode, operands[0]);
2016 operands[4] = gen_highpart (SImode, operands[1]);
2017 operands[1] = gen_lowpart (SImode, operands[1]);
2018 operands[5] = gen_highpart (SImode, operands[2]);
2019 operands[2] = gen_lowpart (SImode, operands[2]);
2023 ;; The zero extend of operand 2 means we can just copy the high part of
2024 ;; operand1 into operand0.
2026 [(set (match_operand:DI 0 "s_register_operand" "")
2028 (zero_extend:DI (match_operand:SI 2 "s_register_operand" ""))
2029 (match_operand:DI 1 "s_register_operand" "")))]
2030 "TARGET_32BIT && operands[0] != operands[1] && reload_completed"
2031 [(set (match_dup 0) (ior:SI (match_dup 1) (match_dup 2)))
2032 (set (match_dup 3) (match_dup 4))]
2035 operands[4] = gen_highpart (SImode, operands[1]);
2036 operands[3] = gen_highpart (SImode, operands[0]);
2037 operands[0] = gen_lowpart (SImode, operands[0]);
2038 operands[1] = gen_lowpart (SImode, operands[1]);
2042 ;; The zero extend of operand 2 means we can just copy the high part of
2043 ;; operand1 into operand0.
2045 [(set (match_operand:DI 0 "s_register_operand" "")
2047 (zero_extend:DI (match_operand:SI 2 "s_register_operand" ""))
2048 (match_operand:DI 1 "s_register_operand" "")))]
2049 "TARGET_32BIT && operands[0] != operands[1] && reload_completed"
2050 [(set (match_dup 0) (xor:SI (match_dup 1) (match_dup 2)))
2051 (set (match_dup 3) (match_dup 4))]
2054 operands[4] = gen_highpart (SImode, operands[1]);
2055 operands[3] = gen_highpart (SImode, operands[0]);
2056 operands[0] = gen_lowpart (SImode, operands[0]);
2057 operands[1] = gen_lowpart (SImode, operands[1]);
2061 (define_expand "anddi3"
2062 [(set (match_operand:DI 0 "s_register_operand" "")
2063 (and:DI (match_operand:DI 1 "s_register_operand" "")
2064 (match_operand:DI 2 "neon_inv_logic_op2" "")))]
2069 (define_insn "*anddi3_insn"
2070 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2071 (and:DI (match_operand:DI 1 "s_register_operand" "%0,r")
2072 (match_operand:DI 2 "s_register_operand" "r,r")))]
2073 "TARGET_32BIT && !TARGET_IWMMXT && !TARGET_NEON"
2075 [(set_attr "length" "8")]
2078 (define_insn_and_split "*anddi_zesidi_di"
2079 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2080 (and:DI (zero_extend:DI
2081 (match_operand:SI 2 "s_register_operand" "r,r"))
2082 (match_operand:DI 1 "s_register_operand" "0,r")))]
2085 "TARGET_32BIT && reload_completed"
2086 ; The zero extend of operand 2 clears the high word of the output
2088 [(set (match_dup 0) (and:SI (match_dup 1) (match_dup 2)))
2089 (set (match_dup 3) (const_int 0))]
2092 operands[3] = gen_highpart (SImode, operands[0]);
2093 operands[0] = gen_lowpart (SImode, operands[0]);
2094 operands[1] = gen_lowpart (SImode, operands[1]);
2096 [(set_attr "length" "8")]
2099 (define_insn "*anddi_sesdi_di"
2100 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2101 (and:DI (sign_extend:DI
2102 (match_operand:SI 2 "s_register_operand" "r,r"))
2103 (match_operand:DI 1 "s_register_operand" "0,r")))]
2106 [(set_attr "length" "8")]
2109 (define_expand "andsi3"
2110 [(set (match_operand:SI 0 "s_register_operand" "")
2111 (and:SI (match_operand:SI 1 "s_register_operand" "")
2112 (match_operand:SI 2 "reg_or_int_operand" "")))]
2117 if (GET_CODE (operands[2]) == CONST_INT)
2119 if (INTVAL (operands[2]) == 255 && arm_arch6)
2121 operands[1] = convert_to_mode (QImode, operands[1], 1);
2122 emit_insn (gen_thumb2_zero_extendqisi2_v6 (operands[0],
2126 arm_split_constant (AND, SImode, NULL_RTX,
2127 INTVAL (operands[2]), operands[0],
2129 optimize && can_create_pseudo_p ());
2134 else /* TARGET_THUMB1 */
2136 if (GET_CODE (operands[2]) != CONST_INT)
2138 rtx tmp = force_reg (SImode, operands[2]);
2139 if (rtx_equal_p (operands[0], operands[1]))
2143 operands[2] = operands[1];
2151 if (((unsigned HOST_WIDE_INT) ~INTVAL (operands[2])) < 256)
2153 operands[2] = force_reg (SImode,
2154 GEN_INT (~INTVAL (operands[2])));
2156 emit_insn (gen_thumb1_bicsi3 (operands[0], operands[2], operands[1]));
2161 for (i = 9; i <= 31; i++)
2163 if ((((HOST_WIDE_INT) 1) << i) - 1 == INTVAL (operands[2]))
2165 emit_insn (gen_extzv (operands[0], operands[1], GEN_INT (i),
2169 else if ((((HOST_WIDE_INT) 1) << i) - 1
2170 == ~INTVAL (operands[2]))
2172 rtx shift = GEN_INT (i);
2173 rtx reg = gen_reg_rtx (SImode);
2175 emit_insn (gen_lshrsi3 (reg, operands[1], shift));
2176 emit_insn (gen_ashlsi3 (operands[0], reg, shift));
2182 operands[2] = force_reg (SImode, operands[2]);
2188 ; ??? Check split length for Thumb-2
2189 (define_insn_and_split "*arm_andsi3_insn"
2190 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
2191 (and:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
2192 (match_operand:SI 2 "reg_or_int_operand" "rI,K,?n")))]
2196 bic%?\\t%0, %1, #%B2
2199 && GET_CODE (operands[2]) == CONST_INT
2200 && !(const_ok_for_arm (INTVAL (operands[2]))
2201 || const_ok_for_arm (~INTVAL (operands[2])))"
2202 [(clobber (const_int 0))]
2204 arm_split_constant (AND, SImode, curr_insn,
2205 INTVAL (operands[2]), operands[0], operands[1], 0);
2208 [(set_attr "length" "4,4,16")
2209 (set_attr "predicable" "yes")]
2212 (define_insn "*thumb1_andsi3_insn"
2213 [(set (match_operand:SI 0 "register_operand" "=l")
2214 (and:SI (match_operand:SI 1 "register_operand" "%0")
2215 (match_operand:SI 2 "register_operand" "l")))]
2218 [(set_attr "length" "2")
2219 (set_attr "conds" "set")])
2221 (define_insn "*andsi3_compare0"
2222 [(set (reg:CC_NOOV CC_REGNUM)
2224 (and:SI (match_operand:SI 1 "s_register_operand" "r,r")
2225 (match_operand:SI 2 "arm_not_operand" "rI,K"))
2227 (set (match_operand:SI 0 "s_register_operand" "=r,r")
2228 (and:SI (match_dup 1) (match_dup 2)))]
2232 bic%.\\t%0, %1, #%B2"
2233 [(set_attr "conds" "set")]
2236 (define_insn "*andsi3_compare0_scratch"
2237 [(set (reg:CC_NOOV CC_REGNUM)
2239 (and:SI (match_operand:SI 0 "s_register_operand" "r,r")
2240 (match_operand:SI 1 "arm_not_operand" "rI,K"))
2242 (clobber (match_scratch:SI 2 "=X,r"))]
2246 bic%.\\t%2, %0, #%B1"
2247 [(set_attr "conds" "set")]
2250 (define_insn "*zeroextractsi_compare0_scratch"
2251 [(set (reg:CC_NOOV CC_REGNUM)
2252 (compare:CC_NOOV (zero_extract:SI
2253 (match_operand:SI 0 "s_register_operand" "r")
2254 (match_operand 1 "const_int_operand" "n")
2255 (match_operand 2 "const_int_operand" "n"))
2258 && (INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) < 32
2259 && INTVAL (operands[1]) > 0
2260 && INTVAL (operands[1]) + (INTVAL (operands[2]) & 1) <= 8
2261 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32)"
2263 operands[1] = GEN_INT (((1 << INTVAL (operands[1])) - 1)
2264 << INTVAL (operands[2]));
2265 output_asm_insn (\"tst%?\\t%0, %1\", operands);
2268 [(set_attr "conds" "set")
2269 (set_attr "predicable" "yes")]
2272 (define_insn_and_split "*ne_zeroextractsi"
2273 [(set (match_operand:SI 0 "s_register_operand" "=r")
2274 (ne:SI (zero_extract:SI
2275 (match_operand:SI 1 "s_register_operand" "r")
2276 (match_operand:SI 2 "const_int_operand" "n")
2277 (match_operand:SI 3 "const_int_operand" "n"))
2279 (clobber (reg:CC CC_REGNUM))]
2281 && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
2282 && INTVAL (operands[2]) > 0
2283 && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
2284 && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)"
2287 && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
2288 && INTVAL (operands[2]) > 0
2289 && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
2290 && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)"
2291 [(parallel [(set (reg:CC_NOOV CC_REGNUM)
2292 (compare:CC_NOOV (and:SI (match_dup 1) (match_dup 2))
2294 (set (match_dup 0) (and:SI (match_dup 1) (match_dup 2)))])
2296 (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
2297 (match_dup 0) (const_int 1)))]
2299 operands[2] = GEN_INT (((1 << INTVAL (operands[2])) - 1)
2300 << INTVAL (operands[3]));
2302 [(set_attr "conds" "clob")
2303 (set (attr "length")
2304 (if_then_else (eq_attr "is_thumb" "yes")
2309 (define_insn_and_split "*ne_zeroextractsi_shifted"
2310 [(set (match_operand:SI 0 "s_register_operand" "=r")
2311 (ne:SI (zero_extract:SI
2312 (match_operand:SI 1 "s_register_operand" "r")
2313 (match_operand:SI 2 "const_int_operand" "n")
2316 (clobber (reg:CC CC_REGNUM))]
2320 [(parallel [(set (reg:CC_NOOV CC_REGNUM)
2321 (compare:CC_NOOV (ashift:SI (match_dup 1) (match_dup 2))
2323 (set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 2)))])
2325 (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
2326 (match_dup 0) (const_int 1)))]
2328 operands[2] = GEN_INT (32 - INTVAL (operands[2]));
2330 [(set_attr "conds" "clob")
2331 (set_attr "length" "8")]
2334 (define_insn_and_split "*ite_ne_zeroextractsi"
2335 [(set (match_operand:SI 0 "s_register_operand" "=r")
2336 (if_then_else:SI (ne (zero_extract:SI
2337 (match_operand:SI 1 "s_register_operand" "r")
2338 (match_operand:SI 2 "const_int_operand" "n")
2339 (match_operand:SI 3 "const_int_operand" "n"))
2341 (match_operand:SI 4 "arm_not_operand" "rIK")
2343 (clobber (reg:CC CC_REGNUM))]
2345 && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
2346 && INTVAL (operands[2]) > 0
2347 && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
2348 && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)
2349 && !reg_overlap_mentioned_p (operands[0], operands[4])"
2352 && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
2353 && INTVAL (operands[2]) > 0
2354 && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
2355 && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)
2356 && !reg_overlap_mentioned_p (operands[0], operands[4])"
2357 [(parallel [(set (reg:CC_NOOV CC_REGNUM)
2358 (compare:CC_NOOV (and:SI (match_dup 1) (match_dup 2))
2360 (set (match_dup 0) (and:SI (match_dup 1) (match_dup 2)))])
2362 (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
2363 (match_dup 0) (match_dup 4)))]
2365 operands[2] = GEN_INT (((1 << INTVAL (operands[2])) - 1)
2366 << INTVAL (operands[3]));
2368 [(set_attr "conds" "clob")
2369 (set_attr "length" "8")]
2372 (define_insn_and_split "*ite_ne_zeroextractsi_shifted"
2373 [(set (match_operand:SI 0 "s_register_operand" "=r")
2374 (if_then_else:SI (ne (zero_extract:SI
2375 (match_operand:SI 1 "s_register_operand" "r")
2376 (match_operand:SI 2 "const_int_operand" "n")
2379 (match_operand:SI 3 "arm_not_operand" "rIK")
2381 (clobber (reg:CC CC_REGNUM))]
2382 "TARGET_ARM && !reg_overlap_mentioned_p (operands[0], operands[3])"
2384 "TARGET_ARM && !reg_overlap_mentioned_p (operands[0], operands[3])"
2385 [(parallel [(set (reg:CC_NOOV CC_REGNUM)
2386 (compare:CC_NOOV (ashift:SI (match_dup 1) (match_dup 2))
2388 (set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 2)))])
2390 (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
2391 (match_dup 0) (match_dup 3)))]
2393 operands[2] = GEN_INT (32 - INTVAL (operands[2]));
2395 [(set_attr "conds" "clob")
2396 (set_attr "length" "8")]
2400 [(set (match_operand:SI 0 "s_register_operand" "")
2401 (zero_extract:SI (match_operand:SI 1 "s_register_operand" "")
2402 (match_operand:SI 2 "const_int_operand" "")
2403 (match_operand:SI 3 "const_int_operand" "")))
2404 (clobber (match_operand:SI 4 "s_register_operand" ""))]
2406 [(set (match_dup 4) (ashift:SI (match_dup 1) (match_dup 2)))
2407 (set (match_dup 0) (lshiftrt:SI (match_dup 4) (match_dup 3)))]
2409 HOST_WIDE_INT temp = INTVAL (operands[2]);
2411 operands[2] = GEN_INT (32 - temp - INTVAL (operands[3]));
2412 operands[3] = GEN_INT (32 - temp);
2416 ;; ??? Use Thumb-2 has bitfield insert/extract instructions.
2418 [(set (match_operand:SI 0 "s_register_operand" "")
2419 (match_operator:SI 1 "shiftable_operator"
2420 [(zero_extract:SI (match_operand:SI 2 "s_register_operand" "")
2421 (match_operand:SI 3 "const_int_operand" "")
2422 (match_operand:SI 4 "const_int_operand" ""))
2423 (match_operand:SI 5 "s_register_operand" "")]))
2424 (clobber (match_operand:SI 6 "s_register_operand" ""))]
2426 [(set (match_dup 6) (ashift:SI (match_dup 2) (match_dup 3)))
2429 [(lshiftrt:SI (match_dup 6) (match_dup 4))
2432 HOST_WIDE_INT temp = INTVAL (operands[3]);
2434 operands[3] = GEN_INT (32 - temp - INTVAL (operands[4]));
2435 operands[4] = GEN_INT (32 - temp);
2440 [(set (match_operand:SI 0 "s_register_operand" "")
2441 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "")
2442 (match_operand:SI 2 "const_int_operand" "")
2443 (match_operand:SI 3 "const_int_operand" "")))]
2445 [(set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 2)))
2446 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (match_dup 3)))]
2448 HOST_WIDE_INT temp = INTVAL (operands[2]);
2450 operands[2] = GEN_INT (32 - temp - INTVAL (operands[3]));
2451 operands[3] = GEN_INT (32 - temp);
2456 [(set (match_operand:SI 0 "s_register_operand" "")
2457 (match_operator:SI 1 "shiftable_operator"
2458 [(sign_extract:SI (match_operand:SI 2 "s_register_operand" "")
2459 (match_operand:SI 3 "const_int_operand" "")
2460 (match_operand:SI 4 "const_int_operand" ""))
2461 (match_operand:SI 5 "s_register_operand" "")]))
2462 (clobber (match_operand:SI 6 "s_register_operand" ""))]
2464 [(set (match_dup 6) (ashift:SI (match_dup 2) (match_dup 3)))
2467 [(ashiftrt:SI (match_dup 6) (match_dup 4))
2470 HOST_WIDE_INT temp = INTVAL (operands[3]);
2472 operands[3] = GEN_INT (32 - temp - INTVAL (operands[4]));
2473 operands[4] = GEN_INT (32 - temp);
2477 ;;; ??? This pattern is bogus. If operand3 has bits outside the range
2478 ;;; represented by the bitfield, then this will produce incorrect results.
2479 ;;; Somewhere, the value needs to be truncated. On targets like the m68k,
2480 ;;; which have a real bit-field insert instruction, the truncation happens
2481 ;;; in the bit-field insert instruction itself. Since arm does not have a
2482 ;;; bit-field insert instruction, we would have to emit code here to truncate
2483 ;;; the value before we insert. This loses some of the advantage of having
2484 ;;; this insv pattern, so this pattern needs to be reevalutated.
2486 (define_expand "insv"
2487 [(set (zero_extract (match_operand 0 "nonimmediate_operand" "")
2488 (match_operand 1 "general_operand" "")
2489 (match_operand 2 "general_operand" ""))
2490 (match_operand 3 "reg_or_int_operand" ""))]
2491 "TARGET_ARM || arm_arch_thumb2"
2494 int start_bit = INTVAL (operands[2]);
2495 int width = INTVAL (operands[1]);
2496 HOST_WIDE_INT mask = (((HOST_WIDE_INT)1) << width) - 1;
2497 rtx target, subtarget;
2499 if (arm_arch_thumb2)
2501 if (unaligned_access && MEM_P (operands[0])
2502 && s_register_operand (operands[3], GET_MODE (operands[3]))
2503 && (width == 16 || width == 32) && (start_bit % BITS_PER_UNIT) == 0)
2507 if (BYTES_BIG_ENDIAN)
2508 start_bit = GET_MODE_BITSIZE (GET_MODE (operands[3])) - width
2513 base_addr = adjust_address (operands[0], SImode,
2514 start_bit / BITS_PER_UNIT);
2515 emit_insn (gen_unaligned_storesi (base_addr, operands[3]));
2519 rtx tmp = gen_reg_rtx (HImode);
2521 base_addr = adjust_address (operands[0], HImode,
2522 start_bit / BITS_PER_UNIT);
2523 emit_move_insn (tmp, gen_lowpart (HImode, operands[3]));
2524 emit_insn (gen_unaligned_storehi (base_addr, tmp));
2528 else if (s_register_operand (operands[0], GET_MODE (operands[0])))
2530 bool use_bfi = TRUE;
2532 if (GET_CODE (operands[3]) == CONST_INT)
2534 HOST_WIDE_INT val = INTVAL (operands[3]) & mask;
2538 emit_insn (gen_insv_zero (operands[0], operands[1],
2543 /* See if the set can be done with a single orr instruction. */
2544 if (val == mask && const_ok_for_arm (val << start_bit))
2550 if (GET_CODE (operands[3]) != REG)
2551 operands[3] = force_reg (SImode, operands[3]);
2553 emit_insn (gen_insv_t2 (operands[0], operands[1], operands[2],
2562 if (!s_register_operand (operands[0], GET_MODE (operands[0])))
2565 target = copy_rtx (operands[0]);
2566 /* Avoid using a subreg as a subtarget, and avoid writing a paradoxical
2567 subreg as the final target. */
2568 if (GET_CODE (target) == SUBREG)
2570 subtarget = gen_reg_rtx (SImode);
2571 if (GET_MODE_SIZE (GET_MODE (SUBREG_REG (target)))
2572 < GET_MODE_SIZE (SImode))
2573 target = SUBREG_REG (target);
2578 if (GET_CODE (operands[3]) == CONST_INT)
2580 /* Since we are inserting a known constant, we may be able to
2581 reduce the number of bits that we have to clear so that
2582 the mask becomes simple. */
2583 /* ??? This code does not check to see if the new mask is actually
2584 simpler. It may not be. */
2585 rtx op1 = gen_reg_rtx (SImode);
2586 /* ??? Truncate operand3 to fit in the bitfield. See comment before
2587 start of this pattern. */
2588 HOST_WIDE_INT op3_value = mask & INTVAL (operands[3]);
2589 HOST_WIDE_INT mask2 = ((mask & ~op3_value) << start_bit);
2591 emit_insn (gen_andsi3 (op1, operands[0],
2592 gen_int_mode (~mask2, SImode)));
2593 emit_insn (gen_iorsi3 (subtarget, op1,
2594 gen_int_mode (op3_value << start_bit, SImode)));
2596 else if (start_bit == 0
2597 && !(const_ok_for_arm (mask)
2598 || const_ok_for_arm (~mask)))
2600 /* A Trick, since we are setting the bottom bits in the word,
2601 we can shift operand[3] up, operand[0] down, OR them together
2602 and rotate the result back again. This takes 3 insns, and
2603 the third might be mergeable into another op. */
2604 /* The shift up copes with the possibility that operand[3] is
2605 wider than the bitfield. */
2606 rtx op0 = gen_reg_rtx (SImode);
2607 rtx op1 = gen_reg_rtx (SImode);
2609 emit_insn (gen_ashlsi3 (op0, operands[3], GEN_INT (32 - width)));
2610 emit_insn (gen_lshrsi3 (op1, operands[0], operands[1]));
2611 emit_insn (gen_iorsi3 (op1, op1, op0));
2612 emit_insn (gen_rotlsi3 (subtarget, op1, operands[1]));
2614 else if ((width + start_bit == 32)
2615 && !(const_ok_for_arm (mask)
2616 || const_ok_for_arm (~mask)))
2618 /* Similar trick, but slightly less efficient. */
2620 rtx op0 = gen_reg_rtx (SImode);
2621 rtx op1 = gen_reg_rtx (SImode);
2623 emit_insn (gen_ashlsi3 (op0, operands[3], GEN_INT (32 - width)));
2624 emit_insn (gen_ashlsi3 (op1, operands[0], operands[1]));
2625 emit_insn (gen_lshrsi3 (op1, op1, operands[1]));
2626 emit_insn (gen_iorsi3 (subtarget, op1, op0));
2630 rtx op0 = gen_int_mode (mask, SImode);
2631 rtx op1 = gen_reg_rtx (SImode);
2632 rtx op2 = gen_reg_rtx (SImode);
2634 if (!(const_ok_for_arm (mask) || const_ok_for_arm (~mask)))
2636 rtx tmp = gen_reg_rtx (SImode);
2638 emit_insn (gen_movsi (tmp, op0));
2642 /* Mask out any bits in operand[3] that are not needed. */
2643 emit_insn (gen_andsi3 (op1, operands[3], op0));
2645 if (GET_CODE (op0) == CONST_INT
2646 && (const_ok_for_arm (mask << start_bit)
2647 || const_ok_for_arm (~(mask << start_bit))))
2649 op0 = gen_int_mode (~(mask << start_bit), SImode);
2650 emit_insn (gen_andsi3 (op2, operands[0], op0));
2654 if (GET_CODE (op0) == CONST_INT)
2656 rtx tmp = gen_reg_rtx (SImode);
2658 emit_insn (gen_movsi (tmp, op0));
2663 emit_insn (gen_ashlsi3 (op0, op0, operands[2]));
2665 emit_insn (gen_andsi_notsi_si (op2, operands[0], op0));
2669 emit_insn (gen_ashlsi3 (op1, op1, operands[2]));
2671 emit_insn (gen_iorsi3 (subtarget, op1, op2));
2674 if (subtarget != target)
2676 /* If TARGET is still a SUBREG, then it must be wider than a word,
2677 so we must be careful only to set the subword we were asked to. */
2678 if (GET_CODE (target) == SUBREG)
2679 emit_move_insn (target, subtarget);
2681 emit_move_insn (target, gen_lowpart (GET_MODE (target), subtarget));
2688 (define_insn "insv_zero"
2689 [(set (zero_extract:SI (match_operand:SI 0 "s_register_operand" "+r")
2690 (match_operand:SI 1 "const_int_operand" "M")
2691 (match_operand:SI 2 "const_int_operand" "M"))
2695 [(set_attr "length" "4")
2696 (set_attr "predicable" "yes")]
2699 (define_insn "insv_t2"
2700 [(set (zero_extract:SI (match_operand:SI 0 "s_register_operand" "+r")
2701 (match_operand:SI 1 "const_int_operand" "M")
2702 (match_operand:SI 2 "const_int_operand" "M"))
2703 (match_operand:SI 3 "s_register_operand" "r"))]
2705 "bfi%?\t%0, %3, %2, %1"
2706 [(set_attr "length" "4")
2707 (set_attr "predicable" "yes")]
2710 ; constants for op 2 will never be given to these patterns.
2711 (define_insn_and_split "*anddi_notdi_di"
2712 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2713 (and:DI (not:DI (match_operand:DI 1 "s_register_operand" "0,r"))
2714 (match_operand:DI 2 "s_register_operand" "r,0")))]
2717 "TARGET_32BIT && reload_completed
2718 && ! (TARGET_NEON && IS_VFP_REGNUM (REGNO (operands[0])))
2719 && ! IS_IWMMXT_REGNUM (REGNO (operands[0]))"
2720 [(set (match_dup 0) (and:SI (not:SI (match_dup 1)) (match_dup 2)))
2721 (set (match_dup 3) (and:SI (not:SI (match_dup 4)) (match_dup 5)))]
2724 operands[3] = gen_highpart (SImode, operands[0]);
2725 operands[0] = gen_lowpart (SImode, operands[0]);
2726 operands[4] = gen_highpart (SImode, operands[1]);
2727 operands[1] = gen_lowpart (SImode, operands[1]);
2728 operands[5] = gen_highpart (SImode, operands[2]);
2729 operands[2] = gen_lowpart (SImode, operands[2]);
2731 [(set_attr "length" "8")
2732 (set_attr "predicable" "yes")]
2735 (define_insn_and_split "*anddi_notzesidi_di"
2736 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2737 (and:DI (not:DI (zero_extend:DI
2738 (match_operand:SI 2 "s_register_operand" "r,r")))
2739 (match_operand:DI 1 "s_register_operand" "0,?r")))]
2742 bic%?\\t%Q0, %Q1, %2
2744 ; (not (zero_extend ...)) allows us to just copy the high word from
2745 ; operand1 to operand0.
2748 && operands[0] != operands[1]"
2749 [(set (match_dup 0) (and:SI (not:SI (match_dup 2)) (match_dup 1)))
2750 (set (match_dup 3) (match_dup 4))]
2753 operands[3] = gen_highpart (SImode, operands[0]);
2754 operands[0] = gen_lowpart (SImode, operands[0]);
2755 operands[4] = gen_highpart (SImode, operands[1]);
2756 operands[1] = gen_lowpart (SImode, operands[1]);
2758 [(set_attr "length" "4,8")
2759 (set_attr "predicable" "yes")]
2762 (define_insn_and_split "*anddi_notsesidi_di"
2763 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2764 (and:DI (not:DI (sign_extend:DI
2765 (match_operand:SI 2 "s_register_operand" "r,r")))
2766 (match_operand:DI 1 "s_register_operand" "0,r")))]
2769 "TARGET_32BIT && reload_completed"
2770 [(set (match_dup 0) (and:SI (not:SI (match_dup 2)) (match_dup 1)))
2771 (set (match_dup 3) (and:SI (not:SI
2772 (ashiftrt:SI (match_dup 2) (const_int 31)))
2776 operands[3] = gen_highpart (SImode, operands[0]);
2777 operands[0] = gen_lowpart (SImode, operands[0]);
2778 operands[4] = gen_highpart (SImode, operands[1]);
2779 operands[1] = gen_lowpart (SImode, operands[1]);
2781 [(set_attr "length" "8")
2782 (set_attr "predicable" "yes")]
2785 (define_insn "andsi_notsi_si"
2786 [(set (match_operand:SI 0 "s_register_operand" "=r")
2787 (and:SI (not:SI (match_operand:SI 2 "s_register_operand" "r"))
2788 (match_operand:SI 1 "s_register_operand" "r")))]
2790 "bic%?\\t%0, %1, %2"
2791 [(set_attr "predicable" "yes")]
2794 (define_insn "thumb1_bicsi3"
2795 [(set (match_operand:SI 0 "register_operand" "=l")
2796 (and:SI (not:SI (match_operand:SI 1 "register_operand" "l"))
2797 (match_operand:SI 2 "register_operand" "0")))]
2800 [(set_attr "length" "2")
2801 (set_attr "conds" "set")])
2803 (define_insn "andsi_not_shiftsi_si"
2804 [(set (match_operand:SI 0 "s_register_operand" "=r")
2805 (and:SI (not:SI (match_operator:SI 4 "shift_operator"
2806 [(match_operand:SI 2 "s_register_operand" "r")
2807 (match_operand:SI 3 "arm_rhs_operand" "rM")]))
2808 (match_operand:SI 1 "s_register_operand" "r")))]
2810 "bic%?\\t%0, %1, %2%S4"
2811 [(set_attr "predicable" "yes")
2812 (set_attr "shift" "2")
2813 (set (attr "type") (if_then_else (match_operand 3 "const_int_operand" "")
2814 (const_string "alu_shift")
2815 (const_string "alu_shift_reg")))]
2818 (define_insn "*andsi_notsi_si_compare0"
2819 [(set (reg:CC_NOOV CC_REGNUM)
2821 (and:SI (not:SI (match_operand:SI 2 "s_register_operand" "r"))
2822 (match_operand:SI 1 "s_register_operand" "r"))
2824 (set (match_operand:SI 0 "s_register_operand" "=r")
2825 (and:SI (not:SI (match_dup 2)) (match_dup 1)))]
2827 "bic%.\\t%0, %1, %2"
2828 [(set_attr "conds" "set")]
2831 (define_insn "*andsi_notsi_si_compare0_scratch"
2832 [(set (reg:CC_NOOV CC_REGNUM)
2834 (and:SI (not:SI (match_operand:SI 2 "s_register_operand" "r"))
2835 (match_operand:SI 1 "s_register_operand" "r"))
2837 (clobber (match_scratch:SI 0 "=r"))]
2839 "bic%.\\t%0, %1, %2"
2840 [(set_attr "conds" "set")]
2843 (define_expand "iordi3"
2844 [(set (match_operand:DI 0 "s_register_operand" "")
2845 (ior:DI (match_operand:DI 1 "s_register_operand" "")
2846 (match_operand:DI 2 "neon_logic_op2" "")))]
2851 (define_insn "*iordi3_insn"
2852 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2853 (ior:DI (match_operand:DI 1 "s_register_operand" "%0,r")
2854 (match_operand:DI 2 "s_register_operand" "r,r")))]
2855 "TARGET_32BIT && !TARGET_IWMMXT && !TARGET_NEON"
2857 [(set_attr "length" "8")
2858 (set_attr "predicable" "yes")]
2861 (define_insn "*iordi_zesidi_di"
2862 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2863 (ior:DI (zero_extend:DI
2864 (match_operand:SI 2 "s_register_operand" "r,r"))
2865 (match_operand:DI 1 "s_register_operand" "0,?r")))]
2868 orr%?\\t%Q0, %Q1, %2
2870 [(set_attr "length" "4,8")
2871 (set_attr "predicable" "yes")]
2874 (define_insn "*iordi_sesidi_di"
2875 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2876 (ior:DI (sign_extend:DI
2877 (match_operand:SI 2 "s_register_operand" "r,r"))
2878 (match_operand:DI 1 "s_register_operand" "0,r")))]
2881 [(set_attr "length" "8")
2882 (set_attr "predicable" "yes")]
2885 (define_expand "iorsi3"
2886 [(set (match_operand:SI 0 "s_register_operand" "")
2887 (ior:SI (match_operand:SI 1 "s_register_operand" "")
2888 (match_operand:SI 2 "reg_or_int_operand" "")))]
2891 if (GET_CODE (operands[2]) == CONST_INT)
2895 arm_split_constant (IOR, SImode, NULL_RTX,
2896 INTVAL (operands[2]), operands[0], operands[1],
2897 optimize && can_create_pseudo_p ());
2900 else /* TARGET_THUMB1 */
2902 rtx tmp = force_reg (SImode, operands[2]);
2903 if (rtx_equal_p (operands[0], operands[1]))
2907 operands[2] = operands[1];
2915 (define_insn_and_split "*iorsi3_insn"
2916 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
2917 (ior:SI (match_operand:SI 1 "s_register_operand" "%r,r,r")
2918 (match_operand:SI 2 "reg_or_int_operand" "rI,K,?n")))]
2922 orn%?\\t%0, %1, #%B2
2925 && GET_CODE (operands[2]) == CONST_INT
2926 && !(const_ok_for_arm (INTVAL (operands[2]))
2927 || (TARGET_THUMB2 && const_ok_for_arm (~INTVAL (operands[2]))))"
2928 [(clobber (const_int 0))]
2930 arm_split_constant (IOR, SImode, curr_insn,
2931 INTVAL (operands[2]), operands[0], operands[1], 0);
2934 [(set_attr "length" "4,4,16")
2935 (set_attr "arch" "32,t2,32")
2936 (set_attr "predicable" "yes")])
2938 (define_insn "*thumb1_iorsi3_insn"
2939 [(set (match_operand:SI 0 "register_operand" "=l")
2940 (ior:SI (match_operand:SI 1 "register_operand" "%0")
2941 (match_operand:SI 2 "register_operand" "l")))]
2944 [(set_attr "length" "2")
2945 (set_attr "conds" "set")])
2948 [(match_scratch:SI 3 "r")
2949 (set (match_operand:SI 0 "arm_general_register_operand" "")
2950 (ior:SI (match_operand:SI 1 "arm_general_register_operand" "")
2951 (match_operand:SI 2 "const_int_operand" "")))]
2953 && !const_ok_for_arm (INTVAL (operands[2]))
2954 && const_ok_for_arm (~INTVAL (operands[2]))"
2955 [(set (match_dup 3) (match_dup 2))
2956 (set (match_dup 0) (ior:SI (match_dup 1) (match_dup 3)))]
2960 (define_insn "*iorsi3_compare0"
2961 [(set (reg:CC_NOOV CC_REGNUM)
2962 (compare:CC_NOOV (ior:SI (match_operand:SI 1 "s_register_operand" "%r")
2963 (match_operand:SI 2 "arm_rhs_operand" "rI"))
2965 (set (match_operand:SI 0 "s_register_operand" "=r")
2966 (ior:SI (match_dup 1) (match_dup 2)))]
2968 "orr%.\\t%0, %1, %2"
2969 [(set_attr "conds" "set")]
2972 (define_insn "*iorsi3_compare0_scratch"
2973 [(set (reg:CC_NOOV CC_REGNUM)
2974 (compare:CC_NOOV (ior:SI (match_operand:SI 1 "s_register_operand" "%r")
2975 (match_operand:SI 2 "arm_rhs_operand" "rI"))
2977 (clobber (match_scratch:SI 0 "=r"))]
2979 "orr%.\\t%0, %1, %2"
2980 [(set_attr "conds" "set")]
2983 (define_expand "xordi3"
2984 [(set (match_operand:DI 0 "s_register_operand" "")
2985 (xor:DI (match_operand:DI 1 "s_register_operand" "")
2986 (match_operand:DI 2 "s_register_operand" "")))]
2991 (define_insn "*xordi3_insn"
2992 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2993 (xor:DI (match_operand:DI 1 "s_register_operand" "%0,r")
2994 (match_operand:DI 2 "s_register_operand" "r,r")))]
2995 "TARGET_32BIT && !TARGET_IWMMXT && !TARGET_NEON"
2997 [(set_attr "length" "8")
2998 (set_attr "predicable" "yes")]
3001 (define_insn "*xordi_zesidi_di"
3002 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
3003 (xor:DI (zero_extend:DI
3004 (match_operand:SI 2 "s_register_operand" "r,r"))
3005 (match_operand:DI 1 "s_register_operand" "0,?r")))]
3008 eor%?\\t%Q0, %Q1, %2
3010 [(set_attr "length" "4,8")
3011 (set_attr "predicable" "yes")]
3014 (define_insn "*xordi_sesidi_di"
3015 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
3016 (xor:DI (sign_extend:DI
3017 (match_operand:SI 2 "s_register_operand" "r,r"))
3018 (match_operand:DI 1 "s_register_operand" "0,r")))]
3021 [(set_attr "length" "8")
3022 (set_attr "predicable" "yes")]
3025 (define_expand "xorsi3"
3026 [(set (match_operand:SI 0 "s_register_operand" "")
3027 (xor:SI (match_operand:SI 1 "s_register_operand" "")
3028 (match_operand:SI 2 "reg_or_int_operand" "")))]
3030 "if (GET_CODE (operands[2]) == CONST_INT)
3034 arm_split_constant (XOR, SImode, NULL_RTX,
3035 INTVAL (operands[2]), operands[0], operands[1],
3036 optimize && can_create_pseudo_p ());
3039 else /* TARGET_THUMB1 */
3041 rtx tmp = force_reg (SImode, operands[2]);
3042 if (rtx_equal_p (operands[0], operands[1]))
3046 operands[2] = operands[1];
3053 (define_insn_and_split "*arm_xorsi3"
3054 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
3055 (xor:SI (match_operand:SI 1 "s_register_operand" "%r,r")
3056 (match_operand:SI 2 "reg_or_int_operand" "rI,?n")))]
3062 && GET_CODE (operands[2]) == CONST_INT
3063 && !const_ok_for_arm (INTVAL (operands[2]))"
3064 [(clobber (const_int 0))]
3066 arm_split_constant (XOR, SImode, curr_insn,
3067 INTVAL (operands[2]), operands[0], operands[1], 0);
3070 [(set_attr "length" "4,16")
3071 (set_attr "predicable" "yes")]
3074 (define_insn "*thumb1_xorsi3_insn"
3075 [(set (match_operand:SI 0 "register_operand" "=l")
3076 (xor:SI (match_operand:SI 1 "register_operand" "%0")
3077 (match_operand:SI 2 "register_operand" "l")))]
3080 [(set_attr "length" "2")
3081 (set_attr "conds" "set")])
3083 (define_insn "*xorsi3_compare0"
3084 [(set (reg:CC_NOOV CC_REGNUM)
3085 (compare:CC_NOOV (xor:SI (match_operand:SI 1 "s_register_operand" "r")
3086 (match_operand:SI 2 "arm_rhs_operand" "rI"))
3088 (set (match_operand:SI 0 "s_register_operand" "=r")
3089 (xor:SI (match_dup 1) (match_dup 2)))]
3091 "eor%.\\t%0, %1, %2"
3092 [(set_attr "conds" "set")]
3095 (define_insn "*xorsi3_compare0_scratch"
3096 [(set (reg:CC_NOOV CC_REGNUM)
3097 (compare:CC_NOOV (xor:SI (match_operand:SI 0 "s_register_operand" "r")
3098 (match_operand:SI 1 "arm_rhs_operand" "rI"))
3102 [(set_attr "conds" "set")]
3105 ; By splitting (IOR (AND (NOT A) (NOT B)) C) as D = AND (IOR A B) (NOT C),
3106 ; (NOT D) we can sometimes merge the final NOT into one of the following
3110 [(set (match_operand:SI 0 "s_register_operand" "")
3111 (ior:SI (and:SI (not:SI (match_operand:SI 1 "s_register_operand" ""))
3112 (not:SI (match_operand:SI 2 "arm_rhs_operand" "")))
3113 (match_operand:SI 3 "arm_rhs_operand" "")))
3114 (clobber (match_operand:SI 4 "s_register_operand" ""))]
3116 [(set (match_dup 4) (and:SI (ior:SI (match_dup 1) (match_dup 2))
3117 (not:SI (match_dup 3))))
3118 (set (match_dup 0) (not:SI (match_dup 4)))]
3122 (define_insn "*andsi_iorsi3_notsi"
3123 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r")
3124 (and:SI (ior:SI (match_operand:SI 1 "s_register_operand" "%0,r,r")
3125 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI"))
3126 (not:SI (match_operand:SI 3 "arm_rhs_operand" "rI,rI,rI"))))]
3128 "orr%?\\t%0, %1, %2\;bic%?\\t%0, %0, %3"
3129 [(set_attr "length" "8")
3130 (set_attr "ce_count" "2")
3131 (set_attr "predicable" "yes")]
3134 ; ??? Are these four splitters still beneficial when the Thumb-2 bitfield
3135 ; insns are available?
3137 [(set (match_operand:SI 0 "s_register_operand" "")
3138 (match_operator:SI 1 "logical_binary_operator"
3139 [(zero_extract:SI (match_operand:SI 2 "s_register_operand" "")
3140 (match_operand:SI 3 "const_int_operand" "")
3141 (match_operand:SI 4 "const_int_operand" ""))
3142 (match_operator:SI 9 "logical_binary_operator"
3143 [(lshiftrt:SI (match_operand:SI 5 "s_register_operand" "")
3144 (match_operand:SI 6 "const_int_operand" ""))
3145 (match_operand:SI 7 "s_register_operand" "")])]))
3146 (clobber (match_operand:SI 8 "s_register_operand" ""))]
3148 && GET_CODE (operands[1]) == GET_CODE (operands[9])
3149 && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
3152 [(ashift:SI (match_dup 2) (match_dup 4))
3156 [(lshiftrt:SI (match_dup 8) (match_dup 6))
3159 operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
3163 [(set (match_operand:SI 0 "s_register_operand" "")
3164 (match_operator:SI 1 "logical_binary_operator"
3165 [(match_operator:SI 9 "logical_binary_operator"
3166 [(lshiftrt:SI (match_operand:SI 5 "s_register_operand" "")
3167 (match_operand:SI 6 "const_int_operand" ""))
3168 (match_operand:SI 7 "s_register_operand" "")])
3169 (zero_extract:SI (match_operand:SI 2 "s_register_operand" "")
3170 (match_operand:SI 3 "const_int_operand" "")
3171 (match_operand:SI 4 "const_int_operand" ""))]))
3172 (clobber (match_operand:SI 8 "s_register_operand" ""))]
3174 && GET_CODE (operands[1]) == GET_CODE (operands[9])
3175 && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
3178 [(ashift:SI (match_dup 2) (match_dup 4))
3182 [(lshiftrt:SI (match_dup 8) (match_dup 6))
3185 operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
3189 [(set (match_operand:SI 0 "s_register_operand" "")
3190 (match_operator:SI 1 "logical_binary_operator"
3191 [(sign_extract:SI (match_operand:SI 2 "s_register_operand" "")
3192 (match_operand:SI 3 "const_int_operand" "")
3193 (match_operand:SI 4 "const_int_operand" ""))
3194 (match_operator:SI 9 "logical_binary_operator"
3195 [(ashiftrt:SI (match_operand:SI 5 "s_register_operand" "")
3196 (match_operand:SI 6 "const_int_operand" ""))
3197 (match_operand:SI 7 "s_register_operand" "")])]))
3198 (clobber (match_operand:SI 8 "s_register_operand" ""))]
3200 && GET_CODE (operands[1]) == GET_CODE (operands[9])
3201 && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
3204 [(ashift:SI (match_dup 2) (match_dup 4))
3208 [(ashiftrt:SI (match_dup 8) (match_dup 6))
3211 operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
3215 [(set (match_operand:SI 0 "s_register_operand" "")
3216 (match_operator:SI 1 "logical_binary_operator"
3217 [(match_operator:SI 9 "logical_binary_operator"
3218 [(ashiftrt:SI (match_operand:SI 5 "s_register_operand" "")
3219 (match_operand:SI 6 "const_int_operand" ""))
3220 (match_operand:SI 7 "s_register_operand" "")])
3221 (sign_extract:SI (match_operand:SI 2 "s_register_operand" "")
3222 (match_operand:SI 3 "const_int_operand" "")
3223 (match_operand:SI 4 "const_int_operand" ""))]))
3224 (clobber (match_operand:SI 8 "s_register_operand" ""))]
3226 && GET_CODE (operands[1]) == GET_CODE (operands[9])
3227 && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
3230 [(ashift:SI (match_dup 2) (match_dup 4))
3234 [(ashiftrt:SI (match_dup 8) (match_dup 6))
3237 operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
3241 ;; Minimum and maximum insns
3243 (define_expand "smaxsi3"
3245 (set (match_operand:SI 0 "s_register_operand" "")
3246 (smax:SI (match_operand:SI 1 "s_register_operand" "")
3247 (match_operand:SI 2 "arm_rhs_operand" "")))
3248 (clobber (reg:CC CC_REGNUM))])]
3251 if (operands[2] == const0_rtx || operands[2] == constm1_rtx)
3253 /* No need for a clobber of the condition code register here. */
3254 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
3255 gen_rtx_SMAX (SImode, operands[1],
3261 (define_insn "*smax_0"
3262 [(set (match_operand:SI 0 "s_register_operand" "=r")
3263 (smax:SI (match_operand:SI 1 "s_register_operand" "r")
3266 "bic%?\\t%0, %1, %1, asr #31"
3267 [(set_attr "predicable" "yes")]
3270 (define_insn "*smax_m1"
3271 [(set (match_operand:SI 0 "s_register_operand" "=r")
3272 (smax:SI (match_operand:SI 1 "s_register_operand" "r")
3275 "orr%?\\t%0, %1, %1, asr #31"
3276 [(set_attr "predicable" "yes")]
3279 (define_insn "*arm_smax_insn"
3280 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
3281 (smax:SI (match_operand:SI 1 "s_register_operand" "%0,?r")
3282 (match_operand:SI 2 "arm_rhs_operand" "rI,rI")))
3283 (clobber (reg:CC CC_REGNUM))]
3286 cmp\\t%1, %2\;movlt\\t%0, %2
3287 cmp\\t%1, %2\;movge\\t%0, %1\;movlt\\t%0, %2"
3288 [(set_attr "conds" "clob")
3289 (set_attr "length" "8,12")]
3292 (define_expand "sminsi3"
3294 (set (match_operand:SI 0 "s_register_operand" "")
3295 (smin:SI (match_operand:SI 1 "s_register_operand" "")
3296 (match_operand:SI 2 "arm_rhs_operand" "")))
3297 (clobber (reg:CC CC_REGNUM))])]
3300 if (operands[2] == const0_rtx)
3302 /* No need for a clobber of the condition code register here. */
3303 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
3304 gen_rtx_SMIN (SImode, operands[1],
3310 (define_insn "*smin_0"
3311 [(set (match_operand:SI 0 "s_register_operand" "=r")
3312 (smin:SI (match_operand:SI 1 "s_register_operand" "r")
3315 "and%?\\t%0, %1, %1, asr #31"
3316 [(set_attr "predicable" "yes")]
3319 (define_insn "*arm_smin_insn"
3320 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
3321 (smin:SI (match_operand:SI 1 "s_register_operand" "%0,?r")
3322 (match_operand:SI 2 "arm_rhs_operand" "rI,rI")))
3323 (clobber (reg:CC CC_REGNUM))]
3326 cmp\\t%1, %2\;movge\\t%0, %2
3327 cmp\\t%1, %2\;movlt\\t%0, %1\;movge\\t%0, %2"
3328 [(set_attr "conds" "clob")
3329 (set_attr "length" "8,12")]
3332 (define_expand "umaxsi3"
3334 (set (match_operand:SI 0 "s_register_operand" "")
3335 (umax:SI (match_operand:SI 1 "s_register_operand" "")
3336 (match_operand:SI 2 "arm_rhs_operand" "")))
3337 (clobber (reg:CC CC_REGNUM))])]