]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/config/arm/arm.md
Fix typo in comment
[thirdparty/gcc.git] / gcc / config / arm / arm.md
CommitLineData
129a2fe4 1;;- Machine description for ARM for GNU compiler
711789cc 2;; Copyright (C) 1991-2013 Free Software Foundation, Inc.
b11cae9e 3;; Contributed by Pieter `Tiggr' Schoenmakers (rcpieter@win.tue.nl)
f082f1c4 4;; and Martin Simmons (@harleqn.co.uk).
129a2fe4 5;; More major hacks by Richard Earnshaw (rearnsha@arm.com).
b11cae9e 6
acf6ed70 7;; This file is part of GCC.
b11cae9e 8
acf6ed70 9;; GCC is free software; you can redistribute it and/or modify it
10;; under the terms of the GNU General Public License as published
038d1e19 11;; by the Free Software Foundation; either version 3, or (at your
acf6ed70 12;; option) any later version.
b11cae9e 13
acf6ed70 14;; GCC is distributed in the hope that it will be useful, but WITHOUT
15;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
16;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
17;; License for more details.
b11cae9e 18
19;; You should have received a copy of the GNU General Public License
038d1e19 20;; along with GCC; see the file COPYING3. If not see
21;; <http://www.gnu.org/licenses/>.
b11cae9e 22
23;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
24
cb860649 25;; Beware of splitting Thumb1 patterns that output multiple
26;; assembly instructions, in particular instruction such as SBC and
27;; ADC which consume flags. For example, in the pattern thumb_subdi3
28;; below, the output SUB implicitly sets the flags (assembled to SUBS)
29;; and then the Carry flag is used by SBC to compute the correct
30;; result. If we split thumb_subdi3 pattern into two separate RTL
31;; insns (using define_insn_and_split), the scheduler might place
32;; other RTL insns between SUB and SBC, possibly modifying the Carry
33;; flag used by SBC. This might happen because most Thumb1 patterns
34;; for flag-setting instructions do not have explicit RTL for setting
35;; or clobbering the flags. Instead, they have the attribute "conds"
36;; with value "set" or "clob". However, this attribute is not used to
37;; identify dependencies and therefore the scheduler might reorder
38;; these instruction. Currenly, this problem cannot happen because
39;; there are no separate Thumb1 patterns for individual instruction
40;; that consume flags (except conditional execution, which is treated
41;; differently). In particular there is no Thumb1 armv6-m pattern for
42;; sbc or adc.
43
9c08d1fa 44\f
e1159bbe 45;;---------------------------------------------------------------------------
46;; Constants
47
bffbb863 48;; Register numbers -- All machine registers should be defined here
e1159bbe 49(define_constants
bffbb863 50 [(R0_REGNUM 0) ; First CORE register
51 (R1_REGNUM 1) ; Second CORE register
52 (IP_REGNUM 12) ; Scratch register
53 (SP_REGNUM 13) ; Stack pointer
54 (LR_REGNUM 14) ; Return address register
55 (PC_REGNUM 15) ; Program counter
56 (LAST_ARM_REGNUM 15) ;
57 (CC_REGNUM 100) ; Condition code pseudo register
58 (VFPCC_REGNUM 101) ; VFP Condition code pseudo register
e1159bbe 59 ]
60)
3c5afce6 61;; 3rd operand to select_dominance_cc_mode
62(define_constants
63 [(DOM_CC_X_AND_Y 0)
64 (DOM_CC_NX_OR_Y 1)
65 (DOM_CC_X_OR_Y 2)
66 ]
67)
2ff91fec 68;; conditional compare combination
69(define_constants
70 [(CMP_CMP 0)
71 (CMN_CMP 1)
72 (CMP_CMN 2)
73 (CMN_CMN 3)
74 (NUM_OF_COND_CMP 4)
75 ]
76)
e1159bbe 77
b11cae9e 78\f
e1159bbe 79;;---------------------------------------------------------------------------
9c08d1fa 80;; Attributes
81
a651f34d 82;; Processor type. This is created automatically from arm-cores.def.
83(include "arm-tune.md")
84
215b30b3 85; IS_THUMB is set to 'yes' when we are generating Thumb code, and 'no' when
86; generating ARM code. This is used to control the length of some insn
87; patterns that share the same RTL in both ARM and Thumb code.
1c494086 88(define_attr "is_thumb" "no,yes" (const (symbol_ref "thumb_code")))
cffb2a26 89
ef51b8e1 90; IS_ARCH6 is set to 'yes' when we are generating code form ARMv6.
91(define_attr "is_arch6" "no,yes" (const (symbol_ref "arm_arch6")))
92
747b7458 93; IS_THUMB1 is set to 'yes' iff we are generating Thumb-1 code.
94(define_attr "is_thumb1" "no,yes" (const (symbol_ref "thumb1_code")))
95
c7a58118 96; We use this attribute to disable alternatives that can produce 32-bit
97; instructions inside an IT-block in Thumb2 state. ARMv8 deprecates IT blocks
98; that contain 32-bit instructions.
99(define_attr "enabled_for_depr_it" "no,yes" (const_string "yes"))
100
101; This attribute is used to disable a predicated alternative when we have
102; arm_restrict_it.
103(define_attr "predicable_short_it" "no,yes" (const_string "yes"))
104
331beb1a 105;; Operand number of an input operand that is shifted. Zero if the
106;; given instruction does not shift one of its input operands.
331beb1a 107(define_attr "shift" "" (const_int 0))
108
3d91c5d6 109; Floating Point Unit. If we only have floating point emulation, then there
110; is no point in scheduling the floating point insns. (Well, for best
111; performance we should try and group them together).
bffbb863 112(define_attr "fpu" "none,vfp"
c7f506fd 113 (const (symbol_ref "arm_fpu_attr")))
3d91c5d6 114
c7a58118 115(define_attr "predicated" "yes,no" (const_string "no"))
116
094e994f 117; LENGTH of an instruction (in bytes)
06df6b17 118(define_attr "length" ""
e1b93706 119 (const_int 4))
9c08d1fa 120
d5d4dc8d 121; The architecture which supports the instruction (or alternative).
122; This can be "a" for ARM, "t" for either of the Thumbs, "32" for
123; TARGET_32BIT, "t1" or "t2" to specify a specific Thumb mode. "v6"
124; for ARM or Thumb-2 with arm_arch6, and nov6 for ARM without
125; arm_arch6. This attribute is used to compute attribute "enabled",
126; use type "any" to enable an alternative in all cases.
b6779ddc 127(define_attr "arch" "any,a,t,32,t1,t2,v6,nov6,neon_for_64bits,avoid_neon_for_64bits,iwmmxt,iwmmxt2"
d5d4dc8d 128 (const_string "any"))
129
130(define_attr "arch_enabled" "no,yes"
131 (cond [(eq_attr "arch" "any")
132 (const_string "yes")
133
134 (and (eq_attr "arch" "a")
0bf497f5 135 (match_test "TARGET_ARM"))
d5d4dc8d 136 (const_string "yes")
137
138 (and (eq_attr "arch" "t")
0bf497f5 139 (match_test "TARGET_THUMB"))
d5d4dc8d 140 (const_string "yes")
141
142 (and (eq_attr "arch" "t1")
0bf497f5 143 (match_test "TARGET_THUMB1"))
d5d4dc8d 144 (const_string "yes")
145
146 (and (eq_attr "arch" "t2")
0bf497f5 147 (match_test "TARGET_THUMB2"))
d5d4dc8d 148 (const_string "yes")
149
150 (and (eq_attr "arch" "32")
0bf497f5 151 (match_test "TARGET_32BIT"))
d5d4dc8d 152 (const_string "yes")
153
154 (and (eq_attr "arch" "v6")
0bf497f5 155 (match_test "TARGET_32BIT && arm_arch6"))
d5d4dc8d 156 (const_string "yes")
157
158 (and (eq_attr "arch" "nov6")
0bf497f5 159 (match_test "TARGET_32BIT && !arm_arch6"))
a651f34d 160 (const_string "yes")
161
b6779ddc 162 (and (eq_attr "arch" "avoid_neon_for_64bits")
163 (match_test "TARGET_NEON")
164 (not (match_test "TARGET_PREFER_NEON_64BITS")))
a651f34d 165 (const_string "yes")
166
b6779ddc 167 (and (eq_attr "arch" "neon_for_64bits")
168 (match_test "TARGET_NEON")
169 (match_test "TARGET_PREFER_NEON_64BITS"))
6b8f7c28 170 (const_string "yes")
171
172 (and (eq_attr "arch" "iwmmxt2")
173 (match_test "TARGET_REALLY_IWMMXT2"))
d5d4dc8d 174 (const_string "yes")]
6b8f7c28 175
d5d4dc8d 176 (const_string "no")))
177
aa06c51c 178(define_attr "opt" "any,speed,size"
179 (const_string "any"))
180
181(define_attr "opt_enabled" "no,yes"
182 (cond [(eq_attr "opt" "any")
183 (const_string "yes")
184
185 (and (eq_attr "opt" "speed")
186 (match_test "optimize_function_for_speed_p (cfun)"))
187 (const_string "yes")
188
189 (and (eq_attr "opt" "size")
190 (match_test "optimize_function_for_size_p (cfun)"))
191 (const_string "yes")]
192 (const_string "no")))
193
d5d4dc8d 194; Allows an insn to disable certain alternatives for reasons other than
195; arch support.
196(define_attr "insn_enabled" "no,yes"
197 (const_string "yes"))
198
199; Enable all alternatives that are both arch_enabled and insn_enabled.
93b431d9 200 (define_attr "enabled" "no,yes"
aa06c51c 201 (cond [(eq_attr "insn_enabled" "no")
202 (const_string "no")
203
c7a58118 204 (and (eq_attr "predicable_short_it" "no")
205 (and (eq_attr "predicated" "yes")
206 (match_test "arm_restrict_it")))
207 (const_string "no")
208
209 (and (eq_attr "enabled_for_depr_it" "no")
210 (match_test "arm_restrict_it"))
211 (const_string "no")
212
aa06c51c 213 (eq_attr "arch_enabled" "no")
214 (const_string "no")
215
216 (eq_attr "opt_enabled" "no")
217 (const_string "no")]
218 (const_string "yes")))
d5d4dc8d 219
56d27660 220; POOL_RANGE is how far away from a constant pool entry that this insn
221; can be placed. If the distance is zero, then this insn will never
222; reference the pool.
42e1de19 223; Note that for Thumb constant pools the PC value is rounded down to the
224; nearest multiple of four. Therefore, THUMB2_POOL_RANGE (and POOL_RANGE for
225; Thumb insns) should be set to <max_range> - 2.
cffb2a26 226; NEG_POOL_RANGE is nonzero for insns that can reference a constant pool entry
8848d797 227; before its address. It is set to <max_range> - (8 + <data_size>).
cde1623a 228(define_attr "arm_pool_range" "" (const_int 0))
229(define_attr "thumb2_pool_range" "" (const_int 0))
230(define_attr "arm_neg_pool_range" "" (const_int 0))
231(define_attr "thumb2_neg_pool_range" "" (const_int 0))
232
233(define_attr "pool_range" ""
234 (cond [(eq_attr "is_thumb" "yes") (attr "thumb2_pool_range")]
235 (attr "arm_pool_range")))
236(define_attr "neg_pool_range" ""
237 (cond [(eq_attr "is_thumb" "yes") (attr "thumb2_neg_pool_range")]
238 (attr "arm_neg_pool_range")))
56d27660 239
215b30b3 240; An assembler sequence may clobber the condition codes without us knowing.
4d7a8451 241; If such an insn references the pool, then we have no way of knowing how,
242; so use the most conservative value for pool_range.
9c08d1fa 243(define_asm_attributes
4d7a8451 244 [(set_attr "conds" "clob")
245 (set_attr "length" "4")
246 (set_attr "pool_range" "250")])
9c08d1fa 247
e15a9970 248;; Instruction classification types
249(include "types.md")
65f2f758 250
9888ad6d 251; Load scheduling, set from the arm_ld_sched variable
4c834714 252; initialized by arm_option_override()
9888ad6d 253(define_attr "ldsched" "no,yes" (const (symbol_ref "arm_ld_sched")))
849170fd 254
c52acdd2 255;; Classification of NEON instructions for scheduling purposes.
c52acdd2 256(define_attr "neon_type"
257 "neon_int_1,\
258 neon_int_2,\
259 neon_int_3,\
260 neon_int_4,\
261 neon_int_5,\
262 neon_vqneg_vqabs,\
263 neon_vmov,\
264 neon_vaba,\
265 neon_vsma,\
266 neon_vaba_qqq,\
267 neon_mul_ddd_8_16_qdd_16_8_long_32_16_long,\
268 neon_mul_qqq_8_16_32_ddd_32,\
269 neon_mul_qdd_64_32_long_qqd_16_ddd_32_scalar_64_32_long_scalar,\
270 neon_mla_ddd_8_16_qdd_16_8_long_32_16_long,\
271 neon_mla_qqq_8_16,\
272 neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long,\
273 neon_mla_qqq_32_qqd_32_scalar,\
274 neon_mul_ddd_16_scalar_32_16_long_scalar,\
275 neon_mul_qqd_32_scalar,\
276 neon_mla_ddd_16_scalar_qdd_32_16_long_scalar,\
277 neon_shift_1,\
278 neon_shift_2,\
279 neon_shift_3,\
280 neon_vshl_ddd,\
281 neon_vqshl_vrshl_vqrshl_qqq,\
282 neon_vsra_vrsra,\
283 neon_fp_vadd_ddd_vabs_dd,\
284 neon_fp_vadd_qqq_vabs_qq,\
285 neon_fp_vsum,\
286 neon_fp_vmul_ddd,\
287 neon_fp_vmul_qqd,\
288 neon_fp_vmla_ddd,\
289 neon_fp_vmla_qqq,\
290 neon_fp_vmla_ddd_scalar,\
291 neon_fp_vmla_qqq_scalar,\
292 neon_fp_vrecps_vrsqrts_ddd,\
293 neon_fp_vrecps_vrsqrts_qqq,\
294 neon_bp_simple,\
295 neon_bp_2cycle,\
296 neon_bp_3cycle,\
297 neon_ldr,\
298 neon_str,\
299 neon_vld1_1_2_regs,\
300 neon_vld1_3_4_regs,\
301 neon_vld2_2_regs_vld1_vld2_all_lanes,\
302 neon_vld2_4_regs,\
303 neon_vld3_vld4,\
304 neon_vst1_1_2_regs_vst2_2_regs,\
305 neon_vst1_3_4_regs,\
306 neon_vst2_4_regs_vst3_vst4,\
307 neon_vst3_vst4,\
308 neon_vld1_vld2_lane,\
309 neon_vld3_vld4_lane,\
310 neon_vst1_vst2_lane,\
311 neon_vst3_vst4_lane,\
312 neon_vld3_vld4_all_lanes,\
313 neon_mcr,\
314 neon_mcr_2_mcrr,\
315 neon_mrc,\
316 neon_mrrc,\
317 neon_ldm_2,\
318 neon_stm_2,\
319 none"
320 (const_string "none"))
321
f7fbdd4a 322; condition codes: this one is used by final_prescan_insn to speed up
323; conditionalizing instructions. It saves having to scan the rtl to see if
324; it uses or alters the condition codes.
215b30b3 325;
f7fbdd4a 326; USE means that the condition codes are used by the insn in the process of
215b30b3 327; outputting code, this means (at present) that we can't use the insn in
328; inlined branches
329;
f7fbdd4a 330; SET means that the purpose of the insn is to set the condition codes in a
215b30b3 331; well defined manner.
332;
f7fbdd4a 333; CLOB means that the condition codes are altered in an undefined manner, if
215b30b3 334; they are altered at all
335;
ad6d3e2a 336; UNCONDITIONAL means the instruction can not be conditionally executed and
337; that the instruction does not use or alter the condition codes.
c52acdd2 338;
ad6d3e2a 339; NOCOND means that the instruction does not use or alter the condition
340; codes but can be converted into a conditionally exectuted instruction.
f7fbdd4a 341
b0694be0 342(define_attr "conds" "use,set,clob,unconditional,nocond"
747b7458 343 (if_then_else
344 (ior (eq_attr "is_thumb1" "yes")
345 (eq_attr "type" "call"))
c1a66faf 346 (const_string "clob")
c52acdd2 347 (if_then_else (eq_attr "neon_type" "none")
348 (const_string "nocond")
349 (const_string "unconditional"))))
f7fbdd4a 350
215b30b3 351; Predicable means that the insn can be conditionally executed based on
352; an automatically added predicate (additional patterns are generated by
353; gen...). We default to 'no' because no Thumb patterns match this rule
354; and not all ARM patterns do.
0d66636f 355(define_attr "predicable" "no,yes" (const_string "no"))
356
129a2fe4 357; Only model the write buffer for ARM6 and ARM7. Earlier processors don't
358; have one. Later ones, such as StrongARM, have write-back caches, so don't
8d232dc7 359; suffer blockages enough to warrant modelling this (and it can adversely
129a2fe4 360; affect the schedule).
74a71f7d 361(define_attr "model_wbuf" "no,yes" (const (symbol_ref "arm_tune_wbuf")))
129a2fe4 362
215b30b3 363; WRITE_CONFLICT implies that a read following an unrelated write is likely
364; to stall the processor. Used with model_wbuf above.
9c08d1fa 365(define_attr "write_conflict" "no,yes"
366 (if_then_else (eq_attr "type"
96854199 367 "block,call,load1")
9c08d1fa 368 (const_string "yes")
369 (const_string "no")))
370
215b30b3 371; Classify the insns into those that take one cycle and those that take more
372; than one on the main cpu execution unit.
f7fbdd4a 373(define_attr "core_cycles" "single,multi"
374 (if_then_else (eq_attr "type"
6b6abc9c 375 "arlo_imm, arlo_reg,\
376 extend, shift, arlo_shift, float, fdivd, fdivs,\
7cb6c048 377 wmmx_wor, wmmx_wxor, wmmx_wand, wmmx_wandn, wmmx_wmov, wmmx_tmcrr,\
378 wmmx_tmrrc, wmmx_wldr, wmmx_wstr, wmmx_tmcr, wmmx_tmrc, wmmx_wadd,\
379 wmmx_wsub, wmmx_wmul, wmmx_wmac, wmmx_wavg2, wmmx_tinsr, wmmx_textrm,\
380 wmmx_wshufh, wmmx_wcmpeq, wmmx_wcmpgt, wmmx_wmax, wmmx_wmin, wmmx_wpack,\
381 wmmx_wunpckih, wmmx_wunpckil, wmmx_wunpckeh, wmmx_wunpckel, wmmx_wror,\
382 wmmx_wsra, wmmx_wsrl, wmmx_wsll, wmmx_wmadd, wmmx_tmia, wmmx_tmiaph,\
383 wmmx_tmiaxy, wmmx_tbcst, wmmx_tmovmsk, wmmx_wacc, wmmx_waligni,\
384 wmmx_walignr, wmmx_tandc, wmmx_textrc, wmmx_torc, wmmx_torvsc, wmmx_wsad,\
385 wmmx_wabs, wmmx_wabsdiff, wmmx_waddsubhx, wmmx_wsubaddhx, wmmx_wavg4,\
386 wmmx_wmulw, wmmx_wqmulm, wmmx_wqmulwm, wmmx_waddbhus, wmmx_wqmiaxy,\
387 wmmx_wmiaxy, wmmx_wmiawxy, wmmx_wmerge")
f7fbdd4a 388 (const_string "single")
389 (const_string "multi")))
390
cffb2a26 391;; FAR_JUMP is "yes" if a BL instruction is used to generate a branch to a
215b30b3 392;; distant label. Only applicable to Thumb code.
cffb2a26 393(define_attr "far_jump" "yes,no" (const_string "no"))
394
d51f92df 395
25f905c2 396;; The number of machine instructions this pattern expands to.
397;; Used for Thumb-2 conditional execution.
398(define_attr "ce_count" "" (const_int 1))
399
4182b724 400;;---------------------------------------------------------------------------
401;; Unspecs
402
403(include "unspecs.md")
404
d51f92df 405;;---------------------------------------------------------------------------
fd781bb2 406;; Mode iterators
d51f92df 407
3de0dec6 408(include "iterators.md")
03770691 409
d51f92df 410;;---------------------------------------------------------------------------
411;; Predicates
412
9c9db025 413(include "predicates.md")
234f6557 414(include "constraints.md")
9c9db025 415
a2cd141b 416;;---------------------------------------------------------------------------
417;; Pipeline descriptions
215b30b3 418
e3879fd0 419(define_attr "tune_cortexr4" "yes,no"
420 (const (if_then_else
7d3cda8c 421 (eq_attr "tune" "cortexr4,cortexr4f,cortexr5")
e3879fd0 422 (const_string "yes")
423 (const_string "no"))))
424
a2cd141b 425;; True if the generic scheduling description should be used.
426
427(define_attr "generic_sched" "yes,no"
2546d93a 428 (const (if_then_else
da10bc87 429 (ior (eq_attr "tune" "fa526,fa626,fa606te,fa626te,fmp626,fa726te,arm926ejs,arm1020e,arm1026ejs,arm1136js,arm1136jfs,cortexa5,cortexa7,cortexa8,cortexa9,cortexa15,cortexa53,cortexm4,marvell_pj4")
2546d93a 430 (eq_attr "tune_cortexr4" "yes"))
4d5cb40d 431 (const_string "no")
432 (const_string "yes"))))
433
c0e1af52 434(define_attr "generic_vfp" "yes,no"
435 (const (if_then_else
436 (and (eq_attr "fpu" "vfp")
da10bc87 437 (eq_attr "tune" "!arm1020e,arm1022e,cortexa5,cortexa7,cortexa8,cortexa9,cortexa53,cortexm4,marvell_pj4")
e3879fd0 438 (eq_attr "tune_cortexr4" "no"))
c0e1af52 439 (const_string "yes")
440 (const_string "no"))))
441
6b8f7c28 442(include "marvell-f-iwmmxt.md")
a2cd141b 443(include "arm-generic.md")
444(include "arm926ejs.md")
c0e1af52 445(include "arm1020e.md")
a2cd141b 446(include "arm1026ejs.md")
447(include "arm1136jfs.md")
0e266d06 448(include "fa526.md")
449(include "fa606te.md")
450(include "fa626te.md")
451(include "fmp626.md")
452(include "fa726te.md")
3f1e069f 453(include "cortex-a5.md")
d6b7f019 454(include "cortex-a7.md")
bcaec148 455(include "cortex-a8.md")
036068af 456(include "cortex-a9.md")
65f2f758 457(include "cortex-a15.md")
da10bc87 458(include "cortex-a53.md")
934a1e72 459(include "cortex-r4.md")
e3879fd0 460(include "cortex-r4f.md")
2546d93a 461(include "cortex-m4.md")
462(include "cortex-m4-fpu.md")
55e3ada8 463(include "vfp11.md")
ea7d210b 464(include "marvell-pj4.md")
3586df96 465
9c08d1fa 466\f
215b30b3 467;;---------------------------------------------------------------------------
e1159bbe 468;; Insn patterns
469;;
a0f94409 470;; Addition insns.
215b30b3 471
9c08d1fa 472;; Note: For DImode insns, there is normally no reason why operands should
473;; not be in the same register, what we don't want is for something being
474;; written to partially overlap something that is an input.
475
cffb2a26 476(define_expand "adddi3"
477 [(parallel
215b30b3 478 [(set (match_operand:DI 0 "s_register_operand" "")
cffb2a26 479 (plus:DI (match_operand:DI 1 "s_register_operand" "")
10e5ccd5 480 (match_operand:DI 2 "arm_adddi_operand" "")))
bd5b4116 481 (clobber (reg:CC CC_REGNUM))])]
cffb2a26 482 "TARGET_EITHER"
483 "
25f905c2 484 if (TARGET_THUMB1)
cffb2a26 485 {
0438d37f 486 if (!REG_P (operands[1]))
bc5a93af 487 operands[1] = force_reg (DImode, operands[1]);
0438d37f 488 if (!REG_P (operands[2]))
bc5a93af 489 operands[2] = force_reg (DImode, operands[2]);
cffb2a26 490 }
491 "
492)
493
25f905c2 494(define_insn "*thumb1_adddi3"
cffb2a26 495 [(set (match_operand:DI 0 "register_operand" "=l")
496 (plus:DI (match_operand:DI 1 "register_operand" "%0")
215b30b3 497 (match_operand:DI 2 "register_operand" "l")))
bd5b4116 498 (clobber (reg:CC CC_REGNUM))
cffb2a26 499 ]
25f905c2 500 "TARGET_THUMB1"
cffb2a26 501 "add\\t%Q0, %Q0, %Q2\;adc\\t%R0, %R0, %R2"
502 [(set_attr "length" "4")]
503)
504
a0f94409 505(define_insn_and_split "*arm_adddi3"
10e5ccd5 506 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r,&r,&r,&r")
507 (plus:DI (match_operand:DI 1 "s_register_operand" "%0, 0, r, 0, r")
508 (match_operand:DI 2 "arm_adddi_operand" "r, 0, r, Dd, Dd")))
bd5b4116 509 (clobber (reg:CC CC_REGNUM))]
b805622c 510 "TARGET_32BIT && !TARGET_NEON"
33782ec7 511 "#"
94829feb 512 "TARGET_32BIT && reload_completed
513 && ! (TARGET_NEON && IS_VFP_REGNUM (REGNO (operands[0])))"
a0f94409 514 [(parallel [(set (reg:CC_C CC_REGNUM)
515 (compare:CC_C (plus:SI (match_dup 1) (match_dup 2))
516 (match_dup 1)))
517 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
080c0b9a 518 (set (match_dup 3) (plus:SI (plus:SI (match_dup 4) (match_dup 5))
519 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
a0f94409 520 "
521 {
522 operands[3] = gen_highpart (SImode, operands[0]);
523 operands[0] = gen_lowpart (SImode, operands[0]);
524 operands[4] = gen_highpart (SImode, operands[1]);
525 operands[1] = gen_lowpart (SImode, operands[1]);
10e5ccd5 526 operands[5] = gen_highpart_mode (SImode, DImode, operands[2]);
a0f94409 527 operands[2] = gen_lowpart (SImode, operands[2]);
528 }"
cffb2a26 529 [(set_attr "conds" "clob")
530 (set_attr "length" "8")]
531)
9c08d1fa 532
a0f94409 533(define_insn_and_split "*adddi_sesidi_di"
9c08d1fa 534 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
535 (plus:DI (sign_extend:DI
97499065 536 (match_operand:SI 2 "s_register_operand" "r,r"))
e5fea38e 537 (match_operand:DI 1 "s_register_operand" "0,r")))
bd5b4116 538 (clobber (reg:CC CC_REGNUM))]
b805622c 539 "TARGET_32BIT"
33782ec7 540 "#"
25f905c2 541 "TARGET_32BIT && reload_completed"
a0f94409 542 [(parallel [(set (reg:CC_C CC_REGNUM)
543 (compare:CC_C (plus:SI (match_dup 1) (match_dup 2))
544 (match_dup 1)))
545 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
080c0b9a 546 (set (match_dup 3) (plus:SI (plus:SI (ashiftrt:SI (match_dup 2)
a0f94409 547 (const_int 31))
080c0b9a 548 (match_dup 4))
549 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
a0f94409 550 "
551 {
552 operands[3] = gen_highpart (SImode, operands[0]);
553 operands[0] = gen_lowpart (SImode, operands[0]);
554 operands[4] = gen_highpart (SImode, operands[1]);
555 operands[1] = gen_lowpart (SImode, operands[1]);
556 operands[2] = gen_lowpart (SImode, operands[2]);
557 }"
215b30b3 558 [(set_attr "conds" "clob")
559 (set_attr "length" "8")]
560)
9c08d1fa 561
a0f94409 562(define_insn_and_split "*adddi_zesidi_di"
9c08d1fa 563 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
564 (plus:DI (zero_extend:DI
97499065 565 (match_operand:SI 2 "s_register_operand" "r,r"))
e5fea38e 566 (match_operand:DI 1 "s_register_operand" "0,r")))
a0f94409 567 (clobber (reg:CC CC_REGNUM))]
b805622c 568 "TARGET_32BIT"
33782ec7 569 "#"
25f905c2 570 "TARGET_32BIT && reload_completed"
a0f94409 571 [(parallel [(set (reg:CC_C CC_REGNUM)
572 (compare:CC_C (plus:SI (match_dup 1) (match_dup 2))
573 (match_dup 1)))
574 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
080c0b9a 575 (set (match_dup 3) (plus:SI (plus:SI (match_dup 4) (const_int 0))
576 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
a0f94409 577 "
578 {
579 operands[3] = gen_highpart (SImode, operands[0]);
580 operands[0] = gen_lowpart (SImode, operands[0]);
581 operands[4] = gen_highpart (SImode, operands[1]);
582 operands[1] = gen_lowpart (SImode, operands[1]);
583 operands[2] = gen_lowpart (SImode, operands[2]);
584 }"
cffb2a26 585 [(set_attr "conds" "clob")
586 (set_attr "length" "8")]
587)
b11cae9e 588
87b22bf7 589(define_expand "addsi3"
cffb2a26 590 [(set (match_operand:SI 0 "s_register_operand" "")
87b22bf7 591 (plus:SI (match_operand:SI 1 "s_register_operand" "")
592 (match_operand:SI 2 "reg_or_int_operand" "")))]
cffb2a26 593 "TARGET_EITHER"
87b22bf7 594 "
0438d37f 595 if (TARGET_32BIT && CONST_INT_P (operands[2]))
87b22bf7 596 {
96f57e36 597 arm_split_constant (PLUS, SImode, NULL_RTX,
598 INTVAL (operands[2]), operands[0], operands[1],
e1ba4a27 599 optimize && can_create_pseudo_p ());
87b22bf7 600 DONE;
601 }
cffb2a26 602 "
603)
87b22bf7 604
5bd751ff 605; If there is a scratch available, this will be faster than synthesizing the
a0f94409 606; addition.
607(define_peephole2
608 [(match_scratch:SI 3 "r")
372575c7 609 (set (match_operand:SI 0 "arm_general_register_operand" "")
610 (plus:SI (match_operand:SI 1 "arm_general_register_operand" "")
cffb2a26 611 (match_operand:SI 2 "const_int_operand" "")))]
25f905c2 612 "TARGET_32BIT &&
a0f94409 613 !(const_ok_for_arm (INTVAL (operands[2]))
614 || const_ok_for_arm (-INTVAL (operands[2])))
615 && const_ok_for_arm (~INTVAL (operands[2]))"
616 [(set (match_dup 3) (match_dup 2))
617 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 3)))]
618 ""
619)
87b22bf7 620
2f02c19f 621;; The r/r/k alternative is required when reloading the address
622;; (plus (reg rN) (reg sp)) into (reg rN). In this case reload will
623;; put the duplicated register first, and not try the commutative version.
a0f94409 624(define_insn_and_split "*arm_addsi3"
7c36fe71 625 [(set (match_operand:SI 0 "s_register_operand" "=rk,l,l ,l ,r ,k ,r,r ,k ,r ,k,k,r ,k ,r")
626 (plus:SI (match_operand:SI 1 "s_register_operand" "%0 ,l,0 ,l ,rk,k ,r,rk,k ,rk,k,r,rk,k ,rk")
627 (match_operand:SI 2 "reg_or_int_operand" "rk ,l,Py,Pd,rI,rI,k,Pj,Pj,L ,L,L,PJ,PJ,?n")))]
25f905c2 628 "TARGET_32BIT"
5565501b 629 "@
c24d855d 630 add%?\\t%0, %0, %2
5565501b 631 add%?\\t%0, %1, %2
a0b3420a 632 add%?\\t%0, %1, %2
7c36fe71 633 add%?\\t%0, %1, %2
634 add%?\\t%0, %1, %2
aaa37ad6 635 add%?\\t%0, %1, %2
2f02c19f 636 add%?\\t%0, %2, %1
d5cbae34 637 addw%?\\t%0, %1, %2
638 addw%?\\t%0, %1, %2
aaa37ad6 639 sub%?\\t%0, %1, #%n2
87b22bf7 640 sub%?\\t%0, %1, #%n2
d7757711 641 sub%?\\t%0, %1, #%n2
d5cbae34 642 subw%?\\t%0, %1, #%n2
643 subw%?\\t%0, %1, #%n2
87b22bf7 644 #"
a3ffc315 645 "TARGET_32BIT
0438d37f 646 && CONST_INT_P (operands[2])
d5cbae34 647 && !const_ok_for_op (INTVAL (operands[2]), PLUS)
a3ffc315 648 && (reload_completed || !arm_eliminable_register (operands[1]))"
a0f94409 649 [(clobber (const_int 0))]
650 "
96f57e36 651 arm_split_constant (PLUS, SImode, curr_insn,
652 INTVAL (operands[2]), operands[0],
a0f94409 653 operands[1], 0);
654 DONE;
655 "
7c36fe71 656 [(set_attr "length" "2,4,4,4,4,4,4,4,4,4,4,4,4,4,16")
d5cbae34 657 (set_attr "predicable" "yes")
7c36fe71 658 (set_attr "predicable_short_it" "yes,yes,yes,yes,no,no,no,no,no,no,no,no,no,no,no")
659 (set_attr "arch" "t2,t2,t2,t2,*,*,*,t2,t2,*,*,a,t2,t2,*")
65f68e55 660 (set (attr "type") (if_then_else (match_operand 2 "const_int_operand" "")
6b6abc9c 661 (const_string "arlo_imm")
662 (const_string "arlo_reg")))
65f68e55 663 ]
cffb2a26 664)
665
0bdb6455 666(define_insn_and_split "*thumb1_addsi3"
bf7bc2f6 667 [(set (match_operand:SI 0 "register_operand" "=l,l,l,*rk,*hk,l,k,l,l,l")
668 (plus:SI (match_operand:SI 1 "register_operand" "%0,0,l,*0,*0,k,k,0,l,k")
669 (match_operand:SI 2 "nonmemory_operand" "I,J,lL,*hk,*rk,M,O,Pa,Pb,Pc")))]
25f905c2 670 "TARGET_THUMB1"
cffb2a26 671 "*
0d66636f 672 static const char * const asms[] =
cffb2a26 673 {
674 \"add\\t%0, %0, %2\",
675 \"sub\\t%0, %0, #%n2\",
676 \"add\\t%0, %1, %2\",
677 \"add\\t%0, %0, %2\",
678 \"add\\t%0, %0, %2\",
679 \"add\\t%0, %1, %2\",
0bdb6455 680 \"add\\t%0, %1, %2\",
681 \"#\",
bf7bc2f6 682 \"#\",
0bdb6455 683 \"#\"
cffb2a26 684 };
685 if ((which_alternative == 2 || which_alternative == 6)
0438d37f 686 && CONST_INT_P (operands[2])
cffb2a26 687 && INTVAL (operands[2]) < 0)
688 return \"sub\\t%0, %1, #%n2\";
689 return asms[which_alternative];
690 "
0bdb6455 691 "&& reload_completed && CONST_INT_P (operands[2])
bf7bc2f6 692 && ((operands[1] != stack_pointer_rtx
693 && (INTVAL (operands[2]) > 255 || INTVAL (operands[2]) < -255))
694 || (operands[1] == stack_pointer_rtx
695 && INTVAL (operands[2]) > 1020))"
0bdb6455 696 [(set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))
697 (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 3)))]
698 {
699 HOST_WIDE_INT offset = INTVAL (operands[2]);
bf7bc2f6 700 if (operands[1] == stack_pointer_rtx)
701 offset -= 1020;
702 else
703 {
704 if (offset > 255)
705 offset = 255;
706 else if (offset < -255)
707 offset = -255;
708 }
0bdb6455 709 operands[3] = GEN_INT (offset);
710 operands[2] = GEN_INT (INTVAL (operands[2]) - offset);
711 }
bf7bc2f6 712 [(set_attr "length" "2,2,2,2,2,2,2,4,4,4")]
cffb2a26 713)
714
715;; Reloading and elimination of the frame pointer can
716;; sometimes cause this optimization to be missed.
a0f94409 717(define_peephole2
372575c7 718 [(set (match_operand:SI 0 "arm_general_register_operand" "")
a058e94a 719 (match_operand:SI 1 "const_int_operand" ""))
cffb2a26 720 (set (match_dup 0)
372575c7 721 (plus:SI (match_dup 0) (reg:SI SP_REGNUM)))]
25f905c2 722 "TARGET_THUMB1
cffb2a26 723 && (unsigned HOST_WIDE_INT) (INTVAL (operands[1])) < 1024
724 && (INTVAL (operands[1]) & 3) == 0"
372575c7 725 [(set (match_dup 0) (plus:SI (reg:SI SP_REGNUM) (match_dup 1)))]
a0f94409 726 ""
cffb2a26 727)
b11cae9e 728
90c2bcf0 729(define_insn "addsi3_compare0"
bd5b4116 730 [(set (reg:CC_NOOV CC_REGNUM)
5565501b 731 (compare:CC_NOOV
65f68e55 732 (plus:SI (match_operand:SI 1 "s_register_operand" "r, r,r")
733 (match_operand:SI 2 "arm_add_operand" "I,L,r"))
5565501b 734 (const_int 0)))
65f68e55 735 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9c08d1fa 736 (plus:SI (match_dup 1) (match_dup 2)))]
ec792a7b 737 "TARGET_ARM"
5565501b 738 "@
25f905c2 739 add%.\\t%0, %1, %2
65f68e55 740 sub%.\\t%0, %1, #%n2
741 add%.\\t%0, %1, %2"
742 [(set_attr "conds" "set")
6b6abc9c 743 (set_attr "type" "arlo_imm,arlo_imm,*")]
cffb2a26 744)
9c08d1fa 745
aea4c774 746(define_insn "*addsi3_compare0_scratch"
bd5b4116 747 [(set (reg:CC_NOOV CC_REGNUM)
aea4c774 748 (compare:CC_NOOV
65f68e55 749 (plus:SI (match_operand:SI 0 "s_register_operand" "r, r, r")
750 (match_operand:SI 1 "arm_add_operand" "I,L, r"))
aea4c774 751 (const_int 0)))]
ec792a7b 752 "TARGET_ARM"
cffb2a26 753 "@
754 cmn%?\\t%0, %1
65f68e55 755 cmp%?\\t%0, #%n1
756 cmn%?\\t%0, %1"
596e5e8f 757 [(set_attr "conds" "set")
65f68e55 758 (set_attr "predicable" "yes")
6b6abc9c 759 (set_attr "type" "arlo_imm,arlo_imm,*")
65f68e55 760 ]
0d66636f 761)
cffb2a26 762
aed179ae 763(define_insn "*compare_negsi_si"
764 [(set (reg:CC_Z CC_REGNUM)
765 (compare:CC_Z
7c36fe71 766 (neg:SI (match_operand:SI 0 "s_register_operand" "l,r"))
767 (match_operand:SI 1 "s_register_operand" "l,r")))]
25f905c2 768 "TARGET_32BIT"
aed179ae 769 "cmn%?\\t%1, %0"
596e5e8f 770 [(set_attr "conds" "set")
7c36fe71 771 (set_attr "predicable" "yes")
772 (set_attr "arch" "t2,*")
773 (set_attr "length" "2,4")
774 (set_attr "predicable_short_it" "yes,no")]
0d66636f 775)
aea4c774 776
203c488f 777;; This is the canonicalization of addsi3_compare0_for_combiner when the
778;; addend is a constant.
190efb17 779(define_insn "cmpsi2_addneg"
203c488f 780 [(set (reg:CC CC_REGNUM)
781 (compare:CC
782 (match_operand:SI 1 "s_register_operand" "r,r")
2a977b78 783 (match_operand:SI 2 "arm_addimm_operand" "L,I")))
203c488f 784 (set (match_operand:SI 0 "s_register_operand" "=r,r")
785 (plus:SI (match_dup 1)
2a977b78 786 (match_operand:SI 3 "arm_addimm_operand" "I,L")))]
25f905c2 787 "TARGET_32BIT && INTVAL (operands[2]) == -INTVAL (operands[3])"
203c488f 788 "@
2a977b78 789 add%.\\t%0, %1, %3
790 sub%.\\t%0, %1, #%n3"
203c488f 791 [(set_attr "conds" "set")]
792)
793
794;; Convert the sequence
795;; sub rd, rn, #1
796;; cmn rd, #1 (equivalent to cmp rd, #-1)
797;; bne dest
798;; into
799;; subs rd, rn, #1
800;; bcs dest ((unsigned)rn >= 1)
801;; similarly for the beq variant using bcc.
802;; This is a common looping idiom (while (n--))
803(define_peephole2
372575c7 804 [(set (match_operand:SI 0 "arm_general_register_operand" "")
805 (plus:SI (match_operand:SI 1 "arm_general_register_operand" "")
203c488f 806 (const_int -1)))
807 (set (match_operand 2 "cc_register" "")
808 (compare (match_dup 0) (const_int -1)))
809 (set (pc)
810 (if_then_else (match_operator 3 "equality_operator"
811 [(match_dup 2) (const_int 0)])
812 (match_operand 4 "" "")
813 (match_operand 5 "" "")))]
25f905c2 814 "TARGET_32BIT && peep2_reg_dead_p (3, operands[2])"
203c488f 815 [(parallel[
816 (set (match_dup 2)
817 (compare:CC
818 (match_dup 1) (const_int 1)))
819 (set (match_dup 0) (plus:SI (match_dup 1) (const_int -1)))])
820 (set (pc)
821 (if_then_else (match_op_dup 3 [(match_dup 2) (const_int 0)])
822 (match_dup 4)
823 (match_dup 5)))]
824 "operands[2] = gen_rtx_REG (CCmode, CC_REGNUM);
825 operands[3] = gen_rtx_fmt_ee ((GET_CODE (operands[3]) == NE
826 ? GEU : LTU),
827 VOIDmode,
828 operands[2], const0_rtx);"
829)
830
ebcc79bc 831;; The next four insns work because they compare the result with one of
832;; the operands, and we know that the use of the condition code is
833;; either GEU or LTU, so we can use the carry flag from the addition
834;; instead of doing the compare a second time.
835(define_insn "*addsi3_compare_op1"
bd5b4116 836 [(set (reg:CC_C CC_REGNUM)
ebcc79bc 837 (compare:CC_C
65f68e55 838 (plus:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
839 (match_operand:SI 2 "arm_add_operand" "I,L,r"))
ebcc79bc 840 (match_dup 1)))
65f68e55 841 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
ebcc79bc 842 (plus:SI (match_dup 1) (match_dup 2)))]
25f905c2 843 "TARGET_32BIT"
ebcc79bc 844 "@
25f905c2 845 add%.\\t%0, %1, %2
65f68e55 846 sub%.\\t%0, %1, #%n2
847 add%.\\t%0, %1, %2"
848 [(set_attr "conds" "set")
6b6abc9c 849 (set_attr "type" "arlo_imm,arlo_imm,*")]
0d66636f 850)
ebcc79bc 851
852(define_insn "*addsi3_compare_op2"
bd5b4116 853 [(set (reg:CC_C CC_REGNUM)
ebcc79bc 854 (compare:CC_C
65f68e55 855 (plus:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
856 (match_operand:SI 2 "arm_add_operand" "I,L,r"))
ebcc79bc 857 (match_dup 2)))
65f68e55 858 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9c08d1fa 859 (plus:SI (match_dup 1) (match_dup 2)))]
25f905c2 860 "TARGET_32BIT"
5565501b 861 "@
65f68e55 862 add%.\\t%0, %1, %2
25f905c2 863 add%.\\t%0, %1, %2
864 sub%.\\t%0, %1, #%n2"
65f68e55 865 [(set_attr "conds" "set")
6b6abc9c 866 (set_attr "type" "arlo_imm,arlo_imm,*")]
0d66636f 867)
9c08d1fa 868
ebcc79bc 869(define_insn "*compare_addsi2_op0"
bd5b4116 870 [(set (reg:CC_C CC_REGNUM)
7c36fe71 871 (compare:CC_C
872 (plus:SI (match_operand:SI 0 "s_register_operand" "l,l,r,r,r")
873 (match_operand:SI 1 "arm_add_operand" "Pv,l,I,L,r"))
874 (match_dup 0)))]
25f905c2 875 "TARGET_32BIT"
ebcc79bc 876 "@
7c36fe71 877 cmp%?\\t%0, #%n1
878 cmn%?\\t%0, %1
ebcc79bc 879 cmn%?\\t%0, %1
65f68e55 880 cmp%?\\t%0, #%n1
881 cmn%?\\t%0, %1"
596e5e8f 882 [(set_attr "conds" "set")
65f68e55 883 (set_attr "predicable" "yes")
7c36fe71 884 (set_attr "arch" "t2,t2,*,*,*")
885 (set_attr "predicable_short_it" "yes,yes,no,no,no")
886 (set_attr "length" "2,2,4,4,4")
887 (set_attr "type" "arlo_imm,*,arlo_imm,arlo_imm,*")]
0d66636f 888)
ebcc79bc 889
890(define_insn "*compare_addsi2_op1"
bd5b4116 891 [(set (reg:CC_C CC_REGNUM)
7c36fe71 892 (compare:CC_C
893 (plus:SI (match_operand:SI 0 "s_register_operand" "l,l,r,r,r")
894 (match_operand:SI 1 "arm_add_operand" "Pv,l,I,L,r"))
895 (match_dup 1)))]
25f905c2 896 "TARGET_32BIT"
ebcc79bc 897 "@
7c36fe71 898 cmp%?\\t%0, #%n1
899 cmn%?\\t%0, %1
ebcc79bc 900 cmn%?\\t%0, %1
65f68e55 901 cmp%?\\t%0, #%n1
902 cmn%?\\t%0, %1"
596e5e8f 903 [(set_attr "conds" "set")
65f68e55 904 (set_attr "predicable" "yes")
7c36fe71 905 (set_attr "arch" "t2,t2,*,*,*")
906 (set_attr "predicable_short_it" "yes,yes,no,no,no")
907 (set_attr "length" "2,2,4,4,4")
908 (set_attr "type"
909 "arlo_imm,*,arlo_imm,arlo_imm,*")]
910 )
ebcc79bc 911
080c0b9a 912(define_insn "*addsi3_carryin_<optab>"
7c36fe71 913 [(set (match_operand:SI 0 "s_register_operand" "=l,r,r")
914 (plus:SI (plus:SI (match_operand:SI 1 "s_register_operand" "%l,r,r")
915 (match_operand:SI 2 "arm_not_operand" "0,rI,K"))
916 (LTUGEU:SI (reg:<cnb> CC_REGNUM) (const_int 0))))]
25f905c2 917 "TARGET_32BIT"
10e5ccd5 918 "@
a0b3420a 919 adc%?\\t%0, %1, %2
10e5ccd5 920 adc%?\\t%0, %1, %2
921 sbc%?\\t%0, %1, #%B2"
a7de272d 922 [(set_attr "conds" "use")
7c36fe71 923 (set_attr "predicable" "yes")
924 (set_attr "arch" "t2,*,*")
925 (set_attr "length" "4")
926 (set_attr "predicable_short_it" "yes,no,no")]
cffb2a26 927)
ebcc79bc 928
080c0b9a 929(define_insn "*addsi3_carryin_alt2_<optab>"
7c36fe71 930 [(set (match_operand:SI 0 "s_register_operand" "=l,r,r")
931 (plus:SI (plus:SI (LTUGEU:SI (reg:<cnb> CC_REGNUM) (const_int 0))
932 (match_operand:SI 1 "s_register_operand" "%l,r,r"))
933 (match_operand:SI 2 "arm_rhs_operand" "l,rI,K")))]
25f905c2 934 "TARGET_32BIT"
10e5ccd5 935 "@
a0b3420a 936 adc%?\\t%0, %1, %2
10e5ccd5 937 adc%?\\t%0, %1, %2
938 sbc%?\\t%0, %1, #%B2"
a7de272d 939 [(set_attr "conds" "use")
7c36fe71 940 (set_attr "predicable" "yes")
941 (set_attr "arch" "t2,*,*")
942 (set_attr "length" "4")
943 (set_attr "predicable_short_it" "yes,no,no")]
0d66636f 944)
ebcc79bc 945
080c0b9a 946(define_insn "*addsi3_carryin_shift_<optab>"
ebcc79bc 947 [(set (match_operand:SI 0 "s_register_operand" "=r")
080c0b9a 948 (plus:SI (plus:SI
949 (match_operator:SI 2 "shift_operator"
950 [(match_operand:SI 3 "s_register_operand" "r")
951 (match_operand:SI 4 "reg_or_int_operand" "rM")])
952 (match_operand:SI 1 "s_register_operand" "r"))
953 (LTUGEU:SI (reg:<cnb> CC_REGNUM) (const_int 0))))]
25f905c2 954 "TARGET_32BIT"
080c0b9a 955 "adc%?\\t%0, %1, %3%S2"
956 [(set_attr "conds" "use")
a7de272d 957 (set_attr "predicable" "yes")
7c36fe71 958 (set_attr "predicable_short_it" "no")
080c0b9a 959 (set (attr "type") (if_then_else (match_operand 4 "const_int_operand" "")
6b6abc9c 960 (const_string "arlo_shift")
961 (const_string "arlo_shift_reg")))]
cffb2a26 962)
ebcc79bc 963
922b6913 964(define_insn "*addsi3_carryin_clobercc_<optab>"
965 [(set (match_operand:SI 0 "s_register_operand" "=r")
966 (plus:SI (plus:SI (match_operand:SI 1 "s_register_operand" "%r")
967 (match_operand:SI 2 "arm_rhs_operand" "rI"))
968 (LTUGEU:SI (reg:<cnb> CC_REGNUM) (const_int 0))))
969 (clobber (reg:CC CC_REGNUM))]
970 "TARGET_32BIT"
971 "adc%.\\t%0, %1, %2"
972 [(set_attr "conds" "set")]
973)
974
9154bd82 975(define_insn "*subsi3_carryin"
976 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
977 (minus:SI (minus:SI (match_operand:SI 1 "reg_or_int_operand" "r,I")
978 (match_operand:SI 2 "s_register_operand" "r,r"))
979 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
980 "TARGET_32BIT"
981 "@
982 sbc%?\\t%0, %1, %2
983 rsc%?\\t%0, %2, %1"
984 [(set_attr "conds" "use")
985 (set_attr "arch" "*,a")
7c36fe71 986 (set_attr "predicable" "yes")
987 (set_attr "predicable_short_it" "no")]
9154bd82 988)
989
990(define_insn "*subsi3_carryin_const"
991 [(set (match_operand:SI 0 "s_register_operand" "=r")
992 (minus:SI (plus:SI (match_operand:SI 1 "reg_or_int_operand" "r")
993 (match_operand:SI 2 "arm_not_operand" "K"))
994 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
995 "TARGET_32BIT"
996 "sbc\\t%0, %1, #%B2"
997 [(set_attr "conds" "use")]
998)
999
1000(define_insn "*subsi3_carryin_compare"
1001 [(set (reg:CC CC_REGNUM)
1002 (compare:CC (match_operand:SI 1 "s_register_operand" "r")
1003 (match_operand:SI 2 "s_register_operand" "r")))
1004 (set (match_operand:SI 0 "s_register_operand" "=r")
1005 (minus:SI (minus:SI (match_dup 1)
1006 (match_dup 2))
1007 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1008 "TARGET_32BIT"
1009 "sbcs\\t%0, %1, %2"
1010 [(set_attr "conds" "set")]
1011)
1012
1013(define_insn "*subsi3_carryin_compare_const"
1014 [(set (reg:CC CC_REGNUM)
1015 (compare:CC (match_operand:SI 1 "reg_or_int_operand" "r")
1016 (match_operand:SI 2 "arm_not_operand" "K")))
1017 (set (match_operand:SI 0 "s_register_operand" "=r")
1018 (minus:SI (plus:SI (match_dup 1)
1019 (match_dup 2))
1020 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1021 "TARGET_32BIT"
1022 "sbcs\\t%0, %1, #%B2"
1023 [(set_attr "conds" "set")]
1024)
1025
1026(define_insn "*subsi3_carryin_shift"
1027 [(set (match_operand:SI 0 "s_register_operand" "=r")
1028 (minus:SI (minus:SI
1029 (match_operand:SI 1 "s_register_operand" "r")
1030 (match_operator:SI 2 "shift_operator"
1031 [(match_operand:SI 3 "s_register_operand" "r")
1032 (match_operand:SI 4 "reg_or_int_operand" "rM")]))
1033 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1034 "TARGET_32BIT"
1035 "sbc%?\\t%0, %1, %3%S2"
1036 [(set_attr "conds" "use")
1037 (set_attr "predicable" "yes")
1038 (set (attr "type") (if_then_else (match_operand 4 "const_int_operand" "")
6b6abc9c 1039 (const_string "arlo_shift")
1040 (const_string "arlo_shift_reg")))]
9154bd82 1041)
1042
1043(define_insn "*rsbsi3_carryin_shift"
1044 [(set (match_operand:SI 0 "s_register_operand" "=r")
1045 (minus:SI (minus:SI
1046 (match_operator:SI 2 "shift_operator"
1047 [(match_operand:SI 3 "s_register_operand" "r")
1048 (match_operand:SI 4 "reg_or_int_operand" "rM")])
1049 (match_operand:SI 1 "s_register_operand" "r"))
1050 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1051 "TARGET_ARM"
1052 "rsc%?\\t%0, %1, %3%S2"
1053 [(set_attr "conds" "use")
1054 (set_attr "predicable" "yes")
1055 (set (attr "type") (if_then_else (match_operand 4 "const_int_operand" "")
6b6abc9c 1056 (const_string "arlo_shift")
1057 (const_string "arlo_shift_reg")))]
9154bd82 1058)
1059
d795fb69 1060; transform ((x << y) - 1) to ~(~(x-1) << y) Where X is a constant.
1061(define_split
1062 [(set (match_operand:SI 0 "s_register_operand" "")
1063 (plus:SI (ashift:SI (match_operand:SI 1 "const_int_operand" "")
1064 (match_operand:SI 2 "s_register_operand" ""))
1065 (const_int -1)))
1066 (clobber (match_operand:SI 3 "s_register_operand" ""))]
25f905c2 1067 "TARGET_32BIT"
d795fb69 1068 [(set (match_dup 3) (match_dup 1))
1069 (set (match_dup 0) (not:SI (ashift:SI (match_dup 3) (match_dup 2))))]
1070 "
1071 operands[1] = GEN_INT (~(INTVAL (operands[1]) - 1));
1072")
1073
604f3a0a 1074(define_expand "addsf3"
1075 [(set (match_operand:SF 0 "s_register_operand" "")
1076 (plus:SF (match_operand:SF 1 "s_register_operand" "")
d86c91f6 1077 (match_operand:SF 2 "s_register_operand" "")))]
25f905c2 1078 "TARGET_32BIT && TARGET_HARD_FLOAT"
604f3a0a 1079 "
604f3a0a 1080")
1081
604f3a0a 1082(define_expand "adddf3"
1083 [(set (match_operand:DF 0 "s_register_operand" "")
1084 (plus:DF (match_operand:DF 1 "s_register_operand" "")
d86c91f6 1085 (match_operand:DF 2 "s_register_operand" "")))]
a50d7267 1086 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
604f3a0a 1087 "
604f3a0a 1088")
1089
cffb2a26 1090(define_expand "subdi3"
1091 [(parallel
1092 [(set (match_operand:DI 0 "s_register_operand" "")
1093 (minus:DI (match_operand:DI 1 "s_register_operand" "")
1094 (match_operand:DI 2 "s_register_operand" "")))
bd5b4116 1095 (clobber (reg:CC CC_REGNUM))])]
cffb2a26 1096 "TARGET_EITHER"
1097 "
25f905c2 1098 if (TARGET_THUMB1)
cffb2a26 1099 {
0438d37f 1100 if (!REG_P (operands[1]))
5aa8c5f0 1101 operands[1] = force_reg (DImode, operands[1]);
0438d37f 1102 if (!REG_P (operands[2]))
5aa8c5f0 1103 operands[2] = force_reg (DImode, operands[2]);
cffb2a26 1104 }
1105 "
1106)
1107
2f9b23e3 1108(define_insn_and_split "*arm_subdi3"
cffb2a26 1109 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r,&r")
9c08d1fa 1110 (minus:DI (match_operand:DI 1 "s_register_operand" "0,r,0")
1111 (match_operand:DI 2 "s_register_operand" "r,0,0")))
bd5b4116 1112 (clobber (reg:CC CC_REGNUM))]
94829feb 1113 "TARGET_32BIT && !TARGET_NEON"
2f9b23e3 1114 "#" ; "subs\\t%Q0, %Q1, %Q2\;sbc\\t%R0, %R1, %R2"
1115 "&& reload_completed"
1116 [(parallel [(set (reg:CC CC_REGNUM)
1117 (compare:CC (match_dup 1) (match_dup 2)))
1118 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
1119 (set (match_dup 3) (minus:SI (minus:SI (match_dup 4) (match_dup 5))
1120 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1121 {
1122 operands[3] = gen_highpart (SImode, operands[0]);
1123 operands[0] = gen_lowpart (SImode, operands[0]);
1124 operands[4] = gen_highpart (SImode, operands[1]);
1125 operands[1] = gen_lowpart (SImode, operands[1]);
1126 operands[5] = gen_highpart (SImode, operands[2]);
1127 operands[2] = gen_lowpart (SImode, operands[2]);
1128 }
cffb2a26 1129 [(set_attr "conds" "clob")
1130 (set_attr "length" "8")]
1131)
1132
1133(define_insn "*thumb_subdi3"
1134 [(set (match_operand:DI 0 "register_operand" "=l")
1135 (minus:DI (match_operand:DI 1 "register_operand" "0")
1136 (match_operand:DI 2 "register_operand" "l")))
bd5b4116 1137 (clobber (reg:CC CC_REGNUM))]
25f905c2 1138 "TARGET_THUMB1"
cffb2a26 1139 "sub\\t%Q0, %Q0, %Q2\;sbc\\t%R0, %R0, %R2"
1140 [(set_attr "length" "4")]
1141)
9c08d1fa 1142
2f9b23e3 1143(define_insn_and_split "*subdi_di_zesidi"
cffb2a26 1144 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
e5fea38e 1145 (minus:DI (match_operand:DI 1 "s_register_operand" "0,r")
9c08d1fa 1146 (zero_extend:DI
cffb2a26 1147 (match_operand:SI 2 "s_register_operand" "r,r"))))
bd5b4116 1148 (clobber (reg:CC CC_REGNUM))]
25f905c2 1149 "TARGET_32BIT"
2f9b23e3 1150 "#" ; "subs\\t%Q0, %Q1, %2\;sbc\\t%R0, %R1, #0"
1151 "&& reload_completed"
1152 [(parallel [(set (reg:CC CC_REGNUM)
1153 (compare:CC (match_dup 1) (match_dup 2)))
1154 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
1155 (set (match_dup 3) (minus:SI (plus:SI (match_dup 4) (match_dup 5))
1156 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1157 {
1158 operands[3] = gen_highpart (SImode, operands[0]);
1159 operands[0] = gen_lowpart (SImode, operands[0]);
1160 operands[4] = gen_highpart (SImode, operands[1]);
1161 operands[1] = gen_lowpart (SImode, operands[1]);
1162 operands[5] = GEN_INT (~0);
1163 }
cffb2a26 1164 [(set_attr "conds" "clob")
1165 (set_attr "length" "8")]
1166)
9c08d1fa 1167
2f9b23e3 1168(define_insn_and_split "*subdi_di_sesidi"
cffb2a26 1169 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
e5fea38e 1170 (minus:DI (match_operand:DI 1 "s_register_operand" "0,r")
9c08d1fa 1171 (sign_extend:DI
cffb2a26 1172 (match_operand:SI 2 "s_register_operand" "r,r"))))
bd5b4116 1173 (clobber (reg:CC CC_REGNUM))]
25f905c2 1174 "TARGET_32BIT"
2f9b23e3 1175 "#" ; "subs\\t%Q0, %Q1, %2\;sbc\\t%R0, %R1, %2, asr #31"
1176 "&& reload_completed"
1177 [(parallel [(set (reg:CC CC_REGNUM)
1178 (compare:CC (match_dup 1) (match_dup 2)))
1179 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
1180 (set (match_dup 3) (minus:SI (minus:SI (match_dup 4)
1181 (ashiftrt:SI (match_dup 2)
1182 (const_int 31)))
1183 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1184 {
1185 operands[3] = gen_highpart (SImode, operands[0]);
1186 operands[0] = gen_lowpart (SImode, operands[0]);
1187 operands[4] = gen_highpart (SImode, operands[1]);
1188 operands[1] = gen_lowpart (SImode, operands[1]);
1189 }
cffb2a26 1190 [(set_attr "conds" "clob")
1191 (set_attr "length" "8")]
1192)
9c08d1fa 1193
2f9b23e3 1194(define_insn_and_split "*subdi_zesidi_di"
cffb2a26 1195 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
9c08d1fa 1196 (minus:DI (zero_extend:DI
cffb2a26 1197 (match_operand:SI 2 "s_register_operand" "r,r"))
e5fea38e 1198 (match_operand:DI 1 "s_register_operand" "0,r")))
bd5b4116 1199 (clobber (reg:CC CC_REGNUM))]
cffb2a26 1200 "TARGET_ARM"
2f9b23e3 1201 "#" ; "rsbs\\t%Q0, %Q1, %2\;rsc\\t%R0, %R1, #0"
1202 ; is equivalent to:
1203 ; "subs\\t%Q0, %2, %Q1\;rsc\\t%R0, %R1, #0"
1204 "&& reload_completed"
1205 [(parallel [(set (reg:CC CC_REGNUM)
1206 (compare:CC (match_dup 2) (match_dup 1)))
1207 (set (match_dup 0) (minus:SI (match_dup 2) (match_dup 1)))])
1208 (set (match_dup 3) (minus:SI (minus:SI (const_int 0) (match_dup 4))
1209 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1210 {
1211 operands[3] = gen_highpart (SImode, operands[0]);
1212 operands[0] = gen_lowpart (SImode, operands[0]);
1213 operands[4] = gen_highpart (SImode, operands[1]);
1214 operands[1] = gen_lowpart (SImode, operands[1]);
1215 }
cffb2a26 1216 [(set_attr "conds" "clob")
1217 (set_attr "length" "8")]
1218)
9c08d1fa 1219
2f9b23e3 1220(define_insn_and_split "*subdi_sesidi_di"
cffb2a26 1221 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
9c08d1fa 1222 (minus:DI (sign_extend:DI
cffb2a26 1223 (match_operand:SI 2 "s_register_operand" "r,r"))
e5fea38e 1224 (match_operand:DI 1 "s_register_operand" "0,r")))
bd5b4116 1225 (clobber (reg:CC CC_REGNUM))]
cffb2a26 1226 "TARGET_ARM"
2f9b23e3 1227 "#" ; "rsbs\\t%Q0, %Q1, %2\;rsc\\t%R0, %R1, %2, asr #31"
1228 ; is equivalent to:
1229 ; "subs\\t%Q0, %2, %Q1\;rsc\\t%R0, %R1, %2, asr #31"
1230 "&& reload_completed"
1231 [(parallel [(set (reg:CC CC_REGNUM)
1232 (compare:CC (match_dup 2) (match_dup 1)))
1233 (set (match_dup 0) (minus:SI (match_dup 2) (match_dup 1)))])
1234 (set (match_dup 3) (minus:SI (minus:SI
1235 (ashiftrt:SI (match_dup 2)
1236 (const_int 31))
1237 (match_dup 4))
1238 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1239 {
1240 operands[3] = gen_highpart (SImode, operands[0]);
1241 operands[0] = gen_lowpart (SImode, operands[0]);
1242 operands[4] = gen_highpart (SImode, operands[1]);
1243 operands[1] = gen_lowpart (SImode, operands[1]);
1244 }
cffb2a26 1245 [(set_attr "conds" "clob")
1246 (set_attr "length" "8")]
1247)
9c08d1fa 1248
2f9b23e3 1249(define_insn_and_split "*subdi_zesidi_zesidi"
cffb2a26 1250 [(set (match_operand:DI 0 "s_register_operand" "=r")
9c08d1fa 1251 (minus:DI (zero_extend:DI
cffb2a26 1252 (match_operand:SI 1 "s_register_operand" "r"))
9c08d1fa 1253 (zero_extend:DI
cffb2a26 1254 (match_operand:SI 2 "s_register_operand" "r"))))
bd5b4116 1255 (clobber (reg:CC CC_REGNUM))]
25f905c2 1256 "TARGET_32BIT"
2f9b23e3 1257 "#" ; "subs\\t%Q0, %1, %2\;sbc\\t%R0, %1, %1"
1258 "&& reload_completed"
1259 [(parallel [(set (reg:CC CC_REGNUM)
1260 (compare:CC (match_dup 1) (match_dup 2)))
1261 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
1262 (set (match_dup 3) (minus:SI (minus:SI (match_dup 1) (match_dup 1))
1263 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1264 {
1265 operands[3] = gen_highpart (SImode, operands[0]);
1266 operands[0] = gen_lowpart (SImode, operands[0]);
1267 }
cffb2a26 1268 [(set_attr "conds" "clob")
1269 (set_attr "length" "8")]
1270)
b11cae9e 1271
87b22bf7 1272(define_expand "subsi3"
cffb2a26 1273 [(set (match_operand:SI 0 "s_register_operand" "")
87b22bf7 1274 (minus:SI (match_operand:SI 1 "reg_or_int_operand" "")
1275 (match_operand:SI 2 "s_register_operand" "")))]
cffb2a26 1276 "TARGET_EITHER"
87b22bf7 1277 "
0438d37f 1278 if (CONST_INT_P (operands[1]))
87b22bf7 1279 {
25f905c2 1280 if (TARGET_32BIT)
cffb2a26 1281 {
96f57e36 1282 arm_split_constant (MINUS, SImode, NULL_RTX,
1283 INTVAL (operands[1]), operands[0],
e1ba4a27 1284 operands[2], optimize && can_create_pseudo_p ());
cffb2a26 1285 DONE;
1286 }
25f905c2 1287 else /* TARGET_THUMB1 */
cffb2a26 1288 operands[1] = force_reg (SImode, operands[1]);
87b22bf7 1289 }
cffb2a26 1290 "
1291)
87b22bf7 1292
747b7458 1293(define_insn "thumb1_subsi3_insn"
cffb2a26 1294 [(set (match_operand:SI 0 "register_operand" "=l")
1295 (minus:SI (match_operand:SI 1 "register_operand" "l")
747b7458 1296 (match_operand:SI 2 "reg_or_int_operand" "lPd")))]
25f905c2 1297 "TARGET_THUMB1"
cffb2a26 1298 "sub\\t%0, %1, %2"
747b7458 1299 [(set_attr "length" "2")
1300 (set_attr "conds" "set")])
cffb2a26 1301
25f905c2 1302; ??? Check Thumb-2 split length
a0f94409 1303(define_insn_and_split "*arm_subsi3_insn"
7c36fe71 1304 [(set (match_operand:SI 0 "s_register_operand" "=l,l ,l ,l ,r ,r,r,rk,r")
1305 (minus:SI (match_operand:SI 1 "reg_or_int_operand" "l ,0 ,l ,Pz,rI,r,r,k ,?n")
1306 (match_operand:SI 2 "reg_or_int_operand" "l ,Py,Pd,l ,r ,I,r,r ,r")))]
25f905c2 1307 "TARGET_32BIT"
e2348bcb 1308 "@
7c36fe71 1309 sub%?\\t%0, %1, %2
1310 sub%?\\t%0, %2
1311 sub%?\\t%0, %1, %2
1312 rsb%?\\t%0, %2, %1
87b22bf7 1313 rsb%?\\t%0, %2, %1
aaa37ad6 1314 sub%?\\t%0, %1, %2
080c0b9a 1315 sub%?\\t%0, %1, %2
65f68e55 1316 sub%?\\t%0, %1, %2
87b22bf7 1317 #"
0438d37f 1318 "&& (CONST_INT_P (operands[1])
91a5e339 1319 && !const_ok_for_arm (INTVAL (operands[1])))"
87b22bf7 1320 [(clobber (const_int 0))]
1321 "
96f57e36 1322 arm_split_constant (MINUS, SImode, curr_insn,
1323 INTVAL (operands[1]), operands[0], operands[2], 0);
87b22bf7 1324 DONE;
cffb2a26 1325 "
7c36fe71 1326 [(set_attr "length" "4,4,4,4,4,4,4,4,16")
1327 (set_attr "arch" "t2,t2,t2,t2,*,*,*,*,*")
65f68e55 1328 (set_attr "predicable" "yes")
7c36fe71 1329 (set_attr "predicable_short_it" "yes,yes,yes,yes,no,no,no,no,no")
1330 (set_attr "type" "*,*,*,*,arlo_imm,arlo_imm,*,*,arlo_imm")]
a0f94409 1331)
1332
1333(define_peephole2
1334 [(match_scratch:SI 3 "r")
372575c7 1335 (set (match_operand:SI 0 "arm_general_register_operand" "")
a0f94409 1336 (minus:SI (match_operand:SI 1 "const_int_operand" "")
372575c7 1337 (match_operand:SI 2 "arm_general_register_operand" "")))]
25f905c2 1338 "TARGET_32BIT
a0f94409 1339 && !const_ok_for_arm (INTVAL (operands[1]))
1340 && const_ok_for_arm (~INTVAL (operands[1]))"
1341 [(set (match_dup 3) (match_dup 1))
1342 (set (match_dup 0) (minus:SI (match_dup 3) (match_dup 2)))]
1343 ""
cffb2a26 1344)
b11cae9e 1345
f7fbdd4a 1346(define_insn "*subsi3_compare0"
bd5b4116 1347 [(set (reg:CC_NOOV CC_REGNUM)
215b30b3 1348 (compare:CC_NOOV
65f68e55 1349 (minus:SI (match_operand:SI 1 "arm_rhs_operand" "r,r,I")
1350 (match_operand:SI 2 "arm_rhs_operand" "I,r,r"))
215b30b3 1351 (const_int 0)))
65f68e55 1352 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9c08d1fa 1353 (minus:SI (match_dup 1) (match_dup 2)))]
25f905c2 1354 "TARGET_32BIT"
e2348bcb 1355 "@
65f68e55 1356 sub%.\\t%0, %1, %2
25f905c2 1357 sub%.\\t%0, %1, %2
1358 rsb%.\\t%0, %2, %1"
65f68e55 1359 [(set_attr "conds" "set")
6b6abc9c 1360 (set_attr "type" "arlo_imm,*,*")]
cffb2a26 1361)
9c08d1fa 1362
190efb17 1363(define_insn "subsi3_compare"
080c0b9a 1364 [(set (reg:CC CC_REGNUM)
65f68e55 1365 (compare:CC (match_operand:SI 1 "arm_rhs_operand" "r,r,I")
1366 (match_operand:SI 2 "arm_rhs_operand" "I,r,r")))
1367 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
2df9477b 1368 (minus:SI (match_dup 1) (match_dup 2)))]
1369 "TARGET_32BIT"
1370 "@
65f68e55 1371 sub%.\\t%0, %1, %2
2df9477b 1372 sub%.\\t%0, %1, %2
1373 rsb%.\\t%0, %2, %1"
65f68e55 1374 [(set_attr "conds" "set")
6b6abc9c 1375 (set_attr "type" "arlo_imm,*,*")]
2df9477b 1376)
1377
604f3a0a 1378(define_expand "subsf3"
1379 [(set (match_operand:SF 0 "s_register_operand" "")
d86c91f6 1380 (minus:SF (match_operand:SF 1 "s_register_operand" "")
1381 (match_operand:SF 2 "s_register_operand" "")))]
25f905c2 1382 "TARGET_32BIT && TARGET_HARD_FLOAT"
604f3a0a 1383 "
604f3a0a 1384")
1385
604f3a0a 1386(define_expand "subdf3"
1387 [(set (match_operand:DF 0 "s_register_operand" "")
d86c91f6 1388 (minus:DF (match_operand:DF 1 "s_register_operand" "")
1389 (match_operand:DF 2 "s_register_operand" "")))]
a50d7267 1390 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
604f3a0a 1391 "
604f3a0a 1392")
1393
b11cae9e 1394\f
1395;; Multiplication insns
1396
4422d91f 1397(define_expand "mulhi3"
1398 [(set (match_operand:HI 0 "s_register_operand" "")
1399 (mult:HI (match_operand:HI 1 "s_register_operand" "")
1400 (match_operand:HI 2 "s_register_operand" "")))]
1401 "TARGET_DSP_MULTIPLY"
1402 "
1403 {
1404 rtx result = gen_reg_rtx (SImode);
1405 emit_insn (gen_mulhisi3 (result, operands[1], operands[2]));
1406 emit_move_insn (operands[0], gen_lowpart (HImode, result));
1407 DONE;
1408 }"
1409)
1410
cffb2a26 1411(define_expand "mulsi3"
1412 [(set (match_operand:SI 0 "s_register_operand" "")
1413 (mult:SI (match_operand:SI 2 "s_register_operand" "")
1414 (match_operand:SI 1 "s_register_operand" "")))]
1415 "TARGET_EITHER"
1416 ""
1417)
1418
9c08d1fa 1419;; Use `&' and then `0' to prevent the operands 0 and 1 being the same
cffb2a26 1420(define_insn "*arm_mulsi3"
1421 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r")
9c08d1fa 1422 (mult:SI (match_operand:SI 2 "s_register_operand" "r,r")
e5fea38e 1423 (match_operand:SI 1 "s_register_operand" "%0,r")))]
58d7d654 1424 "TARGET_32BIT && !arm_arch6"
f7fbdd4a 1425 "mul%?\\t%0, %2, %1"
9da0ec36 1426 [(set_attr "type" "mul")
0d66636f 1427 (set_attr "predicable" "yes")]
cffb2a26 1428)
1429
58d7d654 1430(define_insn "*arm_mulsi3_v6"
d952d547 1431 [(set (match_operand:SI 0 "s_register_operand" "=l,l,r")
1432 (mult:SI (match_operand:SI 1 "s_register_operand" "0,l,r")
1433 (match_operand:SI 2 "s_register_operand" "l,0,r")))]
58d7d654 1434 "TARGET_32BIT && arm_arch6"
1435 "mul%?\\t%0, %1, %2"
9da0ec36 1436 [(set_attr "type" "mul")
d952d547 1437 (set_attr "predicable" "yes")
1438 (set_attr "arch" "t2,t2,*")
1439 (set_attr "length" "4")
1440 (set_attr "predicable_short_it" "yes,yes,no")]
58d7d654 1441)
1442
215b30b3 1443; Unfortunately with the Thumb the '&'/'0' trick can fails when operands
1444; 1 and 2; are the same, because reload will make operand 0 match
1445; operand 1 without realizing that this conflicts with operand 2. We fix
1446; this by adding another alternative to match this case, and then `reload'
1447; it ourselves. This alternative must come first.
cffb2a26 1448(define_insn "*thumb_mulsi3"
1449 [(set (match_operand:SI 0 "register_operand" "=&l,&l,&l")
1450 (mult:SI (match_operand:SI 1 "register_operand" "%l,*h,0")
1451 (match_operand:SI 2 "register_operand" "l,l,l")))]
58d7d654 1452 "TARGET_THUMB1 && !arm_arch6"
cffb2a26 1453 "*
1454 if (which_alternative < 2)
20c4e896 1455 return \"mov\\t%0, %1\;mul\\t%0, %2\";
cffb2a26 1456 else
20c4e896 1457 return \"mul\\t%0, %2\";
cffb2a26 1458 "
1459 [(set_attr "length" "4,4,2")
9da0ec36 1460 (set_attr "type" "muls")]
cffb2a26 1461)
b11cae9e 1462
58d7d654 1463(define_insn "*thumb_mulsi3_v6"
1464 [(set (match_operand:SI 0 "register_operand" "=l,l,l")
1465 (mult:SI (match_operand:SI 1 "register_operand" "0,l,0")
1466 (match_operand:SI 2 "register_operand" "l,0,0")))]
1467 "TARGET_THUMB1 && arm_arch6"
1468 "@
1490694c 1469 mul\\t%0, %2
1470 mul\\t%0, %1
58d7d654 1471 mul\\t%0, %1"
1472 [(set_attr "length" "2")
9da0ec36 1473 (set_attr "type" "muls")]
58d7d654 1474)
1475
f7fbdd4a 1476(define_insn "*mulsi3_compare0"
bd5b4116 1477 [(set (reg:CC_NOOV CC_REGNUM)
9c08d1fa 1478 (compare:CC_NOOV (mult:SI
1479 (match_operand:SI 2 "s_register_operand" "r,r")
e5fea38e 1480 (match_operand:SI 1 "s_register_operand" "%0,r"))
9c08d1fa 1481 (const_int 0)))
1482 (set (match_operand:SI 0 "s_register_operand" "=&r,&r")
1483 (mult:SI (match_dup 2) (match_dup 1)))]
58d7d654 1484 "TARGET_ARM && !arm_arch6"
1485 "mul%.\\t%0, %2, %1"
1486 [(set_attr "conds" "set")
9da0ec36 1487 (set_attr "type" "muls")]
58d7d654 1488)
1489
1490(define_insn "*mulsi3_compare0_v6"
1491 [(set (reg:CC_NOOV CC_REGNUM)
1492 (compare:CC_NOOV (mult:SI
1493 (match_operand:SI 2 "s_register_operand" "r")
1494 (match_operand:SI 1 "s_register_operand" "r"))
1495 (const_int 0)))
1496 (set (match_operand:SI 0 "s_register_operand" "=r")
1497 (mult:SI (match_dup 2) (match_dup 1)))]
1498 "TARGET_ARM && arm_arch6 && optimize_size"
25f905c2 1499 "mul%.\\t%0, %2, %1"
cffb2a26 1500 [(set_attr "conds" "set")
9da0ec36 1501 (set_attr "type" "muls")]
cffb2a26 1502)
9c08d1fa 1503
f7fbdd4a 1504(define_insn "*mulsi_compare0_scratch"
bd5b4116 1505 [(set (reg:CC_NOOV CC_REGNUM)
9c08d1fa 1506 (compare:CC_NOOV (mult:SI
1507 (match_operand:SI 2 "s_register_operand" "r,r")
e5fea38e 1508 (match_operand:SI 1 "s_register_operand" "%0,r"))
9c08d1fa 1509 (const_int 0)))
1510 (clobber (match_scratch:SI 0 "=&r,&r"))]
58d7d654 1511 "TARGET_ARM && !arm_arch6"
1512 "mul%.\\t%0, %2, %1"
1513 [(set_attr "conds" "set")
9da0ec36 1514 (set_attr "type" "muls")]
58d7d654 1515)
1516
1517(define_insn "*mulsi_compare0_scratch_v6"
1518 [(set (reg:CC_NOOV CC_REGNUM)
1519 (compare:CC_NOOV (mult:SI
1520 (match_operand:SI 2 "s_register_operand" "r")
1521 (match_operand:SI 1 "s_register_operand" "r"))
1522 (const_int 0)))
1523 (clobber (match_scratch:SI 0 "=r"))]
1524 "TARGET_ARM && arm_arch6 && optimize_size"
25f905c2 1525 "mul%.\\t%0, %2, %1"
cffb2a26 1526 [(set_attr "conds" "set")
9da0ec36 1527 (set_attr "type" "muls")]
cffb2a26 1528)
9c08d1fa 1529
b11cae9e 1530;; Unnamed templates to match MLA instruction.
1531
f7fbdd4a 1532(define_insn "*mulsi3addsi"
9c08d1fa 1533 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r,&r")
c8f69309 1534 (plus:SI
9c08d1fa 1535 (mult:SI (match_operand:SI 2 "s_register_operand" "r,r,r,r")
e5fea38e 1536 (match_operand:SI 1 "s_register_operand" "%0,r,0,r"))
1537 (match_operand:SI 3 "s_register_operand" "r,r,0,0")))]
58d7d654 1538 "TARGET_32BIT && !arm_arch6"
1539 "mla%?\\t%0, %2, %1, %3"
9da0ec36 1540 [(set_attr "type" "mla")
58d7d654 1541 (set_attr "predicable" "yes")]
1542)
1543
1544(define_insn "*mulsi3addsi_v6"
1545 [(set (match_operand:SI 0 "s_register_operand" "=r")
1546 (plus:SI
1547 (mult:SI (match_operand:SI 2 "s_register_operand" "r")
1548 (match_operand:SI 1 "s_register_operand" "r"))
1549 (match_operand:SI 3 "s_register_operand" "r")))]
1550 "TARGET_32BIT && arm_arch6"
f7fbdd4a 1551 "mla%?\\t%0, %2, %1, %3"
9da0ec36 1552 [(set_attr "type" "mla")
d952d547 1553 (set_attr "predicable" "yes")
1554 (set_attr "predicable_short_it" "no")]
0d66636f 1555)
b11cae9e 1556
f7fbdd4a 1557(define_insn "*mulsi3addsi_compare0"
bd5b4116 1558 [(set (reg:CC_NOOV CC_REGNUM)
215b30b3 1559 (compare:CC_NOOV
1560 (plus:SI (mult:SI
1561 (match_operand:SI 2 "s_register_operand" "r,r,r,r")
e5fea38e 1562 (match_operand:SI 1 "s_register_operand" "%0,r,0,r"))
1563 (match_operand:SI 3 "s_register_operand" "r,r,0,0"))
215b30b3 1564 (const_int 0)))
9c08d1fa 1565 (set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r,&r")
1566 (plus:SI (mult:SI (match_dup 2) (match_dup 1))
1567 (match_dup 3)))]
58d7d654 1568 "TARGET_ARM && arm_arch6"
1569 "mla%.\\t%0, %2, %1, %3"
1570 [(set_attr "conds" "set")
9da0ec36 1571 (set_attr "type" "mlas")]
58d7d654 1572)
1573
1574(define_insn "*mulsi3addsi_compare0_v6"
1575 [(set (reg:CC_NOOV CC_REGNUM)
1576 (compare:CC_NOOV
1577 (plus:SI (mult:SI
1578 (match_operand:SI 2 "s_register_operand" "r")
1579 (match_operand:SI 1 "s_register_operand" "r"))
1580 (match_operand:SI 3 "s_register_operand" "r"))
1581 (const_int 0)))
1582 (set (match_operand:SI 0 "s_register_operand" "=r")
1583 (plus:SI (mult:SI (match_dup 2) (match_dup 1))
1584 (match_dup 3)))]
1585 "TARGET_ARM && arm_arch6 && optimize_size"
25f905c2 1586 "mla%.\\t%0, %2, %1, %3"
0d66636f 1587 [(set_attr "conds" "set")
9da0ec36 1588 (set_attr "type" "mlas")]
0d66636f 1589)
9c08d1fa 1590
f7fbdd4a 1591(define_insn "*mulsi3addsi_compare0_scratch"
bd5b4116 1592 [(set (reg:CC_NOOV CC_REGNUM)
215b30b3 1593 (compare:CC_NOOV
1594 (plus:SI (mult:SI
1595 (match_operand:SI 2 "s_register_operand" "r,r,r,r")
e5fea38e 1596 (match_operand:SI 1 "s_register_operand" "%0,r,0,r"))
215b30b3 1597 (match_operand:SI 3 "s_register_operand" "?r,r,0,0"))
1598 (const_int 0)))
9c08d1fa 1599 (clobber (match_scratch:SI 0 "=&r,&r,&r,&r"))]
58d7d654 1600 "TARGET_ARM && !arm_arch6"
1601 "mla%.\\t%0, %2, %1, %3"
1602 [(set_attr "conds" "set")
9da0ec36 1603 (set_attr "type" "mlas")]
58d7d654 1604)
1605
1606(define_insn "*mulsi3addsi_compare0_scratch_v6"
1607 [(set (reg:CC_NOOV CC_REGNUM)
1608 (compare:CC_NOOV
1609 (plus:SI (mult:SI
1610 (match_operand:SI 2 "s_register_operand" "r")
1611 (match_operand:SI 1 "s_register_operand" "r"))
1612 (match_operand:SI 3 "s_register_operand" "r"))
1613 (const_int 0)))
1614 (clobber (match_scratch:SI 0 "=r"))]
1615 "TARGET_ARM && arm_arch6 && optimize_size"
25f905c2 1616 "mla%.\\t%0, %2, %1, %3"
cffb2a26 1617 [(set_attr "conds" "set")
9da0ec36 1618 (set_attr "type" "mlas")]
cffb2a26 1619)
f7fbdd4a 1620
89545238 1621(define_insn "*mulsi3subsi"
1622 [(set (match_operand:SI 0 "s_register_operand" "=r")
1623 (minus:SI
1624 (match_operand:SI 3 "s_register_operand" "r")
1625 (mult:SI (match_operand:SI 2 "s_register_operand" "r")
1626 (match_operand:SI 1 "s_register_operand" "r"))))]
1627 "TARGET_32BIT && arm_arch_thumb2"
1628 "mls%?\\t%0, %2, %1, %3"
9da0ec36 1629 [(set_attr "type" "mla")
d952d547 1630 (set_attr "predicable" "yes")
1631 (set_attr "predicable_short_it" "no")]
89545238 1632)
1633
5cdca009 1634(define_expand "maddsidi4"
1635 [(set (match_operand:DI 0 "s_register_operand" "")
1636 (plus:DI
1637 (mult:DI
1638 (sign_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1639 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "")))
1640 (match_operand:DI 3 "s_register_operand" "")))]
1641 "TARGET_32BIT && arm_arch3m"
1642 "")
82b85d08 1643
1644(define_insn "*mulsidi3adddi"
fe8dbf85 1645 [(set (match_operand:DI 0 "s_register_operand" "=&r")
82b85d08 1646 (plus:DI
215b30b3 1647 (mult:DI
fe8dbf85 1648 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "%r"))
1649 (sign_extend:DI (match_operand:SI 3 "s_register_operand" "r")))
1650 (match_operand:DI 1 "s_register_operand" "0")))]
58d7d654 1651 "TARGET_32BIT && arm_arch3m && !arm_arch6"
1652 "smlal%?\\t%Q0, %R0, %3, %2"
9da0ec36 1653 [(set_attr "type" "smlal")
58d7d654 1654 (set_attr "predicable" "yes")]
1655)
1656
1657(define_insn "*mulsidi3adddi_v6"
1658 [(set (match_operand:DI 0 "s_register_operand" "=r")
1659 (plus:DI
1660 (mult:DI
1661 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r"))
1662 (sign_extend:DI (match_operand:SI 3 "s_register_operand" "r")))
1663 (match_operand:DI 1 "s_register_operand" "0")))]
1664 "TARGET_32BIT && arm_arch6"
fe8dbf85 1665 "smlal%?\\t%Q0, %R0, %3, %2"
9da0ec36 1666 [(set_attr "type" "smlal")
d952d547 1667 (set_attr "predicable" "yes")
1668 (set_attr "predicable_short_it" "no")]
0d66636f 1669)
82b85d08 1670
957788b0 1671;; 32x32->64 widening multiply.
1672;; As with mulsi3, the only difference between the v3-5 and v6+
1673;; versions of these patterns is the requirement that the output not
1674;; overlap the inputs, but that still means we have to have a named
1675;; expander and two different starred insns.
1676
1677(define_expand "mulsidi3"
1678 [(set (match_operand:DI 0 "s_register_operand" "")
1679 (mult:DI
1680 (sign_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1681 (sign_extend:DI (match_operand:SI 2 "s_register_operand" ""))))]
1682 "TARGET_32BIT && arm_arch3m"
1683 ""
1684)
1685
1686(define_insn "*mulsidi3_nov6"
f7fbdd4a 1687 [(set (match_operand:DI 0 "s_register_operand" "=&r")
215b30b3 1688 (mult:DI
1689 (sign_extend:DI (match_operand:SI 1 "s_register_operand" "%r"))
1690 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))]
58d7d654 1691 "TARGET_32BIT && arm_arch3m && !arm_arch6"
1692 "smull%?\\t%Q0, %R0, %1, %2"
9da0ec36 1693 [(set_attr "type" "smull")
58d7d654 1694 (set_attr "predicable" "yes")]
1695)
1696
957788b0 1697(define_insn "*mulsidi3_v6"
58d7d654 1698 [(set (match_operand:DI 0 "s_register_operand" "=r")
1699 (mult:DI
1700 (sign_extend:DI (match_operand:SI 1 "s_register_operand" "r"))
1701 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))]
1702 "TARGET_32BIT && arm_arch6"
97499065 1703 "smull%?\\t%Q0, %R0, %1, %2"
9da0ec36 1704 [(set_attr "type" "smull")
d952d547 1705 (set_attr "predicable" "yes")
1706 (set_attr "predicable_short_it" "no")]
0d66636f 1707)
f7fbdd4a 1708
957788b0 1709(define_expand "umulsidi3"
1710 [(set (match_operand:DI 0 "s_register_operand" "")
1711 (mult:DI
1712 (zero_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1713 (zero_extend:DI (match_operand:SI 2 "s_register_operand" ""))))]
1714 "TARGET_32BIT && arm_arch3m"
1715 ""
1716)
1717
1718(define_insn "*umulsidi3_nov6"
f7fbdd4a 1719 [(set (match_operand:DI 0 "s_register_operand" "=&r")
215b30b3 1720 (mult:DI
1721 (zero_extend:DI (match_operand:SI 1 "s_register_operand" "%r"))
1722 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))]
58d7d654 1723 "TARGET_32BIT && arm_arch3m && !arm_arch6"
1724 "umull%?\\t%Q0, %R0, %1, %2"
9da0ec36 1725 [(set_attr "type" "umull")
58d7d654 1726 (set_attr "predicable" "yes")]
1727)
1728
957788b0 1729(define_insn "*umulsidi3_v6"
58d7d654 1730 [(set (match_operand:DI 0 "s_register_operand" "=r")
1731 (mult:DI
1732 (zero_extend:DI (match_operand:SI 1 "s_register_operand" "r"))
1733 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))]
1734 "TARGET_32BIT && arm_arch6"
97499065 1735 "umull%?\\t%Q0, %R0, %1, %2"
9da0ec36 1736 [(set_attr "type" "umull")
d952d547 1737 (set_attr "predicable" "yes")
1738 (set_attr "predicable_short_it" "no")]
0d66636f 1739)
b11cae9e 1740
5cdca009 1741(define_expand "umaddsidi4"
1742 [(set (match_operand:DI 0 "s_register_operand" "")
1743 (plus:DI
1744 (mult:DI
1745 (zero_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1746 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "")))
1747 (match_operand:DI 3 "s_register_operand" "")))]
1748 "TARGET_32BIT && arm_arch3m"
1749 "")
82b85d08 1750
1751(define_insn "*umulsidi3adddi"
8ead09f9 1752 [(set (match_operand:DI 0 "s_register_operand" "=&r")
82b85d08 1753 (plus:DI
215b30b3 1754 (mult:DI
fe8dbf85 1755 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "%r"))
1756 (zero_extend:DI (match_operand:SI 3 "s_register_operand" "r")))
1757 (match_operand:DI 1 "s_register_operand" "0")))]
58d7d654 1758 "TARGET_32BIT && arm_arch3m && !arm_arch6"
1759 "umlal%?\\t%Q0, %R0, %3, %2"
9da0ec36 1760 [(set_attr "type" "umlal")
58d7d654 1761 (set_attr "predicable" "yes")]
1762)
1763
1764(define_insn "*umulsidi3adddi_v6"
1765 [(set (match_operand:DI 0 "s_register_operand" "=r")
1766 (plus:DI
1767 (mult:DI
1768 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r"))
1769 (zero_extend:DI (match_operand:SI 3 "s_register_operand" "r")))
1770 (match_operand:DI 1 "s_register_operand" "0")))]
1771 "TARGET_32BIT && arm_arch6"
fe8dbf85 1772 "umlal%?\\t%Q0, %R0, %3, %2"
9da0ec36 1773 [(set_attr "type" "umlal")
d952d547 1774 (set_attr "predicable" "yes")
1775 (set_attr "predicable_short_it" "no")]
0d66636f 1776)
82b85d08 1777
957788b0 1778(define_expand "smulsi3_highpart"
1779 [(parallel
1780 [(set (match_operand:SI 0 "s_register_operand" "")
1781 (truncate:SI
1782 (lshiftrt:DI
1783 (mult:DI
1784 (sign_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1785 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "")))
1786 (const_int 32))))
1787 (clobber (match_scratch:SI 3 ""))])]
1788 "TARGET_32BIT && arm_arch3m"
1789 ""
1790)
1791
1792(define_insn "*smulsi3_highpart_nov6"
f082f1c4 1793 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r")
1794 (truncate:SI
1795 (lshiftrt:DI
215b30b3 1796 (mult:DI
e5fea38e 1797 (sign_extend:DI (match_operand:SI 1 "s_register_operand" "%0,r"))
215b30b3 1798 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r,r")))
f082f1c4 1799 (const_int 32))))
1800 (clobber (match_scratch:SI 3 "=&r,&r"))]
58d7d654 1801 "TARGET_32BIT && arm_arch3m && !arm_arch6"
1802 "smull%?\\t%3, %0, %2, %1"
9da0ec36 1803 [(set_attr "type" "smull")
58d7d654 1804 (set_attr "predicable" "yes")]
1805)
1806
957788b0 1807(define_insn "*smulsi3_highpart_v6"
58d7d654 1808 [(set (match_operand:SI 0 "s_register_operand" "=r")
1809 (truncate:SI
1810 (lshiftrt:DI
1811 (mult:DI
1812 (sign_extend:DI (match_operand:SI 1 "s_register_operand" "r"))
1813 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r")))
1814 (const_int 32))))
1815 (clobber (match_scratch:SI 3 "=r"))]
1816 "TARGET_32BIT && arm_arch6"
f082f1c4 1817 "smull%?\\t%3, %0, %2, %1"
9da0ec36 1818 [(set_attr "type" "smull")
d952d547 1819 (set_attr "predicable" "yes")
1820 (set_attr "predicable_short_it" "no")]
cffb2a26 1821)
f082f1c4 1822
957788b0 1823(define_expand "umulsi3_highpart"
1824 [(parallel
1825 [(set (match_operand:SI 0 "s_register_operand" "")
1826 (truncate:SI
1827 (lshiftrt:DI
1828 (mult:DI
1829 (zero_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1830 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "")))
1831 (const_int 32))))
1832 (clobber (match_scratch:SI 3 ""))])]
1833 "TARGET_32BIT && arm_arch3m"
1834 ""
1835)
1836
1837(define_insn "*umulsi3_highpart_nov6"
f082f1c4 1838 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r")
1839 (truncate:SI
1840 (lshiftrt:DI
215b30b3 1841 (mult:DI
e5fea38e 1842 (zero_extend:DI (match_operand:SI 1 "s_register_operand" "%0,r"))
215b30b3 1843 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r,r")))
f082f1c4 1844 (const_int 32))))
1845 (clobber (match_scratch:SI 3 "=&r,&r"))]
58d7d654 1846 "TARGET_32BIT && arm_arch3m && !arm_arch6"
1847 "umull%?\\t%3, %0, %2, %1"
9da0ec36 1848 [(set_attr "type" "umull")
58d7d654 1849 (set_attr "predicable" "yes")]
1850)
1851
957788b0 1852(define_insn "*umulsi3_highpart_v6"
58d7d654 1853 [(set (match_operand:SI 0 "s_register_operand" "=r")
1854 (truncate:SI
1855 (lshiftrt:DI
1856 (mult:DI
1857 (zero_extend:DI (match_operand:SI 1 "s_register_operand" "r"))
1858 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r")))
1859 (const_int 32))))
1860 (clobber (match_scratch:SI 3 "=r"))]
1861 "TARGET_32BIT && arm_arch6"
f082f1c4 1862 "umull%?\\t%3, %0, %2, %1"
9da0ec36 1863 [(set_attr "type" "umull")
d952d547 1864 (set_attr "predicable" "yes")
1865 (set_attr "predicable_short_it" "no")]
cffb2a26 1866)
f082f1c4 1867
331beb1a 1868(define_insn "mulhisi3"
1869 [(set (match_operand:SI 0 "s_register_operand" "=r")
1870 (mult:SI (sign_extend:SI
1871 (match_operand:HI 1 "s_register_operand" "%r"))
1872 (sign_extend:SI
1873 (match_operand:HI 2 "s_register_operand" "r"))))]
25f905c2 1874 "TARGET_DSP_MULTIPLY"
61a2d04c 1875 "smulbb%?\\t%0, %1, %2"
9da0ec36 1876 [(set_attr "type" "smulxy")
fec538d9 1877 (set_attr "predicable" "yes")]
1878)
1879
1880(define_insn "*mulhisi3tb"
1881 [(set (match_operand:SI 0 "s_register_operand" "=r")
1882 (mult:SI (ashiftrt:SI
1883 (match_operand:SI 1 "s_register_operand" "r")
1884 (const_int 16))
1885 (sign_extend:SI
1886 (match_operand:HI 2 "s_register_operand" "r"))))]
25f905c2 1887 "TARGET_DSP_MULTIPLY"
fec538d9 1888 "smultb%?\\t%0, %1, %2"
9da0ec36 1889 [(set_attr "type" "smulxy")
d952d547 1890 (set_attr "predicable" "yes")
1891 (set_attr "predicable_short_it" "no")]
fec538d9 1892)
1893
1894(define_insn "*mulhisi3bt"
1895 [(set (match_operand:SI 0 "s_register_operand" "=r")
1896 (mult:SI (sign_extend:SI
1897 (match_operand:HI 1 "s_register_operand" "r"))
1898 (ashiftrt:SI
1899 (match_operand:SI 2 "s_register_operand" "r")
1900 (const_int 16))))]
25f905c2 1901 "TARGET_DSP_MULTIPLY"
fec538d9 1902 "smulbt%?\\t%0, %1, %2"
9da0ec36 1903 [(set_attr "type" "smulxy")
d952d547 1904 (set_attr "predicable" "yes")
1905 (set_attr "predicable_short_it" "no")]
fec538d9 1906)
1907
1908(define_insn "*mulhisi3tt"
1909 [(set (match_operand:SI 0 "s_register_operand" "=r")
1910 (mult:SI (ashiftrt:SI
1911 (match_operand:SI 1 "s_register_operand" "r")
1912 (const_int 16))
1913 (ashiftrt:SI
1914 (match_operand:SI 2 "s_register_operand" "r")
1915 (const_int 16))))]
25f905c2 1916 "TARGET_DSP_MULTIPLY"
fec538d9 1917 "smultt%?\\t%0, %1, %2"
9da0ec36 1918 [(set_attr "type" "smulxy")
d952d547 1919 (set_attr "predicable" "yes")
1920 (set_attr "predicable_short_it" "no")]
331beb1a 1921)
1922
5cdca009 1923(define_insn "maddhisi4"
331beb1a 1924 [(set (match_operand:SI 0 "s_register_operand" "=r")
cfa6c608 1925 (plus:SI (mult:SI (sign_extend:SI
1926 (match_operand:HI 1 "s_register_operand" "r"))
331beb1a 1927 (sign_extend:SI
cfa6c608 1928 (match_operand:HI 2 "s_register_operand" "r")))
1929 (match_operand:SI 3 "s_register_operand" "r")))]
25f905c2 1930 "TARGET_DSP_MULTIPLY"
5cdca009 1931 "smlabb%?\\t%0, %1, %2, %3"
9da0ec36 1932 [(set_attr "type" "smlaxy")
d952d547 1933 (set_attr "predicable" "yes")
1934 (set_attr "predicable_short_it" "no")]
331beb1a 1935)
1936
9a92f368 1937;; Note: there is no maddhisi4ibt because this one is canonical form
1938(define_insn "*maddhisi4tb"
1939 [(set (match_operand:SI 0 "s_register_operand" "=r")
1940 (plus:SI (mult:SI (ashiftrt:SI
1941 (match_operand:SI 1 "s_register_operand" "r")
1942 (const_int 16))
1943 (sign_extend:SI
1944 (match_operand:HI 2 "s_register_operand" "r")))
1945 (match_operand:SI 3 "s_register_operand" "r")))]
1946 "TARGET_DSP_MULTIPLY"
1947 "smlatb%?\\t%0, %1, %2, %3"
9da0ec36 1948 [(set_attr "type" "smlaxy")
d952d547 1949 (set_attr "predicable" "yes")
1950 (set_attr "predicable_short_it" "no")]
9a92f368 1951)
1952
1953(define_insn "*maddhisi4tt"
1954 [(set (match_operand:SI 0 "s_register_operand" "=r")
1955 (plus:SI (mult:SI (ashiftrt:SI
1956 (match_operand:SI 1 "s_register_operand" "r")
1957 (const_int 16))
1958 (ashiftrt:SI
1959 (match_operand:SI 2 "s_register_operand" "r")
1960 (const_int 16)))
1961 (match_operand:SI 3 "s_register_operand" "r")))]
1962 "TARGET_DSP_MULTIPLY"
1963 "smlatt%?\\t%0, %1, %2, %3"
9da0ec36 1964 [(set_attr "type" "smlaxy")
d952d547 1965 (set_attr "predicable" "yes")
1966 (set_attr "predicable_short_it" "no")]
9a92f368 1967)
1968
aff5fb4d 1969(define_insn "maddhidi4"
331beb1a 1970 [(set (match_operand:DI 0 "s_register_operand" "=r")
1971 (plus:DI
331beb1a 1972 (mult:DI (sign_extend:DI
d952d547 1973 (match_operand:HI 1 "s_register_operand" "r"))
331beb1a 1974 (sign_extend:DI
cfa6c608 1975 (match_operand:HI 2 "s_register_operand" "r")))
1976 (match_operand:DI 3 "s_register_operand" "0")))]
25f905c2 1977 "TARGET_DSP_MULTIPLY"
5cdca009 1978 "smlalbb%?\\t%Q0, %R0, %1, %2"
9da0ec36 1979 [(set_attr "type" "smlalxy")
d952d547 1980 (set_attr "predicable" "yes")
1981 (set_attr "predicable_short_it" "no")])
331beb1a 1982
9a92f368 1983;; Note: there is no maddhidi4ibt because this one is canonical form
1984(define_insn "*maddhidi4tb"
1985 [(set (match_operand:DI 0 "s_register_operand" "=r")
1986 (plus:DI
1987 (mult:DI (sign_extend:DI
1988 (ashiftrt:SI
1989 (match_operand:SI 1 "s_register_operand" "r")
1990 (const_int 16)))
1991 (sign_extend:DI
1992 (match_operand:HI 2 "s_register_operand" "r")))
1993 (match_operand:DI 3 "s_register_operand" "0")))]
1994 "TARGET_DSP_MULTIPLY"
1995 "smlaltb%?\\t%Q0, %R0, %1, %2"
9da0ec36 1996 [(set_attr "type" "smlalxy")
d952d547 1997 (set_attr "predicable" "yes")
1998 (set_attr "predicable_short_it" "no")])
9a92f368 1999
2000(define_insn "*maddhidi4tt"
2001 [(set (match_operand:DI 0 "s_register_operand" "=r")
2002 (plus:DI
2003 (mult:DI (sign_extend:DI
2004 (ashiftrt:SI
2005 (match_operand:SI 1 "s_register_operand" "r")
2006 (const_int 16)))
2007 (sign_extend:DI
2008 (ashiftrt:SI
2009 (match_operand:SI 2 "s_register_operand" "r")
2010 (const_int 16))))
2011 (match_operand:DI 3 "s_register_operand" "0")))]
2012 "TARGET_DSP_MULTIPLY"
2013 "smlaltt%?\\t%Q0, %R0, %1, %2"
9da0ec36 2014 [(set_attr "type" "smlalxy")
d952d547 2015 (set_attr "predicable" "yes")
2016 (set_attr "predicable_short_it" "no")])
9a92f368 2017
604f3a0a 2018(define_expand "mulsf3"
2019 [(set (match_operand:SF 0 "s_register_operand" "")
2020 (mult:SF (match_operand:SF 1 "s_register_operand" "")
d86c91f6 2021 (match_operand:SF 2 "s_register_operand" "")))]
25f905c2 2022 "TARGET_32BIT && TARGET_HARD_FLOAT"
604f3a0a 2023 "
604f3a0a 2024")
2025
604f3a0a 2026(define_expand "muldf3"
2027 [(set (match_operand:DF 0 "s_register_operand" "")
2028 (mult:DF (match_operand:DF 1 "s_register_operand" "")
d86c91f6 2029 (match_operand:DF 2 "s_register_operand" "")))]
a50d7267 2030 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
604f3a0a 2031 "
604f3a0a 2032")
b11cae9e 2033\f
2034;; Division insns
2035
7db9af5d 2036(define_expand "divsf3"
2037 [(set (match_operand:SF 0 "s_register_operand" "")
d86c91f6 2038 (div:SF (match_operand:SF 1 "s_register_operand" "")
2039 (match_operand:SF 2 "s_register_operand" "")))]
994606f8 2040 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
7db9af5d 2041 "")
9c08d1fa 2042
7db9af5d 2043(define_expand "divdf3"
2044 [(set (match_operand:DF 0 "s_register_operand" "")
d86c91f6 2045 (div:DF (match_operand:DF 1 "s_register_operand" "")
2046 (match_operand:DF 2 "s_register_operand" "")))]
994606f8 2047 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
7db9af5d 2048 "")
b11cae9e 2049\f
2050;; Boolean and,ior,xor insns
2051
f6ebffac 2052;; Split up double word logical operations
2053
2054;; Split up simple DImode logical operations. Simply perform the logical
2055;; operation on the upper and lower halves of the registers.
2056(define_split
2057 [(set (match_operand:DI 0 "s_register_operand" "")
2058 (match_operator:DI 6 "logical_binary_operator"
2059 [(match_operand:DI 1 "s_register_operand" "")
2060 (match_operand:DI 2 "s_register_operand" "")]))]
25f905c2 2061 "TARGET_32BIT && reload_completed
e2669ea7 2062 && ! (TARGET_NEON && IS_VFP_REGNUM (REGNO (operands[0])))
25f905c2 2063 && ! IS_IWMMXT_REGNUM (REGNO (operands[0]))"
f6ebffac 2064 [(set (match_dup 0) (match_op_dup:SI 6 [(match_dup 1) (match_dup 2)]))
2065 (set (match_dup 3) (match_op_dup:SI 6 [(match_dup 4) (match_dup 5)]))]
2066 "
215b30b3 2067 {
2068 operands[3] = gen_highpart (SImode, operands[0]);
2069 operands[0] = gen_lowpart (SImode, operands[0]);
2070 operands[4] = gen_highpart (SImode, operands[1]);
2071 operands[1] = gen_lowpart (SImode, operands[1]);
2072 operands[5] = gen_highpart (SImode, operands[2]);
2073 operands[2] = gen_lowpart (SImode, operands[2]);
2074 }"
2075)
f6ebffac 2076
f6ebffac 2077(define_split
2078 [(set (match_operand:DI 0 "s_register_operand" "")
2079 (match_operator:DI 6 "logical_binary_operator"
2080 [(sign_extend:DI (match_operand:SI 2 "s_register_operand" ""))
2081 (match_operand:DI 1 "s_register_operand" "")]))]
25f905c2 2082 "TARGET_32BIT && reload_completed"
f6ebffac 2083 [(set (match_dup 0) (match_op_dup:SI 6 [(match_dup 1) (match_dup 2)]))
2084 (set (match_dup 3) (match_op_dup:SI 6
2085 [(ashiftrt:SI (match_dup 2) (const_int 31))
2086 (match_dup 4)]))]
2087 "
215b30b3 2088 {
2089 operands[3] = gen_highpart (SImode, operands[0]);
2090 operands[0] = gen_lowpart (SImode, operands[0]);
2091 operands[4] = gen_highpart (SImode, operands[1]);
2092 operands[1] = gen_lowpart (SImode, operands[1]);
2093 operands[5] = gen_highpart (SImode, operands[2]);
2094 operands[2] = gen_lowpart (SImode, operands[2]);
2095 }"
2096)
f6ebffac 2097
f6ebffac 2098;; The zero extend of operand 2 means we can just copy the high part of
2099;; operand1 into operand0.
2100(define_split
2101 [(set (match_operand:DI 0 "s_register_operand" "")
2102 (ior:DI
2103 (zero_extend:DI (match_operand:SI 2 "s_register_operand" ""))
2104 (match_operand:DI 1 "s_register_operand" "")))]
25f905c2 2105 "TARGET_32BIT && operands[0] != operands[1] && reload_completed"
f6ebffac 2106 [(set (match_dup 0) (ior:SI (match_dup 1) (match_dup 2)))
2107 (set (match_dup 3) (match_dup 4))]
2108 "
215b30b3 2109 {
2110 operands[4] = gen_highpart (SImode, operands[1]);
2111 operands[3] = gen_highpart (SImode, operands[0]);
2112 operands[0] = gen_lowpart (SImode, operands[0]);
2113 operands[1] = gen_lowpart (SImode, operands[1]);
2114 }"
2115)
f6ebffac 2116
2117;; The zero extend of operand 2 means we can just copy the high part of
2118;; operand1 into operand0.
2119(define_split
2120 [(set (match_operand:DI 0 "s_register_operand" "")
2121 (xor:DI
2122 (zero_extend:DI (match_operand:SI 2 "s_register_operand" ""))
2123 (match_operand:DI 1 "s_register_operand" "")))]
25f905c2 2124 "TARGET_32BIT && operands[0] != operands[1] && reload_completed"
f6ebffac 2125 [(set (match_dup 0) (xor:SI (match_dup 1) (match_dup 2)))
2126 (set (match_dup 3) (match_dup 4))]
2127 "
215b30b3 2128 {
2129 operands[4] = gen_highpart (SImode, operands[1]);
2130 operands[3] = gen_highpart (SImode, operands[0]);
2131 operands[0] = gen_lowpart (SImode, operands[0]);
2132 operands[1] = gen_lowpart (SImode, operands[1]);
2133 }"
2134)
f6ebffac 2135
e2669ea7 2136(define_expand "anddi3"
2137 [(set (match_operand:DI 0 "s_register_operand" "")
2138 (and:DI (match_operand:DI 1 "s_register_operand" "")
2139 (match_operand:DI 2 "neon_inv_logic_op2" "")))]
2140 "TARGET_32BIT"
2141 ""
2142)
2143
f6bbdcf6 2144(define_insn_and_split "*anddi3_insn"
0a314dcd 2145 [(set (match_operand:DI 0 "s_register_operand" "=w,w ,&r,&r,&r,&r,?w,?w")
2146 (and:DI (match_operand:DI 1 "s_register_operand" "%w,0 ,0 ,r ,0 ,r ,w ,0")
2147 (match_operand:DI 2 "arm_anddi_operand_neon" "w ,DL,r ,r ,De,De,w ,DL")))]
f6bbdcf6 2148 "TARGET_32BIT && !TARGET_IWMMXT"
2149{
2150 switch (which_alternative)
2151 {
0a314dcd 2152 case 0: /* fall through */
2153 case 6: return "vand\t%P0, %P1, %P2";
2154 case 1: /* fall through */
2155 case 7: return neon_output_logic_immediate ("vand", &operands[2],
2156 DImode, 1, VALID_NEON_QREG_MODE (DImode));
f6bbdcf6 2157 case 2:
0a314dcd 2158 case 3:
2159 case 4:
f6bbdcf6 2160 case 5: /* fall through */
0a314dcd 2161 return "#";
f6bbdcf6 2162 default: gcc_unreachable ();
2163 }
2164}
0a314dcd 2165 "TARGET_32BIT && !TARGET_IWMMXT && reload_completed
2166 && !(IS_VFP_REGNUM (REGNO (operands[0])))"
f6bbdcf6 2167 [(set (match_dup 3) (match_dup 4))
2168 (set (match_dup 5) (match_dup 6))]
2169 "
2170 {
2171 operands[3] = gen_lowpart (SImode, operands[0]);
2172 operands[5] = gen_highpart (SImode, operands[0]);
2173
2174 operands[4] = simplify_gen_binary (AND, SImode,
2175 gen_lowpart (SImode, operands[1]),
2176 gen_lowpart (SImode, operands[2]));
2177 operands[6] = simplify_gen_binary (AND, SImode,
2178 gen_highpart (SImode, operands[1]),
2179 gen_highpart_mode (SImode, DImode, operands[2]));
2180
2181 }"
0a314dcd 2182 [(set_attr "neon_type" "neon_int_1,neon_int_1,*,*,*,*,neon_int_1,neon_int_1")
2183 (set_attr "arch" "neon_for_64bits,neon_for_64bits,*,*,*,*,
f6bbdcf6 2184 avoid_neon_for_64bits,avoid_neon_for_64bits")
0a314dcd 2185 (set_attr "length" "*,*,8,8,8,8,*,*")
2186 ]
215b30b3 2187)
b11cae9e 2188
a0f94409 2189(define_insn_and_split "*anddi_zesidi_di"
9c08d1fa 2190 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2191 (and:DI (zero_extend:DI
2192 (match_operand:SI 2 "s_register_operand" "r,r"))
e5fea38e 2193 (match_operand:DI 1 "s_register_operand" "0,r")))]
25f905c2 2194 "TARGET_32BIT"
f6ebffac 2195 "#"
25f905c2 2196 "TARGET_32BIT && reload_completed"
a0f94409 2197 ; The zero extend of operand 2 clears the high word of the output
2198 ; operand.
2199 [(set (match_dup 0) (and:SI (match_dup 1) (match_dup 2)))
2200 (set (match_dup 3) (const_int 0))]
2201 "
2202 {
2203 operands[3] = gen_highpart (SImode, operands[0]);
2204 operands[0] = gen_lowpart (SImode, operands[0]);
2205 operands[1] = gen_lowpart (SImode, operands[1]);
2206 }"
215b30b3 2207 [(set_attr "length" "8")]
2208)
b11cae9e 2209
f7fbdd4a 2210(define_insn "*anddi_sesdi_di"
cffb2a26 2211 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
9c08d1fa 2212 (and:DI (sign_extend:DI
2213 (match_operand:SI 2 "s_register_operand" "r,r"))
e5fea38e 2214 (match_operand:DI 1 "s_register_operand" "0,r")))]
25f905c2 2215 "TARGET_32BIT"
f6ebffac 2216 "#"
cffb2a26 2217 [(set_attr "length" "8")]
2218)
b11cae9e 2219
87b22bf7 2220(define_expand "andsi3"
cffb2a26 2221 [(set (match_operand:SI 0 "s_register_operand" "")
87b22bf7 2222 (and:SI (match_operand:SI 1 "s_register_operand" "")
2223 (match_operand:SI 2 "reg_or_int_operand" "")))]
cffb2a26 2224 "TARGET_EITHER"
87b22bf7 2225 "
25f905c2 2226 if (TARGET_32BIT)
87b22bf7 2227 {
0438d37f 2228 if (CONST_INT_P (operands[2]))
cffb2a26 2229 {
47b5b27b 2230 if (INTVAL (operands[2]) == 255 && arm_arch6)
2231 {
2232 operands[1] = convert_to_mode (QImode, operands[1], 1);
2233 emit_insn (gen_thumb2_zero_extendqisi2_v6 (operands[0],
2234 operands[1]));
2235 }
2236 else
2237 arm_split_constant (AND, SImode, NULL_RTX,
2238 INTVAL (operands[2]), operands[0],
2239 operands[1],
2240 optimize && can_create_pseudo_p ());
615caa51 2241
cffb2a26 2242 DONE;
2243 }
87b22bf7 2244 }
25f905c2 2245 else /* TARGET_THUMB1 */
cffb2a26 2246 {
0438d37f 2247 if (!CONST_INT_P (operands[2]))
923ffadb 2248 {
2249 rtx tmp = force_reg (SImode, operands[2]);
2250 if (rtx_equal_p (operands[0], operands[1]))
2251 operands[2] = tmp;
2252 else
2253 {
2254 operands[2] = operands[1];
2255 operands[1] = tmp;
2256 }
2257 }
cffb2a26 2258 else
2259 {
2260 int i;
2261
215b30b3 2262 if (((unsigned HOST_WIDE_INT) ~INTVAL (operands[2])) < 256)
cffb2a26 2263 {
215b30b3 2264 operands[2] = force_reg (SImode,
2265 GEN_INT (~INTVAL (operands[2])));
cffb2a26 2266
747b7458 2267 emit_insn (gen_thumb1_bicsi3 (operands[0], operands[2], operands[1]));
cffb2a26 2268
2269 DONE;
2270 }
87b22bf7 2271
cffb2a26 2272 for (i = 9; i <= 31; i++)
2273 {
2274 if ((((HOST_WIDE_INT) 1) << i) - 1 == INTVAL (operands[2]))
2275 {
2276 emit_insn (gen_extzv (operands[0], operands[1], GEN_INT (i),
2277 const0_rtx));
2278 DONE;
2279 }
215b30b3 2280 else if ((((HOST_WIDE_INT) 1) << i) - 1
2281 == ~INTVAL (operands[2]))
cffb2a26 2282 {
2283 rtx shift = GEN_INT (i);
2284 rtx reg = gen_reg_rtx (SImode);
2285
2286 emit_insn (gen_lshrsi3 (reg, operands[1], shift));
2287 emit_insn (gen_ashlsi3 (operands[0], reg, shift));
2288
2289 DONE;
2290 }
2291 }
2292
2293 operands[2] = force_reg (SImode, operands[2]);
2294 }
215b30b3 2295 }
2296 "
cffb2a26 2297)
2298
25f905c2 2299; ??? Check split length for Thumb-2
a0f94409 2300(define_insn_and_split "*arm_andsi3_insn"
29e234a3 2301 [(set (match_operand:SI 0 "s_register_operand" "=r,l,r,r,r")
2302 (and:SI (match_operand:SI 1 "s_register_operand" "%r,0,r,r,r")
2303 (match_operand:SI 2 "reg_or_int_operand" "I,l,K,r,?n")))]
25f905c2 2304 "TARGET_32BIT"
5565501b 2305 "@
29e234a3 2306 and%?\\t%0, %1, %2
5565501b 2307 and%?\\t%0, %1, %2
87b22bf7 2308 bic%?\\t%0, %1, #%B2
65f68e55 2309 and%?\\t%0, %1, %2
87b22bf7 2310 #"
25f905c2 2311 "TARGET_32BIT
0438d37f 2312 && CONST_INT_P (operands[2])
a0f94409 2313 && !(const_ok_for_arm (INTVAL (operands[2]))
2314 || const_ok_for_arm (~INTVAL (operands[2])))"
2315 [(clobber (const_int 0))]
2316 "
96f57e36 2317 arm_split_constant (AND, SImode, curr_insn,
2318 INTVAL (operands[2]), operands[0], operands[1], 0);
a0f94409 2319 DONE;
2320 "
29e234a3 2321 [(set_attr "length" "4,4,4,4,16")
65f68e55 2322 (set_attr "predicable" "yes")
29e234a3 2323 (set_attr "predicable_short_it" "no,yes,no,no,no")
2324 (set_attr "type"
6b6abc9c 2325 "arlo_imm,arlo_imm,*,*,arlo_imm")]
cffb2a26 2326)
2327
25f905c2 2328(define_insn "*thumb1_andsi3_insn"
cffb2a26 2329 [(set (match_operand:SI 0 "register_operand" "=l")
2330 (and:SI (match_operand:SI 1 "register_operand" "%0")
2331 (match_operand:SI 2 "register_operand" "l")))]
25f905c2 2332 "TARGET_THUMB1"
747b7458 2333 "and\\t%0, %2"
2334 [(set_attr "length" "2")
6b6abc9c 2335 (set_attr "type" "arlo_imm")
747b7458 2336 (set_attr "conds" "set")])
87b22bf7 2337
f7fbdd4a 2338(define_insn "*andsi3_compare0"
bd5b4116 2339 [(set (reg:CC_NOOV CC_REGNUM)
5565501b 2340 (compare:CC_NOOV
65f68e55 2341 (and:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
2342 (match_operand:SI 2 "arm_not_operand" "I,K,r"))
5565501b 2343 (const_int 0)))
65f68e55 2344 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9c08d1fa 2345 (and:SI (match_dup 1) (match_dup 2)))]
25f905c2 2346 "TARGET_32BIT"
5565501b 2347 "@
25f905c2 2348 and%.\\t%0, %1, %2
65f68e55 2349 bic%.\\t%0, %1, #%B2
2350 and%.\\t%0, %1, %2"
2351 [(set_attr "conds" "set")
6b6abc9c 2352 (set_attr "type" "arlo_imm,arlo_imm,*")]
cffb2a26 2353)
9c08d1fa 2354
f7fbdd4a 2355(define_insn "*andsi3_compare0_scratch"
bd5b4116 2356 [(set (reg:CC_NOOV CC_REGNUM)
5565501b 2357 (compare:CC_NOOV
65f68e55 2358 (and:SI (match_operand:SI 0 "s_register_operand" "r,r,r")
2359 (match_operand:SI 1 "arm_not_operand" "I,K,r"))
5565501b 2360 (const_int 0)))
65f68e55 2361 (clobber (match_scratch:SI 2 "=X,r,X"))]
25f905c2 2362 "TARGET_32BIT"
5565501b 2363 "@
2364 tst%?\\t%0, %1
65f68e55 2365 bic%.\\t%2, %0, #%B1
2366 tst%?\\t%0, %1"
2367 [(set_attr "conds" "set")
6b6abc9c 2368 (set_attr "type" "arlo_imm,arlo_imm,*")]
0d66636f 2369)
9c08d1fa 2370
f7fbdd4a 2371(define_insn "*zeroextractsi_compare0_scratch"
bd5b4116 2372 [(set (reg:CC_NOOV CC_REGNUM)
9c08d1fa 2373 (compare:CC_NOOV (zero_extract:SI
2374 (match_operand:SI 0 "s_register_operand" "r")
d952d547 2375 (match_operand 1 "const_int_operand" "n")
206ee9a2 2376 (match_operand 2 "const_int_operand" "n"))
9c08d1fa 2377 (const_int 0)))]
25f905c2 2378 "TARGET_32BIT
cffb2a26 2379 && (INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) < 32
2380 && INTVAL (operands[1]) > 0
2381 && INTVAL (operands[1]) + (INTVAL (operands[2]) & 1) <= 8
2382 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32)"
9c08d1fa 2383 "*
5c49a439 2384 operands[1] = GEN_INT (((1 << INTVAL (operands[1])) - 1)
2385 << INTVAL (operands[2]));
40dbec34 2386 output_asm_insn (\"tst%?\\t%0, %1\", operands);
e2348bcb 2387 return \"\";
0d66636f 2388 "
596e5e8f 2389 [(set_attr "conds" "set")
65f68e55 2390 (set_attr "predicable" "yes")
d952d547 2391 (set_attr "predicable_short_it" "no")
6b6abc9c 2392 (set_attr "type" "arlo_imm")]
0d66636f 2393)
9c08d1fa 2394
f4462328 2395(define_insn_and_split "*ne_zeroextractsi"
c4034607 2396 [(set (match_operand:SI 0 "s_register_operand" "=r")
2397 (ne:SI (zero_extract:SI
2398 (match_operand:SI 1 "s_register_operand" "r")
2399 (match_operand:SI 2 "const_int_operand" "n")
2400 (match_operand:SI 3 "const_int_operand" "n"))
3b8c7f7a 2401 (const_int 0)))
2402 (clobber (reg:CC CC_REGNUM))]
25f905c2 2403 "TARGET_32BIT
cffb2a26 2404 && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
2405 && INTVAL (operands[2]) > 0
2406 && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
2407 && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)"
f4462328 2408 "#"
25f905c2 2409 "TARGET_32BIT
f4462328 2410 && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
2411 && INTVAL (operands[2]) > 0
2412 && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
2413 && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)"
2414 [(parallel [(set (reg:CC_NOOV CC_REGNUM)
2415 (compare:CC_NOOV (and:SI (match_dup 1) (match_dup 2))
2416 (const_int 0)))
2417 (set (match_dup 0) (and:SI (match_dup 1) (match_dup 2)))])
2418 (set (match_dup 0)
2419 (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
2420 (match_dup 0) (const_int 1)))]
2421 "
2422 operands[2] = GEN_INT (((1 << INTVAL (operands[2])) - 1)
2423 << INTVAL (operands[3]));
2424 "
2425 [(set_attr "conds" "clob")
25f905c2 2426 (set (attr "length")
2427 (if_then_else (eq_attr "is_thumb" "yes")
2428 (const_int 12)
2429 (const_int 8)))]
f4462328 2430)
2431
2432(define_insn_and_split "*ne_zeroextractsi_shifted"
2433 [(set (match_operand:SI 0 "s_register_operand" "=r")
2434 (ne:SI (zero_extract:SI
2435 (match_operand:SI 1 "s_register_operand" "r")
2436 (match_operand:SI 2 "const_int_operand" "n")
2437 (const_int 0))
2438 (const_int 0)))
2439 (clobber (reg:CC CC_REGNUM))]
2440 "TARGET_ARM"
2441 "#"
2442 "TARGET_ARM"
2443 [(parallel [(set (reg:CC_NOOV CC_REGNUM)
2444 (compare:CC_NOOV (ashift:SI (match_dup 1) (match_dup 2))
2445 (const_int 0)))
2446 (set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 2)))])
2447 (set (match_dup 0)
2448 (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
2449 (match_dup 0) (const_int 1)))]
2450 "
2451 operands[2] = GEN_INT (32 - INTVAL (operands[2]));
2452 "
2453 [(set_attr "conds" "clob")
2454 (set_attr "length" "8")]
2455)
2456
2457(define_insn_and_split "*ite_ne_zeroextractsi"
2458 [(set (match_operand:SI 0 "s_register_operand" "=r")
2459 (if_then_else:SI (ne (zero_extract:SI
2460 (match_operand:SI 1 "s_register_operand" "r")
2461 (match_operand:SI 2 "const_int_operand" "n")
2462 (match_operand:SI 3 "const_int_operand" "n"))
2463 (const_int 0))
2464 (match_operand:SI 4 "arm_not_operand" "rIK")
2465 (const_int 0)))
2466 (clobber (reg:CC CC_REGNUM))]
2467 "TARGET_ARM
2468 && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
2469 && INTVAL (operands[2]) > 0
2470 && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
f8d7bf2f 2471 && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)
2472 && !reg_overlap_mentioned_p (operands[0], operands[4])"
f4462328 2473 "#"
2474 "TARGET_ARM
2475 && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
2476 && INTVAL (operands[2]) > 0
2477 && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
f8d7bf2f 2478 && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)
2479 && !reg_overlap_mentioned_p (operands[0], operands[4])"
f4462328 2480 [(parallel [(set (reg:CC_NOOV CC_REGNUM)
2481 (compare:CC_NOOV (and:SI (match_dup 1) (match_dup 2))
2482 (const_int 0)))
2483 (set (match_dup 0) (and:SI (match_dup 1) (match_dup 2)))])
2484 (set (match_dup 0)
2485 (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
2486 (match_dup 0) (match_dup 4)))]
2487 "
c4034607 2488 operands[2] = GEN_INT (((1 << INTVAL (operands[2])) - 1)
f4462328 2489 << INTVAL (operands[3]));
2490 "
2491 [(set_attr "conds" "clob")
2492 (set_attr "length" "8")]
2493)
2494
2495(define_insn_and_split "*ite_ne_zeroextractsi_shifted"
2496 [(set (match_operand:SI 0 "s_register_operand" "=r")
2497 (if_then_else:SI (ne (zero_extract:SI
2498 (match_operand:SI 1 "s_register_operand" "r")
2499 (match_operand:SI 2 "const_int_operand" "n")
2500 (const_int 0))
2501 (const_int 0))
2502 (match_operand:SI 3 "arm_not_operand" "rIK")
2503 (const_int 0)))
2504 (clobber (reg:CC CC_REGNUM))]
f8d7bf2f 2505 "TARGET_ARM && !reg_overlap_mentioned_p (operands[0], operands[3])"
f4462328 2506 "#"
f8d7bf2f 2507 "TARGET_ARM && !reg_overlap_mentioned_p (operands[0], operands[3])"
f4462328 2508 [(parallel [(set (reg:CC_NOOV CC_REGNUM)
2509 (compare:CC_NOOV (ashift:SI (match_dup 1) (match_dup 2))
2510 (const_int 0)))
2511 (set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 2)))])
2512 (set (match_dup 0)
2513 (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
2514 (match_dup 0) (match_dup 3)))]
2515 "
2516 operands[2] = GEN_INT (32 - INTVAL (operands[2]));
0d66636f 2517 "
2518 [(set_attr "conds" "clob")
215b30b3 2519 (set_attr "length" "8")]
2520)
9c08d1fa 2521
58d6528b 2522(define_split
2523 [(set (match_operand:SI 0 "s_register_operand" "")
2524 (zero_extract:SI (match_operand:SI 1 "s_register_operand" "")
2525 (match_operand:SI 2 "const_int_operand" "")
2526 (match_operand:SI 3 "const_int_operand" "")))
2527 (clobber (match_operand:SI 4 "s_register_operand" ""))]
25f905c2 2528 "TARGET_THUMB1"
58d6528b 2529 [(set (match_dup 4) (ashift:SI (match_dup 1) (match_dup 2)))
2530 (set (match_dup 0) (lshiftrt:SI (match_dup 4) (match_dup 3)))]
2531 "{
2532 HOST_WIDE_INT temp = INTVAL (operands[2]);
2533
2534 operands[2] = GEN_INT (32 - temp - INTVAL (operands[3]));
2535 operands[3] = GEN_INT (32 - temp);
2536 }"
2537)
2538
25f905c2 2539;; ??? Use Thumb-2 has bitfield insert/extract instructions.
d7863cfe 2540(define_split
2541 [(set (match_operand:SI 0 "s_register_operand" "")
2542 (match_operator:SI 1 "shiftable_operator"
2543 [(zero_extract:SI (match_operand:SI 2 "s_register_operand" "")
2544 (match_operand:SI 3 "const_int_operand" "")
2545 (match_operand:SI 4 "const_int_operand" ""))
2546 (match_operand:SI 5 "s_register_operand" "")]))
2547 (clobber (match_operand:SI 6 "s_register_operand" ""))]
2548 "TARGET_ARM"
2549 [(set (match_dup 6) (ashift:SI (match_dup 2) (match_dup 3)))
2550 (set (match_dup 0)
2551 (match_op_dup 1
2552 [(lshiftrt:SI (match_dup 6) (match_dup 4))
2553 (match_dup 5)]))]
2554 "{
2555 HOST_WIDE_INT temp = INTVAL (operands[3]);
2556
2557 operands[3] = GEN_INT (32 - temp - INTVAL (operands[4]));
2558 operands[4] = GEN_INT (32 - temp);
2559 }"
2560)
2561
58d6528b 2562(define_split
2563 [(set (match_operand:SI 0 "s_register_operand" "")
2564 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "")
2565 (match_operand:SI 2 "const_int_operand" "")
2566 (match_operand:SI 3 "const_int_operand" "")))]
25f905c2 2567 "TARGET_THUMB1"
58d6528b 2568 [(set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 2)))
2569 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (match_dup 3)))]
2570 "{
2571 HOST_WIDE_INT temp = INTVAL (operands[2]);
2572
2573 operands[2] = GEN_INT (32 - temp - INTVAL (operands[3]));
2574 operands[3] = GEN_INT (32 - temp);
2575 }"
2576)
2577
d7863cfe 2578(define_split
2579 [(set (match_operand:SI 0 "s_register_operand" "")
2580 (match_operator:SI 1 "shiftable_operator"
2581 [(sign_extract:SI (match_operand:SI 2 "s_register_operand" "")
2582 (match_operand:SI 3 "const_int_operand" "")
2583 (match_operand:SI 4 "const_int_operand" ""))
2584 (match_operand:SI 5 "s_register_operand" "")]))
2585 (clobber (match_operand:SI 6 "s_register_operand" ""))]
2586 "TARGET_ARM"
2587 [(set (match_dup 6) (ashift:SI (match_dup 2) (match_dup 3)))
2588 (set (match_dup 0)
2589 (match_op_dup 1
2590 [(ashiftrt:SI (match_dup 6) (match_dup 4))
2591 (match_dup 5)]))]
2592 "{
2593 HOST_WIDE_INT temp = INTVAL (operands[3]);
2594
2595 operands[3] = GEN_INT (32 - temp - INTVAL (operands[4]));
2596 operands[4] = GEN_INT (32 - temp);
2597 }"
2598)
2599
a42059fd 2600;;; ??? This pattern is bogus. If operand3 has bits outside the range
2601;;; represented by the bitfield, then this will produce incorrect results.
2602;;; Somewhere, the value needs to be truncated. On targets like the m68k,
ceb2fe0f 2603;;; which have a real bit-field insert instruction, the truncation happens
2604;;; in the bit-field insert instruction itself. Since arm does not have a
2605;;; bit-field insert instruction, we would have to emit code here to truncate
a42059fd 2606;;; the value before we insert. This loses some of the advantage of having
2607;;; this insv pattern, so this pattern needs to be reevalutated.
2608
8a18b90c 2609(define_expand "insv"
eb04cafb 2610 [(set (zero_extract (match_operand 0 "nonimmediate_operand" "")
2611 (match_operand 1 "general_operand" "")
2612 (match_operand 2 "general_operand" ""))
2613 (match_operand 3 "reg_or_int_operand" ""))]
8b054d5a 2614 "TARGET_ARM || arm_arch_thumb2"
8a18b90c 2615 "
215b30b3 2616 {
2617 int start_bit = INTVAL (operands[2]);
2618 int width = INTVAL (operands[1]);
2619 HOST_WIDE_INT mask = (((HOST_WIDE_INT)1) << width) - 1;
2620 rtx target, subtarget;
2621
8b054d5a 2622 if (arm_arch_thumb2)
2623 {
eb04cafb 2624 if (unaligned_access && MEM_P (operands[0])
2625 && s_register_operand (operands[3], GET_MODE (operands[3]))
2626 && (width == 16 || width == 32) && (start_bit % BITS_PER_UNIT) == 0)
8b054d5a 2627 {
eb04cafb 2628 rtx base_addr;
2629
2630 if (BYTES_BIG_ENDIAN)
2631 start_bit = GET_MODE_BITSIZE (GET_MODE (operands[3])) - width
2632 - start_bit;
8b054d5a 2633
eb04cafb 2634 if (width == 32)
8b054d5a 2635 {
eb04cafb 2636 base_addr = adjust_address (operands[0], SImode,
2637 start_bit / BITS_PER_UNIT);
2638 emit_insn (gen_unaligned_storesi (base_addr, operands[3]));
8b054d5a 2639 }
eb04cafb 2640 else
2641 {
2642 rtx tmp = gen_reg_rtx (HImode);
8b054d5a 2643
eb04cafb 2644 base_addr = adjust_address (operands[0], HImode,
2645 start_bit / BITS_PER_UNIT);
2646 emit_move_insn (tmp, gen_lowpart (HImode, operands[3]));
2647 emit_insn (gen_unaligned_storehi (base_addr, tmp));
2648 }
2649 DONE;
8b054d5a 2650 }
eb04cafb 2651 else if (s_register_operand (operands[0], GET_MODE (operands[0])))
8b054d5a 2652 {
eb04cafb 2653 bool use_bfi = TRUE;
8b054d5a 2654
0438d37f 2655 if (CONST_INT_P (operands[3]))
eb04cafb 2656 {
2657 HOST_WIDE_INT val = INTVAL (operands[3]) & mask;
2658
2659 if (val == 0)
2660 {
2661 emit_insn (gen_insv_zero (operands[0], operands[1],
2662 operands[2]));
2663 DONE;
2664 }
2665
2666 /* See if the set can be done with a single orr instruction. */
2667 if (val == mask && const_ok_for_arm (val << start_bit))
2668 use_bfi = FALSE;
2669 }
2670
2671 if (use_bfi)
2672 {
0438d37f 2673 if (!REG_P (operands[3]))
eb04cafb 2674 operands[3] = force_reg (SImode, operands[3]);
2675
2676 emit_insn (gen_insv_t2 (operands[0], operands[1], operands[2],
2677 operands[3]));
2678 DONE;
2679 }
8b054d5a 2680 }
eb04cafb 2681 else
2682 FAIL;
8b054d5a 2683 }
2684
eb04cafb 2685 if (!s_register_operand (operands[0], GET_MODE (operands[0])))
2686 FAIL;
2687
3f8fde42 2688 target = copy_rtx (operands[0]);
215b30b3 2689 /* Avoid using a subreg as a subtarget, and avoid writing a paradoxical
2690 subreg as the final target. */
2691 if (GET_CODE (target) == SUBREG)
2692 {
2693 subtarget = gen_reg_rtx (SImode);
2694 if (GET_MODE_SIZE (GET_MODE (SUBREG_REG (target)))
2695 < GET_MODE_SIZE (SImode))
2696 target = SUBREG_REG (target);
2697 }
2698 else
2699 subtarget = target;
8a18b90c 2700
0438d37f 2701 if (CONST_INT_P (operands[3]))
215b30b3 2702 {
2703 /* Since we are inserting a known constant, we may be able to
2704 reduce the number of bits that we have to clear so that
2705 the mask becomes simple. */
2706 /* ??? This code does not check to see if the new mask is actually
2707 simpler. It may not be. */
2708 rtx op1 = gen_reg_rtx (SImode);
2709 /* ??? Truncate operand3 to fit in the bitfield. See comment before
2710 start of this pattern. */
2711 HOST_WIDE_INT op3_value = mask & INTVAL (operands[3]);
2712 HOST_WIDE_INT mask2 = ((mask & ~op3_value) << start_bit);
2713
c5b3a71b 2714 emit_insn (gen_andsi3 (op1, operands[0],
2715 gen_int_mode (~mask2, SImode)));
215b30b3 2716 emit_insn (gen_iorsi3 (subtarget, op1,
4292ca6b 2717 gen_int_mode (op3_value << start_bit, SImode)));
215b30b3 2718 }
2719 else if (start_bit == 0
2720 && !(const_ok_for_arm (mask)
2721 || const_ok_for_arm (~mask)))
2722 {
2723 /* A Trick, since we are setting the bottom bits in the word,
2724 we can shift operand[3] up, operand[0] down, OR them together
2725 and rotate the result back again. This takes 3 insns, and
5910bb95 2726 the third might be mergeable into another op. */
215b30b3 2727 /* The shift up copes with the possibility that operand[3] is
2728 wider than the bitfield. */
2729 rtx op0 = gen_reg_rtx (SImode);
2730 rtx op1 = gen_reg_rtx (SImode);
2731
2732 emit_insn (gen_ashlsi3 (op0, operands[3], GEN_INT (32 - width)));
2733 emit_insn (gen_lshrsi3 (op1, operands[0], operands[1]));
2734 emit_insn (gen_iorsi3 (op1, op1, op0));
2735 emit_insn (gen_rotlsi3 (subtarget, op1, operands[1]));
2736 }
2737 else if ((width + start_bit == 32)
2738 && !(const_ok_for_arm (mask)
2739 || const_ok_for_arm (~mask)))
2740 {
2741 /* Similar trick, but slightly less efficient. */
8a18b90c 2742
215b30b3 2743 rtx op0 = gen_reg_rtx (SImode);
2744 rtx op1 = gen_reg_rtx (SImode);
8a18b90c 2745
215b30b3 2746 emit_insn (gen_ashlsi3 (op0, operands[3], GEN_INT (32 - width)));
2747 emit_insn (gen_ashlsi3 (op1, operands[0], operands[1]));
2748 emit_insn (gen_lshrsi3 (op1, op1, operands[1]));
2749 emit_insn (gen_iorsi3 (subtarget, op1, op0));
2750 }
2751 else
2752 {
c5b3a71b 2753 rtx op0 = gen_int_mode (mask, SImode);
215b30b3 2754 rtx op1 = gen_reg_rtx (SImode);
2755 rtx op2 = gen_reg_rtx (SImode);
8a18b90c 2756
215b30b3 2757 if (!(const_ok_for_arm (mask) || const_ok_for_arm (~mask)))
2758 {
2759 rtx tmp = gen_reg_rtx (SImode);
8a18b90c 2760
215b30b3 2761 emit_insn (gen_movsi (tmp, op0));
2762 op0 = tmp;
2763 }
8a18b90c 2764
215b30b3 2765 /* Mask out any bits in operand[3] that are not needed. */
2766 emit_insn (gen_andsi3 (op1, operands[3], op0));
8a18b90c 2767
0438d37f 2768 if (CONST_INT_P (op0)
215b30b3 2769 && (const_ok_for_arm (mask << start_bit)
2770 || const_ok_for_arm (~(mask << start_bit))))
2771 {
c5b3a71b 2772 op0 = gen_int_mode (~(mask << start_bit), SImode);
215b30b3 2773 emit_insn (gen_andsi3 (op2, operands[0], op0));
2774 }
2775 else
2776 {
0438d37f 2777 if (CONST_INT_P (op0))
215b30b3 2778 {
2779 rtx tmp = gen_reg_rtx (SImode);
8a18b90c 2780
215b30b3 2781 emit_insn (gen_movsi (tmp, op0));
2782 op0 = tmp;
2783 }
2784
2785 if (start_bit != 0)
2786 emit_insn (gen_ashlsi3 (op0, op0, operands[2]));
a42059fd 2787
215b30b3 2788 emit_insn (gen_andsi_notsi_si (op2, operands[0], op0));
2789 }
8a18b90c 2790
215b30b3 2791 if (start_bit != 0)
2792 emit_insn (gen_ashlsi3 (op1, op1, operands[2]));
8a18b90c 2793
215b30b3 2794 emit_insn (gen_iorsi3 (subtarget, op1, op2));
2795 }
f082f1c4 2796
215b30b3 2797 if (subtarget != target)
2798 {
2799 /* If TARGET is still a SUBREG, then it must be wider than a word,
2800 so we must be careful only to set the subword we were asked to. */
2801 if (GET_CODE (target) == SUBREG)
2802 emit_move_insn (target, subtarget);
2803 else
2804 emit_move_insn (target, gen_lowpart (GET_MODE (target), subtarget));
2805 }
8a18b90c 2806
215b30b3 2807 DONE;
2808 }"
2809)
8a18b90c 2810
8b054d5a 2811(define_insn "insv_zero"
2812 [(set (zero_extract:SI (match_operand:SI 0 "s_register_operand" "+r")
2813 (match_operand:SI 1 "const_int_operand" "M")
2814 (match_operand:SI 2 "const_int_operand" "M"))
2815 (const_int 0))]
2816 "arm_arch_thumb2"
2817 "bfc%?\t%0, %2, %1"
2818 [(set_attr "length" "4")
d952d547 2819 (set_attr "predicable" "yes")
2820 (set_attr "predicable_short_it" "no")]
8b054d5a 2821)
2822
2823(define_insn "insv_t2"
2824 [(set (zero_extract:SI (match_operand:SI 0 "s_register_operand" "+r")
2825 (match_operand:SI 1 "const_int_operand" "M")
2826 (match_operand:SI 2 "const_int_operand" "M"))
2827 (match_operand:SI 3 "s_register_operand" "r"))]
2828 "arm_arch_thumb2"
2829 "bfi%?\t%0, %3, %2, %1"
2830 [(set_attr "length" "4")
d952d547 2831 (set_attr "predicable" "yes")
2832 (set_attr "predicable_short_it" "no")]
8b054d5a 2833)
2834
215b30b3 2835; constants for op 2 will never be given to these patterns.
a0f94409 2836(define_insn_and_split "*anddi_notdi_di"
9c08d1fa 2837 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
e5fea38e 2838 (and:DI (not:DI (match_operand:DI 1 "s_register_operand" "0,r"))
2839 (match_operand:DI 2 "s_register_operand" "r,0")))]
25f905c2 2840 "TARGET_32BIT"
f6ebffac 2841 "#"
e2669ea7 2842 "TARGET_32BIT && reload_completed
2843 && ! (TARGET_NEON && IS_VFP_REGNUM (REGNO (operands[0])))
2844 && ! IS_IWMMXT_REGNUM (REGNO (operands[0]))"
a0f94409 2845 [(set (match_dup 0) (and:SI (not:SI (match_dup 1)) (match_dup 2)))
2846 (set (match_dup 3) (and:SI (not:SI (match_dup 4)) (match_dup 5)))]
2847 "
2848 {
2849 operands[3] = gen_highpart (SImode, operands[0]);
2850 operands[0] = gen_lowpart (SImode, operands[0]);
2851 operands[4] = gen_highpart (SImode, operands[1]);
2852 operands[1] = gen_lowpart (SImode, operands[1]);
2853 operands[5] = gen_highpart (SImode, operands[2]);
2854 operands[2] = gen_lowpart (SImode, operands[2]);
2855 }"
0d66636f 2856 [(set_attr "length" "8")
2857 (set_attr "predicable" "yes")]
2858)
d952d547 2859
a0f94409 2860(define_insn_and_split "*anddi_notzesidi_di"
9c08d1fa 2861 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2862 (and:DI (not:DI (zero_extend:DI
2863 (match_operand:SI 2 "s_register_operand" "r,r")))
e2348bcb 2864 (match_operand:DI 1 "s_register_operand" "0,?r")))]
25f905c2 2865 "TARGET_32BIT"
e2348bcb 2866 "@
97499065 2867 bic%?\\t%Q0, %Q1, %2
f6ebffac 2868 #"
a0f94409 2869 ; (not (zero_extend ...)) allows us to just copy the high word from
2870 ; operand1 to operand0.
25f905c2 2871 "TARGET_32BIT
a0f94409 2872 && reload_completed
2873 && operands[0] != operands[1]"
5a097f7d 2874 [(set (match_dup 0) (and:SI (not:SI (match_dup 2)) (match_dup 1)))
a0f94409 2875 (set (match_dup 3) (match_dup 4))]
2876 "
2877 {
2878 operands[3] = gen_highpart (SImode, operands[0]);
2879 operands[0] = gen_lowpart (SImode, operands[0]);
2880 operands[4] = gen_highpart (SImode, operands[1]);
2881 operands[1] = gen_lowpart (SImode, operands[1]);
2882 }"
0d66636f 2883 [(set_attr "length" "4,8")
d952d547 2884 (set_attr "predicable" "yes")
2885 (set_attr "predicable_short_it" "no")]
0d66636f 2886)
d952d547 2887
a0f94409 2888(define_insn_and_split "*anddi_notsesidi_di"
9c08d1fa 2889 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2890 (and:DI (not:DI (sign_extend:DI
2891 (match_operand:SI 2 "s_register_operand" "r,r")))
5a097f7d 2892 (match_operand:DI 1 "s_register_operand" "0,r")))]
25f905c2 2893 "TARGET_32BIT"
f6ebffac 2894 "#"
25f905c2 2895 "TARGET_32BIT && reload_completed"
5a097f7d 2896 [(set (match_dup 0) (and:SI (not:SI (match_dup 2)) (match_dup 1)))
a0f94409 2897 (set (match_dup 3) (and:SI (not:SI
2898 (ashiftrt:SI (match_dup 2) (const_int 31)))
2899 (match_dup 4)))]
2900 "
2901 {
2902 operands[3] = gen_highpart (SImode, operands[0]);
2903 operands[0] = gen_lowpart (SImode, operands[0]);
2904 operands[4] = gen_highpart (SImode, operands[1]);
2905 operands[1] = gen_lowpart (SImode, operands[1]);
2906 }"
0d66636f 2907 [(set_attr "length" "8")
d952d547 2908 (set_attr "predicable" "yes")
2909 (set_attr "predicable_short_it" "no")]
0d66636f 2910)
d952d547 2911
8a18b90c 2912(define_insn "andsi_notsi_si"
9c08d1fa 2913 [(set (match_operand:SI 0 "s_register_operand" "=r")
2914 (and:SI (not:SI (match_operand:SI 2 "s_register_operand" "r"))
2915 (match_operand:SI 1 "s_register_operand" "r")))]
25f905c2 2916 "TARGET_32BIT"
0d66636f 2917 "bic%?\\t%0, %1, %2"
d952d547 2918 [(set_attr "predicable" "yes")
2919 (set_attr "predicable_short_it" "no")]
0d66636f 2920)
b11cae9e 2921
747b7458 2922(define_insn "thumb1_bicsi3"
cffb2a26 2923 [(set (match_operand:SI 0 "register_operand" "=l")
2924 (and:SI (not:SI (match_operand:SI 1 "register_operand" "l"))
2925 (match_operand:SI 2 "register_operand" "0")))]
25f905c2 2926 "TARGET_THUMB1"
747b7458 2927 "bic\\t%0, %1"
2928 [(set_attr "length" "2")
2929 (set_attr "conds" "set")])
cffb2a26 2930
8a18b90c 2931(define_insn "andsi_not_shiftsi_si"
a2cd141b 2932 [(set (match_operand:SI 0 "s_register_operand" "=r")
2933 (and:SI (not:SI (match_operator:SI 4 "shift_operator"
2934 [(match_operand:SI 2 "s_register_operand" "r")
2935 (match_operand:SI 3 "arm_rhs_operand" "rM")]))
2936 (match_operand:SI 1 "s_register_operand" "r")))]
cffb2a26 2937 "TARGET_ARM"
6c4c2133 2938 "bic%?\\t%0, %1, %2%S4"
344495ea 2939 [(set_attr "predicable" "yes")
331beb1a 2940 (set_attr "shift" "2")
a2cd141b 2941 (set (attr "type") (if_then_else (match_operand 3 "const_int_operand" "")
6b6abc9c 2942 (const_string "arlo_shift")
2943 (const_string "arlo_shift_reg")))]
6c4c2133 2944)
8a18b90c 2945
f7fbdd4a 2946(define_insn "*andsi_notsi_si_compare0"
bd5b4116 2947 [(set (reg:CC_NOOV CC_REGNUM)
e2348bcb 2948 (compare:CC_NOOV
2949 (and:SI (not:SI (match_operand:SI 2 "s_register_operand" "r"))
2950 (match_operand:SI 1 "s_register_operand" "r"))
2951 (const_int 0)))
9c08d1fa 2952 (set (match_operand:SI 0 "s_register_operand" "=r")
2953 (and:SI (not:SI (match_dup 2)) (match_dup 1)))]
25f905c2 2954 "TARGET_32BIT"
2955 "bic%.\\t%0, %1, %2"
0d66636f 2956 [(set_attr "conds" "set")]
2957)
9c08d1fa 2958
f7fbdd4a 2959(define_insn "*andsi_notsi_si_compare0_scratch"
bd5b4116 2960 [(set (reg:CC_NOOV CC_REGNUM)
e2348bcb 2961 (compare:CC_NOOV
2962 (and:SI (not:SI (match_operand:SI 2 "s_register_operand" "r"))
2963 (match_operand:SI 1 "s_register_operand" "r"))
2964 (const_int 0)))
9c08d1fa 2965 (clobber (match_scratch:SI 0 "=r"))]
25f905c2 2966 "TARGET_32BIT"
2967 "bic%.\\t%0, %1, %2"
0d66636f 2968 [(set_attr "conds" "set")]
2969)
9c08d1fa 2970
e2669ea7 2971(define_expand "iordi3"
2972 [(set (match_operand:DI 0 "s_register_operand" "")
2973 (ior:DI (match_operand:DI 1 "s_register_operand" "")
2974 (match_operand:DI 2 "neon_logic_op2" "")))]
2975 "TARGET_32BIT"
2976 ""
2977)
2978
74d6113f 2979(define_insn_and_split "*iordi3_insn"
2980 [(set (match_operand:DI 0 "s_register_operand" "=w,w ,&r,&r,&r,&r,?w,?w")
2981 (ior:DI (match_operand:DI 1 "s_register_operand" "%w,0 ,0 ,r ,0 ,r ,w ,0")
e0fe6977 2982 (match_operand:DI 2 "arm_iordi_operand_neon" "w ,Dl,r ,r ,Df,Df,w ,Dl")))]
74d6113f 2983 "TARGET_32BIT && !TARGET_IWMMXT"
2984 {
2985 switch (which_alternative)
2986 {
2987 case 0: /* fall through */
2988 case 6: return "vorr\t%P0, %P1, %P2";
2989 case 1: /* fall through */
2990 case 7: return neon_output_logic_immediate ("vorr", &operands[2],
2991 DImode, 0, VALID_NEON_QREG_MODE (DImode));
2992 case 2:
2993 case 3:
2994 case 4:
2995 case 5:
2996 return "#";
2997 default: gcc_unreachable ();
2998 }
2999 }
3000 "TARGET_32BIT && !TARGET_IWMMXT && reload_completed
3001 && !(IS_VFP_REGNUM (REGNO (operands[0])))"
3002 [(set (match_dup 3) (match_dup 4))
3003 (set (match_dup 5) (match_dup 6))]
3004 "
3005 {
3006 operands[3] = gen_lowpart (SImode, operands[0]);
3007 operands[5] = gen_highpart (SImode, operands[0]);
3008
3009 operands[4] = simplify_gen_binary (IOR, SImode,
3010 gen_lowpart (SImode, operands[1]),
3011 gen_lowpart (SImode, operands[2]));
3012 operands[6] = simplify_gen_binary (IOR, SImode,
3013 gen_highpart (SImode, operands[1]),
3014 gen_highpart_mode (SImode, DImode, operands[2]));
3015
3016 }"
3017 [(set_attr "neon_type" "neon_int_1,neon_int_1,*,*,*,*,neon_int_1,neon_int_1")
e0fe6977 3018 (set_attr "length" "*,*,8,8,8,8,*,*")
74d6113f 3019 (set_attr "arch" "neon_for_64bits,neon_for_64bits,*,*,*,*,avoid_neon_for_64bits,avoid_neon_for_64bits")]
cffb2a26 3020)
9c08d1fa 3021
f7fbdd4a 3022(define_insn "*iordi_zesidi_di"
9c08d1fa 3023 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
3024 (ior:DI (zero_extend:DI
3025 (match_operand:SI 2 "s_register_operand" "r,r"))
e2348bcb 3026 (match_operand:DI 1 "s_register_operand" "0,?r")))]
25f905c2 3027 "TARGET_32BIT"
e2348bcb 3028 "@
97499065 3029 orr%?\\t%Q0, %Q1, %2
f6ebffac 3030 #"
0d66636f 3031 [(set_attr "length" "4,8")
d952d547 3032 (set_attr "predicable" "yes")
3033 (set_attr "predicable_short_it" "no")]
cffb2a26 3034)
9c08d1fa 3035
f7fbdd4a 3036(define_insn "*iordi_sesidi_di"
9c08d1fa 3037 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
3038 (ior:DI (sign_extend:DI
3039 (match_operand:SI 2 "s_register_operand" "r,r"))
e5fea38e 3040 (match_operand:DI 1 "s_register_operand" "0,r")))]
25f905c2 3041 "TARGET_32BIT"
f6ebffac 3042 "#"
0d66636f 3043 [(set_attr "length" "8")
3044 (set_attr "predicable" "yes")]
cffb2a26 3045)
9c08d1fa 3046
87b22bf7 3047(define_expand "iorsi3"
cffb2a26 3048 [(set (match_operand:SI 0 "s_register_operand" "")
87b22bf7 3049 (ior:SI (match_operand:SI 1 "s_register_operand" "")
3050 (match_operand:SI 2 "reg_or_int_operand" "")))]
cffb2a26 3051 "TARGET_EITHER"
87b22bf7 3052 "
0438d37f 3053 if (CONST_INT_P (operands[2]))
87b22bf7 3054 {
25f905c2 3055 if (TARGET_32BIT)
cffb2a26 3056 {
96f57e36 3057 arm_split_constant (IOR, SImode, NULL_RTX,
3058 INTVAL (operands[2]), operands[0], operands[1],
e1ba4a27 3059 optimize && can_create_pseudo_p ());
cffb2a26 3060 DONE;
3061 }
25f905c2 3062 else /* TARGET_THUMB1 */
923ffadb 3063 {
3064 rtx tmp = force_reg (SImode, operands[2]);
3065 if (rtx_equal_p (operands[0], operands[1]))
3066 operands[2] = tmp;
3067 else
3068 {
3069 operands[2] = operands[1];
3070 operands[1] = tmp;
3071 }
3072 }
87b22bf7 3073 }
cffb2a26 3074 "
3075)
87b22bf7 3076
d5d4dc8d 3077(define_insn_and_split "*iorsi3_insn"
29e234a3 3078 [(set (match_operand:SI 0 "s_register_operand" "=r,l,r,r,r")
3079 (ior:SI (match_operand:SI 1 "s_register_operand" "%r,0,r,r,r")
3080 (match_operand:SI 2 "reg_or_int_operand" "I,l,K,r,?n")))]
d5d4dc8d 3081 "TARGET_32BIT"
87b22bf7 3082 "@
29e234a3 3083 orr%?\\t%0, %1, %2
87b22bf7 3084 orr%?\\t%0, %1, %2
d5d4dc8d 3085 orn%?\\t%0, %1, #%B2
65f68e55 3086 orr%?\\t%0, %1, %2
87b22bf7 3087 #"
d5d4dc8d 3088 "TARGET_32BIT
0438d37f 3089 && CONST_INT_P (operands[2])
d5d4dc8d 3090 && !(const_ok_for_arm (INTVAL (operands[2]))
3091 || (TARGET_THUMB2 && const_ok_for_arm (~INTVAL (operands[2]))))"
a0f94409 3092 [(clobber (const_int 0))]
d5d4dc8d 3093{
29e234a3 3094 arm_split_constant (IOR, SImode, curr_insn,
96f57e36 3095 INTVAL (operands[2]), operands[0], operands[1], 0);
a0f94409 3096 DONE;
d5d4dc8d 3097}
29e234a3 3098 [(set_attr "length" "4,4,4,4,16")
3099 (set_attr "arch" "32,t2,t2,32,32")
65f68e55 3100 (set_attr "predicable" "yes")
29e234a3 3101 (set_attr "predicable_short_it" "no,yes,no,no,no")
6b6abc9c 3102 (set_attr "type" "arlo_imm,*,arlo_imm,*,*")]
65f68e55 3103)
cffb2a26 3104
747b7458 3105(define_insn "*thumb1_iorsi3_insn"
cffb2a26 3106 [(set (match_operand:SI 0 "register_operand" "=l")
3107 (ior:SI (match_operand:SI 1 "register_operand" "%0")
3108 (match_operand:SI 2 "register_operand" "l")))]
25f905c2 3109 "TARGET_THUMB1"
747b7458 3110 "orr\\t%0, %2"
3111 [(set_attr "length" "2")
3112 (set_attr "conds" "set")])
9c08d1fa 3113
a0f94409 3114(define_peephole2
3115 [(match_scratch:SI 3 "r")
372575c7 3116 (set (match_operand:SI 0 "arm_general_register_operand" "")
3117 (ior:SI (match_operand:SI 1 "arm_general_register_operand" "")
87b22bf7 3118 (match_operand:SI 2 "const_int_operand" "")))]
90560cad 3119 "TARGET_ARM
a0f94409 3120 && !const_ok_for_arm (INTVAL (operands[2]))
3121 && const_ok_for_arm (~INTVAL (operands[2]))"
3122 [(set (match_dup 3) (match_dup 2))
3123 (set (match_dup 0) (ior:SI (match_dup 1) (match_dup 3)))]
3124 ""
215b30b3 3125)
a0f94409 3126
f7fbdd4a 3127(define_insn "*iorsi3_compare0"
bd5b4116 3128 [(set (reg:CC_NOOV CC_REGNUM)
65f68e55 3129 (compare:CC_NOOV (ior:SI (match_operand:SI 1 "s_register_operand" "%r,r")
3130 (match_operand:SI 2 "arm_rhs_operand" "I,r"))
9c08d1fa 3131 (const_int 0)))
65f68e55 3132 (set (match_operand:SI 0 "s_register_operand" "=r,r")
9c08d1fa 3133 (ior:SI (match_dup 1) (match_dup 2)))]
25f905c2 3134 "TARGET_32BIT"
3135 "orr%.\\t%0, %1, %2"
65f68e55 3136 [(set_attr "conds" "set")
6b6abc9c 3137 (set_attr "type" "arlo_imm,*")]
cffb2a26 3138)
9c08d1fa 3139
f7fbdd4a 3140(define_insn "*iorsi3_compare0_scratch"
bd5b4116 3141 [(set (reg:CC_NOOV CC_REGNUM)
65f68e55 3142 (compare:CC_NOOV (ior:SI (match_operand:SI 1 "s_register_operand" "%r,r")
3143 (match_operand:SI 2 "arm_rhs_operand" "I,r"))
9c08d1fa 3144 (const_int 0)))
65f68e55 3145 (clobber (match_scratch:SI 0 "=r,r"))]
25f905c2 3146 "TARGET_32BIT"
3147 "orr%.\\t%0, %1, %2"
65f68e55 3148 [(set_attr "conds" "set")
6b6abc9c 3149 (set_attr "type" "arlo_imm,*")]
0d66636f 3150)
9c08d1fa 3151
e2669ea7 3152(define_expand "xordi3"
3153 [(set (match_operand:DI 0 "s_register_operand" "")
3154 (xor:DI (match_operand:DI 1 "s_register_operand" "")
8ee7dc6f 3155 (match_operand:DI 2 "arm_xordi_operand" "")))]
e2669ea7 3156 "TARGET_32BIT"
3157 ""
3158)
3159
8ee7dc6f 3160(define_insn_and_split "*xordi3_insn"
3161 [(set (match_operand:DI 0 "s_register_operand" "=w,&r,&r,&r,&r,?w")
3162 (xor:DI (match_operand:DI 1 "s_register_operand" "w ,%0,r ,0 ,r ,w")
3163 (match_operand:DI 2 "arm_xordi_operand" "w ,r ,r ,Dg,Dg,w")))]
3164 "TARGET_32BIT && !TARGET_IWMMXT"
3165{
3166 switch (which_alternative)
3167 {
3168 case 1:
3169 case 2:
3170 case 3:
3171 case 4: /* fall through */
3172 return "#";
3173 case 0: /* fall through */
3174 case 5: return "veor\t%P0, %P1, %P2";
3175 default: gcc_unreachable ();
3176 }
3177}
3178 "TARGET_32BIT && !TARGET_IWMMXT && reload_completed
3179 && !(IS_VFP_REGNUM (REGNO (operands[0])))"
3180 [(set (match_dup 3) (match_dup 4))
3181 (set (match_dup 5) (match_dup 6))]
3182 "
3183 {
3184 operands[3] = gen_lowpart (SImode, operands[0]);
3185 operands[5] = gen_highpart (SImode, operands[0]);
3186
3187 operands[4] = simplify_gen_binary (XOR, SImode,
3188 gen_lowpart (SImode, operands[1]),
3189 gen_lowpart (SImode, operands[2]));
3190 operands[6] = simplify_gen_binary (XOR, SImode,
3191 gen_highpart (SImode, operands[1]),
3192 gen_highpart_mode (SImode, DImode, operands[2]));
3193
3194 }"
3195 [(set_attr "length" "*,8,8,8,8,*")
3196 (set_attr "neon_type" "neon_int_1,*,*,*,*,neon_int_1")
3197 (set_attr "arch" "neon_for_64bits,*,*,*,*,avoid_neon_for_64bits")]
cffb2a26 3198)
9c08d1fa 3199
f7fbdd4a 3200(define_insn "*xordi_zesidi_di"
9c08d1fa 3201 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
3202 (xor:DI (zero_extend:DI
3203 (match_operand:SI 2 "s_register_operand" "r,r"))
e2348bcb 3204 (match_operand:DI 1 "s_register_operand" "0,?r")))]
25f905c2 3205 "TARGET_32BIT"
e2348bcb 3206 "@
97499065 3207 eor%?\\t%Q0, %Q1, %2
f6ebffac 3208 #"
0d66636f 3209 [(set_attr "length" "4,8")
d952d547 3210 (set_attr "predicable" "yes")
3211 (set_attr "predicable_short_it" "no")]
cffb2a26 3212)
9c08d1fa 3213
f7fbdd4a 3214(define_insn "*xordi_sesidi_di"
9c08d1fa 3215 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
3216 (xor:DI (sign_extend:DI
3217 (match_operand:SI 2 "s_register_operand" "r,r"))
e5fea38e 3218 (match_operand:DI 1 "s_register_operand" "0,r")))]
25f905c2 3219 "TARGET_32BIT"
f6ebffac 3220 "#"
0d66636f 3221 [(set_attr "length" "8")
3222 (set_attr "predicable" "yes")]
cffb2a26 3223)
9c08d1fa 3224
cffb2a26 3225(define_expand "xorsi3"
3226 [(set (match_operand:SI 0 "s_register_operand" "")
3227 (xor:SI (match_operand:SI 1 "s_register_operand" "")
923ffadb 3228 (match_operand:SI 2 "reg_or_int_operand" "")))]
cffb2a26 3229 "TARGET_EITHER"
0438d37f 3230 "if (CONST_INT_P (operands[2]))
923ffadb 3231 {
3232 if (TARGET_32BIT)
3233 {
3234 arm_split_constant (XOR, SImode, NULL_RTX,
3235 INTVAL (operands[2]), operands[0], operands[1],
3236 optimize && can_create_pseudo_p ());
3237 DONE;
3238 }
3239 else /* TARGET_THUMB1 */
3240 {
3241 rtx tmp = force_reg (SImode, operands[2]);
3242 if (rtx_equal_p (operands[0], operands[1]))
3243 operands[2] = tmp;
3244 else
3245 {
3246 operands[2] = operands[1];
3247 operands[1] = tmp;
3248 }
3249 }
3250 }"
cffb2a26 3251)
3252
5dcb35d9 3253(define_insn_and_split "*arm_xorsi3"
29e234a3 3254 [(set (match_operand:SI 0 "s_register_operand" "=r,l,r,r")
3255 (xor:SI (match_operand:SI 1 "s_register_operand" "%r,0,r,r")
3256 (match_operand:SI 2 "reg_or_int_operand" "I,l,r,?n")))]
25f905c2 3257 "TARGET_32BIT"
5dcb35d9 3258 "@
29e234a3 3259 eor%?\\t%0, %1, %2
65f68e55 3260 eor%?\\t%0, %1, %2
5dcb35d9 3261 eor%?\\t%0, %1, %2
3262 #"
3263 "TARGET_32BIT
0438d37f 3264 && CONST_INT_P (operands[2])
5dcb35d9 3265 && !const_ok_for_arm (INTVAL (operands[2]))"
3266 [(clobber (const_int 0))]
3267{
3268 arm_split_constant (XOR, SImode, curr_insn,
3269 INTVAL (operands[2]), operands[0], operands[1], 0);
3270 DONE;
3271}
29e234a3 3272 [(set_attr "length" "4,4,4,16")
65f68e55 3273 (set_attr "predicable" "yes")
29e234a3 3274 (set_attr "predicable_short_it" "no,yes,no,no")
6b6abc9c 3275 (set_attr "type" "arlo_imm,*,*,*")]
cffb2a26 3276)
3277
747b7458 3278(define_insn "*thumb1_xorsi3_insn"
cffb2a26 3279 [(set (match_operand:SI 0 "register_operand" "=l")
3280 (xor:SI (match_operand:SI 1 "register_operand" "%0")
3281 (match_operand:SI 2 "register_operand" "l")))]
25f905c2 3282 "TARGET_THUMB1"
747b7458 3283 "eor\\t%0, %2"
3284 [(set_attr "length" "2")
65f68e55 3285 (set_attr "conds" "set")
6b6abc9c 3286 (set_attr "type" "arlo_imm")]
65f68e55 3287)
9c08d1fa 3288
f7fbdd4a 3289(define_insn "*xorsi3_compare0"
bd5b4116 3290 [(set (reg:CC_NOOV CC_REGNUM)
65f68e55 3291 (compare:CC_NOOV (xor:SI (match_operand:SI 1 "s_register_operand" "r,r")
3292 (match_operand:SI 2 "arm_rhs_operand" "I,r"))
9c08d1fa 3293 (const_int 0)))
65f68e55 3294 (set (match_operand:SI 0 "s_register_operand" "=r,r")
9c08d1fa 3295 (xor:SI (match_dup 1) (match_dup 2)))]
25f905c2 3296 "TARGET_32BIT"
3297 "eor%.\\t%0, %1, %2"
65f68e55 3298 [(set_attr "conds" "set")
6b6abc9c 3299 (set_attr "type" "arlo_imm,*")]
0d66636f 3300)
9c08d1fa 3301
f7fbdd4a 3302(define_insn "*xorsi3_compare0_scratch"
bd5b4116 3303 [(set (reg:CC_NOOV CC_REGNUM)
65f68e55 3304 (compare:CC_NOOV (xor:SI (match_operand:SI 0 "s_register_operand" "r,r")
3305 (match_operand:SI 1 "arm_rhs_operand" "I,r"))
9c08d1fa 3306 (const_int 0)))]
25f905c2 3307 "TARGET_32BIT"
40dbec34 3308 "teq%?\\t%0, %1"
65f68e55 3309 [(set_attr "conds" "set")
6b6abc9c 3310 (set_attr "type" "arlo_imm,*")]
cffb2a26 3311)
9c08d1fa 3312
215b30b3 3313; By splitting (IOR (AND (NOT A) (NOT B)) C) as D = AND (IOR A B) (NOT C),
3314; (NOT D) we can sometimes merge the final NOT into one of the following
3315; insns.
9c08d1fa 3316
3317(define_split
a058e94a 3318 [(set (match_operand:SI 0 "s_register_operand" "")
3319 (ior:SI (and:SI (not:SI (match_operand:SI 1 "s_register_operand" ""))
3320 (not:SI (match_operand:SI 2 "arm_rhs_operand" "")))
3321 (match_operand:SI 3 "arm_rhs_operand" "")))
3322 (clobber (match_operand:SI 4 "s_register_operand" ""))]
25f905c2 3323 "TARGET_32BIT"
9c08d1fa 3324 [(set (match_dup 4) (and:SI (ior:SI (match_dup 1) (match_dup 2))
3325 (not:SI (match_dup 3))))
3326 (set (match_dup 0) (not:SI (match_dup 4)))]
3327 ""
3328)
3329
ba6a3b2f 3330(define_insn_and_split "*andsi_iorsi3_notsi"
9c08d1fa 3331 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r")
e5fea38e 3332 (and:SI (ior:SI (match_operand:SI 1 "s_register_operand" "%0,r,r")
9c08d1fa 3333 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI"))
3334 (not:SI (match_operand:SI 3 "arm_rhs_operand" "rI,rI,rI"))))]
25f905c2 3335 "TARGET_32BIT"
ba6a3b2f 3336 "#" ; "orr%?\\t%0, %1, %2\;bic%?\\t%0, %0, %3"
3337 "&& reload_completed"
3338 [(set (match_dup 0) (ior:SI (match_dup 1) (match_dup 2)))
3339 (set (match_dup 0) (and:SI (not:SI (match_dup 3)) (match_dup 0)))]
3340 ""
0d66636f 3341 [(set_attr "length" "8")
25f905c2 3342 (set_attr "ce_count" "2")
d952d547 3343 (set_attr "predicable" "yes")
3344 (set_attr "predicable_short_it" "no")]
cffb2a26 3345)
9c08d1fa 3346
25f905c2 3347; ??? Are these four splitters still beneficial when the Thumb-2 bitfield
3348; insns are available?
d7863cfe 3349(define_split
3350 [(set (match_operand:SI 0 "s_register_operand" "")
3351 (match_operator:SI 1 "logical_binary_operator"
3352 [(zero_extract:SI (match_operand:SI 2 "s_register_operand" "")
3353 (match_operand:SI 3 "const_int_operand" "")
3354 (match_operand:SI 4 "const_int_operand" ""))
3355 (match_operator:SI 9 "logical_binary_operator"
3356 [(lshiftrt:SI (match_operand:SI 5 "s_register_operand" "")
3357 (match_operand:SI 6 "const_int_operand" ""))
3358 (match_operand:SI 7 "s_register_operand" "")])]))
3359 (clobber (match_operand:SI 8 "s_register_operand" ""))]
25f905c2 3360 "TARGET_32BIT
d7863cfe 3361 && GET_CODE (operands[1]) == GET_CODE (operands[9])
3362 && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
3363 [(set (match_dup 8)
3364 (match_op_dup 1
3365 [(ashift:SI (match_dup 2) (match_dup 4))
3366 (match_dup 5)]))
3367 (set (match_dup 0)
3368 (match_op_dup 1
3369 [(lshiftrt:SI (match_dup 8) (match_dup 6))
3370 (match_dup 7)]))]
3371 "
3372 operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
3373")
3374
3375(define_split
3376 [(set (match_operand:SI 0 "s_register_operand" "")
3377 (match_operator:SI 1 "logical_binary_operator"
3378 [(match_operator:SI 9 "logical_binary_operator"
3379 [(lshiftrt:SI (match_operand:SI 5 "s_register_operand" "")
3380 (match_operand:SI 6 "const_int_operand" ""))
3381 (match_operand:SI 7 "s_register_operand" "")])
3382 (zero_extract:SI (match_operand:SI 2 "s_register_operand" "")
3383 (match_operand:SI 3 "const_int_operand" "")
3384 (match_operand:SI 4 "const_int_operand" ""))]))
3385 (clobber (match_operand:SI 8 "s_register_operand" ""))]
25f905c2 3386 "TARGET_32BIT
d7863cfe 3387 && GET_CODE (operands[1]) == GET_CODE (operands[9])
3388 && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
3389 [(set (match_dup 8)
3390 (match_op_dup 1
3391 [(ashift:SI (match_dup 2) (match_dup 4))
3392 (match_dup 5)]))
3393 (set (match_dup 0)
3394 (match_op_dup 1
3395 [(lshiftrt:SI (match_dup 8) (match_dup 6))
3396 (match_dup 7)]))]
3397 "
3398 operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
3399")
3400
3401(define_split
3402 [(set (match_operand:SI 0 "s_register_operand" "")
3403 (match_operator:SI 1 "logical_binary_operator"
3404 [(sign_extract:SI (match_operand:SI 2 "s_register_operand" "")
3405 (match_operand:SI 3 "const_int_operand" "")
3406 (match_operand:SI 4 "const_int_operand" ""))
3407 (match_operator:SI 9 "logical_binary_operator"
3408 [(ashiftrt:SI (match_operand:SI 5 "s_register_operand" "")
3409 (match_operand:SI 6 "const_int_operand" ""))
3410 (match_operand:SI 7 "s_register_operand" "")])]))
3411 (clobber (match_operand:SI 8 "s_register_operand" ""))]
25f905c2 3412 "TARGET_32BIT
d7863cfe 3413 && GET_CODE (operands[1]) == GET_CODE (operands[9])
3414 && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
3415 [(set (match_dup 8)
3416 (match_op_dup 1
3417 [(ashift:SI (match_dup 2) (match_dup 4))
3418 (match_dup 5)]))
3419 (set (match_dup 0)
3420 (match_op_dup 1
3421 [(ashiftrt:SI (match_dup 8) (match_dup 6))
3422 (match_dup 7)]))]
3423 "
3424 operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
3425")
3426
3427(define_split
3428 [(set (match_operand:SI 0 "s_register_operand" "")
3429 (match_operator:SI 1 "logical_binary_operator"
3430 [(match_operator:SI 9 "logical_binary_operator"
3431 [(ashiftrt:SI (match_operand:SI 5 "s_register_operand" "")
3432 (match_operand:SI 6 "const_int_operand" ""))
3433 (match_operand:SI 7 "s_register_operand" "")])
3434 (sign_extract:SI (match_operand:SI 2 "s_register_operand" "")
3435 (match_operand:SI 3 "const_int_operand" "")
3436 (match_operand:SI 4 "const_int_operand" ""))]))
3437 (clobber (match_operand:SI 8 "s_register_operand" ""))]
25f905c2 3438 "TARGET_32BIT
d7863cfe 3439 && GET_CODE (operands[1]) == GET_CODE (operands[9])
3440 && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
3441 [(set (match_dup 8)
3442 (match_op_dup 1
3443 [(ashift:SI (match_dup 2) (match_dup 4))
3444 (match_dup 5)]))
3445 (set (match_dup 0)
3446 (match_op_dup 1
3447 [(ashiftrt:SI (match_dup 8) (match_dup 6))
3448 (match_dup 7)]))]
3449 "
3450 operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
3451")
9c08d1fa 3452\f
3453
3454;; Minimum and maximum insns
3455
8b9dc177 3456(define_expand "smaxsi3"
3457 [(parallel [
3458 (set (match_operand:SI 0 "s_register_operand" "")
3459 (smax:SI (match_operand:SI 1 "s_register_operand" "")
3460 (match_operand:SI 2 "arm_rhs_operand" "")))
3461 (clobber (reg:CC CC_REGNUM))])]
25f905c2 3462 "TARGET_32BIT"
8b9dc177 3463 "
8774928b 3464 if (operands[2] == const0_rtx || operands[2] == constm1_rtx)
8b9dc177 3465 {
3466 /* No need for a clobber of the condition code register here. */
3467 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
3468 gen_rtx_SMAX (SImode, operands[1],
3469 operands[2])));
3470 DONE;
3471 }
3472")
3473
3474(define_insn "*smax_0"
3475 [(set (match_operand:SI 0 "s_register_operand" "=r")
3476 (smax:SI (match_operand:SI 1 "s_register_operand" "r")
3477 (const_int 0)))]
25f905c2 3478 "TARGET_32BIT"
8b9dc177 3479 "bic%?\\t%0, %1, %1, asr #31"
d952d547 3480 [(set_attr "predicable" "yes")
3481 (set_attr "predicable_short_it" "no")]
8b9dc177 3482)
3483
8774928b 3484(define_insn "*smax_m1"
3485 [(set (match_operand:SI 0 "s_register_operand" "=r")
3486 (smax:SI (match_operand:SI 1 "s_register_operand" "r")
3487 (const_int -1)))]
25f905c2 3488 "TARGET_32BIT"
8774928b 3489 "orr%?\\t%0, %1, %1, asr #31"
d952d547 3490 [(set_attr "predicable" "yes")
3491 (set_attr "predicable_short_it" "no")]
8774928b 3492)
3493
3dc953f2 3494(define_insn_and_split "*arm_smax_insn"
8b9dc177 3495 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
3496 (smax:SI (match_operand:SI 1 "s_register_operand" "%0,?r")
3497 (match_operand:SI 2 "arm_rhs_operand" "rI,rI")))
bd5b4116 3498 (clobber (reg:CC CC_REGNUM))]
cffb2a26 3499 "TARGET_ARM"
3dc953f2 3500 "#"
3501 ; cmp\\t%1, %2\;movlt\\t%0, %2
3502 ; cmp\\t%1, %2\;movge\\t%0, %1\;movlt\\t%0, %2"
3503 "TARGET_ARM"
3504 [(set (reg:CC CC_REGNUM)
3505 (compare:CC (match_dup 1) (match_dup 2)))
3506 (set (match_dup 0)
3507 (if_then_else:SI (ge:SI (reg:CC CC_REGNUM) (const_int 0))
3508 (match_dup 1)
3509 (match_dup 2)))]
3510 ""
cffb2a26 3511 [(set_attr "conds" "clob")
8b9dc177 3512 (set_attr "length" "8,12")]
cffb2a26 3513)
9c08d1fa 3514
8b9dc177 3515(define_expand "sminsi3"
3516 [(parallel [
3517 (set (match_operand:SI 0 "s_register_operand" "")
3518 (smin:SI (match_operand:SI 1 "s_register_operand" "")
3519 (match_operand:SI 2 "arm_rhs_operand" "")))
3520 (clobber (reg:CC CC_REGNUM))])]
25f905c2 3521 "TARGET_32BIT"
8b9dc177 3522 "
3523 if (operands[2] == const0_rtx)
3524 {
3525 /* No need for a clobber of the condition code register here. */
3526 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
3527 gen_rtx_SMIN (SImode, operands[1],
3528 operands[2])));
3529 DONE;
3530 }
3531")
3532
3533(define_insn "*smin_0"
3534 [(set (match_operand:SI 0 "s_register_operand" "=r")
3535 (smin:SI (match_operand:SI 1 "s_register_operand" "r")
3536 (const_int 0)))]
25f905c2 3537 "TARGET_32BIT"
8b9dc177 3538 "and%?\\t%0, %1, %1, asr #31"
d952d547 3539 [(set_attr "predicable" "yes")
3540 (set_attr "predicable_short_it" "no")]
8b9dc177 3541)
3542
3dc953f2 3543(define_insn_and_split "*arm_smin_insn"
8b9dc177 3544 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
3545 (smin:SI (match_operand:SI 1 "s_register_operand" "%0,?r")
3546 (match_operand:SI 2 "arm_rhs_operand" "rI,rI")))
bd5b4116 3547 (clobber (reg:CC CC_REGNUM))]
cffb2a26 3548 "TARGET_ARM"
3dc953f2 3549 "#"
3550 ; cmp\\t%1, %2\;movge\\t%0, %2
3551 ; cmp\\t%1, %2\;movlt\\t%0, %1\;movge\\t%0, %2"
3552 "TARGET_ARM"
3553 [(set (reg:CC CC_REGNUM)
3554 (compare:CC (match_dup 1) (match_dup 2)))
3555 (set (match_dup 0)
3556 (if_then_else:SI (lt:SI (reg:CC CC_REGNUM) (const_int 0))
3557 (match_dup 1)
3558 (match_dup 2)))]
3559 ""
0d66636f 3560 [(set_attr "conds" "clob")
8b9dc177 3561 (set_attr "length" "8,12")]
0d66636f 3562)
9c08d1fa 3563
25f905c2 3564(define_expand "umaxsi3"
3565 [(parallel [
3566 (set (match_operand:SI 0 "s_register_operand" "")
3567 (umax:SI (match_operand:SI 1 "s_register_operand" "")
3568 (match_operand:SI 2 "arm_rhs_operand" "")))
3569 (clobber (reg:CC CC_REGNUM))])]
3570 "TARGET_32BIT"
3571 ""
3572)
3573
3dc953f2 3574(define_insn_and_split "*arm_umaxsi3"
9c08d1fa 3575 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
3576 (umax:SI (match_operand:SI 1 "s_register_operand" "0,r,?r")
3577 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
bd5b4116 3578 (clobber (reg:CC CC_REGNUM))]
cffb2a26 3579 "TARGET_ARM"
3dc953f2 3580 "#"
3581 ; cmp\\t%1, %2\;movcc\\t%0, %2
3582 ; cmp\\t%1, %2\;movcs\\t%0, %1
3583 ; cmp\\t%1, %2\;movcs\\t%0, %1\;movcc\\t%0, %2"
3584 "TARGET_ARM"
3585 [(set (reg:CC CC_REGNUM)
3586 (compare:CC (match_dup 1) (match_dup 2)))
3587 (set (match_dup 0)
3588 (if_then_else:SI (geu:SI (reg:CC CC_REGNUM) (const_int 0))
3589 (match_dup 1)
3590 (match_dup 2)))]
3591 ""
0d66636f 3592 [(set_attr "conds" "clob")
3593 (set_attr "length" "8,8,12")]
3594)
9c08d1fa 3595
25f905c2 3596(define_expand "uminsi3"
3597 [(parallel [
3598 (set (match_operand:SI 0 "s_register_operand" "")
3599 (umin:SI (match_operand:SI 1 "s_register_operand" "")
3600 (match_operand:SI 2 "arm_rhs_operand" "")))
3601 (clobber (reg:CC CC_REGNUM))])]
3602 "TARGET_32BIT"
3603 ""
3604)
3605
3dc953f2 3606(define_insn_and_split "*arm_uminsi3"
9c08d1fa 3607 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
3608 (umin:SI (match_operand:SI 1 "s_register_operand" "0,r,?r")
3609 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
bd5b4116 3610 (clobber (reg:CC CC_REGNUM))]
cffb2a26 3611 "TARGET_ARM"
3dc953f2 3612 "#"
3613 ; cmp\\t%1, %2\;movcs\\t%0, %2
3614 ; cmp\\t%1, %2\;movcc\\t%0, %1
3615 ; cmp\\t%1, %2\;movcc\\t%0, %1\;movcs\\t%0, %2"
3616 "TARGET_ARM"
3617 [(set (reg:CC CC_REGNUM)
3618 (compare:CC (match_dup 1) (match_dup 2)))
3619 (set (match_dup 0)
3620 (if_then_else:SI (ltu:SI (reg:CC CC_REGNUM) (const_int 0))
3621 (match_dup 1)
3622 (match_dup 2)))]
3623 ""
0d66636f 3624 [(set_attr "conds" "clob")
3625 (set_attr "length" "8,8,12")]
3626)
9c08d1fa 3627
8a18b90c 3628(define_insn "*store_minmaxsi"
9c08d1fa 3629 [(set (match_operand:SI 0 "memory_operand" "=m")
3630 (match_operator:SI 3 "minmax_operator"
3631 [(match_operand:SI 1 "s_register_operand" "r")
3632 (match_operand:SI 2 "s_register_operand" "r")]))
bd5b4116 3633 (clobber (reg:CC CC_REGNUM))]
f15d4d96 3634 "TARGET_32BIT && optimize_insn_for_size_p()"
9c08d1fa 3635 "*
dc55b8a9 3636 operands[3] = gen_rtx_fmt_ee (minmax_code (operands[3]), SImode,
3637 operands[1], operands[2]);
e2348bcb 3638 output_asm_insn (\"cmp\\t%1, %2\", operands);
25f905c2 3639 if (TARGET_THUMB2)
3640 output_asm_insn (\"ite\t%d3\", operands);
e2348bcb 3641 output_asm_insn (\"str%d3\\t%1, %0\", operands);
3642 output_asm_insn (\"str%D3\\t%2, %0\", operands);
3643 return \"\";
0d66636f 3644 "
3645 [(set_attr "conds" "clob")
25f905c2 3646 (set (attr "length")
3647 (if_then_else (eq_attr "is_thumb" "yes")
3648 (const_int 14)
3649 (const_int 12)))
0d66636f 3650 (set_attr "type" "store1")]
3651)
9c08d1fa 3652
8a18b90c 3653; Reject the frame pointer in operand[1], since reloading this after
3654; it has been eliminated can cause carnage.
f7fbdd4a 3655(define_insn "*minmax_arithsi"
9c08d1fa 3656 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
3657 (match_operator:SI 4 "shiftable_operator"
3658 [(match_operator:SI 5 "minmax_operator"
3659 [(match_operand:SI 2 "s_register_operand" "r,r")
3660 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
3661 (match_operand:SI 1 "s_register_operand" "0,?r")]))
bd5b4116 3662 (clobber (reg:CC CC_REGNUM))]
7c36fe71 3663 "TARGET_32BIT && !arm_eliminable_register (operands[1]) && !arm_restrict_it"
9c08d1fa 3664 "*
0d66636f 3665 {
3666 enum rtx_code code = GET_CODE (operands[4]);
25f905c2 3667 bool need_else;
3668
3669 if (which_alternative != 0 || operands[3] != const0_rtx
ca0fc5a2 3670 || (code != PLUS && code != IOR && code != XOR))
25f905c2 3671 need_else = true;
3672 else
3673 need_else = false;
0d66636f 3674
dc55b8a9 3675 operands[5] = gen_rtx_fmt_ee (minmax_code (operands[5]), SImode,
3676 operands[2], operands[3]);
0d66636f 3677 output_asm_insn (\"cmp\\t%2, %3\", operands);
25f905c2 3678 if (TARGET_THUMB2)
3679 {
3680 if (need_else)
3681 output_asm_insn (\"ite\\t%d5\", operands);
3682 else
3683 output_asm_insn (\"it\\t%d5\", operands);
3684 }
0d66636f 3685 output_asm_insn (\"%i4%d5\\t%0, %1, %2\", operands);
25f905c2 3686 if (need_else)
0d66636f 3687 output_asm_insn (\"%i4%D5\\t%0, %1, %3\", operands);
3688 return \"\";
215b30b3 3689 }"
0d66636f 3690 [(set_attr "conds" "clob")
25f905c2 3691 (set (attr "length")
3692 (if_then_else (eq_attr "is_thumb" "yes")
3693 (const_int 14)
3694 (const_int 12)))]
0d66636f 3695)
9c08d1fa 3696
4164bca1 3697; Reject the frame pointer in operand[1], since reloading this after
3698; it has been eliminated can cause carnage.
3699(define_insn_and_split "*minmax_arithsi_non_canon"
7c36fe71 3700 [(set (match_operand:SI 0 "s_register_operand" "=Ts,Ts")
4164bca1 3701 (minus:SI
7c36fe71 3702 (match_operand:SI 1 "s_register_operand" "0,?Ts")
4164bca1 3703 (match_operator:SI 4 "minmax_operator"
7c36fe71 3704 [(match_operand:SI 2 "s_register_operand" "Ts,Ts")
3705 (match_operand:SI 3 "arm_rhs_operand" "TsI,TsI")])))
4164bca1 3706 (clobber (reg:CC CC_REGNUM))]
7c36fe71 3707 "TARGET_32BIT && !arm_eliminable_register (operands[1])
3708 && !(arm_restrict_it && CONST_INT_P (operands[3]))"
4164bca1 3709 "#"
3710 "TARGET_32BIT && !arm_eliminable_register (operands[1]) && reload_completed"
3711 [(set (reg:CC CC_REGNUM)
3712 (compare:CC (match_dup 2) (match_dup 3)))
3713
3714 (cond_exec (match_op_dup 4 [(reg:CC CC_REGNUM) (const_int 0)])
3715 (set (match_dup 0)
3716 (minus:SI (match_dup 1)
3717 (match_dup 2))))
3718 (cond_exec (match_op_dup 5 [(reg:CC CC_REGNUM) (const_int 0)])
3719 (set (match_dup 0)
36ee0cde 3720 (match_dup 6)))]
4164bca1 3721 {
3722 enum machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
3723 operands[2], operands[3]);
3724 enum rtx_code rc = minmax_code (operands[4]);
3725 operands[4] = gen_rtx_fmt_ee (rc, VOIDmode,
3726 operands[2], operands[3]);
3727
3728 if (mode == CCFPmode || mode == CCFPEmode)
3729 rc = reverse_condition_maybe_unordered (rc);
3730 else
3731 rc = reverse_condition (rc);
3732 operands[5] = gen_rtx_fmt_ee (rc, SImode, operands[2], operands[3]);
36ee0cde 3733 if (CONST_INT_P (operands[3]))
3734 operands[6] = plus_constant (SImode, operands[1], -INTVAL (operands[3]));
3735 else
3736 operands[6] = gen_rtx_MINUS (SImode, operands[1], operands[3]);
4164bca1 3737 }
3738 [(set_attr "conds" "clob")
3739 (set (attr "length")
3740 (if_then_else (eq_attr "is_thumb" "yes")
3741 (const_int 14)
3742 (const_int 12)))]
3743)
3744
b49e3742 3745(define_code_iterator SAT [smin smax])
3746(define_code_iterator SATrev [smin smax])
3747(define_code_attr SATlo [(smin "1") (smax "2")])
3748(define_code_attr SAThi [(smin "2") (smax "1")])
3749
3750(define_insn "*satsi_<SAT:code>"
3751 [(set (match_operand:SI 0 "s_register_operand" "=r")
3752 (SAT:SI (SATrev:SI (match_operand:SI 3 "s_register_operand" "r")
3753 (match_operand:SI 1 "const_int_operand" "i"))
3754 (match_operand:SI 2 "const_int_operand" "i")))]
3755 "TARGET_32BIT && arm_arch6 && <SAT:CODE> != <SATrev:CODE>
3756 && arm_sat_operator_match (operands[<SAT:SATlo>], operands[<SAT:SAThi>], NULL, NULL)"
3757{
3758 int mask;
3759 bool signed_sat;
3760 if (!arm_sat_operator_match (operands[<SAT:SATlo>], operands[<SAT:SAThi>],
3761 &mask, &signed_sat))
3762 gcc_unreachable ();
3763
3764 operands[1] = GEN_INT (mask);
3765 if (signed_sat)
3766 return "ssat%?\t%0, %1, %3";
3767 else
3768 return "usat%?\t%0, %1, %3";
3769}
7c36fe71 3770 [(set_attr "predicable" "yes")
3771 (set_attr "predicable_short_it" "no")]
bebe9bbb 3772)
b49e3742 3773
3774(define_insn "*satsi_<SAT:code>_shift"
3775 [(set (match_operand:SI 0 "s_register_operand" "=r")
3776 (SAT:SI (SATrev:SI (match_operator:SI 3 "sat_shift_operator"
3777 [(match_operand:SI 4 "s_register_operand" "r")
3778 (match_operand:SI 5 "const_int_operand" "i")])
3779 (match_operand:SI 1 "const_int_operand" "i"))
3780 (match_operand:SI 2 "const_int_operand" "i")))]
3781 "TARGET_32BIT && arm_arch6 && <SAT:CODE> != <SATrev:CODE>
3782 && arm_sat_operator_match (operands[<SAT:SATlo>], operands[<SAT:SAThi>], NULL, NULL)"
3783{
3784 int mask;
3785 bool signed_sat;
3786 if (!arm_sat_operator_match (operands[<SAT:SATlo>], operands[<SAT:SAThi>],
3787 &mask, &signed_sat))
3788 gcc_unreachable ();
3789
3790 operands[1] = GEN_INT (mask);
3791 if (signed_sat)
3792 return "ssat%?\t%0, %1, %4%S3";
3793 else
3794 return "usat%?\t%0, %1, %4%S3";
3795}
3796 [(set_attr "predicable" "yes")
7c36fe71 3797 (set_attr "predicable_short_it" "no")
b49e3742 3798 (set_attr "shift" "3")
6b6abc9c 3799 (set_attr "type" "arlo_shift")])
b11cae9e 3800\f
3801;; Shift and rotation insns
3802
a2cd141b 3803(define_expand "ashldi3"
3804 [(set (match_operand:DI 0 "s_register_operand" "")
3805 (ashift:DI (match_operand:DI 1 "s_register_operand" "")
aa06c51c 3806 (match_operand:SI 2 "general_operand" "")))]
25f905c2 3807 "TARGET_32BIT"
a2cd141b 3808 "
aa06c51c 3809 if (TARGET_NEON)
3810 {
3811 /* Delay the decision whether to use NEON or core-regs until
3812 register allocation. */
3813 emit_insn (gen_ashldi3_neon (operands[0], operands[1], operands[2]));
3814 DONE;
3815 }
3816 else
3817 {
3818 /* Only the NEON case can handle in-memory shift counts. */
3819 if (!reg_or_int_operand (operands[2], SImode))
3820 operands[2] = force_reg (SImode, operands[2]);
3821 }
3822
b805622c 3823 if (!CONST_INT_P (operands[2]) && TARGET_REALLY_IWMMXT)
ffcc986d 3824 ; /* No special preparation statements; expand pattern as above. */
3825 else
a2cd141b 3826 {
ffcc986d 3827 rtx scratch1, scratch2;
3828
3829 if (CONST_INT_P (operands[2])
3830 && (HOST_WIDE_INT) INTVAL (operands[2]) == 1)
a2cd141b 3831 {
3832 emit_insn (gen_arm_ashldi3_1bit (operands[0], operands[1]));
3833 DONE;
3834 }
ffcc986d 3835
3836 /* Ideally we should use iwmmxt here if we could know that operands[1]
3837 ends up already living in an iwmmxt register. Otherwise it's
3838 cheaper to have the alternate code being generated than moving
3839 values to iwmmxt regs and back. */
3840
3841 /* If we're optimizing for size, we prefer the libgcc calls. */
3842 if (optimize_function_for_size_p (cfun))
3843 FAIL;
3844
3845 /* Expand operation using core-registers.
3846 'FAIL' would achieve the same thing, but this is a bit smarter. */
3847 scratch1 = gen_reg_rtx (SImode);
3848 scratch2 = gen_reg_rtx (SImode);
3849 arm_emit_coreregs_64bit_shift (ASHIFT, operands[0], operands[1],
3850 operands[2], scratch1, scratch2);
3851 DONE;
a2cd141b 3852 }
a2cd141b 3853 "
3854)
3855
a5b9aa37 3856(define_insn_and_split "arm_ashldi3_1bit"
50ad1bf9 3857 [(set (match_operand:DI 0 "s_register_operand" "=r,&r")
e5fea38e 3858 (ashift:DI (match_operand:DI 1 "s_register_operand" "0,r")
a2cd141b 3859 (const_int 1)))
3860 (clobber (reg:CC CC_REGNUM))]
25f905c2 3861 "TARGET_32BIT"
a5b9aa37 3862 "#" ; "movs\\t%Q0, %Q1, asl #1\;adc\\t%R0, %R1, %R1"
3863 "&& reload_completed"
3864 [(parallel [(set (reg:CC CC_REGNUM)
3865 (compare:CC (ashift:SI (match_dup 1) (const_int 1))
3866 (const_int 0)))
3867 (set (match_dup 0) (ashift:SI (match_dup 1) (const_int 1)))])
3868 (set (match_dup 2) (plus:SI (plus:SI (match_dup 3) (match_dup 3))
3869 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
3870 {
3871 operands[2] = gen_highpart (SImode, operands[0]);
3872 operands[0] = gen_lowpart (SImode, operands[0]);
3873 operands[3] = gen_highpart (SImode, operands[1]);
3874 operands[1] = gen_lowpart (SImode, operands[1]);
3875 }
a2cd141b 3876 [(set_attr "conds" "clob")
3877 (set_attr "length" "8")]
3878)
3879
87b22bf7 3880(define_expand "ashlsi3"
cffb2a26 3881 [(set (match_operand:SI 0 "s_register_operand" "")
87b22bf7 3882 (ashift:SI (match_operand:SI 1 "s_register_operand" "")
3883 (match_operand:SI 2 "arm_rhs_operand" "")))]
cffb2a26 3884 "TARGET_EITHER"
87b22bf7 3885 "
0438d37f 3886 if (CONST_INT_P (operands[2])
87b22bf7 3887 && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) > 31)
3888 {
3889 emit_insn (gen_movsi (operands[0], const0_rtx));
3890 DONE;
3891 }
cffb2a26 3892 "
3893)
3894
25f905c2 3895(define_insn "*thumb1_ashlsi3"
cffb2a26 3896 [(set (match_operand:SI 0 "register_operand" "=l,l")
3897 (ashift:SI (match_operand:SI 1 "register_operand" "l,0")
3898 (match_operand:SI 2 "nonmemory_operand" "N,l")))]
25f905c2 3899 "TARGET_THUMB1"
cffb2a26 3900 "lsl\\t%0, %1, %2"
747b7458 3901 [(set_attr "length" "2")
6b6abc9c 3902 (set_attr "type" "shift,shift_reg")
747b7458 3903 (set_attr "conds" "set")])
b11cae9e 3904
a2cd141b 3905(define_expand "ashrdi3"
3906 [(set (match_operand:DI 0 "s_register_operand" "")
3907 (ashiftrt:DI (match_operand:DI 1 "s_register_operand" "")
3908 (match_operand:SI 2 "reg_or_int_operand" "")))]
25f905c2 3909 "TARGET_32BIT"
a2cd141b 3910 "
aa06c51c 3911 if (TARGET_NEON)
3912 {
3913 /* Delay the decision whether to use NEON or core-regs until
3914 register allocation. */
3915 emit_insn (gen_ashrdi3_neon (operands[0], operands[1], operands[2]));
3916 DONE;
3917 }
3918
b805622c 3919 if (!CONST_INT_P (operands[2]) && TARGET_REALLY_IWMMXT)
ffcc986d 3920 ; /* No special preparation statements; expand pattern as above. */
3921 else
a2cd141b 3922 {
ffcc986d 3923 rtx scratch1, scratch2;
3924
3925 if (CONST_INT_P (operands[2])
3926 && (HOST_WIDE_INT) INTVAL (operands[2]) == 1)
a2cd141b 3927 {
3928 emit_insn (gen_arm_ashrdi3_1bit (operands[0], operands[1]));
3929 DONE;
3930 }
ffcc986d 3931
3932 /* Ideally we should use iwmmxt here if we could know that operands[1]
3933 ends up already living in an iwmmxt register. Otherwise it's
3934 cheaper to have the alternate code being generated than moving
3935 values to iwmmxt regs and back. */
3936
3937 /* If we're optimizing for size, we prefer the libgcc calls. */
3938 if (optimize_function_for_size_p (cfun))
3939 FAIL;
3940
3941 /* Expand operation using core-registers.
3942 'FAIL' would achieve the same thing, but this is a bit smarter. */
3943 scratch1 = gen_reg_rtx (SImode);
3944 scratch2 = gen_reg_rtx (SImode);
3945 arm_emit_coreregs_64bit_shift (ASHIFTRT, operands[0], operands[1],
3946 operands[2], scratch1, scratch2);
3947 DONE;
a2cd141b 3948 }
a2cd141b 3949 "
3950)
3951
a5b9aa37 3952(define_insn_and_split "arm_ashrdi3_1bit"
50ad1bf9 3953 [(set (match_operand:DI 0 "s_register_operand" "=r,&r")
e5fea38e 3954 (ashiftrt:DI (match_operand:DI 1 "s_register_operand" "0,r")
a2cd141b 3955 (const_int 1)))
3956 (clobber (reg:CC CC_REGNUM))]
25f905c2 3957 "TARGET_32BIT"
a5b9aa37 3958 "#" ; "movs\\t%R0, %R1, asr #1\;mov\\t%Q0, %Q1, rrx"
3959 "&& reload_completed"
3960 [(parallel [(set (reg:CC CC_REGNUM)
3961 (compare:CC (ashiftrt:SI (match_dup 3) (const_int 1))
3962 (const_int 0)))
3963 (set (match_dup 2) (ashiftrt:SI (match_dup 3) (const_int 1)))])
3964 (set (match_dup 0) (unspec:SI [(match_dup 1)
3965 (reg:CC_C CC_REGNUM)]
3966 UNSPEC_RRX))]
3967 {
3968 operands[2] = gen_highpart (SImode, operands[0]);
3969 operands[0] = gen_lowpart (SImode, operands[0]);
3970 operands[3] = gen_highpart (SImode, operands[1]);
3971 operands[1] = gen_lowpart (SImode, operands[1]);
3972 }
a2cd141b 3973 [(set_attr "conds" "clob")
3974 (set_attr "length" "8")]
3975)
3976
a5b9aa37 3977(define_insn "*rrx"
3978 [(set (match_operand:SI 0 "s_register_operand" "=r")
3979 (unspec:SI [(match_operand:SI 1 "s_register_operand" "r")
3980 (reg:CC_C CC_REGNUM)]
3981 UNSPEC_RRX))]
3982 "TARGET_32BIT"
3983 "mov\\t%0, %1, rrx"
3984 [(set_attr "conds" "use")
1aed5204 3985 (set_attr "type" "mov_shift")]
a5b9aa37 3986)
3987
87b22bf7 3988(define_expand "ashrsi3"
cffb2a26 3989 [(set (match_operand:SI 0 "s_register_operand" "")
87b22bf7 3990 (ashiftrt:SI (match_operand:SI 1 "s_register_operand" "")
3991 (match_operand:SI 2 "arm_rhs_operand" "")))]
cffb2a26 3992 "TARGET_EITHER"
87b22bf7 3993 "
0438d37f 3994 if (CONST_INT_P (operands[2])
87b22bf7 3995 && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) > 31)
3996 operands[2] = GEN_INT (31);
cffb2a26 3997 "
3998)
3999
25f905c2 4000(define_insn "*thumb1_ashrsi3"
cffb2a26 4001 [(set (match_operand:SI 0 "register_operand" "=l,l")
4002 (ashiftrt:SI (match_operand:SI 1 "register_operand" "l,0")
4003 (match_operand:SI 2 "nonmemory_operand" "N,l")))]
25f905c2 4004 "TARGET_THUMB1"
cffb2a26 4005 "asr\\t%0, %1, %2"
747b7458 4006 [(set_attr "length" "2")
6b6abc9c 4007 (set_attr "type" "shift,shift_reg")
747b7458 4008 (set_attr "conds" "set")])
b11cae9e 4009
a2cd141b 4010(define_expand "lshrdi3"
4011 [(set (match_operand:DI 0 "s_register_operand" "")
4012 (lshiftrt:DI (match_operand:DI 1 "s_register_operand" "")
4013 (match_operand:SI 2 "reg_or_int_operand" "")))]
25f905c2 4014 "TARGET_32BIT"
a2cd141b 4015 "
aa06c51c 4016 if (TARGET_NEON)
4017 {
4018 /* Delay the decision whether to use NEON or core-regs until
4019 register allocation. */
4020 emit_insn (gen_lshrdi3_neon (operands[0], operands[1], operands[2]));
4021 DONE;
4022 }
4023
b805622c 4024 if (!CONST_INT_P (operands[2]) && TARGET_REALLY_IWMMXT)
ffcc986d 4025 ; /* No special preparation statements; expand pattern as above. */
4026 else
a2cd141b 4027 {
ffcc986d 4028 rtx scratch1, scratch2;
4029
4030 if (CONST_INT_P (operands[2])
4031 && (HOST_WIDE_INT) INTVAL (operands[2]) == 1)
a2cd141b 4032 {
4033 emit_insn (gen_arm_lshrdi3_1bit (operands[0], operands[1]));
4034 DONE;
4035 }
ffcc986d 4036
4037 /* Ideally we should use iwmmxt here if we could know that operands[1]
4038 ends up already living in an iwmmxt register. Otherwise it's
4039 cheaper to have the alternate code being generated than moving
4040 values to iwmmxt regs and back. */
4041
4042 /* If we're optimizing for size, we prefer the libgcc calls. */
4043 if (optimize_function_for_size_p (cfun))
4044 FAIL;
4045
4046 /* Expand operation using core-registers.
4047 'FAIL' would achieve the same thing, but this is a bit smarter. */
4048 scratch1 = gen_reg_rtx (SImode);
4049 scratch2 = gen_reg_rtx (SImode);
4050 arm_emit_coreregs_64bit_shift (LSHIFTRT, operands[0], operands[1],
4051 operands[2], scratch1, scratch2);
4052 DONE;
a2cd141b 4053 }
a2cd141b 4054 "
4055)
4056
a5b9aa37 4057(define_insn_and_split "arm_lshrdi3_1bit"
50ad1bf9 4058 [(set (match_operand:DI 0 "s_register_operand" "=r,&r")
e5fea38e 4059 (lshiftrt:DI (match_operand:DI 1 "s_register_operand" "0,r")
a2cd141b 4060 (const_int 1)))
4061 (clobber (reg:CC CC_REGNUM))]
25f905c2 4062 "TARGET_32BIT"
a5b9aa37 4063 "#" ; "movs\\t%R0, %R1, lsr #1\;mov\\t%Q0, %Q1, rrx"
4064 "&& reload_completed"
4065 [(parallel [(set (reg:CC CC_REGNUM)
4066 (compare:CC (lshiftrt:SI (match_dup 3) (const_int 1))
4067 (const_int 0)))
4068 (set (match_dup 2) (lshiftrt:SI (match_dup 3) (const_int 1)))])
4069 (set (match_dup 0) (unspec:SI [(match_dup 1)
4070 (reg:CC_C CC_REGNUM)]
4071 UNSPEC_RRX))]
4072 {
4073 operands[2] = gen_highpart (SImode, operands[0]);
4074 operands[0] = gen_lowpart (SImode, operands[0]);
4075 operands[3] = gen_highpart (SImode, operands[1]);
4076 operands[1] = gen_lowpart (SImode, operands[1]);
4077 }
a2cd141b 4078 [(set_attr "conds" "clob")
4079 (set_attr "length" "8")]
4080)
4081
87b22bf7 4082(define_expand "lshrsi3"
cffb2a26 4083 [(set (match_operand:SI 0 "s_register_operand" "")
87b22bf7 4084 (lshiftrt:SI (match_operand:SI 1 "s_register_operand" "")
4085 (match_operand:SI 2 "arm_rhs_operand" "")))]
cffb2a26 4086 "TARGET_EITHER"
87b22bf7 4087 "
0438d37f 4088 if (CONST_INT_P (operands[2])
87b22bf7 4089 && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) > 31)
4090 {
4091 emit_insn (gen_movsi (operands[0], const0_rtx));
4092 DONE;
4093 }
cffb2a26 4094 "
4095)
4096
25f905c2 4097(define_insn "*thumb1_lshrsi3"
cffb2a26 4098 [(set (match_operand:SI 0 "register_operand" "=l,l")
4099 (lshiftrt:SI (match_operand:SI 1 "register_operand" "l,0")
4100 (match_operand:SI 2 "nonmemory_operand" "N,l")))]
25f905c2 4101 "TARGET_THUMB1"
cffb2a26 4102 "lsr\\t%0, %1, %2"
747b7458 4103 [(set_attr "length" "2")
6b6abc9c 4104 (set_attr "type" "shift,shift_reg")
747b7458 4105 (set_attr "conds" "set")])
b11cae9e 4106
87b22bf7 4107(define_expand "rotlsi3"
cffb2a26 4108 [(set (match_operand:SI 0 "s_register_operand" "")
87b22bf7 4109 (rotatert:SI (match_operand:SI 1 "s_register_operand" "")
4110 (match_operand:SI 2 "reg_or_int_operand" "")))]
25f905c2 4111 "TARGET_32BIT"
87b22bf7 4112 "
0438d37f 4113 if (CONST_INT_P (operands[2]))
87b22bf7 4114 operands[2] = GEN_INT ((32 - INTVAL (operands[2])) % 32);
4115 else
b11cae9e 4116 {
87b22bf7 4117 rtx reg = gen_reg_rtx (SImode);
4118 emit_insn (gen_subsi3 (reg, GEN_INT (32), operands[2]));
4119 operands[2] = reg;
b11cae9e 4120 }
cffb2a26 4121 "
4122)
9c08d1fa 4123
87b22bf7 4124(define_expand "rotrsi3"
cffb2a26 4125 [(set (match_operand:SI 0 "s_register_operand" "")
87b22bf7 4126 (rotatert:SI (match_operand:SI 1 "s_register_operand" "")
4127 (match_operand:SI 2 "arm_rhs_operand" "")))]
cffb2a26 4128 "TARGET_EITHER"
87b22bf7 4129 "
25f905c2 4130 if (TARGET_32BIT)
cffb2a26 4131 {
0438d37f 4132 if (CONST_INT_P (operands[2])
cffb2a26 4133 && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) > 31)
4134 operands[2] = GEN_INT (INTVAL (operands[2]) % 32);
4135 }
25f905c2 4136 else /* TARGET_THUMB1 */
cffb2a26 4137 {
0438d37f 4138 if (CONST_INT_P (operands [2]))
cffb2a26 4139 operands [2] = force_reg (SImode, operands[2]);
4140 }
4141 "
4142)
87b22bf7 4143
25f905c2 4144(define_insn "*thumb1_rotrsi3"
cffb2a26 4145 [(set (match_operand:SI 0 "register_operand" "=l")
4146 (rotatert:SI (match_operand:SI 1 "register_operand" "0")
4147 (match_operand:SI 2 "register_operand" "l")))]
25f905c2 4148 "TARGET_THUMB1"
cffb2a26 4149 "ror\\t%0, %0, %2"
6b6abc9c 4150 [(set_attr "type" "shift_reg")
4151 (set_attr "length" "2")]
cffb2a26 4152)
4153
4154(define_insn "*arm_shiftsi3"
7c36fe71 4155 [(set (match_operand:SI 0 "s_register_operand" "=l,r,r")
cffb2a26 4156 (match_operator:SI 3 "shift_operator"
7c36fe71 4157 [(match_operand:SI 1 "s_register_operand" "0,r,r")
4158 (match_operand:SI 2 "reg_or_int_operand" "l,M,r")]))]
25f905c2 4159 "TARGET_32BIT"
4160 "* return arm_output_shift(operands, 0);"
344495ea 4161 [(set_attr "predicable" "yes")
7c36fe71 4162 (set_attr "arch" "t2,*,*")
4163 (set_attr "predicable_short_it" "yes,no,no")
4164 (set_attr "length" "4")
331beb1a 4165 (set_attr "shift" "1")
7c36fe71 4166 (set_attr "type" "arlo_shift_reg,arlo_shift,arlo_shift_reg")]
6c4c2133 4167)
87b22bf7 4168
a5b9aa37 4169(define_insn "*shiftsi3_compare"
4170 [(set (reg:CC CC_REGNUM)
4171 (compare:CC (match_operator:SI 3 "shift_operator"
6b6abc9c 4172 [(match_operand:SI 1 "s_register_operand" "r,r")
4173 (match_operand:SI 2 "arm_rhs_operand" "M,r")])
a5b9aa37 4174 (const_int 0)))
6b6abc9c 4175 (set (match_operand:SI 0 "s_register_operand" "=r,r")
a5b9aa37 4176 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))]
4177 "TARGET_32BIT"
4178 "* return arm_output_shift(operands, 1);"
4179 [(set_attr "conds" "set")
4180 (set_attr "shift" "1")
6b6abc9c 4181 (set_attr "type" "arlo_shift,arlo_shift_reg")]
a5b9aa37 4182)
4183
f7fbdd4a 4184(define_insn "*shiftsi3_compare0"
bd5b4116 4185 [(set (reg:CC_NOOV CC_REGNUM)
87b22bf7 4186 (compare:CC_NOOV (match_operator:SI 3 "shift_operator"
6b6abc9c 4187 [(match_operand:SI 1 "s_register_operand" "r,r")
4188 (match_operand:SI 2 "arm_rhs_operand" "M,r")])
9c08d1fa 4189 (const_int 0)))
6b6abc9c 4190 (set (match_operand:SI 0 "s_register_operand" "=r,r")
87b22bf7 4191 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))]
25f905c2 4192 "TARGET_32BIT"
4193 "* return arm_output_shift(operands, 1);"
344495ea 4194 [(set_attr "conds" "set")
331beb1a 4195 (set_attr "shift" "1")
6b6abc9c 4196 (set_attr "type" "arlo_shift,arlo_shift_reg")]
0d66636f 4197)
9c08d1fa 4198
f7fbdd4a 4199(define_insn "*shiftsi3_compare0_scratch"
bd5b4116 4200 [(set (reg:CC_NOOV CC_REGNUM)
87b22bf7 4201 (compare:CC_NOOV (match_operator:SI 3 "shift_operator"
6b6abc9c 4202 [(match_operand:SI 1 "s_register_operand" "r,r")
4203 (match_operand:SI 2 "arm_rhs_operand" "M,r")])
9c08d1fa 4204 (const_int 0)))
6b6abc9c 4205 (clobber (match_scratch:SI 0 "=r,r"))]
25f905c2 4206 "TARGET_32BIT"
4207 "* return arm_output_shift(operands, 1);"
344495ea 4208 [(set_attr "conds" "set")
6b6abc9c 4209 (set_attr "shift" "1")
4210 (set_attr "type" "shift,shift_reg")]
0d66636f 4211)
9c08d1fa 4212
d5d4dc8d 4213(define_insn "*not_shiftsi"
4214 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
87b22bf7 4215 (not:SI (match_operator:SI 3 "shift_operator"
d5d4dc8d 4216 [(match_operand:SI 1 "s_register_operand" "r,r")
4217 (match_operand:SI 2 "shift_amount_operand" "M,rM")])))]
4218 "TARGET_32BIT"
6c4c2133 4219 "mvn%?\\t%0, %1%S3"
344495ea 4220 [(set_attr "predicable" "yes")
d952d547 4221 (set_attr "predicable_short_it" "no")
331beb1a 4222 (set_attr "shift" "1")
d5d4dc8d 4223 (set_attr "arch" "32,a")
1aed5204 4224 (set_attr "type" "mvn_shift,mvn_shift_reg")])
9c08d1fa 4225
d5d4dc8d 4226(define_insn "*not_shiftsi_compare0"
bd5b4116 4227 [(set (reg:CC_NOOV CC_REGNUM)
d5d4dc8d 4228 (compare:CC_NOOV
4229 (not:SI (match_operator:SI 3 "shift_operator"
4230 [(match_operand:SI 1 "s_register_operand" "r,r")
4231 (match_operand:SI 2 "shift_amount_operand" "M,rM")]))
4232 (const_int 0)))
4233 (set (match_operand:SI 0 "s_register_operand" "=r,r")
87b22bf7 4234 (not:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)])))]
d5d4dc8d 4235 "TARGET_32BIT"
25f905c2 4236 "mvn%.\\t%0, %1%S3"
344495ea 4237 [(set_attr "conds" "set")
331beb1a 4238 (set_attr "shift" "1")
d5d4dc8d 4239 (set_attr "arch" "32,a")
1aed5204 4240 (set_attr "type" "mvn_shift,mvn_shift_reg")])
9c08d1fa 4241
d5d4dc8d 4242(define_insn "*not_shiftsi_compare0_scratch"
bd5b4116 4243 [(set (reg:CC_NOOV CC_REGNUM)
d5d4dc8d 4244 (compare:CC_NOOV
4245 (not:SI (match_operator:SI 3 "shift_operator"
4246 [(match_operand:SI 1 "s_register_operand" "r,r")
4247 (match_operand:SI 2 "shift_amount_operand" "M,rM")]))
4248 (const_int 0)))
4249 (clobber (match_scratch:SI 0 "=r,r"))]
4250 "TARGET_32BIT"
25f905c2 4251 "mvn%.\\t%0, %1%S3"
344495ea 4252 [(set_attr "conds" "set")
331beb1a 4253 (set_attr "shift" "1")
d5d4dc8d 4254 (set_attr "arch" "32,a")
1aed5204 4255 (set_attr "type" "mvn_shift,mvn_shift_reg")])
9c08d1fa 4256
cffb2a26 4257;; We don't really have extzv, but defining this using shifts helps
4258;; to reduce register pressure later on.
4259
4260(define_expand "extzv"
eb04cafb 4261 [(set (match_operand 0 "s_register_operand" "")
4262 (zero_extract (match_operand 1 "nonimmediate_operand" "")
4263 (match_operand 2 "const_int_operand" "")
4264 (match_operand 3 "const_int_operand" "")))]
8b054d5a 4265 "TARGET_THUMB1 || arm_arch_thumb2"
cffb2a26 4266 "
4267 {
4268 HOST_WIDE_INT lshift = 32 - INTVAL (operands[2]) - INTVAL (operands[3]);
4269 HOST_WIDE_INT rshift = 32 - INTVAL (operands[2]);
4270
8b054d5a 4271 if (arm_arch_thumb2)
4272 {
eb04cafb 4273 HOST_WIDE_INT width = INTVAL (operands[2]);
4274 HOST_WIDE_INT bitpos = INTVAL (operands[3]);
4275
4276 if (unaligned_access && MEM_P (operands[1])
4277 && (width == 16 || width == 32) && (bitpos % BITS_PER_UNIT) == 0)
4278 {
4279 rtx base_addr;
4280
4281 if (BYTES_BIG_ENDIAN)
4282 bitpos = GET_MODE_BITSIZE (GET_MODE (operands[0])) - width
4283 - bitpos;
4284
4285 if (width == 32)
4286 {
4287 base_addr = adjust_address (operands[1], SImode,
4288 bitpos / BITS_PER_UNIT);
4289 emit_insn (gen_unaligned_loadsi (operands[0], base_addr));
4290 }
4291 else
4292 {
4293 rtx dest = operands[0];
4294 rtx tmp = gen_reg_rtx (SImode);
4295
4296 /* We may get a paradoxical subreg here. Strip it off. */
4297 if (GET_CODE (dest) == SUBREG
4298 && GET_MODE (dest) == SImode
4299 && GET_MODE (SUBREG_REG (dest)) == HImode)
4300 dest = SUBREG_REG (dest);
4301
4302 if (GET_MODE_BITSIZE (GET_MODE (dest)) != width)
4303 FAIL;
4304
4305 base_addr = adjust_address (operands[1], HImode,
4306 bitpos / BITS_PER_UNIT);
4307 emit_insn (gen_unaligned_loadhiu (tmp, base_addr));
4308 emit_move_insn (gen_lowpart (SImode, dest), tmp);
4309 }
4310 DONE;
4311 }
4312 else if (s_register_operand (operands[1], GET_MODE (operands[1])))
4313 {
4314 emit_insn (gen_extzv_t2 (operands[0], operands[1], operands[2],
4315 operands[3]));
4316 DONE;
4317 }
4318 else
4319 FAIL;
8b054d5a 4320 }
eb04cafb 4321
4322 if (!s_register_operand (operands[1], GET_MODE (operands[1])))
4323 FAIL;
8b054d5a 4324
cffb2a26 4325 operands[3] = GEN_INT (rshift);
4326
4327 if (lshift == 0)
4328 {
4329 emit_insn (gen_lshrsi3 (operands[0], operands[1], operands[3]));
4330 DONE;
4331 }
4332
eb04cafb 4333 emit_insn (gen_extzv_t1 (operands[0], operands[1], GEN_INT (lshift),
4334 operands[3], gen_reg_rtx (SImode)));
4335 DONE;
215b30b3 4336 }"
cffb2a26 4337)
4338
eb04cafb 4339;; Helper for extzv, for the Thumb-1 register-shifts case.
4340
4341(define_expand "extzv_t1"
4342 [(set (match_operand:SI 4 "s_register_operand" "")
4343 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
4344 (match_operand:SI 2 "const_int_operand" "")))
4345 (set (match_operand:SI 0 "s_register_operand" "")
4346 (lshiftrt:SI (match_dup 4)
4347 (match_operand:SI 3 "const_int_operand" "")))]
4348 "TARGET_THUMB1"
4349 "")
4350
4351(define_expand "extv"
4352 [(set (match_operand 0 "s_register_operand" "")
4353 (sign_extract (match_operand 1 "nonimmediate_operand" "")
4354 (match_operand 2 "const_int_operand" "")
4355 (match_operand 3 "const_int_operand" "")))]
4356 "arm_arch_thumb2"
4357{
4358 HOST_WIDE_INT width = INTVAL (operands[2]);
4359 HOST_WIDE_INT bitpos = INTVAL (operands[3]);
4360
4361 if (unaligned_access && MEM_P (operands[1]) && (width == 16 || width == 32)
4362 && (bitpos % BITS_PER_UNIT) == 0)
4363 {
4364 rtx base_addr;
4365
4366 if (BYTES_BIG_ENDIAN)
4367 bitpos = GET_MODE_BITSIZE (GET_MODE (operands[0])) - width - bitpos;
4368
4369 if (width == 32)
4370 {
4371 base_addr = adjust_address (operands[1], SImode,
4372 bitpos / BITS_PER_UNIT);
4373 emit_insn (gen_unaligned_loadsi (operands[0], base_addr));
4374 }
4375 else
4376 {
4377 rtx dest = operands[0];
4378 rtx tmp = gen_reg_rtx (SImode);
4379
4380 /* We may get a paradoxical subreg here. Strip it off. */
4381 if (GET_CODE (dest) == SUBREG
4382 && GET_MODE (dest) == SImode
4383 && GET_MODE (SUBREG_REG (dest)) == HImode)
4384 dest = SUBREG_REG (dest);
4385
4386 if (GET_MODE_BITSIZE (GET_MODE (dest)) != width)
4387 FAIL;
4388
4389 base_addr = adjust_address (operands[1], HImode,
4390 bitpos / BITS_PER_UNIT);
4391 emit_insn (gen_unaligned_loadhis (tmp, base_addr));
4392 emit_move_insn (gen_lowpart (SImode, dest), tmp);
4393 }
4394
4395 DONE;
4396 }
4397 else if (!s_register_operand (operands[1], GET_MODE (operands[1])))
4398 FAIL;
4399 else if (GET_MODE (operands[0]) == SImode
4400 && GET_MODE (operands[1]) == SImode)
4401 {
4402 emit_insn (gen_extv_regsi (operands[0], operands[1], operands[2],
4403 operands[3]));
4404 DONE;
4405 }
4406
4407 FAIL;
4408})
4409
4410; Helper to expand register forms of extv with the proper modes.
4411
4412(define_expand "extv_regsi"
4413 [(set (match_operand:SI 0 "s_register_operand" "")
4414 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "")
4415 (match_operand 2 "const_int_operand" "")
4416 (match_operand 3 "const_int_operand" "")))]
4417 ""
4418{
4419})
4420
4421; ARMv6+ unaligned load/store instructions (used for packed structure accesses).
4422
4423(define_insn "unaligned_loadsi"
4424 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
4425 (unspec:SI [(match_operand:SI 1 "memory_operand" "Uw,m")]
4426 UNSPEC_UNALIGNED_LOAD))]
4427 "unaligned_access && TARGET_32BIT"
4428 "ldr%?\t%0, %1\t@ unaligned"
4429 [(set_attr "arch" "t2,any")
4430 (set_attr "length" "2,4")
4431 (set_attr "predicable" "yes")
d952d547 4432 (set_attr "predicable_short_it" "yes,no")
eb04cafb 4433 (set_attr "type" "load1")])
4434
4435(define_insn "unaligned_loadhis"
4436 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
4437 (sign_extend:SI
4438 (unspec:HI [(match_operand:HI 1 "memory_operand" "Uw,m")]
4439 UNSPEC_UNALIGNED_LOAD)))]
4440 "unaligned_access && TARGET_32BIT"
4441 "ldr%(sh%)\t%0, %1\t@ unaligned"
4442 [(set_attr "arch" "t2,any")
4443 (set_attr "length" "2,4")
4444 (set_attr "predicable" "yes")
d952d547 4445 (set_attr "predicable_short_it" "yes,no")
eb04cafb 4446 (set_attr "type" "load_byte")])
4447
4448(define_insn "unaligned_loadhiu"
4449 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
4450 (zero_extend:SI
4451 (unspec:HI [(match_operand:HI 1 "memory_operand" "Uw,m")]
4452 UNSPEC_UNALIGNED_LOAD)))]
4453 "unaligned_access && TARGET_32BIT"
4454 "ldr%(h%)\t%0, %1\t@ unaligned"
4455 [(set_attr "arch" "t2,any")
4456 (set_attr "length" "2,4")
4457 (set_attr "predicable" "yes")
d952d547 4458 (set_attr "predicable_short_it" "yes,no")
eb04cafb 4459 (set_attr "type" "load_byte")])
4460
4461(define_insn "unaligned_storesi"
4462 [(set (match_operand:SI 0 "memory_operand" "=Uw,m")
4463 (unspec:SI [(match_operand:SI 1 "s_register_operand" "l,r")]
4464 UNSPEC_UNALIGNED_STORE))]
4465 "unaligned_access && TARGET_32BIT"
4466 "str%?\t%1, %0\t@ unaligned"
4467 [(set_attr "arch" "t2,any")
4468 (set_attr "length" "2,4")
4469 (set_attr "predicable" "yes")
d952d547 4470 (set_attr "predicable_short_it" "yes,no")
eb04cafb 4471 (set_attr "type" "store1")])
4472
4473(define_insn "unaligned_storehi"
4474 [(set (match_operand:HI 0 "memory_operand" "=Uw,m")
4475 (unspec:HI [(match_operand:HI 1 "s_register_operand" "l,r")]
4476 UNSPEC_UNALIGNED_STORE))]
4477 "unaligned_access && TARGET_32BIT"
4478 "str%(h%)\t%1, %0\t@ unaligned"
4479 [(set_attr "arch" "t2,any")
4480 (set_attr "length" "2,4")
4481 (set_attr "predicable" "yes")
d952d547 4482 (set_attr "predicable_short_it" "yes,no")
eb04cafb 4483 (set_attr "type" "store1")])
4484
ae51a965 4485;; Unaligned double-word load and store.
4486;; Split after reload into two unaligned single-word accesses.
4487;; It prevents lower_subreg from splitting some other aligned
4488;; double-word accesses too early. Used for internal memcpy.
4489
4490(define_insn_and_split "unaligned_loaddi"
4491 [(set (match_operand:DI 0 "s_register_operand" "=l,r")
4492 (unspec:DI [(match_operand:DI 1 "memory_operand" "o,o")]
4493 UNSPEC_UNALIGNED_LOAD))]
4494 "unaligned_access && TARGET_32BIT"
4495 "#"
4496 "&& reload_completed"
4497 [(set (match_dup 0) (unspec:SI [(match_dup 1)] UNSPEC_UNALIGNED_LOAD))
4498 (set (match_dup 2) (unspec:SI [(match_dup 3)] UNSPEC_UNALIGNED_LOAD))]
4499 {
4500 operands[2] = gen_highpart (SImode, operands[0]);
4501 operands[0] = gen_lowpart (SImode, operands[0]);
4502 operands[3] = gen_highpart (SImode, operands[1]);
4503 operands[1] = gen_lowpart (SImode, operands[1]);
4504
4505 /* If the first destination register overlaps with the base address,
4506 swap the order in which the loads are emitted. */
4507 if (reg_overlap_mentioned_p (operands[0], operands[1]))
4508 {
4509 rtx tmp = operands[1];
4510 operands[1] = operands[3];
4511 operands[3] = tmp;
4512 tmp = operands[0];
4513 operands[0] = operands[2];
4514 operands[2] = tmp;
4515 }
4516 }
4517 [(set_attr "arch" "t2,any")
4518 (set_attr "length" "4,8")
4519 (set_attr "predicable" "yes")
4520 (set_attr "type" "load2")])
4521
4522(define_insn_and_split "unaligned_storedi"
4523 [(set (match_operand:DI 0 "memory_operand" "=o,o")
4524 (unspec:DI [(match_operand:DI 1 "s_register_operand" "l,r")]
4525 UNSPEC_UNALIGNED_STORE))]
4526 "unaligned_access && TARGET_32BIT"
4527 "#"
4528 "&& reload_completed"
4529 [(set (match_dup 0) (unspec:SI [(match_dup 1)] UNSPEC_UNALIGNED_STORE))
4530 (set (match_dup 2) (unspec:SI [(match_dup 3)] UNSPEC_UNALIGNED_STORE))]
4531 {
4532 operands[2] = gen_highpart (SImode, operands[0]);
4533 operands[0] = gen_lowpart (SImode, operands[0]);
4534 operands[3] = gen_highpart (SImode, operands[1]);
4535 operands[1] = gen_lowpart (SImode, operands[1]);
4536 }
4537 [(set_attr "arch" "t2,any")
4538 (set_attr "length" "4,8")
4539 (set_attr "predicable" "yes")
4540 (set_attr "type" "store2")])
4541
4542
eb04cafb 4543(define_insn "*extv_reg"
8b054d5a 4544 [(set (match_operand:SI 0 "s_register_operand" "=r")
4545 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
4546 (match_operand:SI 2 "const_int_operand" "M")
4547 (match_operand:SI 3 "const_int_operand" "M")))]
4548 "arm_arch_thumb2"
4549 "sbfx%?\t%0, %1, %3, %2"
4550 [(set_attr "length" "4")
d952d547 4551 (set_attr "predicable" "yes")
4552 (set_attr "predicable_short_it" "no")]
8b054d5a 4553)
4554
4555(define_insn "extzv_t2"
4556 [(set (match_operand:SI 0 "s_register_operand" "=r")
4557 (zero_extract:SI (match_operand:SI 1 "s_register_operand" "r")
4558 (match_operand:SI 2 "const_int_operand" "M")
4559 (match_operand:SI 3 "const_int_operand" "M")))]
4560 "arm_arch_thumb2"
4561 "ubfx%?\t%0, %1, %3, %2"
4562 [(set_attr "length" "4")
d952d547 4563 (set_attr "predicable" "yes")
4564 (set_attr "predicable_short_it" "no")]
8b054d5a 4565)
4566
7d3cda8c 4567
4568;; Division instructions
4569(define_insn "divsi3"
4570 [(set (match_operand:SI 0 "s_register_operand" "=r")
4571 (div:SI (match_operand:SI 1 "s_register_operand" "r")
4572 (match_operand:SI 2 "s_register_operand" "r")))]
4573 "TARGET_IDIV"
4574 "sdiv%?\t%0, %1, %2"
4575 [(set_attr "predicable" "yes")
d952d547 4576 (set_attr "predicable_short_it" "no")
9da0ec36 4577 (set_attr "type" "sdiv")]
7d3cda8c 4578)
4579
4580(define_insn "udivsi3"
4581 [(set (match_operand:SI 0 "s_register_operand" "=r")
4582 (udiv:SI (match_operand:SI 1 "s_register_operand" "r")
4583 (match_operand:SI 2 "s_register_operand" "r")))]
4584 "TARGET_IDIV"
4585 "udiv%?\t%0, %1, %2"
4586 [(set_attr "predicable" "yes")
d952d547 4587 (set_attr "predicable_short_it" "no")
9da0ec36 4588 (set_attr "type" "udiv")]
7d3cda8c 4589)
4590
b11cae9e 4591\f
4592;; Unary arithmetic insns
4593
cffb2a26 4594(define_expand "negdi2"
4595 [(parallel
8135a42b 4596 [(set (match_operand:DI 0 "s_register_operand" "")
4597 (neg:DI (match_operand:DI 1 "s_register_operand" "")))
bd5b4116 4598 (clobber (reg:CC CC_REGNUM))])]
cffb2a26 4599 "TARGET_EITHER"
774d2fbb 4600 {
4601 if (TARGET_NEON)
4602 {
4603 emit_insn (gen_negdi2_neon (operands[0], operands[1]));
4604 DONE;
4605 }
4606 }
cffb2a26 4607)
4608
4609;; The constraints here are to prevent a *partial* overlap (where %Q0 == %R1).
e5fea38e 4610;; The first alternative allows the common case of a *full* overlap.
ba6a3b2f 4611(define_insn_and_split "*arm_negdi2"
458a8706 4612 [(set (match_operand:DI 0 "s_register_operand" "=r,&r")
e5fea38e 4613 (neg:DI (match_operand:DI 1 "s_register_operand" "0,r")))
bd5b4116 4614 (clobber (reg:CC CC_REGNUM))]
cffb2a26 4615 "TARGET_ARM"
ba6a3b2f 4616 "#" ; "rsbs\\t%Q0, %Q1, #0\;rsc\\t%R0, %R1, #0"
4617 "&& reload_completed"
4618 [(parallel [(set (reg:CC CC_REGNUM)
4619 (compare:CC (const_int 0) (match_dup 1)))
4620 (set (match_dup 0) (minus:SI (const_int 0) (match_dup 1)))])
4621 (set (match_dup 2) (minus:SI (minus:SI (const_int 0) (match_dup 3))
4622 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
4623 {
4624 operands[2] = gen_highpart (SImode, operands[0]);
4625 operands[0] = gen_lowpart (SImode, operands[0]);
4626 operands[3] = gen_highpart (SImode, operands[1]);
4627 operands[1] = gen_lowpart (SImode, operands[1]);
4628 }
cffb2a26 4629 [(set_attr "conds" "clob")
4630 (set_attr "length" "8")]
4631)
b11cae9e 4632
25f905c2 4633(define_insn "*thumb1_negdi2"
8135a42b 4634 [(set (match_operand:DI 0 "register_operand" "=&l")
4635 (neg:DI (match_operand:DI 1 "register_operand" "l")))
bd5b4116 4636 (clobber (reg:CC CC_REGNUM))]
25f905c2 4637 "TARGET_THUMB1"
cffb2a26 4638 "mov\\t%R0, #0\;neg\\t%Q0, %Q1\;sbc\\t%R0, %R1"
4639 [(set_attr "length" "6")]
4640)
4641
4642(define_expand "negsi2"
4643 [(set (match_operand:SI 0 "s_register_operand" "")
4644 (neg:SI (match_operand:SI 1 "s_register_operand" "")))]
4645 "TARGET_EITHER"
b11cae9e 4646 ""
cffb2a26 4647)
4648
4649(define_insn "*arm_negsi2"
d952d547 4650 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
4651 (neg:SI (match_operand:SI 1 "s_register_operand" "l,r")))]
25f905c2 4652 "TARGET_32BIT"
cffb2a26 4653 "rsb%?\\t%0, %1, #0"
d952d547 4654 [(set_attr "predicable" "yes")
4655 (set_attr "predicable_short_it" "yes,no")
4656 (set_attr "arch" "t2,*")
4657 (set_attr "length" "4")]
cffb2a26 4658)
4659
25f905c2 4660(define_insn "*thumb1_negsi2"
cffb2a26 4661 [(set (match_operand:SI 0 "register_operand" "=l")
4662 (neg:SI (match_operand:SI 1 "register_operand" "l")))]
25f905c2 4663 "TARGET_THUMB1"
cffb2a26 4664 "neg\\t%0, %1"
4665 [(set_attr "length" "2")]
4666)
b11cae9e 4667
604f3a0a 4668(define_expand "negsf2"
4669 [(set (match_operand:SF 0 "s_register_operand" "")
4670 (neg:SF (match_operand:SF 1 "s_register_operand" "")))]
994606f8 4671 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
604f3a0a 4672 ""
4673)
4674
4675(define_expand "negdf2"
4676 [(set (match_operand:DF 0 "s_register_operand" "")
4677 (neg:DF (match_operand:DF 1 "s_register_operand" "")))]
994606f8 4678 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
604f3a0a 4679 "")
4680
83e2b922 4681;; Negate an extended 32-bit value.
4682(define_insn_and_split "*negdi_extendsidi"
4683 [(set (match_operand:DI 0 "s_register_operand" "=r,&r,l,&l")
4684 (neg:DI (sign_extend:DI (match_operand:SI 1 "s_register_operand" "0,r,0,l"))))
4685 (clobber (reg:CC CC_REGNUM))]
4686 "TARGET_32BIT"
4687 "#" ; rsb\\t%Q0, %1, #0\;asr\\t%R0, %Q0, #31
4688 "&& reload_completed"
4689 [(const_int 0)]
4690 {
4691 operands[2] = gen_highpart (SImode, operands[0]);
4692 operands[0] = gen_lowpart (SImode, operands[0]);
4693 rtx tmp = gen_rtx_SET (VOIDmode,
4694 operands[0],
4695 gen_rtx_MINUS (SImode,
4696 const0_rtx,
4697 operands[1]));
4698 if (TARGET_ARM)
4699 {
4700 emit_insn (tmp);
4701 }
4702 else
4703 {
4704 /* Set the flags, to emit the short encoding in Thumb2. */
4705 rtx flags = gen_rtx_SET (VOIDmode,
4706 gen_rtx_REG (CCmode, CC_REGNUM),
4707 gen_rtx_COMPARE (CCmode,
4708 const0_rtx,
4709 operands[1]));
4710 emit_insn (gen_rtx_PARALLEL (VOIDmode,
4711 gen_rtvec (2,
4712 flags,
4713 tmp)));
4714 }
4715 emit_insn (gen_rtx_SET (VOIDmode,
4716 operands[2],
4717 gen_rtx_ASHIFTRT (SImode,
4718 operands[0],
4719 GEN_INT (31))));
4720 DONE;
4721 }
4722 [(set_attr "length" "8,8,4,4")
4723 (set_attr "arch" "a,a,t2,t2")]
4724)
4725
4726(define_insn_and_split "*negdi_zero_extendsidi"
4727 [(set (match_operand:DI 0 "s_register_operand" "=r,&r")
4728 (neg:DI (zero_extend:DI (match_operand:SI 1 "s_register_operand" "0,r"))))
4729 (clobber (reg:CC CC_REGNUM))]
4730 "TARGET_32BIT"
4731 "#" ; "rsbs\\t%Q0, %1, #0\;sbc\\t%R0,%R0,%R0"
4732 ;; Don't care what register is input to sbc,
4733 ;; since we just just need to propagate the carry.
4734 "&& reload_completed"
4735 [(parallel [(set (reg:CC CC_REGNUM)
4736 (compare:CC (const_int 0) (match_dup 1)))
4737 (set (match_dup 0) (minus:SI (const_int 0) (match_dup 1)))])
4738 (set (match_dup 2) (minus:SI (minus:SI (match_dup 2) (match_dup 2))
4739 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
4740 {
4741 operands[2] = gen_highpart (SImode, operands[0]);
4742 operands[0] = gen_lowpart (SImode, operands[0]);
4743 }
4744 [(set_attr "conds" "clob")
4745 (set_attr "length" "8")] ;; length in thumb is 4
4746)
4747
9c08d1fa 4748;; abssi2 doesn't really clobber the condition codes if a different register
4749;; is being set. To keep things simple, assume during rtl manipulations that
4750;; it does, but tell the final scan operator the truth. Similarly for
4751;; (neg (abs...))
4752
604f3a0a 4753(define_expand "abssi2"
4754 [(parallel
4755 [(set (match_operand:SI 0 "s_register_operand" "")
4756 (abs:SI (match_operand:SI 1 "s_register_operand" "")))
ba156559 4757 (clobber (match_dup 2))])]
4758 "TARGET_EITHER"
4759 "
25f905c2 4760 if (TARGET_THUMB1)
ba156559 4761 operands[2] = gen_rtx_SCRATCH (SImode);
4762 else
4763 operands[2] = gen_rtx_REG (CCmode, CC_REGNUM);
4764")
604f3a0a 4765
ba6a3b2f 4766(define_insn_and_split "*arm_abssi2"
ba156559 4767 [(set (match_operand:SI 0 "s_register_operand" "=r,&r")
9c08d1fa 4768 (abs:SI (match_operand:SI 1 "s_register_operand" "0,r")))
bd5b4116 4769 (clobber (reg:CC CC_REGNUM))]
cffb2a26 4770 "TARGET_ARM"
ba6a3b2f 4771 "#"
4772 "&& reload_completed"
4773 [(const_int 0)]
4774 {
4775 /* if (which_alternative == 0) */
4776 if (REGNO(operands[0]) == REGNO(operands[1]))
4777 {
4778 /* Emit the pattern:
4779 cmp\\t%0, #0\;rsblt\\t%0, %0, #0
4780 [(set (reg:CC CC_REGNUM)
4781 (compare:CC (match_dup 0) (const_int 0)))
4782 (cond_exec (lt:CC (reg:CC CC_REGNUM) (const_int 0))
4783 (set (match_dup 0) (minus:SI (const_int 0) (match_dup 1))))]
4784 */
4785 emit_insn (gen_rtx_SET (VOIDmode,
4786 gen_rtx_REG (CCmode, CC_REGNUM),
4787 gen_rtx_COMPARE (CCmode, operands[0], const0_rtx)));
4788 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
4789 (gen_rtx_LT (SImode,
4790 gen_rtx_REG (CCmode, CC_REGNUM),
4791 const0_rtx)),
4792 (gen_rtx_SET (VOIDmode,
4793 operands[0],
4794 (gen_rtx_MINUS (SImode,
4795 const0_rtx,
4796 operands[1]))))));
4797 DONE;
4798 }
4799 else
4800 {
4801 /* Emit the pattern:
4802 alt1: eor%?\\t%0, %1, %1, asr #31\;sub%?\\t%0, %0, %1, asr #31
4803 [(set (match_dup 0)
4804 (xor:SI (match_dup 1)
4805 (ashiftrt:SI (match_dup 1) (const_int 31))))
4806 (set (match_dup 0)
4807 (minus:SI (match_dup 0)
4808 (ashiftrt:SI (match_dup 1) (const_int 31))))]
4809 */
4810 emit_insn (gen_rtx_SET (VOIDmode,
4811 operands[0],
4812 gen_rtx_XOR (SImode,
4813 gen_rtx_ASHIFTRT (SImode,
4814 operands[1],
4815 GEN_INT (31)),
4816 operands[1])));
4817 emit_insn (gen_rtx_SET (VOIDmode,
4818 operands[0],
4819 gen_rtx_MINUS (SImode,
4820 operands[0],
4821 gen_rtx_ASHIFTRT (SImode,
4822 operands[1],
4823 GEN_INT (31)))));
4824 DONE;
4825 }
4826 }
cffb2a26 4827 [(set_attr "conds" "clob,*")
331beb1a 4828 (set_attr "shift" "1")
2ad08b65 4829 (set_attr "predicable" "no, yes")
cffb2a26 4830 (set_attr "length" "8")]
4831)
9c08d1fa 4832
25f905c2 4833(define_insn_and_split "*thumb1_abssi2"
ba156559 4834 [(set (match_operand:SI 0 "s_register_operand" "=l")
4835 (abs:SI (match_operand:SI 1 "s_register_operand" "l")))
4836 (clobber (match_scratch:SI 2 "=&l"))]
25f905c2 4837 "TARGET_THUMB1"
ba156559 4838 "#"
25f905c2 4839 "TARGET_THUMB1 && reload_completed"
ba156559 4840 [(set (match_dup 2) (ashiftrt:SI (match_dup 1) (const_int 31)))
4841 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))
4842 (set (match_dup 0) (xor:SI (match_dup 0) (match_dup 2)))]
4843 ""
4844 [(set_attr "length" "6")]
4845)
4846
ba6a3b2f 4847(define_insn_and_split "*arm_neg_abssi2"
9c08d1fa 4848 [(set (match_operand:SI 0 "s_register_operand" "=r,&r")
4849 (neg:SI (abs:SI (match_operand:SI 1 "s_register_operand" "0,r"))))
bd5b4116 4850 (clobber (reg:CC CC_REGNUM))]
cffb2a26 4851 "TARGET_ARM"
ba6a3b2f 4852 "#"
4853 "&& reload_completed"
4854 [(const_int 0)]
4855 {
4856 /* if (which_alternative == 0) */
4857 if (REGNO (operands[0]) == REGNO (operands[1]))
4858 {
4859 /* Emit the pattern:
4860 cmp\\t%0, #0\;rsbgt\\t%0, %0, #0
4861 */
4862 emit_insn (gen_rtx_SET (VOIDmode,
4863 gen_rtx_REG (CCmode, CC_REGNUM),
4864 gen_rtx_COMPARE (CCmode, operands[0], const0_rtx)));
4865 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
4866 gen_rtx_GT (SImode,
4867 gen_rtx_REG (CCmode, CC_REGNUM),
4868 const0_rtx),
4869 gen_rtx_SET (VOIDmode,
4870 operands[0],
4871 (gen_rtx_MINUS (SImode,
4872 const0_rtx,
4873 operands[1])))));
4874 }
4875 else
4876 {
4877 /* Emit the pattern:
4878 eor%?\\t%0, %1, %1, asr #31\;rsb%?\\t%0, %0, %1, asr #31
4879 */
4880 emit_insn (gen_rtx_SET (VOIDmode,
4881 operands[0],
4882 gen_rtx_XOR (SImode,
4883 gen_rtx_ASHIFTRT (SImode,
4884 operands[1],
4885 GEN_INT (31)),
4886 operands[1])));
4887 emit_insn (gen_rtx_SET (VOIDmode,
4888 operands[0],
4889 gen_rtx_MINUS (SImode,
4890 gen_rtx_ASHIFTRT (SImode,
4891 operands[1],
4892 GEN_INT (31)),
4893 operands[0])));
4894 }
4895 DONE;
4896 }
cffb2a26 4897 [(set_attr "conds" "clob,*")
331beb1a 4898 (set_attr "shift" "1")
2ad08b65 4899 (set_attr "predicable" "no, yes")
cffb2a26 4900 (set_attr "length" "8")]
4901)
b11cae9e 4902
25f905c2 4903(define_insn_and_split "*thumb1_neg_abssi2"
ba156559 4904 [(set (match_operand:SI 0 "s_register_operand" "=l")
4905 (neg:SI (abs:SI (match_operand:SI 1 "s_register_operand" "l"))))
4906 (clobber (match_scratch:SI 2 "=&l"))]
25f905c2 4907 "TARGET_THUMB1"
ba156559 4908 "#"
25f905c2 4909 "TARGET_THUMB1 && reload_completed"
ba156559 4910 [(set (match_dup 2) (ashiftrt:SI (match_dup 1) (const_int 31)))
4911 (set (match_dup 0) (minus:SI (match_dup 2) (match_dup 1)))
4912 (set (match_dup 0) (xor:SI (match_dup 0) (match_dup 2)))]
4913 ""
4914 [(set_attr "length" "6")]
4915)
4916
604f3a0a 4917(define_expand "abssf2"
4918 [(set (match_operand:SF 0 "s_register_operand" "")
4919 (abs:SF (match_operand:SF 1 "s_register_operand" "")))]
25f905c2 4920 "TARGET_32BIT && TARGET_HARD_FLOAT"
604f3a0a 4921 "")
4922
604f3a0a 4923(define_expand "absdf2"
4924 [(set (match_operand:DF 0 "s_register_operand" "")
4925 (abs:DF (match_operand:DF 1 "s_register_operand" "")))]
a50d7267 4926 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
604f3a0a 4927 "")
4928
7db9af5d 4929(define_expand "sqrtsf2"
4930 [(set (match_operand:SF 0 "s_register_operand" "")
4931 (sqrt:SF (match_operand:SF 1 "s_register_operand" "")))]
994606f8 4932 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
7db9af5d 4933 "")
9c08d1fa 4934
7db9af5d 4935(define_expand "sqrtdf2"
4936 [(set (match_operand:DF 0 "s_register_operand" "")
4937 (sqrt:DF (match_operand:DF 1 "s_register_operand" "")))]
994606f8 4938 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
7db9af5d 4939 "")
9c08d1fa 4940
a0f94409 4941(define_insn_and_split "one_cmpldi2"
10efb95f 4942 [(set (match_operand:DI 0 "s_register_operand" "=w,&r,&r,?w")
4943 (not:DI (match_operand:DI 1 "s_register_operand" " w, 0, r, w")))]
25f905c2 4944 "TARGET_32BIT"
10efb95f 4945 "@
4946 vmvn\t%P0, %P1
4947 #
4948 #
4949 vmvn\t%P0, %P1"
4950 "TARGET_32BIT && reload_completed
4951 && arm_general_register_operand (operands[0], DImode)"
a0f94409 4952 [(set (match_dup 0) (not:SI (match_dup 1)))
4953 (set (match_dup 2) (not:SI (match_dup 3)))]
4954 "
4955 {
4956 operands[2] = gen_highpart (SImode, operands[0]);
4957 operands[0] = gen_lowpart (SImode, operands[0]);
4958 operands[3] = gen_highpart (SImode, operands[1]);
4959 operands[1] = gen_lowpart (SImode, operands[1]);
4960 }"
10efb95f 4961 [(set_attr "length" "*,8,8,*")
4962 (set_attr "predicable" "no,yes,yes,no")
4963 (set_attr "neon_type" "neon_int_1,*,*,neon_int_1")
b6779ddc 4964 (set_attr "arch" "neon_for_64bits,*,*,avoid_neon_for_64bits")]
cffb2a26 4965)
b11cae9e 4966
cffb2a26 4967(define_expand "one_cmplsi2"
4968 [(set (match_operand:SI 0 "s_register_operand" "")
4969 (not:SI (match_operand:SI 1 "s_register_operand" "")))]
4970 "TARGET_EITHER"
b11cae9e 4971 ""
cffb2a26 4972)
4973
4974(define_insn "*arm_one_cmplsi2"
d952d547 4975 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
4976 (not:SI (match_operand:SI 1 "s_register_operand" "l,r")))]
25f905c2 4977 "TARGET_32BIT"
cffb2a26 4978 "mvn%?\\t%0, %1"
d2a518d1 4979 [(set_attr "predicable" "yes")
d952d547 4980 (set_attr "predicable_short_it" "yes,no")
4981 (set_attr "arch" "t2,*")
4982 (set_attr "length" "4")
1aed5204 4983 (set_attr "type" "mvn_reg")]
cffb2a26 4984)
4985
25f905c2 4986(define_insn "*thumb1_one_cmplsi2"
cffb2a26 4987 [(set (match_operand:SI 0 "register_operand" "=l")
4988 (not:SI (match_operand:SI 1 "register_operand" "l")))]
25f905c2 4989 "TARGET_THUMB1"
cffb2a26 4990 "mvn\\t%0, %1"
d2a518d1 4991 [(set_attr "length" "2")
1aed5204 4992 (set_attr "type" "mvn_reg")]
cffb2a26 4993)
9c08d1fa 4994
f7fbdd4a 4995(define_insn "*notsi_compare0"
bd5b4116 4996 [(set (reg:CC_NOOV CC_REGNUM)
9c08d1fa 4997 (compare:CC_NOOV (not:SI (match_operand:SI 1 "s_register_operand" "r"))
4998 (const_int 0)))
4999 (set (match_operand:SI 0 "s_register_operand" "=r")
5000 (not:SI (match_dup 1)))]
25f905c2 5001 "TARGET_32BIT"
5002 "mvn%.\\t%0, %1"
d2a518d1 5003 [(set_attr "conds" "set")
1aed5204 5004 (set_attr "type" "mvn_reg")]
cffb2a26 5005)
9c08d1fa 5006
f7fbdd4a 5007(define_insn "*notsi_compare0_scratch"
bd5b4116 5008 [(set (reg:CC_NOOV CC_REGNUM)
9c08d1fa 5009 (compare:CC_NOOV (not:SI (match_operand:SI 1 "s_register_operand" "r"))
5010 (const_int 0)))
5011 (clobber (match_scratch:SI 0 "=r"))]
25f905c2 5012 "TARGET_32BIT"
5013 "mvn%.\\t%0, %1"
d2a518d1 5014 [(set_attr "conds" "set")
1aed5204 5015 (set_attr "type" "mvn_reg")]
cffb2a26 5016)
b11cae9e 5017\f
5018;; Fixed <--> Floating conversion insns
5019
9b8516be 5020(define_expand "floatsihf2"
5021 [(set (match_operand:HF 0 "general_operand" "")
5022 (float:HF (match_operand:SI 1 "general_operand" "")))]
5023 "TARGET_EITHER"
5024 "
5025 {
5026 rtx op1 = gen_reg_rtx (SFmode);
5027 expand_float (op1, operands[1], 0);
5028 op1 = convert_to_mode (HFmode, op1, 0);
5029 emit_move_insn (operands[0], op1);
5030 DONE;
5031 }"
5032)
5033
5034(define_expand "floatdihf2"
5035 [(set (match_operand:HF 0 "general_operand" "")
5036 (float:HF (match_operand:DI 1 "general_operand" "")))]
5037 "TARGET_EITHER"
5038 "
5039 {
5040 rtx op1 = gen_reg_rtx (SFmode);
5041 expand_float (op1, operands[1], 0);
5042 op1 = convert_to_mode (HFmode, op1, 0);
5043 emit_move_insn (operands[0], op1);
5044 DONE;
5045 }"
5046)
5047
604f3a0a 5048(define_expand "floatsisf2"
5049 [(set (match_operand:SF 0 "s_register_operand" "")
5050 (float:SF (match_operand:SI 1 "s_register_operand" "")))]
25f905c2 5051 "TARGET_32BIT && TARGET_HARD_FLOAT"
604f3a0a 5052 "
604f3a0a 5053")
5054
604f3a0a 5055(define_expand "floatsidf2"
5056 [(set (match_operand:DF 0 "s_register_operand" "")
5057 (float:DF (match_operand:SI 1 "s_register_operand" "")))]
a50d7267 5058 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
604f3a0a 5059 "
604f3a0a 5060")
5061
9b8516be 5062(define_expand "fix_trunchfsi2"
5063 [(set (match_operand:SI 0 "general_operand" "")
5064 (fix:SI (fix:HF (match_operand:HF 1 "general_operand" ""))))]
5065 "TARGET_EITHER"
5066 "
5067 {
5068 rtx op1 = convert_to_mode (SFmode, operands[1], 0);
5069 expand_fix (operands[0], op1, 0);
5070 DONE;
5071 }"
5072)
5073
5074(define_expand "fix_trunchfdi2"
5075 [(set (match_operand:DI 0 "general_operand" "")
5076 (fix:DI (fix:HF (match_operand:HF 1 "general_operand" ""))))]
5077 "TARGET_EITHER"
5078 "
5079 {
5080 rtx op1 = convert_to_mode (SFmode, operands[1], 0);
5081 expand_fix (operands[0], op1, 0);
5082 DONE;
5083 }"
5084)
5085
604f3a0a 5086(define_expand "fix_truncsfsi2"
5087 [(set (match_operand:SI 0 "s_register_operand" "")
a33d5c9c 5088 (fix:SI (fix:SF (match_operand:SF 1 "s_register_operand" ""))))]
25f905c2 5089 "TARGET_32BIT && TARGET_HARD_FLOAT"
604f3a0a 5090 "
604f3a0a 5091")
5092
604f3a0a 5093(define_expand "fix_truncdfsi2"
5094 [(set (match_operand:SI 0 "s_register_operand" "")
a33d5c9c 5095 (fix:SI (fix:DF (match_operand:DF 1 "s_register_operand" ""))))]
a50d7267 5096 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
604f3a0a 5097 "
604f3a0a 5098")
5099
f544c6d2 5100;; Truncation insns
b11cae9e 5101
604f3a0a 5102(define_expand "truncdfsf2"
5103 [(set (match_operand:SF 0 "s_register_operand" "")
5104 (float_truncate:SF
5105 (match_operand:DF 1 "s_register_operand" "")))]
a50d7267 5106 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
604f3a0a 5107 ""
5108)
9b8516be 5109
5110/* DFmode -> HFmode conversions have to go through SFmode. */
5111(define_expand "truncdfhf2"
5112 [(set (match_operand:HF 0 "general_operand" "")
5113 (float_truncate:HF
5114 (match_operand:DF 1 "general_operand" "")))]
5115 "TARGET_EITHER"
5116 "
5117 {
5118 rtx op1;
5119 op1 = convert_to_mode (SFmode, operands[1], 0);
5120 op1 = convert_to_mode (HFmode, op1, 0);
5121 emit_move_insn (operands[0], op1);
5122 DONE;
5123 }"
5124)
b11cae9e 5125\f
9c08d1fa 5126;; Zero and sign extension instructions.
b11cae9e 5127
848e66ac 5128(define_insn "zero_extend<mode>di2"
6aa689e8 5129 [(set (match_operand:DI 0 "s_register_operand" "=w,r,?r,w")
6d97728e 5130 (zero_extend:DI (match_operand:QHSI 1 "<qhs_zextenddi_op>"
5131 "<qhs_zextenddi_cstr>")))]
848e66ac 5132 "TARGET_32BIT <qhs_zextenddi_cond>"
5133 "#"
6aa689e8 5134 [(set_attr "length" "8,4,8,8")
b6779ddc 5135 (set_attr "arch" "neon_for_64bits,*,*,avoid_neon_for_64bits")
848e66ac 5136 (set_attr "ce_count" "2")
5137 (set_attr "predicable" "yes")]
25f905c2 5138)
5139
848e66ac 5140(define_insn "extend<mode>di2"
6aa689e8 5141 [(set (match_operand:DI 0 "s_register_operand" "=w,r,?r,?r,w")
63d204a8 5142 (sign_extend:DI (match_operand:QHSI 1 "<qhs_extenddi_op>"
5143 "<qhs_extenddi_cstr>")))]
848e66ac 5144 "TARGET_32BIT <qhs_sextenddi_cond>"
5145 "#"
6aa689e8 5146 [(set_attr "length" "8,4,8,8,8")
848e66ac 5147 (set_attr "ce_count" "2")
5148 (set_attr "shift" "1")
8012d2c2 5149 (set_attr "predicable" "yes")
b6779ddc 5150 (set_attr "arch" "neon_for_64bits,*,a,t,avoid_neon_for_64bits")]
0d66636f 5151)
9c08d1fa 5152
848e66ac 5153;; Splits for all extensions to DImode
5154(define_split
5155 [(set (match_operand:DI 0 "s_register_operand" "")
5156 (zero_extend:DI (match_operand 1 "nonimmediate_operand" "")))]
6aa689e8 5157 "TARGET_32BIT && reload_completed && !IS_VFP_REGNUM (REGNO (operands[0]))"
848e66ac 5158 [(set (match_dup 0) (match_dup 1))]
5159{
848e66ac 5160 rtx lo_part = gen_lowpart (SImode, operands[0]);
5161 enum machine_mode src_mode = GET_MODE (operands[1]);
5162
5163 if (REG_P (operands[0])
5164 && !reg_overlap_mentioned_p (operands[0], operands[1]))
5165 emit_clobber (operands[0]);
5166 if (!REG_P (lo_part) || src_mode != SImode
5167 || !rtx_equal_p (lo_part, operands[1]))
5168 {
5169 if (src_mode == SImode)
5170 emit_move_insn (lo_part, operands[1]);
5171 else
5172 emit_insn (gen_rtx_SET (VOIDmode, lo_part,
5173 gen_rtx_ZERO_EXTEND (SImode, operands[1])));
5174 operands[1] = lo_part;
5175 }
5176 operands[0] = gen_highpart (SImode, operands[0]);
5177 operands[1] = const0_rtx;
5178})
9c08d1fa 5179
848e66ac 5180(define_split
25f905c2 5181 [(set (match_operand:DI 0 "s_register_operand" "")
848e66ac 5182 (sign_extend:DI (match_operand 1 "nonimmediate_operand" "")))]
6aa689e8 5183 "TARGET_32BIT && reload_completed && !IS_VFP_REGNUM (REGNO (operands[0]))"
848e66ac 5184 [(set (match_dup 0) (ashiftrt:SI (match_dup 1) (const_int 31)))]
5185{
5186 rtx lo_part = gen_lowpart (SImode, operands[0]);
5187 enum machine_mode src_mode = GET_MODE (operands[1]);
25f905c2 5188
848e66ac 5189 if (REG_P (operands[0])
5190 && !reg_overlap_mentioned_p (operands[0], operands[1]))
5191 emit_clobber (operands[0]);
5192
5193 if (!REG_P (lo_part) || src_mode != SImode
5194 || !rtx_equal_p (lo_part, operands[1]))
5195 {
5196 if (src_mode == SImode)
5197 emit_move_insn (lo_part, operands[1]);
5198 else
5199 emit_insn (gen_rtx_SET (VOIDmode, lo_part,
5200 gen_rtx_SIGN_EXTEND (SImode, operands[1])));
5201 operands[1] = lo_part;
5202 }
5203 operands[0] = gen_highpart (SImode, operands[0]);
5204})
9c08d1fa 5205
5206(define_expand "zero_extendhisi2"
ef51b8e1 5207 [(set (match_operand:SI 0 "s_register_operand" "")
5208 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
cffb2a26 5209 "TARGET_EITHER"
ef51b8e1 5210{
5211 if (TARGET_ARM && !arm_arch4 && MEM_P (operands[1]))
f7fbdd4a 5212 {
ef51b8e1 5213 emit_insn (gen_movhi_bytes (operands[0], operands[1]));
5214 DONE;
25f7a26e 5215 }
ef51b8e1 5216 if (!arm_arch6 && !MEM_P (operands[1]))
5217 {
5218 rtx t = gen_lowpart (SImode, operands[1]);
5219 rtx tmp = gen_reg_rtx (SImode);
5220 emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (16)));
5221 emit_insn (gen_lshrsi3 (operands[0], tmp, GEN_INT (16)));
5222 DONE;
5223 }
5224})
9c08d1fa 5225
ef51b8e1 5226(define_split
b146458f 5227 [(set (match_operand:SI 0 "s_register_operand" "")
5228 (zero_extend:SI (match_operand:HI 1 "s_register_operand" "")))]
ef51b8e1 5229 "!TARGET_THUMB2 && !arm_arch6"
5230 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
5231 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 16)))]
5232{
5233 operands[2] = gen_lowpart (SImode, operands[1]);
5234})
5235
5236(define_insn "*thumb1_zero_extendhisi2"
a2cd141b 5237 [(set (match_operand:SI 0 "register_operand" "=l,l")
5238 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "l,m")))]
ef51b8e1 5239 "TARGET_THUMB1"
848e66ac 5240{
a2cd141b 5241 rtx mem;
5242
ef51b8e1 5243 if (which_alternative == 0 && arm_arch6)
848e66ac 5244 return "uxth\t%0, %1";
ef51b8e1 5245 if (which_alternative == 0)
848e66ac 5246 return "#";
a2cd141b 5247
5248 mem = XEXP (operands[1], 0);
5249
5250 if (GET_CODE (mem) == CONST)
5251 mem = XEXP (mem, 0);
5252
a2cd141b 5253 if (GET_CODE (mem) == PLUS)
5254 {
5255 rtx a = XEXP (mem, 0);
a2cd141b 5256
5257 /* This can happen due to bugs in reload. */
0438d37f 5258 if (REG_P (a) && REGNO (a) == SP_REGNUM)
a2cd141b 5259 {
5260 rtx ops[2];
5261 ops[0] = operands[0];
5262 ops[1] = a;
5263
848e66ac 5264 output_asm_insn ("mov\t%0, %1", ops);
a2cd141b 5265
5266 XEXP (mem, 0) = operands[0];
5267 }
a2cd141b 5268 }
5269
848e66ac 5270 return "ldrh\t%0, %1";
5271}
ef51b8e1 5272 [(set_attr_alternative "length"
5273 [(if_then_else (eq_attr "is_arch6" "yes")
5274 (const_int 2) (const_int 4))
5275 (const_int 4)])
6b6abc9c 5276 (set_attr "type" "extend,load_byte")]
a2cd141b 5277)
5278
cffb2a26 5279(define_insn "*arm_zero_extendhisi2"
ef51b8e1 5280 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5281 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
a2cd141b 5282 "TARGET_ARM && arm_arch4 && !arm_arch6"
ef51b8e1 5283 "@
5284 #
5285 ldr%(h%)\\t%0, %1"
6b6abc9c 5286 [(set_attr "type" "arlo_shift,load_byte")
848e66ac 5287 (set_attr "predicable" "yes")]
cffb2a26 5288)
f7fbdd4a 5289
a2cd141b 5290(define_insn "*arm_zero_extendhisi2_v6"
5291 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5292 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
5293 "TARGET_ARM && arm_arch6"
5294 "@
5295 uxth%?\\t%0, %1
25f905c2 5296 ldr%(h%)\\t%0, %1"
65f68e55 5297 [(set_attr "predicable" "yes")
6b6abc9c 5298 (set_attr "type" "extend,load_byte")]
a2cd141b 5299)
5300
5301(define_insn "*arm_zero_extendhisi2addsi"
5302 [(set (match_operand:SI 0 "s_register_operand" "=r")
5303 (plus:SI (zero_extend:SI (match_operand:HI 1 "s_register_operand" "r"))
5304 (match_operand:SI 2 "s_register_operand" "r")))]
25f905c2 5305 "TARGET_INT_SIMD"
a2cd141b 5306 "uxtah%?\\t%0, %2, %1"
6b6abc9c 5307 [(set_attr "type" "arlo_shift")
d952d547 5308 (set_attr "predicable" "yes")
5309 (set_attr "predicable_short_it" "no")]
a2cd141b 5310)
5311
87b22bf7 5312(define_expand "zero_extendqisi2"
cffb2a26 5313 [(set (match_operand:SI 0 "s_register_operand" "")
5314 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))]
5315 "TARGET_EITHER"
ef51b8e1 5316{
0438d37f 5317 if (TARGET_ARM && !arm_arch6 && !MEM_P (operands[1]))
87b22bf7 5318 {
ef51b8e1 5319 emit_insn (gen_andsi3 (operands[0],
5320 gen_lowpart (SImode, operands[1]),
5321 GEN_INT (255)));
5322 DONE;
5323 }
5324 if (!arm_arch6 && !MEM_P (operands[1]))
5325 {
5326 rtx t = gen_lowpart (SImode, operands[1]);
5327 rtx tmp = gen_reg_rtx (SImode);
5328 emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (24)));
5329 emit_insn (gen_lshrsi3 (operands[0], tmp, GEN_INT (24)));
5330 DONE;
5331 }
5332})
cffb2a26 5333
ef51b8e1 5334(define_split
b146458f 5335 [(set (match_operand:SI 0 "s_register_operand" "")
5336 (zero_extend:SI (match_operand:QI 1 "s_register_operand" "")))]
ef51b8e1 5337 "!arm_arch6"
5338 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 24)))
5339 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 24)))]
5340{
5341 operands[2] = simplify_gen_subreg (SImode, operands[1], QImode, 0);
5342 if (TARGET_ARM)
5343 {
5344 emit_insn (gen_andsi3 (operands[0], operands[2], GEN_INT (255)));
87b22bf7 5345 DONE;
5346 }
ef51b8e1 5347})
9c08d1fa 5348
25f905c2 5349(define_insn "*thumb1_zero_extendqisi2"
ef51b8e1 5350 [(set (match_operand:SI 0 "register_operand" "=l,l")
5351 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "l,m")))]
25f905c2 5352 "TARGET_THUMB1 && !arm_arch6"
ef51b8e1 5353 "@
5354 #
5355 ldrb\\t%0, %1"
5356 [(set_attr "length" "4,2")
6b6abc9c 5357 (set_attr "type" "arlo_shift,load_byte")
ef51b8e1 5358 (set_attr "pool_range" "*,32")]
cffb2a26 5359)
5360
25f905c2 5361(define_insn "*thumb1_zero_extendqisi2_v6"
a2cd141b 5362 [(set (match_operand:SI 0 "register_operand" "=l,l")
5363 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "l,m")))]
25f905c2 5364 "TARGET_THUMB1 && arm_arch6"
a2cd141b 5365 "@
5366 uxtb\\t%0, %1
5367 ldrb\\t%0, %1"
848e66ac 5368 [(set_attr "length" "2")
6b6abc9c 5369 (set_attr "type" "extend,load_byte")]
a2cd141b 5370)
5371
cffb2a26 5372(define_insn "*arm_zero_extendqisi2"
ef51b8e1 5373 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5374 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
a2cd141b 5375 "TARGET_ARM && !arm_arch6"
ef51b8e1 5376 "@
5377 #
5378 ldr%(b%)\\t%0, %1\\t%@ zero_extendqisi2"
5379 [(set_attr "length" "8,4")
6b6abc9c 5380 (set_attr "type" "arlo_shift,load_byte")
848e66ac 5381 (set_attr "predicable" "yes")]
cffb2a26 5382)
87b22bf7 5383
a2cd141b 5384(define_insn "*arm_zero_extendqisi2_v6"
5385 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5386 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
5387 "TARGET_ARM && arm_arch6"
5388 "@
25f905c2 5389 uxtb%(%)\\t%0, %1
5390 ldr%(b%)\\t%0, %1\\t%@ zero_extendqisi2"
6b6abc9c 5391 [(set_attr "type" "extend,load_byte")
848e66ac 5392 (set_attr "predicable" "yes")]
a2cd141b 5393)
5394
5395(define_insn "*arm_zero_extendqisi2addsi"
5396 [(set (match_operand:SI 0 "s_register_operand" "=r")
5397 (plus:SI (zero_extend:SI (match_operand:QI 1 "s_register_operand" "r"))
5398 (match_operand:SI 2 "s_register_operand" "r")))]
25f905c2 5399 "TARGET_INT_SIMD"
a2cd141b 5400 "uxtab%?\\t%0, %2, %1"
5401 [(set_attr "predicable" "yes")
d952d547 5402 (set_attr "predicable_short_it" "no")
6b6abc9c 5403 (set_attr "type" "arlo_shift")]
a2cd141b 5404)
5405
87b22bf7 5406(define_split
5407 [(set (match_operand:SI 0 "s_register_operand" "")
5408 (zero_extend:SI (subreg:QI (match_operand:SI 1 "" "") 0)))
5409 (clobber (match_operand:SI 2 "s_register_operand" ""))]
0438d37f 5410 "TARGET_32BIT && (!MEM_P (operands[1])) && ! BYTES_BIG_ENDIAN"
87b22bf7 5411 [(set (match_dup 2) (match_dup 1))
5412 (set (match_dup 0) (and:SI (match_dup 2) (const_int 255)))]
cffb2a26 5413 ""
5414)
9c08d1fa 5415
8a4d25d6 5416(define_split
5417 [(set (match_operand:SI 0 "s_register_operand" "")
5418 (zero_extend:SI (subreg:QI (match_operand:SI 1 "" "") 3)))
5419 (clobber (match_operand:SI 2 "s_register_operand" ""))]
0438d37f 5420 "TARGET_32BIT && (!MEM_P (operands[1])) && BYTES_BIG_ENDIAN"
8a4d25d6 5421 [(set (match_dup 2) (match_dup 1))
5422 (set (match_dup 0) (and:SI (match_dup 2) (const_int 255)))]
5423 ""
5424)
5425
1c274529 5426
5427(define_split
5428 [(set (match_operand:SI 0 "s_register_operand" "")
5429 (ior_xor:SI (and:SI (ashift:SI
5430 (match_operand:SI 1 "s_register_operand" "")
5431 (match_operand:SI 2 "const_int_operand" ""))
5432 (match_operand:SI 3 "const_int_operand" ""))
5433 (zero_extend:SI
5434 (match_operator 5 "subreg_lowpart_operator"
5435 [(match_operand:SI 4 "s_register_operand" "")]))))]
5436 "TARGET_32BIT
63787642 5437 && ((unsigned HOST_WIDE_INT) INTVAL (operands[3])
1c274529 5438 == (GET_MODE_MASK (GET_MODE (operands[5]))
5439 & (GET_MODE_MASK (GET_MODE (operands[5]))
5440 << (INTVAL (operands[2])))))"
5441 [(set (match_dup 0) (ior_xor:SI (ashift:SI (match_dup 1) (match_dup 2))
5442 (match_dup 4)))
5443 (set (match_dup 0) (zero_extend:SI (match_dup 5)))]
5444 "operands[5] = gen_lowpart (GET_MODE (operands[5]), operands[0]);"
5445)
5446
f7fbdd4a 5447(define_insn "*compareqi_eq0"
bd5b4116 5448 [(set (reg:CC_Z CC_REGNUM)
206ee9a2 5449 (compare:CC_Z (match_operand:QI 0 "s_register_operand" "r")
87b22bf7 5450 (const_int 0)))]
25f905c2 5451 "TARGET_32BIT"
596e5e8f 5452 "tst%?\\t%0, #255"
5453 [(set_attr "conds" "set")
d952d547 5454 (set_attr "predicable" "yes")
5455 (set_attr "predicable_short_it" "no")]
cffb2a26 5456)
b11cae9e 5457
b11cae9e 5458(define_expand "extendhisi2"
ef51b8e1 5459 [(set (match_operand:SI 0 "s_register_operand" "")
5460 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
cffb2a26 5461 "TARGET_EITHER"
ef51b8e1 5462{
5463 if (TARGET_THUMB1)
5464 {
5465 emit_insn (gen_thumb1_extendhisi2 (operands[0], operands[1]));
5466 DONE;
5467 }
5468 if (MEM_P (operands[1]) && TARGET_ARM && !arm_arch4)
5469 {
5470 emit_insn (gen_extendhisi2_mem (operands[0], operands[1]));
5471 DONE;
5472 }
ed29c566 5473
ef51b8e1 5474 if (!arm_arch6 && !MEM_P (operands[1]))
5475 {
5476 rtx t = gen_lowpart (SImode, operands[1]);
5477 rtx tmp = gen_reg_rtx (SImode);
5478 emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (16)));
5479 emit_insn (gen_ashrsi3 (operands[0], tmp, GEN_INT (16)));
5480 DONE;
5481 }
5482})
cffb2a26 5483
ef51b8e1 5484(define_split
5485 [(parallel
5486 [(set (match_operand:SI 0 "register_operand" "")
5487 (sign_extend:SI (match_operand:HI 1 "register_operand" "")))
5488 (clobber (match_scratch:SI 2 ""))])]
5489 "!arm_arch6"
5490 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
5491 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 16)))]
5492{
5493 operands[2] = simplify_gen_subreg (SImode, operands[1], HImode, 0);
5494})
25f7a26e 5495
a2cd141b 5496;; We used to have an early-clobber on the scratch register here.
5497;; However, there's a bug somewhere in reload which means that this
5498;; can be partially ignored during spill allocation if the memory
ed29c566 5499;; address also needs reloading; this causes us to die later on when
a2cd141b 5500;; we try to verify the operands. Fortunately, we don't really need
5501;; the early-clobber: we can always use operand 0 if operand 2
5502;; overlaps the address.
ef51b8e1 5503(define_insn "thumb1_extendhisi2"
a2cd141b 5504 [(set (match_operand:SI 0 "register_operand" "=l,l")
5505 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "l,m")))
5506 (clobber (match_scratch:SI 2 "=X,l"))]
ef51b8e1 5507 "TARGET_THUMB1"
a2cd141b 5508 "*
5509 {
5510 rtx ops[4];
5511 rtx mem;
5512
ef51b8e1 5513 if (which_alternative == 0 && !arm_arch6)
5514 return \"#\";
a2cd141b 5515 if (which_alternative == 0)
5516 return \"sxth\\t%0, %1\";
5517
5518 mem = XEXP (operands[1], 0);
5519
5520 /* This code used to try to use 'V', and fix the address only if it was
5521 offsettable, but this fails for e.g. REG+48 because 48 is outside the
5522 range of QImode offsets, and offsettable_address_p does a QImode
5523 address check. */
5524
5525 if (GET_CODE (mem) == CONST)
5526 mem = XEXP (mem, 0);
5527
5528 if (GET_CODE (mem) == LABEL_REF)
5529 return \"ldr\\t%0, %1\";
5530
5531 if (GET_CODE (mem) == PLUS)
5532 {
5533 rtx a = XEXP (mem, 0);
5534 rtx b = XEXP (mem, 1);
5535
5536 if (GET_CODE (a) == LABEL_REF
0438d37f 5537 && CONST_INT_P (b))
a2cd141b 5538 return \"ldr\\t%0, %1\";
5539
0438d37f 5540 if (REG_P (b))
a2cd141b 5541 return \"ldrsh\\t%0, %1\";
5542
5543 ops[1] = a;
5544 ops[2] = b;
5545 }
5546 else
5547 {
5548 ops[1] = mem;
5549 ops[2] = const0_rtx;
5550 }
5551
0438d37f 5552 gcc_assert (REG_P (ops[1]));
a2cd141b 5553
5554 ops[0] = operands[0];
5555 if (reg_mentioned_p (operands[2], ops[1]))
5556 ops[3] = ops[0];
5557 else
5558 ops[3] = operands[2];
5559 output_asm_insn (\"mov\\t%3, %2\;ldrsh\\t%0, [%1, %3]\", ops);
5560 return \"\";
5561 }"
ef51b8e1 5562 [(set_attr_alternative "length"
5563 [(if_then_else (eq_attr "is_arch6" "yes")
5564 (const_int 2) (const_int 4))
5565 (const_int 4)])
6b6abc9c 5566 (set_attr "type" "extend,load_byte")
42e1de19 5567 (set_attr "pool_range" "*,1018")]
a2cd141b 5568)
5569
25f905c2 5570;; This pattern will only be used when ldsh is not available
25f7a26e 5571(define_expand "extendhisi2_mem"
eab14235 5572 [(set (match_dup 2) (zero_extend:SI (match_operand:HI 1 "" "")))
25f7a26e 5573 (set (match_dup 3)
eab14235 5574 (zero_extend:SI (match_dup 7)))
25f7a26e 5575 (set (match_dup 6) (ashift:SI (match_dup 4) (const_int 24)))
5576 (set (match_operand:SI 0 "" "")
5577 (ior:SI (ashiftrt:SI (match_dup 6) (const_int 16)) (match_dup 5)))]
cffb2a26 5578 "TARGET_ARM"
25f7a26e 5579 "
215b30b3 5580 {
5581 rtx mem1, mem2;
5582 rtx addr = copy_to_mode_reg (SImode, XEXP (operands[1], 0));
5583
788fcce0 5584 mem1 = change_address (operands[1], QImode, addr);
29c05e22 5585 mem2 = change_address (operands[1], QImode,
5586 plus_constant (Pmode, addr, 1));
215b30b3 5587 operands[0] = gen_lowpart (SImode, operands[0]);
5588 operands[1] = mem1;
5589 operands[2] = gen_reg_rtx (SImode);
5590 operands[3] = gen_reg_rtx (SImode);
5591 operands[6] = gen_reg_rtx (SImode);
5592 operands[7] = mem2;
25f7a26e 5593
215b30b3 5594 if (BYTES_BIG_ENDIAN)
5595 {
5596 operands[4] = operands[2];
5597 operands[5] = operands[3];
5598 }
5599 else
5600 {
5601 operands[4] = operands[3];
5602 operands[5] = operands[2];
5603 }
5604 }"
5605)
b11cae9e 5606
ef51b8e1 5607(define_split
5608 [(set (match_operand:SI 0 "register_operand" "")
5609 (sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
5610 "!arm_arch6"
5611 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
5612 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 16)))]
5613{
5614 operands[2] = simplify_gen_subreg (SImode, operands[1], HImode, 0);
5615})
5616
a2cd141b 5617(define_insn "*arm_extendhisi2"
ef51b8e1 5618 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5619 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
a2cd141b 5620 "TARGET_ARM && arm_arch4 && !arm_arch6"
ef51b8e1 5621 "@
5622 #
5623 ldr%(sh%)\\t%0, %1"
5624 [(set_attr "length" "8,4")
6b6abc9c 5625 (set_attr "type" "arlo_shift,load_byte")
0d66636f 5626 (set_attr "predicable" "yes")
ef51b8e1 5627 (set_attr "pool_range" "*,256")
5628 (set_attr "neg_pool_range" "*,244")]
cffb2a26 5629)
f7fbdd4a 5630
25f905c2 5631;; ??? Check Thumb-2 pool range
a2cd141b 5632(define_insn "*arm_extendhisi2_v6"
5633 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5634 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
25f905c2 5635 "TARGET_32BIT && arm_arch6"
a2cd141b 5636 "@
5637 sxth%?\\t%0, %1
25f905c2 5638 ldr%(sh%)\\t%0, %1"
6b6abc9c 5639 [(set_attr "type" "extend,load_byte")
a2cd141b 5640 (set_attr "predicable" "yes")
d952d547 5641 (set_attr "predicable_short_it" "no")
a2cd141b 5642 (set_attr "pool_range" "*,256")
5643 (set_attr "neg_pool_range" "*,244")]
5644)
5645
5646(define_insn "*arm_extendhisi2addsi"
5647 [(set (match_operand:SI 0 "s_register_operand" "=r")
5648 (plus:SI (sign_extend:SI (match_operand:HI 1 "s_register_operand" "r"))
5649 (match_operand:SI 2 "s_register_operand" "r")))]
25f905c2 5650 "TARGET_INT_SIMD"
a2cd141b 5651 "sxtah%?\\t%0, %2, %1"
5652)
5653
c8f69309 5654(define_expand "extendqihi2"
5655 [(set (match_dup 2)
bed7d9a5 5656 (ashift:SI (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "")
c8f69309 5657 (const_int 24)))
9c08d1fa 5658 (set (match_operand:HI 0 "s_register_operand" "")
c8f69309 5659 (ashiftrt:SI (match_dup 2)
5660 (const_int 24)))]
cffb2a26 5661 "TARGET_ARM"
c8f69309 5662 "
215b30b3 5663 {
0438d37f 5664 if (arm_arch4 && MEM_P (operands[1]))
215b30b3 5665 {
5666 emit_insn (gen_rtx_SET (VOIDmode,
5667 operands[0],
5668 gen_rtx_SIGN_EXTEND (HImode, operands[1])));
5669 DONE;
5670 }
5671 if (!s_register_operand (operands[1], QImode))
5672 operands[1] = copy_to_mode_reg (QImode, operands[1]);
5673 operands[0] = gen_lowpart (SImode, operands[0]);
5674 operands[1] = gen_lowpart (SImode, operands[1]);
5675 operands[2] = gen_reg_rtx (SImode);
5676 }"
5677)
f7fbdd4a 5678
25f905c2 5679(define_insn "*arm_extendqihi_insn"
b4e8a300 5680 [(set (match_operand:HI 0 "s_register_operand" "=r")
bed7d9a5 5681 (sign_extend:HI (match_operand:QI 1 "arm_extendqisi_mem_op" "Uq")))]
cffb2a26 5682 "TARGET_ARM && arm_arch4"
25f905c2 5683 "ldr%(sb%)\\t%0, %1"
a2cd141b 5684 [(set_attr "type" "load_byte")
0d66636f 5685 (set_attr "predicable" "yes")
cffb2a26 5686 (set_attr "pool_range" "256")
5687 (set_attr "neg_pool_range" "244")]
5688)
3fc2009e 5689
b11cae9e 5690(define_expand "extendqisi2"
ef51b8e1 5691 [(set (match_operand:SI 0 "s_register_operand" "")
5692 (sign_extend:SI (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "")))]
cffb2a26 5693 "TARGET_EITHER"
ef51b8e1 5694{
5695 if (!arm_arch4 && MEM_P (operands[1]))
5696 operands[1] = copy_to_mode_reg (QImode, operands[1]);
a2cd141b 5697
ef51b8e1 5698 if (!arm_arch6 && !MEM_P (operands[1]))
5699 {
5700 rtx t = gen_lowpart (SImode, operands[1]);
5701 rtx tmp = gen_reg_rtx (SImode);
5702 emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (24)));
5703 emit_insn (gen_ashrsi3 (operands[0], tmp, GEN_INT (24)));
5704 DONE;
5705 }
5706})
a2cd141b 5707
ef51b8e1 5708(define_split
5709 [(set (match_operand:SI 0 "register_operand" "")
5710 (sign_extend:SI (match_operand:QI 1 "register_operand" "")))]
5711 "!arm_arch6"
5712 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 24)))
5713 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 24)))]
5714{
5715 operands[2] = simplify_gen_subreg (SImode, operands[1], QImode, 0);
5716})
f7fbdd4a 5717
a2cd141b 5718(define_insn "*arm_extendqisi"
ef51b8e1 5719 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5720 (sign_extend:SI (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "r,Uq")))]
a2cd141b 5721 "TARGET_ARM && arm_arch4 && !arm_arch6"
ef51b8e1 5722 "@
5723 #
5724 ldr%(sb%)\\t%0, %1"
5725 [(set_attr "length" "8,4")
6b6abc9c 5726 (set_attr "type" "arlo_shift,load_byte")
0d66636f 5727 (set_attr "predicable" "yes")
ef51b8e1 5728 (set_attr "pool_range" "*,256")
5729 (set_attr "neg_pool_range" "*,244")]
cffb2a26 5730)
3fc2009e 5731
a2cd141b 5732(define_insn "*arm_extendqisi_v6"
5733 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
bed7d9a5 5734 (sign_extend:SI
5735 (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "r,Uq")))]
a2cd141b 5736 "TARGET_ARM && arm_arch6"
b4e8a300 5737 "@
5738 sxtb%?\\t%0, %1
25f905c2 5739 ldr%(sb%)\\t%0, %1"
6b6abc9c 5740 [(set_attr "type" "extend,load_byte")
a2cd141b 5741 (set_attr "predicable" "yes")
a2cd141b 5742 (set_attr "pool_range" "*,256")
5743 (set_attr "neg_pool_range" "*,244")]
5744)
5745
5746(define_insn "*arm_extendqisi2addsi"
5747 [(set (match_operand:SI 0 "s_register_operand" "=r")
5748 (plus:SI (sign_extend:SI (match_operand:QI 1 "s_register_operand" "r"))
5749 (match_operand:SI 2 "s_register_operand" "r")))]
25f905c2 5750 "TARGET_INT_SIMD"
a2cd141b 5751 "sxtab%?\\t%0, %2, %1"
6b6abc9c 5752 [(set_attr "type" "arlo_shift")
d952d547 5753 (set_attr "predicable" "yes")
5754 (set_attr "predicable_short_it" "no")]
a2cd141b 5755)
5756
ef51b8e1 5757(define_split
5758 [(set (match_operand:SI 0 "register_operand" "")
5759 (sign_extend:SI (match_operand:QI 1 "memory_operand" "")))]
5760 "TARGET_THUMB1 && reload_completed"
5761 [(set (match_dup 0) (match_dup 2))
5762 (set (match_dup 0) (sign_extend:SI (match_dup 3)))]
5763{
5764 rtx addr = XEXP (operands[1], 0);
cffb2a26 5765
ef51b8e1 5766 if (GET_CODE (addr) == CONST)
5767 addr = XEXP (addr, 0);
cffb2a26 5768
ef51b8e1 5769 if (GET_CODE (addr) == PLUS
5770 && REG_P (XEXP (addr, 0)) && REG_P (XEXP (addr, 1)))
5771 /* No split necessary. */
5772 FAIL;
5773
5774 if (GET_CODE (addr) == PLUS
5775 && !REG_P (XEXP (addr, 0)) && !REG_P (XEXP (addr, 1)))
5776 FAIL;
5777
5778 if (reg_overlap_mentioned_p (operands[0], addr))
5779 {
5780 rtx t = gen_lowpart (QImode, operands[0]);
5781 emit_move_insn (t, operands[1]);
5782 emit_insn (gen_thumb1_extendqisi2 (operands[0], t));
5783 DONE;
5784 }
5785
5786 if (REG_P (addr))
5787 {
5788 addr = gen_rtx_PLUS (Pmode, addr, operands[0]);
5789 operands[2] = const0_rtx;
5790 }
5791 else if (GET_CODE (addr) != PLUS)
5792 FAIL;
5793 else if (REG_P (XEXP (addr, 0)))
5794 {
5795 operands[2] = XEXP (addr, 1);
5796 addr = gen_rtx_PLUS (Pmode, XEXP (addr, 0), operands[0]);
5797 }
5798 else
5799 {
5800 operands[2] = XEXP (addr, 0);
5801 addr = gen_rtx_PLUS (Pmode, XEXP (addr, 1), operands[0]);
5802 }
cffb2a26 5803
ef51b8e1 5804 operands[3] = change_address (operands[1], QImode, addr);
5805})
5806
8a3b73a1 5807(define_peephole2
5808 [(set (match_operand:SI 0 "register_operand" "")
5809 (plus:SI (match_dup 0) (match_operand 1 "const_int_operand")))
5810 (set (match_operand:SI 2 "register_operand" "") (const_int 0))
5811 (set (match_operand:SI 3 "register_operand" "")
5812 (sign_extend:SI (match_operand:QI 4 "memory_operand" "")))]
5813 "TARGET_THUMB1
5814 && GET_CODE (XEXP (operands[4], 0)) == PLUS
5815 && rtx_equal_p (operands[0], XEXP (XEXP (operands[4], 0), 0))
5816 && rtx_equal_p (operands[2], XEXP (XEXP (operands[4], 0), 1))
5817 && (peep2_reg_dead_p (3, operands[0])
5818 || rtx_equal_p (operands[0], operands[3]))
5819 && (peep2_reg_dead_p (3, operands[2])
5820 || rtx_equal_p (operands[2], operands[3]))"
5821 [(set (match_dup 2) (match_dup 1))
5822 (set (match_dup 3) (sign_extend:SI (match_dup 4)))]
5823{
5824 rtx addr = gen_rtx_PLUS (Pmode, operands[0], operands[2]);
5825 operands[4] = change_address (operands[4], QImode, addr);
5826})
5827
ef51b8e1 5828(define_insn "thumb1_extendqisi2"
a2cd141b 5829 [(set (match_operand:SI 0 "register_operand" "=l,l,l")
5830 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "l,V,m")))]
ef51b8e1 5831 "TARGET_THUMB1"
5832{
5833 rtx addr;
a2cd141b 5834
ef51b8e1 5835 if (which_alternative == 0 && arm_arch6)
5836 return "sxtb\\t%0, %1";
5837 if (which_alternative == 0)
5838 return "#";
a2cd141b 5839
ef51b8e1 5840 addr = XEXP (operands[1], 0);
5841 if (GET_CODE (addr) == PLUS
5842 && REG_P (XEXP (addr, 0)) && REG_P (XEXP (addr, 1)))
5843 return "ldrsb\\t%0, %1";
a2cd141b 5844
ef51b8e1 5845 return "#";
5846}
5847 [(set_attr_alternative "length"
5848 [(if_then_else (eq_attr "is_arch6" "yes")
5849 (const_int 2) (const_int 4))
5850 (const_int 2)
5851 (if_then_else (eq_attr "is_arch6" "yes")
5852 (const_int 4) (const_int 6))])
6b6abc9c 5853 (set_attr "type" "extend,load_byte,load_byte")]
a2cd141b 5854)
5855
caedf871 5856(define_expand "extendsfdf2"
5857 [(set (match_operand:DF 0 "s_register_operand" "")
5858 (float_extend:DF (match_operand:SF 1 "s_register_operand" "")))]
a50d7267 5859 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
caedf871 5860 ""
5861)
9b8516be 5862
5863/* HFmode -> DFmode conversions have to go through SFmode. */
5864(define_expand "extendhfdf2"
5865 [(set (match_operand:DF 0 "general_operand" "")
5866 (float_extend:DF (match_operand:HF 1 "general_operand" "")))]
5867 "TARGET_EITHER"
5868 "
5869 {
5870 rtx op1;
5871 op1 = convert_to_mode (SFmode, operands[1], 0);
5872 op1 = convert_to_mode (DFmode, op1, 0);
5873 emit_insn (gen_movdf (operands[0], op1));
5874 DONE;
5875 }"
5876)
b11cae9e 5877\f
5878;; Move insns (including loads and stores)
5879
5880;; XXX Just some ideas about movti.
9c08d1fa 5881;; I don't think these are a good idea on the arm, there just aren't enough
5882;; registers
b11cae9e 5883;;(define_expand "loadti"
9c08d1fa 5884;; [(set (match_operand:TI 0 "s_register_operand" "")
b11cae9e 5885;; (mem:TI (match_operand:SI 1 "address_operand" "")))]
5886;; "" "")
5887
5888;;(define_expand "storeti"
5889;; [(set (mem:TI (match_operand:TI 0 "address_operand" ""))
9c08d1fa 5890;; (match_operand:TI 1 "s_register_operand" ""))]
b11cae9e 5891;; "" "")
5892
5893;;(define_expand "movti"
5894;; [(set (match_operand:TI 0 "general_operand" "")
5895;; (match_operand:TI 1 "general_operand" ""))]
5896;; ""
5897;; "
5898;;{
5899;; rtx insn;
5900;;
0438d37f 5901;; if (MEM_P (operands[0]) && MEM_P (operands[1]))
b11cae9e 5902;; operands[1] = copy_to_reg (operands[1]);
0438d37f 5903;; if (MEM_P (operands[0]))
b11cae9e 5904;; insn = gen_storeti (XEXP (operands[0], 0), operands[1]);
0438d37f 5905;; else if (MEM_P (operands[1]))
b11cae9e 5906;; insn = gen_loadti (operands[0], XEXP (operands[1], 0));
5907;; else
5908;; FAIL;
5909;;
5910;; emit_insn (insn);
5911;; DONE;
5912;;}")
5913
a2f10574 5914;; Recognize garbage generated above.
b11cae9e 5915
5916;;(define_insn ""
5917;; [(set (match_operand:TI 0 "general_operand" "=r,r,r,<,>,m")
5918;; (match_operand:TI 1 "general_operand" "<,>,m,r,r,r"))]
5919;; ""
5920;; "*
5921;; {
5922;; register mem = (which_alternative < 3);
0d66636f 5923;; register const char *template;
b11cae9e 5924;;
5925;; operands[mem] = XEXP (operands[mem], 0);
5926;; switch (which_alternative)
5927;; {
5928;; case 0: template = \"ldmdb\\t%1!, %M0\"; break;
5929;; case 1: template = \"ldmia\\t%1!, %M0\"; break;
5930;; case 2: template = \"ldmia\\t%1, %M0\"; break;
5931;; case 3: template = \"stmdb\\t%0!, %M1\"; break;
5932;; case 4: template = \"stmia\\t%0!, %M1\"; break;
5933;; case 5: template = \"stmia\\t%0, %M1\"; break;
5934;; }
e2348bcb 5935;; output_asm_insn (template, operands);
5936;; return \"\";
b11cae9e 5937;; }")
5938
cffb2a26 5939(define_expand "movdi"
5940 [(set (match_operand:DI 0 "general_operand" "")
5941 (match_operand:DI 1 "general_operand" ""))]
5942 "TARGET_EITHER"
5943 "
e1ba4a27 5944 if (can_create_pseudo_p ())
cffb2a26 5945 {
0438d37f 5946 if (!REG_P (operands[0]))
b2778788 5947 operands[1] = force_reg (DImode, operands[1]);
cffb2a26 5948 }
5949 "
5950)
b11cae9e 5951
cffb2a26 5952(define_insn "*arm_movdi"
353cf59a 5953 [(set (match_operand:DI 0 "nonimmediate_di_operand" "=r, r, r, q, m")
5954 (match_operand:DI 1 "di_operand" "rDa,Db,Dc,mi,q"))]
cde1623a 5955 "TARGET_32BIT
b805622c 5956 && !(TARGET_HARD_FLOAT && TARGET_VFP)
b2778788 5957 && !TARGET_IWMMXT
5958 && ( register_operand (operands[0], DImode)
5959 || register_operand (operands[1], DImode))"
b11cae9e 5960 "*
d51f92df 5961 switch (which_alternative)
5962 {
5963 case 0:
5964 case 1:
5965 case 2:
5966 return \"#\";
5967 default:
26ff80c0 5968 return output_move_double (operands, true, NULL);
d51f92df 5969 }
cffb2a26 5970 "
359a6e9f 5971 [(set_attr "length" "8,12,16,8,8")
5972 (set_attr "type" "*,*,*,load2,store2")
cde1623a 5973 (set_attr "arm_pool_range" "*,*,*,1020,*")
8848d797 5974 (set_attr "arm_neg_pool_range" "*,*,*,1004,*")
42e1de19 5975 (set_attr "thumb2_pool_range" "*,*,*,4094,*")
cde1623a 5976 (set_attr "thumb2_neg_pool_range" "*,*,*,0,*")]
cffb2a26 5977)
5978
d51f92df 5979(define_split
5980 [(set (match_operand:ANY64 0 "arm_general_register_operand" "")
5981 (match_operand:ANY64 1 "const_double_operand" ""))]
25f905c2 5982 "TARGET_32BIT
d51f92df 5983 && reload_completed
5984 && (arm_const_double_inline_cost (operands[1])
5985 <= ((optimize_size || arm_ld_sched) ? 3 : 4))"
5986 [(const_int 0)]
5987 "
5988 arm_split_constant (SET, SImode, curr_insn,
5989 INTVAL (gen_lowpart (SImode, operands[1])),
5990 gen_lowpart (SImode, operands[0]), NULL_RTX, 0);
5991 arm_split_constant (SET, SImode, curr_insn,
5992 INTVAL (gen_highpart_mode (SImode,
5993 GET_MODE (operands[0]),
5994 operands[1])),
5995 gen_highpart (SImode, operands[0]), NULL_RTX, 0);
5996 DONE;
5997 "
5998)
5999
e5ba9289 6000; If optimizing for size, or if we have load delay slots, then
6001; we want to split the constant into two separate operations.
6002; In both cases this may split a trivial part into a single data op
6003; leaving a single complex constant to load. We can also get longer
6004; offsets in a LDR which means we get better chances of sharing the pool
6005; entries. Finally, we can normally do a better job of scheduling
6006; LDR instructions than we can with LDM.
6007; This pattern will only match if the one above did not.
6008(define_split
6009 [(set (match_operand:ANY64 0 "arm_general_register_operand" "")
6010 (match_operand:ANY64 1 "const_double_operand" ""))]
6011 "TARGET_ARM && reload_completed
6012 && arm_const_double_by_parts (operands[1])"
6013 [(set (match_dup 0) (match_dup 1))
6014 (set (match_dup 2) (match_dup 3))]
6015 "
6016 operands[2] = gen_highpart (SImode, operands[0]);
6017 operands[3] = gen_highpart_mode (SImode, GET_MODE (operands[0]),
6018 operands[1]);
6019 operands[0] = gen_lowpart (SImode, operands[0]);
6020 operands[1] = gen_lowpart (SImode, operands[1]);
6021 "
6022)
6023
d51f92df 6024(define_split
6025 [(set (match_operand:ANY64 0 "arm_general_register_operand" "")
6026 (match_operand:ANY64 1 "arm_general_register_operand" ""))]
6027 "TARGET_EITHER && reload_completed"
6028 [(set (match_dup 0) (match_dup 1))
6029 (set (match_dup 2) (match_dup 3))]
6030 "
6031 operands[2] = gen_highpart (SImode, operands[0]);
6032 operands[3] = gen_highpart (SImode, operands[1]);
6033 operands[0] = gen_lowpart (SImode, operands[0]);
6034 operands[1] = gen_lowpart (SImode, operands[1]);
6035
6036 /* Handle a partial overlap. */
6037 if (rtx_equal_p (operands[0], operands[3]))
6038 {
6039 rtx tmp0 = operands[0];
6040 rtx tmp1 = operands[1];
6041
6042 operands[0] = operands[2];
6043 operands[1] = operands[3];
6044 operands[2] = tmp0;
6045 operands[3] = tmp1;
6046 }
6047 "
6048)
6049
a8a3b539 6050;; We can't actually do base+index doubleword loads if the index and
6051;; destination overlap. Split here so that we at least have chance to
6052;; schedule.
6053(define_split
6054 [(set (match_operand:DI 0 "s_register_operand" "")
6055 (mem:DI (plus:SI (match_operand:SI 1 "s_register_operand" "")
6056 (match_operand:SI 2 "s_register_operand" ""))))]
6057 "TARGET_LDRD
6058 && reg_overlap_mentioned_p (operands[0], operands[1])
6059 && reg_overlap_mentioned_p (operands[0], operands[2])"
6060 [(set (match_dup 4)
6061 (plus:SI (match_dup 1)
6062 (match_dup 2)))
6063 (set (match_dup 0)
6064 (mem:DI (match_dup 4)))]
6065 "
6066 operands[4] = gen_rtx_REG (SImode, REGNO(operands[0]));
6067 "
6068)
6069
cffb2a26 6070;;; ??? This should have alternatives for constants.
6071;;; ??? This was originally identical to the movdf_insn pattern.
6072;;; ??? The 'i' constraint looks funny, but it should always be replaced by
6073;;; thumb_reorg with a memory reference.
25f905c2 6074(define_insn "*thumb1_movdi_insn"
215b30b3 6075 [(set (match_operand:DI 0 "nonimmediate_operand" "=l,l,l,l,>,l, m,*r")
6076 (match_operand:DI 1 "general_operand" "l, I,J,>,l,mi,l,*r"))]
25f905c2 6077 "TARGET_THUMB1
cffb2a26 6078 && ( register_operand (operands[0], DImode)
6079 || register_operand (operands[1], DImode))"
6080 "*
6081 {
6082 switch (which_alternative)
6083 {
6084 default:
6085 case 0:
6086 if (REGNO (operands[1]) == REGNO (operands[0]) + 1)
6087 return \"add\\t%0, %1, #0\;add\\t%H0, %H1, #0\";
6088 return \"add\\t%H0, %H1, #0\;add\\t%0, %1, #0\";
6089 case 1:
6090 return \"mov\\t%Q0, %1\;mov\\t%R0, #0\";
6091 case 2:
6092 operands[1] = GEN_INT (- INTVAL (operands[1]));
6093 return \"mov\\t%Q0, %1\;neg\\t%Q0, %Q0\;asr\\t%R0, %Q0, #31\";
6094 case 3:
6095 return \"ldmia\\t%1, {%0, %H0}\";
6096 case 4:
6097 return \"stmia\\t%0, {%1, %H1}\";
6098 case 5:
6099 return thumb_load_double_from_address (operands);
6100 case 6:
1a83b3ff 6101 operands[2] = gen_rtx_MEM (SImode,
29c05e22 6102 plus_constant (Pmode, XEXP (operands[0], 0), 4));
cffb2a26 6103 output_asm_insn (\"str\\t%1, %0\;str\\t%H1, %2\", operands);
6104 return \"\";
6105 case 7:
6106 if (REGNO (operands[1]) == REGNO (operands[0]) + 1)
6107 return \"mov\\t%0, %1\;mov\\t%H0, %H1\";
6108 return \"mov\\t%H0, %H1\;mov\\t%0, %1\";
6109 }
6110 }"
6111 [(set_attr "length" "4,4,6,2,2,6,4,4")
1aed5204 6112 (set_attr "type" "*,mov_reg,*,load2,store2,load2,store2,mov_reg")
42e1de19 6113 (set_attr "pool_range" "*,*,*,*,*,1018,*,*")]
cffb2a26 6114)
b11cae9e 6115
9c08d1fa 6116(define_expand "movsi"
6117 [(set (match_operand:SI 0 "general_operand" "")
6118 (match_operand:SI 1 "general_operand" ""))]
cffb2a26 6119 "TARGET_EITHER"
9c08d1fa 6120 "
befb0bac 6121 {
e348ff3e 6122 rtx base, offset, tmp;
6123
25f905c2 6124 if (TARGET_32BIT)
9c08d1fa 6125 {
674a8f0b 6126 /* Everything except mem = const or mem = mem can be done easily. */
0438d37f 6127 if (MEM_P (operands[0]))
cffb2a26 6128 operands[1] = force_reg (SImode, operands[1]);
a2cd141b 6129 if (arm_general_register_operand (operands[0], SImode)
0438d37f 6130 && CONST_INT_P (operands[1])
cffb2a26 6131 && !(const_ok_for_arm (INTVAL (operands[1]))
6132 || const_ok_for_arm (~INTVAL (operands[1]))))
6133 {
96f57e36 6134 arm_split_constant (SET, SImode, NULL_RTX,
6135 INTVAL (operands[1]), operands[0], NULL_RTX,
e1ba4a27 6136 optimize && can_create_pseudo_p ());
cffb2a26 6137 DONE;
6138 }
6139 }
25f905c2 6140 else /* TARGET_THUMB1... */
cffb2a26 6141 {
e1ba4a27 6142 if (can_create_pseudo_p ())
cffb2a26 6143 {
0438d37f 6144 if (!REG_P (operands[0]))
cffb2a26 6145 operands[1] = force_reg (SImode, operands[1]);
6146 }
9c08d1fa 6147 }
f655717d 6148
e348ff3e 6149 if (ARM_OFFSETS_MUST_BE_WITHIN_SECTIONS_P)
6150 {
6151 split_const (operands[1], &base, &offset);
6152 if (GET_CODE (base) == SYMBOL_REF
6153 && !offset_within_block_p (base, INTVAL (offset)))
6154 {
b308ddcf 6155 tmp = can_create_pseudo_p () ? gen_reg_rtx (SImode) : operands[0];
e348ff3e 6156 emit_move_insn (tmp, base);
6157 emit_insn (gen_addsi3 (operands[0], tmp, offset));
6158 DONE;
6159 }
6160 }
6161
f655717d 6162 /* Recognize the case where operand[1] is a reference to thread-local
6163 data and load its address to a register. */
6164 if (arm_tls_referenced_p (operands[1]))
6165 {
6166 rtx tmp = operands[1];
6167 rtx addend = NULL;
6168
6169 if (GET_CODE (tmp) == CONST && GET_CODE (XEXP (tmp, 0)) == PLUS)
6170 {
6171 addend = XEXP (XEXP (tmp, 0), 1);
6172 tmp = XEXP (XEXP (tmp, 0), 0);
6173 }
6174
6175 gcc_assert (GET_CODE (tmp) == SYMBOL_REF);
6176 gcc_assert (SYMBOL_REF_TLS_MODEL (tmp) != 0);
6177
e1ba4a27 6178 tmp = legitimize_tls_address (tmp,
6179 !can_create_pseudo_p () ? operands[0] : 0);
f655717d 6180 if (addend)
6181 {
6182 tmp = gen_rtx_PLUS (SImode, tmp, addend);
6183 tmp = force_operand (tmp, operands[0]);
6184 }
6185 operands[1] = tmp;
6186 }
6187 else if (flag_pic
6188 && (CONSTANT_P (operands[1])
6189 || symbol_mentioned_p (operands[1])
6190 || label_mentioned_p (operands[1])))
6191 operands[1] = legitimize_pic_address (operands[1], SImode,
e1ba4a27 6192 (!can_create_pseudo_p ()
6193 ? operands[0]
6194 : 0));
befb0bac 6195 }
215b30b3 6196 "
6197)
9c08d1fa 6198
d0e6a121 6199;; The ARM LO_SUM and HIGH are backwards - HIGH sets the low bits, and
6200;; LO_SUM adds in the high bits. Fortunately these are opaque operations
6201;; so this does not matter.
6202(define_insn "*arm_movt"
6203 [(set (match_operand:SI 0 "nonimmediate_operand" "=r")
6204 (lo_sum:SI (match_operand:SI 1 "nonimmediate_operand" "0")
6205 (match_operand:SI 2 "general_operand" "i")))]
c9b2ce40 6206 "arm_arch_thumb2"
d0e6a121 6207 "movt%?\t%0, #:upper16:%c2"
6208 [(set_attr "predicable" "yes")
d952d547 6209 (set_attr "predicable_short_it" "no")
d0e6a121 6210 (set_attr "length" "4")]
6211)
6212
cffb2a26 6213(define_insn "*arm_movsi_insn"
aaa37ad6 6214 [(set (match_operand:SI 0 "nonimmediate_operand" "=rk,r,r,r,rk,m")
110eae03 6215 (match_operand:SI 1 "general_operand" "rk, I,K,j,mi,rk"))]
755eb2b4 6216 "TARGET_ARM && ! TARGET_IWMMXT
a2cd141b 6217 && !(TARGET_HARD_FLOAT && TARGET_VFP)
cffb2a26 6218 && ( register_operand (operands[0], SImode)
6219 || register_operand (operands[1], SImode))"
f7fbdd4a 6220 "@
aaa37ad6 6221 mov%?\\t%0, %1
f7fbdd4a 6222 mov%?\\t%0, %1
6223 mvn%?\\t%0, #%B1
25f905c2 6224 movw%?\\t%0, %1
f7fbdd4a 6225 ldr%?\\t%0, %1
6226 str%?\\t%1, %0"
1aed5204 6227 [(set_attr "type" "mov_reg,mov_imm,mvn_imm,mov_imm,load1,store1")
0d66636f 6228 (set_attr "predicable" "yes")
aaa37ad6 6229 (set_attr "pool_range" "*,*,*,*,4096,*")
6230 (set_attr "neg_pool_range" "*,*,*,*,4084,*")]
cffb2a26 6231)
87b22bf7 6232
6233(define_split
a2cd141b 6234 [(set (match_operand:SI 0 "arm_general_register_operand" "")
87b22bf7 6235 (match_operand:SI 1 "const_int_operand" ""))]
25f905c2 6236 "TARGET_32BIT
215b30b3 6237 && (!(const_ok_for_arm (INTVAL (operands[1]))
6238 || const_ok_for_arm (~INTVAL (operands[1]))))"
87b22bf7 6239 [(clobber (const_int 0))]
6240 "
96f57e36 6241 arm_split_constant (SET, SImode, NULL_RTX,
6242 INTVAL (operands[1]), operands[0], NULL_RTX, 0);
87b22bf7 6243 DONE;
215b30b3 6244 "
6245)
9c08d1fa 6246
b8d5d078 6247;; Split symbol_refs at the later stage (after cprop), instead of generating
6248;; movt/movw pair directly at expand. Otherwise corresponding high_sum
6249;; and lo_sum would be merged back into memory load at cprop. However,
6250;; if the default is to prefer movt/movw rather than a load from the constant
6251;; pool, the performance is better.
6252(define_split
6253 [(set (match_operand:SI 0 "arm_general_register_operand" "")
6254 (match_operand:SI 1 "general_operand" ""))]
6255 "TARGET_32BIT
6256 && TARGET_USE_MOVT && GET_CODE (operands[1]) == SYMBOL_REF
6257 && !flag_pic && !target_word_relocations
6258 && !arm_tls_referenced_p (operands[1])"
6259 [(clobber (const_int 0))]
6260{
6261 arm_emit_movpair (operands[0], operands[1]);
6262 DONE;
6263})
6264
25f905c2 6265(define_insn "*thumb1_movsi_insn"
55a0d64c 6266 [(set (match_operand:SI 0 "nonimmediate_operand" "=l,l,l,l,l,>,l, m,*l*h*k")
6267 (match_operand:SI 1 "general_operand" "l, I,J,K,>,l,mi,l,*l*h*k"))]
25f905c2 6268 "TARGET_THUMB1
cffb2a26 6269 && ( register_operand (operands[0], SImode)
6270 || register_operand (operands[1], SImode))"
6271 "@
6272 mov %0, %1
6273 mov %0, %1
6274 #
6275 #
6276 ldmia\\t%1, {%0}
6277 stmia\\t%0, {%1}
6278 ldr\\t%0, %1
6279 str\\t%1, %0
6280 mov\\t%0, %1"
6281 [(set_attr "length" "2,2,4,4,2,2,2,2,2")
a2cd141b 6282 (set_attr "type" "*,*,*,*,load1,store1,load1,store1,*")
42e1de19 6283 (set_attr "pool_range" "*,*,*,*,*,*,1018,*,*")
747b7458 6284 (set_attr "conds" "set,clob,*,*,nocond,nocond,nocond,nocond,nocond")])
cffb2a26 6285
6286(define_split
6287 [(set (match_operand:SI 0 "register_operand" "")
6288 (match_operand:SI 1 "const_int_operand" ""))]
25f905c2 6289 "TARGET_THUMB1 && satisfies_constraint_J (operands[1])"
1276f1b8 6290 [(set (match_dup 2) (match_dup 1))
6291 (set (match_dup 0) (neg:SI (match_dup 2)))]
6292 "
6293 {
6294 operands[1] = GEN_INT (- INTVAL (operands[1]));
6295 operands[2] = can_create_pseudo_p () ? gen_reg_rtx (SImode) : operands[0];
6296 }"
cffb2a26 6297)
6298
6299(define_split
6300 [(set (match_operand:SI 0 "register_operand" "")
6301 (match_operand:SI 1 "const_int_operand" ""))]
25f905c2 6302 "TARGET_THUMB1 && satisfies_constraint_K (operands[1])"
1276f1b8 6303 [(set (match_dup 2) (match_dup 1))
6304 (set (match_dup 0) (ashift:SI (match_dup 2) (match_dup 3)))]
cffb2a26 6305 "
6306 {
e4aeee53 6307 unsigned HOST_WIDE_INT val = INTVAL (operands[1]) & 0xffffffffu;
cffb2a26 6308 unsigned HOST_WIDE_INT mask = 0xff;
6309 int i;
6310
6311 for (i = 0; i < 25; i++)
6312 if ((val & (mask << i)) == val)
6313 break;
6314
1276f1b8 6315 /* Don't split if the shift is zero. */
cffb2a26 6316 if (i == 0)
6317 FAIL;
6318
6319 operands[1] = GEN_INT (val >> i);
1276f1b8 6320 operands[2] = can_create_pseudo_p () ? gen_reg_rtx (SImode) : operands[0];
6321 operands[3] = GEN_INT (i);
cffb2a26 6322 }"
6323)
6324
c5b75283 6325;; For thumb1 split imm move [256-510] into mov [1-255] and add #255
6326(define_split
6327 [(set (match_operand:SI 0 "register_operand" "")
6328 (match_operand:SI 1 "const_int_operand" ""))]
6329 "TARGET_THUMB1 && satisfies_constraint_Pe (operands[1])"
6330 [(set (match_dup 2) (match_dup 1))
6331 (set (match_dup 0) (plus:SI (match_dup 2) (match_dup 3)))]
6332 "
6333 {
6334 operands[1] = GEN_INT (INTVAL (operands[1]) - 255);
6335 operands[2] = can_create_pseudo_p () ? gen_reg_rtx (SImode) : operands[0];
6336 operands[3] = GEN_INT (255);
6337 }"
6338)
6339
67336bcf 6340;; When generating pic, we need to load the symbol offset into a register.
6341;; So that the optimizer does not confuse this with a normal symbol load
6342;; we use an unspec. The offset will be loaded from a constant pool entry,
6343;; since that is the only type of relocation we can use.
6344
94f8caca 6345;; Wrap calculation of the whole PIC address in a single pattern for the
6346;; benefit of optimizers, particularly, PRE and HOIST. Calculation of
6347;; a PIC address involves two loads from memory, so we want to CSE it
6348;; as often as possible.
6349;; This pattern will be split into one of the pic_load_addr_* patterns
6350;; and a move after GCSE optimizations.
6351;;
6352;; Note: Update arm.c: legitimize_pic_address() when changing this pattern.
6353(define_expand "calculate_pic_address"
6354 [(set (match_operand:SI 0 "register_operand" "")
6355 (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "")
6356 (unspec:SI [(match_operand:SI 2 "" "")]
6357 UNSPEC_PIC_SYM))))]
6358 "flag_pic"
6359)
6360
6361;; Split calculate_pic_address into pic_load_addr_* and a move.
6362(define_split
6363 [(set (match_operand:SI 0 "register_operand" "")
6364 (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "")
6365 (unspec:SI [(match_operand:SI 2 "" "")]
6366 UNSPEC_PIC_SYM))))]
6367 "flag_pic"
6368 [(set (match_dup 3) (unspec:SI [(match_dup 2)] UNSPEC_PIC_SYM))
6369 (set (match_dup 0) (mem:SI (plus:SI (match_dup 1) (match_dup 3))))]
6370 "operands[3] = can_create_pseudo_p () ? gen_reg_rtx (SImode) : operands[0];"
6371)
6372
350ccca5 6373;; operand1 is the memory address to go into
6374;; pic_load_addr_32bit.
6375;; operand2 is the PIC label to be emitted
6376;; from pic_add_dot_plus_eight.
6377;; We do this to allow hoisting of the entire insn.
6378(define_insn_and_split "pic_load_addr_unified"
6379 [(set (match_operand:SI 0 "s_register_operand" "=r,r,l")
6380 (unspec:SI [(match_operand:SI 1 "" "mX,mX,mX")
6381 (match_operand:SI 2 "" "")]
6382 UNSPEC_PIC_UNIFIED))]
6383 "flag_pic"
6384 "#"
6385 "&& reload_completed"
6386 [(set (match_dup 0) (unspec:SI [(match_dup 1)] UNSPEC_PIC_SYM))
6387 (set (match_dup 0) (unspec:SI [(match_dup 0) (match_dup 3)
6388 (match_dup 2)] UNSPEC_PIC_BASE))]
6389 "operands[3] = TARGET_THUMB ? GEN_INT (4) : GEN_INT (8);"
6390 [(set_attr "type" "load1,load1,load1")
42e1de19 6391 (set_attr "pool_range" "4096,4094,1022")
350ccca5 6392 (set_attr "neg_pool_range" "4084,0,0")
6393 (set_attr "arch" "a,t2,t1")
6394 (set_attr "length" "8,6,4")]
6395)
6396
67336bcf 6397;; The rather odd constraints on the following are to force reload to leave
6398;; the insn alone, and to force the minipool generation pass to then move
6399;; the GOT symbol to memory.
849170fd 6400
b3cd5f55 6401(define_insn "pic_load_addr_32bit"
849170fd 6402 [(set (match_operand:SI 0 "s_register_operand" "=r")
e1159bbe 6403 (unspec:SI [(match_operand:SI 1 "" "mX")] UNSPEC_PIC_SYM))]
b3cd5f55 6404 "TARGET_32BIT && flag_pic"
67336bcf 6405 "ldr%?\\t%0, %1"
a2cd141b 6406 [(set_attr "type" "load1")
42e1de19 6407 (set (attr "pool_range")
6408 (if_then_else (eq_attr "is_thumb" "no")
6409 (const_int 4096)
6410 (const_int 4094)))
b3cd5f55 6411 (set (attr "neg_pool_range")
6412 (if_then_else (eq_attr "is_thumb" "no")
6413 (const_int 4084)
6414 (const_int 0)))]
8c4d8060 6415)
6416
25f905c2 6417(define_insn "pic_load_addr_thumb1"
8c4d8060 6418 [(set (match_operand:SI 0 "s_register_operand" "=l")
e1159bbe 6419 (unspec:SI [(match_operand:SI 1 "" "mX")] UNSPEC_PIC_SYM))]
25f905c2 6420 "TARGET_THUMB1 && flag_pic"
8c4d8060 6421 "ldr\\t%0, %1"
a2cd141b 6422 [(set_attr "type" "load1")
42e1de19 6423 (set (attr "pool_range") (const_int 1018))]
cffb2a26 6424)
849170fd 6425
cffb2a26 6426(define_insn "pic_add_dot_plus_four"
15d5d060 6427 [(set (match_operand:SI 0 "register_operand" "=r")
c0c1fba5 6428 (unspec:SI [(match_operand:SI 1 "register_operand" "0")
6429 (const_int 4)
beef0fb5 6430 (match_operand 2 "" "")]
6431 UNSPEC_PIC_BASE))]
b3cd5f55 6432 "TARGET_THUMB"
cffb2a26 6433 "*
6cdcb15c 6434 (*targetm.asm_out.internal_label) (asm_out_file, \"LPIC\",
6435 INTVAL (operands[2]));
cffb2a26 6436 return \"add\\t%0, %|pc\";
6437 "
6438 [(set_attr "length" "2")]
6439)
849170fd 6440
6441(define_insn "pic_add_dot_plus_eight"
15d5d060 6442 [(set (match_operand:SI 0 "register_operand" "=r")
c0c1fba5 6443 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
6444 (const_int 8)
beef0fb5 6445 (match_operand 2 "" "")]
6446 UNSPEC_PIC_BASE))]
f655717d 6447 "TARGET_ARM"
c4034607 6448 "*
6cdcb15c 6449 (*targetm.asm_out.internal_label) (asm_out_file, \"LPIC\",
6450 INTVAL (operands[2]));
15d5d060 6451 return \"add%?\\t%0, %|pc, %1\";
cffb2a26 6452 "
0d66636f 6453 [(set_attr "predicable" "yes")]
cffb2a26 6454)
849170fd 6455
f655717d 6456(define_insn "tls_load_dot_plus_eight"
cc071db6 6457 [(set (match_operand:SI 0 "register_operand" "=r")
c0c1fba5 6458 (mem:SI (unspec:SI [(match_operand:SI 1 "register_operand" "r")
6459 (const_int 8)
beef0fb5 6460 (match_operand 2 "" "")]
6461 UNSPEC_PIC_BASE)))]
f655717d 6462 "TARGET_ARM"
6463 "*
6cdcb15c 6464 (*targetm.asm_out.internal_label) (asm_out_file, \"LPIC\",
6465 INTVAL (operands[2]));
f655717d 6466 return \"ldr%?\\t%0, [%|pc, %1]\t\t@ tls_load_dot_plus_eight\";
6467 "
6468 [(set_attr "predicable" "yes")]
6469)
6470
6471;; PIC references to local variables can generate pic_add_dot_plus_eight
6472;; followed by a load. These sequences can be crunched down to
6473;; tls_load_dot_plus_eight by a peephole.
6474
6475(define_peephole2
c0c1fba5 6476 [(set (match_operand:SI 0 "register_operand" "")
6477 (unspec:SI [(match_operand:SI 3 "register_operand" "")
6478 (const_int 8)
6479 (match_operand 1 "" "")]
6480 UNSPEC_PIC_BASE))
2d05dfad 6481 (set (match_operand:SI 2 "arm_general_register_operand" "")
6482 (mem:SI (match_dup 0)))]
f655717d 6483 "TARGET_ARM && peep2_reg_dead_p (2, operands[0])"
c0c1fba5 6484 [(set (match_dup 2)
6485 (mem:SI (unspec:SI [(match_dup 3)
6486 (const_int 8)
6487 (match_dup 1)]
6488 UNSPEC_PIC_BASE)))]
f655717d 6489 ""
6490)
6491
bac7fc85 6492(define_insn "pic_offset_arm"
6493 [(set (match_operand:SI 0 "register_operand" "=r")
6494 (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
6495 (unspec:SI [(match_operand:SI 2 "" "X")]
6496 UNSPEC_PIC_OFFSET))))]
6497 "TARGET_VXWORKS_RTP && TARGET_ARM && flag_pic"
6498 "ldr%?\\t%0, [%1,%2]"
6499 [(set_attr "type" "load1")]
6500)
6501
95373f08 6502(define_expand "builtin_setjmp_receiver"
6503 [(label_ref (match_operand 0 "" ""))]
6504 "flag_pic"
6505 "
6506{
b935b306 6507 /* r3 is clobbered by set/longjmp, so we can use it as a scratch
6508 register. */
2cb7d577 6509 if (arm_pic_register != INVALID_REGNUM)
6510 arm_load_pic_register (1UL << 3);
95373f08 6511 DONE;
6512}")
6513
9c08d1fa 6514;; If copying one reg to another we can set the condition codes according to
6515;; its value. Such a move is common after a return from subroutine and the
6516;; result is being tested against zero.
6517
f7fbdd4a 6518(define_insn "*movsi_compare0"
bd5b4116 6519 [(set (reg:CC CC_REGNUM)
cffb2a26 6520 (compare:CC (match_operand:SI 1 "s_register_operand" "0,r")
6521 (const_int 0)))
6522 (set (match_operand:SI 0 "s_register_operand" "=r,r")
6523 (match_dup 1))]
25f905c2 6524 "TARGET_32BIT"
e2348bcb 6525 "@
40dbec34 6526 cmp%?\\t%0, #0
25f905c2 6527 sub%.\\t%0, %1, #0"
65f68e55 6528 [(set_attr "conds" "set")
6b6abc9c 6529 (set_attr "type" "arlo_imm,arlo_imm")]
cffb2a26 6530)
b11cae9e 6531
b11cae9e 6532;; Subroutine to store a half word from a register into memory.
6533;; Operand 0 is the source register (HImode)
c8f69309 6534;; Operand 1 is the destination address in a register (SImode)
b11cae9e 6535
9c08d1fa 6536;; In both this routine and the next, we must be careful not to spill
01cc3b75 6537;; a memory address of reg+large_const into a separate PLUS insn, since this
9c08d1fa 6538;; can generate unrecognizable rtl.
6539
b11cae9e 6540(define_expand "storehi"
c8f69309 6541 [;; store the low byte
f082f1c4 6542 (set (match_operand 1 "" "") (match_dup 3))
b11cae9e 6543 ;; extract the high byte
c8f69309 6544 (set (match_dup 2)
6545 (ashiftrt:SI (match_operand 0 "" "") (const_int 8)))
b11cae9e 6546 ;; store the high byte
787f8210 6547 (set (match_dup 4) (match_dup 5))]
cffb2a26 6548 "TARGET_ARM"
b11cae9e 6549 "
215b30b3 6550 {
537ffcfc 6551 rtx op1 = operands[1];
6552 rtx addr = XEXP (op1, 0);
215b30b3 6553 enum rtx_code code = GET_CODE (addr);
6554
0438d37f 6555 if ((code == PLUS && !CONST_INT_P (XEXP (addr, 1)))
215b30b3 6556 || code == MINUS)
537ffcfc 6557 op1 = replace_equiv_address (operands[1], force_reg (SImode, addr));
215b30b3 6558
537ffcfc 6559 operands[4] = adjust_address (op1, QImode, 1);
e513d163 6560 operands[1] = adjust_address (operands[1], QImode, 0);
215b30b3 6561 operands[3] = gen_lowpart (QImode, operands[0]);
6562 operands[0] = gen_lowpart (SImode, operands[0]);
787f8210 6563 operands[2] = gen_reg_rtx (SImode);
6564 operands[5] = gen_lowpart (QImode, operands[2]);
215b30b3 6565 }"
6566)
b11cae9e 6567
c7597b5d 6568(define_expand "storehi_bigend"
f082f1c4 6569 [(set (match_dup 4) (match_dup 3))
c7597b5d 6570 (set (match_dup 2)
6571 (ashiftrt:SI (match_operand 0 "" "") (const_int 8)))
787f8210 6572 (set (match_operand 1 "" "") (match_dup 5))]
cffb2a26 6573 "TARGET_ARM"
b11cae9e 6574 "
215b30b3 6575 {
537ffcfc 6576 rtx op1 = operands[1];
6577 rtx addr = XEXP (op1, 0);
215b30b3 6578 enum rtx_code code = GET_CODE (addr);
6579
0438d37f 6580 if ((code == PLUS && !CONST_INT_P (XEXP (addr, 1)))
215b30b3 6581 || code == MINUS)
537ffcfc 6582 op1 = replace_equiv_address (op1, force_reg (SImode, addr));
215b30b3 6583
537ffcfc 6584 operands[4] = adjust_address (op1, QImode, 1);
e513d163 6585 operands[1] = adjust_address (operands[1], QImode, 0);
215b30b3 6586 operands[3] = gen_lowpart (QImode, operands[0]);
6587 operands[0] = gen_lowpart (SImode, operands[0]);
6588 operands[2] = gen_reg_rtx (SImode);
787f8210 6589 operands[5] = gen_lowpart (QImode, operands[2]);
215b30b3 6590 }"
6591)
c7597b5d 6592
6593;; Subroutine to store a half word integer constant into memory.
6594(define_expand "storeinthi"
f082f1c4 6595 [(set (match_operand 0 "" "")
787f8210 6596 (match_operand 1 "" ""))
9e8503e6 6597 (set (match_dup 3) (match_dup 2))]
cffb2a26 6598 "TARGET_ARM"
c7597b5d 6599 "
215b30b3 6600 {
6601 HOST_WIDE_INT value = INTVAL (operands[1]);
6602 rtx addr = XEXP (operands[0], 0);
537ffcfc 6603 rtx op0 = operands[0];
215b30b3 6604 enum rtx_code code = GET_CODE (addr);
c7597b5d 6605
0438d37f 6606 if ((code == PLUS && !CONST_INT_P (XEXP (addr, 1)))
215b30b3 6607 || code == MINUS)
537ffcfc 6608 op0 = replace_equiv_address (op0, force_reg (SImode, addr));
c7597b5d 6609
215b30b3 6610 operands[1] = gen_reg_rtx (SImode);
6611 if (BYTES_BIG_ENDIAN)
6612 {
6613 emit_insn (gen_movsi (operands[1], GEN_INT ((value >> 8) & 255)));
6614 if ((value & 255) == ((value >> 8) & 255))
6615 operands[2] = operands[1];
6616 else
6617 {
6618 operands[2] = gen_reg_rtx (SImode);
6619 emit_insn (gen_movsi (operands[2], GEN_INT (value & 255)));
6620 }
6621 }
6622 else
6623 {
6624 emit_insn (gen_movsi (operands[1], GEN_INT (value & 255)));
6625 if ((value & 255) == ((value >> 8) & 255))
6626 operands[2] = operands[1];
6627 else
6628 {
6629 operands[2] = gen_reg_rtx (SImode);
6630 emit_insn (gen_movsi (operands[2], GEN_INT ((value >> 8) & 255)));
6631 }
6632 }
c7597b5d 6633
537ffcfc 6634 operands[3] = adjust_address (op0, QImode, 1);
e513d163 6635 operands[0] = adjust_address (operands[0], QImode, 0);
9e8503e6 6636 operands[2] = gen_lowpart (QImode, operands[2]);
787f8210 6637 operands[1] = gen_lowpart (QImode, operands[1]);
215b30b3 6638 }"
6639)
b11cae9e 6640
f7fbdd4a 6641(define_expand "storehi_single_op"
6642 [(set (match_operand:HI 0 "memory_operand" "")
6643 (match_operand:HI 1 "general_operand" ""))]
25f905c2 6644 "TARGET_32BIT && arm_arch4"
f7fbdd4a 6645 "
215b30b3 6646 if (!s_register_operand (operands[1], HImode))
f7fbdd4a 6647 operands[1] = copy_to_mode_reg (HImode, operands[1]);
215b30b3 6648 "
6649)
f7fbdd4a 6650
b11cae9e 6651(define_expand "movhi"
6652 [(set (match_operand:HI 0 "general_operand" "")
c8f69309 6653 (match_operand:HI 1 "general_operand" ""))]
cffb2a26 6654 "TARGET_EITHER"
b11cae9e 6655 "
cffb2a26 6656 if (TARGET_ARM)
b11cae9e 6657 {
e1ba4a27 6658 if (can_create_pseudo_p ())
cffb2a26 6659 {
0438d37f 6660 if (MEM_P (operands[0]))
b11cae9e 6661 {
cffb2a26 6662 if (arm_arch4)
6663 {
6664 emit_insn (gen_storehi_single_op (operands[0], operands[1]));
6665 DONE;
6666 }
0438d37f 6667 if (CONST_INT_P (operands[1]))
cffb2a26 6668 emit_insn (gen_storeinthi (operands[0], operands[1]));
c7597b5d 6669 else
cffb2a26 6670 {
0438d37f 6671 if (MEM_P (operands[1]))
cffb2a26 6672 operands[1] = force_reg (HImode, operands[1]);
6673 if (BYTES_BIG_ENDIAN)
6674 emit_insn (gen_storehi_bigend (operands[1], operands[0]));
6675 else
6676 emit_insn (gen_storehi (operands[1], operands[0]));
6677 }
6678 DONE;
b11cae9e 6679 }
cffb2a26 6680 /* Sign extend a constant, and keep it in an SImode reg. */
0438d37f 6681 else if (CONST_INT_P (operands[1]))
9c08d1fa 6682 {
cffb2a26 6683 rtx reg = gen_reg_rtx (SImode);
6684 HOST_WIDE_INT val = INTVAL (operands[1]) & 0xffff;
6685
6686 /* If the constant is already valid, leave it alone. */
215b30b3 6687 if (!const_ok_for_arm (val))
cffb2a26 6688 {
6689 /* If setting all the top bits will make the constant
6690 loadable in a single instruction, then set them.
6691 Otherwise, sign extend the number. */
6692
215b30b3 6693 if (const_ok_for_arm (~(val | ~0xffff)))
cffb2a26 6694 val |= ~0xffff;
6695 else if (val & 0x8000)
6696 val |= ~0xffff;
6697 }
6698
6699 emit_insn (gen_movsi (reg, GEN_INT (val)));
9e8503e6 6700 operands[1] = gen_lowpart (HImode, reg);
9c08d1fa 6701 }
e1ba4a27 6702 else if (arm_arch4 && optimize && can_create_pseudo_p ()
0438d37f 6703 && MEM_P (operands[1]))
0045890a 6704 {
6705 rtx reg = gen_reg_rtx (SImode);
6706
6707 emit_insn (gen_zero_extendhisi2 (reg, operands[1]));
6708 operands[1] = gen_lowpart (HImode, reg);
6709 }
215b30b3 6710 else if (!arm_arch4)
f7fbdd4a 6711 {
0438d37f 6712 if (MEM_P (operands[1]))
cffb2a26 6713 {
c1a66faf 6714 rtx base;
6715 rtx offset = const0_rtx;
6716 rtx reg = gen_reg_rtx (SImode);
6717
0438d37f 6718 if ((REG_P (base = XEXP (operands[1], 0))
c1a66faf 6719 || (GET_CODE (base) == PLUS
0438d37f 6720 && (CONST_INT_P (offset = XEXP (base, 1)))
c1a66faf 6721 && ((INTVAL(offset) & 1) != 1)
0438d37f 6722 && REG_P (base = XEXP (base, 0))))
c1a66faf 6723 && REGNO_POINTER_ALIGN (REGNO (base)) >= 32)
206ee9a2 6724 {
8deb3959 6725 rtx new_rtx;
c1a66faf 6726
8deb3959 6727 new_rtx = widen_memory_access (operands[1], SImode,
6728 ((INTVAL (offset) & ~3)
6729 - INTVAL (offset)));
6730 emit_insn (gen_movsi (reg, new_rtx));
c1a66faf 6731 if (((INTVAL (offset) & 2) != 0)
6732 ^ (BYTES_BIG_ENDIAN ? 1 : 0))
6733 {
6734 rtx reg2 = gen_reg_rtx (SImode);
6735
6736 emit_insn (gen_lshrsi3 (reg2, reg, GEN_INT (16)));
6737 reg = reg2;
6738 }
206ee9a2 6739 }
c1a66faf 6740 else
6741 emit_insn (gen_movhi_bytes (reg, operands[1]));
6742
6743 operands[1] = gen_lowpart (HImode, reg);
cffb2a26 6744 }
6745 }
6746 }
674a8f0b 6747 /* Handle loading a large integer during reload. */
0438d37f 6748 else if (CONST_INT_P (operands[1])
215b30b3 6749 && !const_ok_for_arm (INTVAL (operands[1]))
6750 && !const_ok_for_arm (~INTVAL (operands[1])))
cffb2a26 6751 {
6752 /* Writing a constant to memory needs a scratch, which should
6753 be handled with SECONDARY_RELOADs. */
0438d37f 6754 gcc_assert (REG_P (operands[0]));
cffb2a26 6755
6756 operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
6757 emit_insn (gen_movsi (operands[0], operands[1]));
6758 DONE;
6759 }
6760 }
25f905c2 6761 else if (TARGET_THUMB2)
6762 {
6763 /* Thumb-2 can do everything except mem=mem and mem=const easily. */
e1ba4a27 6764 if (can_create_pseudo_p ())
25f905c2 6765 {
0438d37f 6766 if (!REG_P (operands[0]))
25f905c2 6767 operands[1] = force_reg (HImode, operands[1]);
6768 /* Zero extend a constant, and keep it in an SImode reg. */
0438d37f 6769 else if (CONST_INT_P (operands[1]))
25f905c2 6770 {
6771 rtx reg = gen_reg_rtx (SImode);
6772 HOST_WIDE_INT val = INTVAL (operands[1]) & 0xffff;
6773
6774 emit_insn (gen_movsi (reg, GEN_INT (val)));
6775 operands[1] = gen_lowpart (HImode, reg);
6776 }
6777 }
6778 }
6779 else /* TARGET_THUMB1 */
cffb2a26 6780 {
e1ba4a27 6781 if (can_create_pseudo_p ())
cffb2a26 6782 {
0438d37f 6783 if (CONST_INT_P (operands[1]))
6cffc037 6784 {
6785 rtx reg = gen_reg_rtx (SImode);
6786
6787 emit_insn (gen_movsi (reg, operands[1]));
6788 operands[1] = gen_lowpart (HImode, reg);
6789 }
cffb2a26 6790
6791 /* ??? We shouldn't really get invalid addresses here, but this can
215b30b3 6792 happen if we are passed a SP (never OK for HImode/QImode) or
bc409cb4 6793 virtual register (also rejected as illegitimate for HImode/QImode)
6794 relative address. */
cffb2a26 6795 /* ??? This should perhaps be fixed elsewhere, for instance, in
6796 fixup_stack_1, by checking for other kinds of invalid addresses,
6797 e.g. a bare reference to a virtual register. This may confuse the
6798 alpha though, which must handle this case differently. */
0438d37f 6799 if (MEM_P (operands[0])
215b30b3 6800 && !memory_address_p (GET_MODE (operands[0]),
6801 XEXP (operands[0], 0)))
537ffcfc 6802 operands[0]
6803 = replace_equiv_address (operands[0],
6804 copy_to_reg (XEXP (operands[0], 0)));
cffb2a26 6805
0438d37f 6806 if (MEM_P (operands[1])
215b30b3 6807 && !memory_address_p (GET_MODE (operands[1]),
6808 XEXP (operands[1], 0)))
537ffcfc 6809 operands[1]
6810 = replace_equiv_address (operands[1],
6811 copy_to_reg (XEXP (operands[1], 0)));
6cffc037 6812
0438d37f 6813 if (MEM_P (operands[1]) && optimize > 0)
6cffc037 6814 {
6815 rtx reg = gen_reg_rtx (SImode);
6816
6817 emit_insn (gen_zero_extendhisi2 (reg, operands[1]));
6818 operands[1] = gen_lowpart (HImode, reg);
6819 }
6820
0438d37f 6821 if (MEM_P (operands[0]))
6cffc037 6822 operands[1] = force_reg (HImode, operands[1]);
cffb2a26 6823 }
0438d37f 6824 else if (CONST_INT_P (operands[1])
234f6557 6825 && !satisfies_constraint_I (operands[1]))
cffb2a26 6826 {
6cffc037 6827 /* Handle loading a large integer during reload. */
6828
cffb2a26 6829 /* Writing a constant to memory needs a scratch, which should
6830 be handled with SECONDARY_RELOADs. */
0438d37f 6831 gcc_assert (REG_P (operands[0]));
cffb2a26 6832
1a83b3ff 6833 operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
cffb2a26 6834 emit_insn (gen_movsi (operands[0], operands[1]));
6835 DONE;
6836 }
b11cae9e 6837 }
cffb2a26 6838 "
6839)
6840
25f905c2 6841(define_insn "*thumb1_movhi_insn"
a941568e 6842 [(set (match_operand:HI 0 "nonimmediate_operand" "=l,l,m,*r,*h,l")
6843 (match_operand:HI 1 "general_operand" "l,m,l,*h,*r,I"))]
25f905c2 6844 "TARGET_THUMB1
cffb2a26 6845 && ( register_operand (operands[0], HImode)
6846 || register_operand (operands[1], HImode))"
6847 "*
6848 switch (which_alternative)
d79300ac 6849 {
cffb2a26 6850 case 0: return \"add %0, %1, #0\";
6851 case 2: return \"strh %1, %0\";
6852 case 3: return \"mov %0, %1\";
6853 case 4: return \"mov %0, %1\";
6854 case 5: return \"mov %0, %1\";
ed29c566 6855 default: gcc_unreachable ();
cffb2a26 6856 case 1:
6857 /* The stack pointer can end up being taken as an index register.
6858 Catch this case here and deal with it. */
6859 if (GET_CODE (XEXP (operands[1], 0)) == PLUS
0438d37f 6860 && REG_P (XEXP (XEXP (operands[1], 0), 0))
cffb2a26 6861 && REGNO (XEXP (XEXP (operands[1], 0), 0)) == SP_REGNUM)
6862 {
6863 rtx ops[2];
6864 ops[0] = operands[0];
6865 ops[1] = XEXP (XEXP (operands[1], 0), 0);
6866
6867 output_asm_insn (\"mov %0, %1\", ops);
6868
6869 XEXP (XEXP (operands[1], 0), 0) = operands[0];
6870
6871 }
6872 return \"ldrh %0, %1\";
6873 }"
6874 [(set_attr "length" "2,4,2,2,2,2")
747b7458 6875 (set_attr "type" "*,load1,store1,*,*,*")
6876 (set_attr "conds" "clob,nocond,nocond,nocond,nocond,clob")])
d79300ac 6877
b11cae9e 6878
25f7a26e 6879(define_expand "movhi_bytes"
eab14235 6880 [(set (match_dup 2) (zero_extend:SI (match_operand:HI 1 "" "")))
25f7a26e 6881 (set (match_dup 3)
eab14235 6882 (zero_extend:SI (match_dup 6)))
25f7a26e 6883 (set (match_operand:SI 0 "" "")
6884 (ior:SI (ashift:SI (match_dup 4) (const_int 8)) (match_dup 5)))]
cffb2a26 6885 "TARGET_ARM"
25f7a26e 6886 "
215b30b3 6887 {
6888 rtx mem1, mem2;
6889 rtx addr = copy_to_mode_reg (SImode, XEXP (operands[1], 0));
6890
788fcce0 6891 mem1 = change_address (operands[1], QImode, addr);
29c05e22 6892 mem2 = change_address (operands[1], QImode,
6893 plus_constant (Pmode, addr, 1));
215b30b3 6894 operands[0] = gen_lowpart (SImode, operands[0]);
6895 operands[1] = mem1;
6896 operands[2] = gen_reg_rtx (SImode);
6897 operands[3] = gen_reg_rtx (SImode);
6898 operands[6] = mem2;
25f7a26e 6899
215b30b3 6900 if (BYTES_BIG_ENDIAN)
6901 {
6902 operands[4] = operands[2];
6903 operands[5] = operands[3];
6904 }
6905 else
6906 {
6907 operands[4] = operands[3];
6908 operands[5] = operands[2];
6909 }
6910 }"
6911)
25f7a26e 6912
c7597b5d 6913(define_expand "movhi_bigend"
6914 [(set (match_dup 2)
6915 (rotate:SI (subreg:SI (match_operand:HI 1 "memory_operand" "") 0)
6916 (const_int 16)))
6917 (set (match_dup 3)
6918 (ashiftrt:SI (match_dup 2) (const_int 16)))
6919 (set (match_operand:HI 0 "s_register_operand" "")
787f8210 6920 (match_dup 4))]
cffb2a26 6921 "TARGET_ARM"
c7597b5d 6922 "
6923 operands[2] = gen_reg_rtx (SImode);
6924 operands[3] = gen_reg_rtx (SImode);
787f8210 6925 operands[4] = gen_lowpart (HImode, operands[3]);
215b30b3 6926 "
6927)
b11cae9e 6928
a2f10574 6929;; Pattern to recognize insn generated default case above
f7fbdd4a 6930(define_insn "*movhi_insn_arch4"
cde1623a 6931 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,m,r")
85e02ccb 6932 (match_operand:HI 1 "general_operand" "rI,K,r,mi"))]
cffb2a26 6933 "TARGET_ARM
6934 && arm_arch4
85e02ccb 6935 && (register_operand (operands[0], HImode)
6936 || register_operand (operands[1], HImode))"
f7fbdd4a 6937 "@
6938 mov%?\\t%0, %1\\t%@ movhi
6939 mvn%?\\t%0, #%B1\\t%@ movhi
25f905c2 6940 str%(h%)\\t%1, %0\\t%@ movhi
6941 ldr%(h%)\\t%0, %1\\t%@ movhi"
65f68e55 6942 [(set_attr "predicable" "yes")
cffb2a26 6943 (set_attr "pool_range" "*,*,*,256")
65f68e55 6944 (set_attr "neg_pool_range" "*,*,*,244")
6945 (set_attr_alternative "type"
6946 [(if_then_else (match_operand 1 "const_int_operand" "")
1aed5204 6947 (const_string "mov_imm" )
6948 (const_string "mov_reg"))
6949 (const_string "mvn_imm")
65f68e55 6950 (const_string "store1")
6951 (const_string "load1")])]
cffb2a26 6952)
f7fbdd4a 6953
f7fbdd4a 6954(define_insn "*movhi_bytes"
65f68e55 6955 [(set (match_operand:HI 0 "s_register_operand" "=r,r,r")
6956 (match_operand:HI 1 "arm_rhs_operand" "I,r,K"))]
c1a66faf 6957 "TARGET_ARM"
25f7a26e 6958 "@
65f68e55 6959 mov%?\\t%0, %1\\t%@ movhi
25f7a26e 6960 mov%?\\t%0, %1\\t%@ movhi
0d66636f 6961 mvn%?\\t%0, #%B1\\t%@ movhi"
d2a518d1 6962 [(set_attr "predicable" "yes")
1aed5204 6963 (set_attr "type" "mov_imm,mov_reg,mvn_imm")]
0d66636f 6964)
25f7a26e 6965
f90b51f1 6966(define_expand "thumb_movhi_clobber"
6967 [(set (match_operand:HI 0 "memory_operand" "")
6968 (match_operand:HI 1 "register_operand" ""))
6969 (clobber (match_operand:DI 2 "register_operand" ""))]
25f905c2 6970 "TARGET_THUMB1"
f90b51f1 6971 "
6972 if (strict_memory_address_p (HImode, XEXP (operands[0], 0))
6973 && REGNO (operands[1]) <= LAST_LO_REGNUM)
6974 {
6975 emit_insn (gen_movhi (operands[0], operands[1]));
6976 DONE;
6977 }
6978 /* XXX Fixme, need to handle other cases here as well. */
6979 gcc_unreachable ();
6980 "
cffb2a26 6981)
6982
bc5c7e08 6983;; We use a DImode scratch because we may occasionally need an additional
6984;; temporary if the address isn't offsettable -- push_reload doesn't seem
6985;; to take any notice of the "o" constraints on reload_memory_operand operand.
d3373b54 6986(define_expand "reload_outhi"
cffb2a26 6987 [(parallel [(match_operand:HI 0 "arm_reload_memory_operand" "=o")
215b30b3 6988 (match_operand:HI 1 "s_register_operand" "r")
6989 (match_operand:DI 2 "s_register_operand" "=&l")])]
cffb2a26 6990 "TARGET_EITHER"
6991 "if (TARGET_ARM)
6992 arm_reload_out_hi (operands);
6993 else
6994 thumb_reload_out_hi (operands);
d3373b54 6995 DONE;
cffb2a26 6996 "
6997)
d3373b54 6998
25f7a26e 6999(define_expand "reload_inhi"
7000 [(parallel [(match_operand:HI 0 "s_register_operand" "=r")
cffb2a26 7001 (match_operand:HI 1 "arm_reload_memory_operand" "o")
bc5c7e08 7002 (match_operand:DI 2 "s_register_operand" "=&r")])]
c1a66faf 7003 "TARGET_EITHER"
25f7a26e 7004 "
cffb2a26 7005 if (TARGET_ARM)
7006 arm_reload_in_hi (operands);
7007 else
7008 thumb_reload_out_hi (operands);
25f7a26e 7009 DONE;
7010")
7011
9c08d1fa 7012(define_expand "movqi"
7013 [(set (match_operand:QI 0 "general_operand" "")
7014 (match_operand:QI 1 "general_operand" ""))]
cffb2a26 7015 "TARGET_EITHER"
9c08d1fa 7016 "
6cffc037 7017 /* Everything except mem = const or mem = mem can be done easily */
0045890a 7018
e1ba4a27 7019 if (can_create_pseudo_p ())
cffb2a26 7020 {
0438d37f 7021 if (CONST_INT_P (operands[1]))
6cffc037 7022 {
7023 rtx reg = gen_reg_rtx (SImode);
7024
03770691 7025 /* For thumb we want an unsigned immediate, then we are more likely
7026 to be able to use a movs insn. */
7027 if (TARGET_THUMB)
7028 operands[1] = GEN_INT (INTVAL (operands[1]) & 255);
7029
6cffc037 7030 emit_insn (gen_movsi (reg, operands[1]));
7031 operands[1] = gen_lowpart (QImode, reg);
7032 }
cffb2a26 7033
6cffc037 7034 if (TARGET_THUMB)
7035 {
cffb2a26 7036 /* ??? We shouldn't really get invalid addresses here, but this can
215b30b3 7037 happen if we are passed a SP (never OK for HImode/QImode) or
bc409cb4 7038 virtual register (also rejected as illegitimate for HImode/QImode)
7039 relative address. */
cffb2a26 7040 /* ??? This should perhaps be fixed elsewhere, for instance, in
7041 fixup_stack_1, by checking for other kinds of invalid addresses,
7042 e.g. a bare reference to a virtual register. This may confuse the
7043 alpha though, which must handle this case differently. */
0438d37f 7044 if (MEM_P (operands[0])
215b30b3 7045 && !memory_address_p (GET_MODE (operands[0]),
cffb2a26 7046 XEXP (operands[0], 0)))
537ffcfc 7047 operands[0]
7048 = replace_equiv_address (operands[0],
7049 copy_to_reg (XEXP (operands[0], 0)));
0438d37f 7050 if (MEM_P (operands[1])
215b30b3 7051 && !memory_address_p (GET_MODE (operands[1]),
cffb2a26 7052 XEXP (operands[1], 0)))
537ffcfc 7053 operands[1]
7054 = replace_equiv_address (operands[1],
7055 copy_to_reg (XEXP (operands[1], 0)));
6cffc037 7056 }
7057
0438d37f 7058 if (MEM_P (operands[1]) && optimize > 0)
6cffc037 7059 {
7060 rtx reg = gen_reg_rtx (SImode);
7061
7062 emit_insn (gen_zero_extendqisi2 (reg, operands[1]));
7063 operands[1] = gen_lowpart (QImode, reg);
7064 }
7065
0438d37f 7066 if (MEM_P (operands[0]))
6cffc037 7067 operands[1] = force_reg (QImode, operands[1]);
7068 }
7069 else if (TARGET_THUMB
0438d37f 7070 && CONST_INT_P (operands[1])
234f6557 7071 && !satisfies_constraint_I (operands[1]))
6cffc037 7072 {
674a8f0b 7073 /* Handle loading a large integer during reload. */
cffb2a26 7074
6cffc037 7075 /* Writing a constant to memory needs a scratch, which should
7076 be handled with SECONDARY_RELOADs. */
0438d37f 7077 gcc_assert (REG_P (operands[0]));
6cffc037 7078
7079 operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
7080 emit_insn (gen_movsi (operands[0], operands[1]));
7081 DONE;
cffb2a26 7082 }
7083 "
7084)
b11cae9e 7085
cffb2a26 7086(define_insn "*arm_movqi_insn"
fd711051 7087 [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,r,l,r,l,Uu,r,m")
7088 (match_operand:QI 1 "general_operand" "r,r,I,Py,K,Uu,l,m,r"))]
25f905c2 7089 "TARGET_32BIT
cffb2a26 7090 && ( register_operand (operands[0], QImode)
7091 || register_operand (operands[1], QImode))"
5565501b 7092 "@
fd711051 7093 mov%?\\t%0, %1
7094 mov%?\\t%0, %1
65f68e55 7095 mov%?\\t%0, %1
5565501b 7096 mov%?\\t%0, %1
7097 mvn%?\\t%0, #%B1
25f905c2 7098 ldr%(b%)\\t%0, %1
a54e3e7b 7099 str%(b%)\\t%1, %0
7100 ldr%(b%)\\t%0, %1
25f905c2 7101 str%(b%)\\t%1, %0"
1aed5204 7102 [(set_attr "type" "mov_reg,mov_reg,mov_imm,mov_imm,mvn_imm,load1,store1,load1,store1")
a54e3e7b 7103 (set_attr "predicable" "yes")
fd711051 7104 (set_attr "predicable_short_it" "yes,yes,yes,no,no,no,no,no,no")
7105 (set_attr "arch" "t2,any,any,t2,any,t2,t2,any,any")
7106 (set_attr "length" "2,4,4,2,4,2,2,4,4")]
cffb2a26 7107)
7108
25f905c2 7109(define_insn "*thumb1_movqi_insn"
cffb2a26 7110 [(set (match_operand:QI 0 "nonimmediate_operand" "=l,l,m,*r,*h,l")
215b30b3 7111 (match_operand:QI 1 "general_operand" "l, m,l,*h,*r,I"))]
25f905c2 7112 "TARGET_THUMB1
cffb2a26 7113 && ( register_operand (operands[0], QImode)
7114 || register_operand (operands[1], QImode))"
7115 "@
7116 add\\t%0, %1, #0
7117 ldrb\\t%0, %1
7118 strb\\t%1, %0
7119 mov\\t%0, %1
7120 mov\\t%0, %1
7121 mov\\t%0, %1"
7122 [(set_attr "length" "2")
1aed5204 7123 (set_attr "type" "arlo_imm,load1,store1,mov_reg,mov_imm,mov_imm")
747b7458 7124 (set_attr "pool_range" "*,32,*,*,*,*")
7125 (set_attr "conds" "clob,nocond,nocond,nocond,nocond,clob")])
b11cae9e 7126
9b8516be 7127;; HFmode moves
7128(define_expand "movhf"
7129 [(set (match_operand:HF 0 "general_operand" "")
7130 (match_operand:HF 1 "general_operand" ""))]
7131 "TARGET_EITHER"
7132 "
7133 if (TARGET_32BIT)
7134 {
0438d37f 7135 if (MEM_P (operands[0]))
9b8516be 7136 operands[1] = force_reg (HFmode, operands[1]);
7137 }
7138 else /* TARGET_THUMB1 */
7139 {
7140 if (can_create_pseudo_p ())
7141 {
0438d37f 7142 if (!REG_P (operands[0]))
9b8516be 7143 operands[1] = force_reg (HFmode, operands[1]);
7144 }
7145 }
7146 "
7147)
7148
7149(define_insn "*arm32_movhf"
7150 [(set (match_operand:HF 0 "nonimmediate_operand" "=r,m,r,r")
7151 (match_operand:HF 1 "general_operand" " m,r,r,F"))]
7c36fe71 7152 "TARGET_32BIT && !(TARGET_HARD_FLOAT && TARGET_FP16) && !arm_restrict_it
9b8516be 7153 && ( s_register_operand (operands[0], HFmode)
7154 || s_register_operand (operands[1], HFmode))"
7155 "*
7156 switch (which_alternative)
7157 {
7158 case 0: /* ARM register from memory */
7159 return \"ldr%(h%)\\t%0, %1\\t%@ __fp16\";
7160 case 1: /* memory from ARM register */
7161 return \"str%(h%)\\t%1, %0\\t%@ __fp16\";
7162 case 2: /* ARM register from ARM register */
7163 return \"mov%?\\t%0, %1\\t%@ __fp16\";
7164 case 3: /* ARM register from constant */
7165 {
7166 REAL_VALUE_TYPE r;
7167 long bits;
7168 rtx ops[4];
7169
7170 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
7171 bits = real_to_target (NULL, &r, HFmode);
7172 ops[0] = operands[0];
7173 ops[1] = GEN_INT (bits);
7174 ops[2] = GEN_INT (bits & 0xff00);
7175 ops[3] = GEN_INT (bits & 0x00ff);
7176
7177 if (arm_arch_thumb2)
7178 output_asm_insn (\"movw%?\\t%0, %1\", ops);
7179 else
7180 output_asm_insn (\"mov%?\\t%0, %2\;orr%?\\t%0, %0, %3\", ops);
7181 return \"\";
7182 }
7183 default:
7184 gcc_unreachable ();
7185 }
7186 "
7187 [(set_attr "conds" "unconditional")
1aed5204 7188 (set_attr "type" "load1,store1,mov_reg,mov_reg")
9b8516be 7189 (set_attr "length" "4,4,4,8")
d2a518d1 7190 (set_attr "predicable" "yes")]
9b8516be 7191)
7192
7193(define_insn "*thumb1_movhf"
7194 [(set (match_operand:HF 0 "nonimmediate_operand" "=l,l,m,*r,*h")
7195 (match_operand:HF 1 "general_operand" "l,mF,l,*h,*r"))]
7196 "TARGET_THUMB1
7197 && ( s_register_operand (operands[0], HFmode)
7198 || s_register_operand (operands[1], HFmode))"
7199 "*
7200 switch (which_alternative)
7201 {
7202 case 1:
7203 {
7204 rtx addr;
0438d37f 7205 gcc_assert (MEM_P (operands[1]));
9b8516be 7206 addr = XEXP (operands[1], 0);
7207 if (GET_CODE (addr) == LABEL_REF
7208 || (GET_CODE (addr) == CONST
7209 && GET_CODE (XEXP (addr, 0)) == PLUS
7210 && GET_CODE (XEXP (XEXP (addr, 0), 0)) == LABEL_REF
0438d37f 7211 && CONST_INT_P (XEXP (XEXP (addr, 0), 1))))
9b8516be 7212 {
7213 /* Constant pool entry. */
7214 return \"ldr\\t%0, %1\";
7215 }
7216 return \"ldrh\\t%0, %1\";
7217 }
7218 case 2: return \"strh\\t%1, %0\";
7219 default: return \"mov\\t%0, %1\";
7220 }
7221 "
7222 [(set_attr "length" "2")
1aed5204 7223 (set_attr "type" "mov_reg,load1,store1,mov_reg,mov_reg")
42e1de19 7224 (set_attr "pool_range" "*,1018,*,*,*")
747b7458 7225 (set_attr "conds" "clob,nocond,nocond,nocond,nocond")])
9b8516be 7226
87b22bf7 7227(define_expand "movsf"
7228 [(set (match_operand:SF 0 "general_operand" "")
7229 (match_operand:SF 1 "general_operand" ""))]
cffb2a26 7230 "TARGET_EITHER"
87b22bf7 7231 "
25f905c2 7232 if (TARGET_32BIT)
cffb2a26 7233 {
0438d37f 7234 if (MEM_P (operands[0]))
cffb2a26 7235 operands[1] = force_reg (SFmode, operands[1]);
7236 }
25f905c2 7237 else /* TARGET_THUMB1 */
cffb2a26 7238 {
e1ba4a27 7239 if (can_create_pseudo_p ())
cffb2a26 7240 {
0438d37f 7241 if (!REG_P (operands[0]))
cffb2a26 7242 operands[1] = force_reg (SFmode, operands[1]);
7243 }
7244 }
7245 "
7246)
7247
03d440a6 7248;; Transform a floating-point move of a constant into a core register into
7249;; an SImode operation.
cffb2a26 7250(define_split
03d440a6 7251 [(set (match_operand:SF 0 "arm_general_register_operand" "")
cffb2a26 7252 (match_operand:SF 1 "immediate_operand" ""))]
339034d0 7253 "TARGET_EITHER
cffb2a26 7254 && reload_completed
0438d37f 7255 && CONST_DOUBLE_P (operands[1])"
cffb2a26 7256 [(set (match_dup 2) (match_dup 3))]
7257 "
7258 operands[2] = gen_lowpart (SImode, operands[0]);
7259 operands[3] = gen_lowpart (SImode, operands[1]);
7260 if (operands[2] == 0 || operands[3] == 0)
7261 FAIL;
215b30b3 7262 "
7263)
87b22bf7 7264
cffb2a26 7265(define_insn "*arm_movsf_soft_insn"
7266 [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,m")
7267 (match_operand:SF 1 "general_operand" "r,mE,r"))]
cde1623a 7268 "TARGET_32BIT
cffb2a26 7269 && TARGET_SOFT_FLOAT
0438d37f 7270 && (!MEM_P (operands[0])
215b30b3 7271 || register_operand (operands[1], SFmode))"
9a1112d7 7272 "@
7273 mov%?\\t%0, %1
7274 ldr%?\\t%0, %1\\t%@ float
7275 str%?\\t%1, %0\\t%@ float"
cde1623a 7276 [(set_attr "predicable" "yes")
7c36fe71 7277 (set_attr "predicable_short_it" "no")
1aed5204 7278 (set_attr "type" "mov_reg,load1,store1")
42e1de19 7279 (set_attr "arm_pool_range" "*,4096,*")
7280 (set_attr "thumb2_pool_range" "*,4094,*")
cde1623a 7281 (set_attr "arm_neg_pool_range" "*,4084,*")
7282 (set_attr "thumb2_neg_pool_range" "*,0,*")]
cffb2a26 7283)
7284
7285;;; ??? This should have alternatives for constants.
25f905c2 7286(define_insn "*thumb1_movsf_insn"
215b30b3 7287 [(set (match_operand:SF 0 "nonimmediate_operand" "=l,l,>,l, m,*r,*h")
7288 (match_operand:SF 1 "general_operand" "l, >,l,mF,l,*h,*r"))]
25f905c2 7289 "TARGET_THUMB1
cffb2a26 7290 && ( register_operand (operands[0], SFmode)
7291 || register_operand (operands[1], SFmode))"
7292 "@
7293 add\\t%0, %1, #0
7294 ldmia\\t%1, {%0}
7295 stmia\\t%0, {%1}
7296 ldr\\t%0, %1
7297 str\\t%1, %0
7298 mov\\t%0, %1
7299 mov\\t%0, %1"
7300 [(set_attr "length" "2")
1aed5204 7301 (set_attr "type" "*,load1,store1,load1,store1,mov_reg,mov_reg")
42e1de19 7302 (set_attr "pool_range" "*,*,*,1018,*,*,*")
747b7458 7303 (set_attr "conds" "clob,nocond,nocond,nocond,nocond,nocond,nocond")]
cffb2a26 7304)
9a1112d7 7305
9c08d1fa 7306(define_expand "movdf"
87b22bf7 7307 [(set (match_operand:DF 0 "general_operand" "")
7308 (match_operand:DF 1 "general_operand" ""))]
cffb2a26 7309 "TARGET_EITHER"
9c08d1fa 7310 "
25f905c2 7311 if (TARGET_32BIT)
cffb2a26 7312 {
0438d37f 7313 if (MEM_P (operands[0]))
cffb2a26 7314 operands[1] = force_reg (DFmode, operands[1]);
7315 }
7316 else /* TARGET_THUMB */
7317 {
e1ba4a27 7318 if (can_create_pseudo_p ())
cffb2a26 7319 {
0438d37f 7320 if (!REG_P (operands[0]))
cffb2a26 7321 operands[1] = force_reg (DFmode, operands[1]);
7322 }
7323 }
7324 "
7325)
b11cae9e 7326
9c08d1fa 7327;; Reloading a df mode value stored in integer regs to memory can require a
7328;; scratch reg.
7329(define_expand "reload_outdf"
cffb2a26 7330 [(match_operand:DF 0 "arm_reload_memory_operand" "=o")
87b22bf7 7331 (match_operand:DF 1 "s_register_operand" "r")
7332 (match_operand:SI 2 "s_register_operand" "=&r")]
06adefdc 7333 "TARGET_THUMB2"
87b22bf7 7334 "
215b30b3 7335 {
7336 enum rtx_code code = GET_CODE (XEXP (operands[0], 0));
f7fbdd4a 7337
215b30b3 7338 if (code == REG)
7339 operands[2] = XEXP (operands[0], 0);
7340 else if (code == POST_INC || code == PRE_DEC)
7341 {
7342 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7343 operands[1] = gen_rtx_SUBREG (DImode, operands[1], 0);
7344 emit_insn (gen_movdi (operands[0], operands[1]));
7345 DONE;
7346 }
7347 else if (code == PRE_INC)
7348 {
7349 rtx reg = XEXP (XEXP (operands[0], 0), 0);
f7fbdd4a 7350
215b30b3 7351 emit_insn (gen_addsi3 (reg, reg, GEN_INT (8)));
7352 operands[2] = reg;
7353 }
7354 else if (code == POST_DEC)
7355 operands[2] = XEXP (XEXP (operands[0], 0), 0);
7356 else
7357 emit_insn (gen_addsi3 (operands[2], XEXP (XEXP (operands[0], 0), 0),
7358 XEXP (XEXP (operands[0], 0), 1)));
f7fbdd4a 7359
788fcce0 7360 emit_insn (gen_rtx_SET (VOIDmode,
7361 replace_equiv_address (operands[0], operands[2]),
215b30b3 7362 operands[1]));
f7fbdd4a 7363
215b30b3 7364 if (code == POST_DEC)
7365 emit_insn (gen_addsi3 (operands[2], operands[2], GEN_INT (-8)));
7366
7367 DONE;
7368 }"
7369)
9c08d1fa 7370
9a1112d7 7371(define_insn "*movdf_soft_insn"
353cf59a 7372 [(set (match_operand:DF 0 "nonimmediate_soft_df_operand" "=r,r,r,q,m")
7373 (match_operand:DF 1 "soft_df_operand" "rDa,Db,Dc,mF,q"))]
cde1623a 7374 "TARGET_32BIT && TARGET_SOFT_FLOAT
b2778788 7375 && ( register_operand (operands[0], DFmode)
7376 || register_operand (operands[1], DFmode))"
d51f92df 7377 "*
7378 switch (which_alternative)
7379 {
7380 case 0:
7381 case 1:
7382 case 2:
7383 return \"#\";
7384 default:
26ff80c0 7385 return output_move_double (operands, true, NULL);
d51f92df 7386 }
7387 "
359a6e9f 7388 [(set_attr "length" "8,12,16,8,8")
7389 (set_attr "type" "*,*,*,load2,store2")
42e1de19 7390 (set_attr "arm_pool_range" "*,*,*,1020,*")
7391 (set_attr "thumb2_pool_range" "*,*,*,1018,*")
8848d797 7392 (set_attr "arm_neg_pool_range" "*,*,*,1004,*")
cde1623a 7393 (set_attr "thumb2_neg_pool_range" "*,*,*,0,*")]
cffb2a26 7394)
7395
7396;;; ??? This should have alternatives for constants.
7397;;; ??? This was originally identical to the movdi_insn pattern.
7398;;; ??? The 'F' constraint looks funny, but it should always be replaced by
7399;;; thumb_reorg with a memory reference.
7400(define_insn "*thumb_movdf_insn"
215b30b3 7401 [(set (match_operand:DF 0 "nonimmediate_operand" "=l,l,>,l, m,*r")
7402 (match_operand:DF 1 "general_operand" "l, >,l,mF,l,*r"))]
25f905c2 7403 "TARGET_THUMB1
cffb2a26 7404 && ( register_operand (operands[0], DFmode)
7405 || register_operand (operands[1], DFmode))"
7406 "*
7407 switch (which_alternative)
7408 {
7409 default:
7410 case 0:
7411 if (REGNO (operands[1]) == REGNO (operands[0]) + 1)
7412 return \"add\\t%0, %1, #0\;add\\t%H0, %H1, #0\";
7413 return \"add\\t%H0, %H1, #0\;add\\t%0, %1, #0\";
7414 case 1:
7415 return \"ldmia\\t%1, {%0, %H0}\";
7416 case 2:
7417 return \"stmia\\t%0, {%1, %H1}\";
7418 case 3:
7419 return thumb_load_double_from_address (operands);
7420 case 4:
1a83b3ff 7421 operands[2] = gen_rtx_MEM (SImode,
29c05e22 7422 plus_constant (Pmode,
7423 XEXP (operands[0], 0), 4));
cffb2a26 7424 output_asm_insn (\"str\\t%1, %0\;str\\t%H1, %2\", operands);
7425 return \"\";
7426 case 5:
7427 if (REGNO (operands[1]) == REGNO (operands[0]) + 1)
7428 return \"mov\\t%0, %1\;mov\\t%H0, %H1\";
7429 return \"mov\\t%H0, %H1\;mov\\t%0, %1\";
7430 }
7431 "
7432 [(set_attr "length" "4,2,2,6,4,4")
1aed5204 7433 (set_attr "type" "*,load2,store2,load2,store2,mov_reg")
42e1de19 7434 (set_attr "pool_range" "*,*,*,1018,*,*")]
cffb2a26 7435)
b11cae9e 7436\f
b11cae9e 7437
9c08d1fa 7438;; load- and store-multiple insns
7439;; The arm can load/store any set of registers, provided that they are in
320ea44d 7440;; ascending order, but these expanders assume a contiguous set.
b11cae9e 7441
9c08d1fa 7442(define_expand "load_multiple"
7443 [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
7444 (match_operand:SI 1 "" ""))
7445 (use (match_operand:SI 2 "" ""))])]
25f905c2 7446 "TARGET_32BIT"
9580c25f 7447{
7448 HOST_WIDE_INT offset = 0;
7449
bd5b4116 7450 /* Support only fixed point registers. */
0438d37f 7451 if (!CONST_INT_P (operands[2])
9c08d1fa 7452 || INTVAL (operands[2]) > 14
7453 || INTVAL (operands[2]) < 2
0438d37f 7454 || !MEM_P (operands[1])
7455 || !REG_P (operands[0])
bd5b4116 7456 || REGNO (operands[0]) > (LAST_ARM_REGNUM - 1)
7457 || REGNO (operands[0]) + INTVAL (operands[2]) > LAST_ARM_REGNUM)
9c08d1fa 7458 FAIL;
7459
7460 operands[3]
320ea44d 7461 = arm_gen_load_multiple (arm_regs_in_sequence + REGNO (operands[0]),
7462 INTVAL (operands[2]),
f082f1c4 7463 force_reg (SImode, XEXP (operands[1], 0)),
320ea44d 7464 FALSE, operands[1], &offset);
9580c25f 7465})
b11cae9e 7466
9c08d1fa 7467(define_expand "store_multiple"
7468 [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
7469 (match_operand:SI 1 "" ""))
7470 (use (match_operand:SI 2 "" ""))])]
25f905c2 7471 "TARGET_32BIT"
9580c25f 7472{
7473 HOST_WIDE_INT offset = 0;
7474
674a8f0b 7475 /* Support only fixed point registers. */
0438d37f 7476 if (!CONST_INT_P (operands[2])
9c08d1fa 7477 || INTVAL (operands[2]) > 14
7478 || INTVAL (operands[2]) < 2
0438d37f 7479 || !REG_P (operands[1])
7480 || !MEM_P (operands[0])
bd5b4116 7481 || REGNO (operands[1]) > (LAST_ARM_REGNUM - 1)
7482 || REGNO (operands[1]) + INTVAL (operands[2]) > LAST_ARM_REGNUM)
9c08d1fa 7483 FAIL;
7484
7485 operands[3]
320ea44d 7486 = arm_gen_store_multiple (arm_regs_in_sequence + REGNO (operands[1]),
7487 INTVAL (operands[2]),
f082f1c4 7488 force_reg (SImode, XEXP (operands[0], 0)),
320ea44d 7489 FALSE, operands[0], &offset);
9580c25f 7490})
b11cae9e 7491
9c08d1fa 7492
7493;; Move a block of memory if it is word aligned and MORE than 2 words long.
7494;; We could let this apply for blocks of less than this, but it clobbers so
7495;; many registers that there is then probably a better way.
7496
008c057d 7497(define_expand "movmemqi"
34191dd1 7498 [(match_operand:BLK 0 "general_operand" "")
7499 (match_operand:BLK 1 "general_operand" "")
7500 (match_operand:SI 2 "const_int_operand" "")
7501 (match_operand:SI 3 "const_int_operand" "")]
ae51a965 7502 ""
9c08d1fa 7503 "
25f905c2 7504 if (TARGET_32BIT)
cffb2a26 7505 {
ae51a965 7506 if (TARGET_LDRD && current_tune->prefer_ldrd_strd
7507 && !optimize_function_for_size_p (cfun))
7508 {
7509 if (gen_movmem_ldrd_strd (operands))
7510 DONE;
7511 FAIL;
7512 }
7513
008c057d 7514 if (arm_gen_movmemqi (operands))
cffb2a26 7515 DONE;
7516 FAIL;
7517 }
25f905c2 7518 else /* TARGET_THUMB1 */
cffb2a26 7519 {
7520 if ( INTVAL (operands[3]) != 4
7521 || INTVAL (operands[2]) > 48)
7522 FAIL;
7523
008c057d 7524 thumb_expand_movmemqi (operands);
cffb2a26 7525 DONE;
7526 }
7527 "
7528)
7529
2162064c 7530;; Thumb block-move insns
cffb2a26 7531
7532(define_insn "movmem12b"
960f3acf 7533 [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
7534 (mem:SI (match_operand:SI 3 "register_operand" "1")))
7535 (set (mem:SI (plus:SI (match_dup 2) (const_int 4)))
7536 (mem:SI (plus:SI (match_dup 3) (const_int 4))))
7537 (set (mem:SI (plus:SI (match_dup 2) (const_int 8)))
7538 (mem:SI (plus:SI (match_dup 3) (const_int 8))))
7539 (set (match_operand:SI 0 "register_operand" "=l")
7540 (plus:SI (match_dup 2) (const_int 12)))
7541 (set (match_operand:SI 1 "register_operand" "=l")
7542 (plus:SI (match_dup 3) (const_int 12)))
7543 (clobber (match_scratch:SI 4 "=&l"))
7544 (clobber (match_scratch:SI 5 "=&l"))
7545 (clobber (match_scratch:SI 6 "=&l"))]
25f905c2 7546 "TARGET_THUMB1"
cffb2a26 7547 "* return thumb_output_move_mem_multiple (3, operands);"
7548 [(set_attr "length" "4")
215b30b3 7549 ; This isn't entirely accurate... It loads as well, but in terms of
7550 ; scheduling the following insn it is better to consider it as a store
cffb2a26 7551 (set_attr "type" "store3")]
7552)
7553
7554(define_insn "movmem8b"
960f3acf 7555 [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
7556 (mem:SI (match_operand:SI 3 "register_operand" "1")))
7557 (set (mem:SI (plus:SI (match_dup 2) (const_int 4)))
7558 (mem:SI (plus:SI (match_dup 3) (const_int 4))))
7559 (set (match_operand:SI 0 "register_operand" "=l")
7560 (plus:SI (match_dup 2) (const_int 8)))
7561 (set (match_operand:SI 1 "register_operand" "=l")
7562 (plus:SI (match_dup 3) (const_int 8)))
7563 (clobber (match_scratch:SI 4 "=&l"))
7564 (clobber (match_scratch:SI 5 "=&l"))]
25f905c2 7565 "TARGET_THUMB1"
cffb2a26 7566 "* return thumb_output_move_mem_multiple (2, operands);"
7567 [(set_attr "length" "4")
215b30b3 7568 ; This isn't entirely accurate... It loads as well, but in terms of
7569 ; scheduling the following insn it is better to consider it as a store
cffb2a26 7570 (set_attr "type" "store2")]
7571)
7572
9c08d1fa 7573\f
b11cae9e 7574
341940e8 7575;; Compare & branch insns
8d232dc7 7576;; The range calculations are based as follows:
341940e8 7577;; For forward branches, the address calculation returns the address of
7578;; the next instruction. This is 2 beyond the branch instruction.
7579;; For backward branches, the address calculation returns the address of
7580;; the first instruction in this pattern (cmp). This is 2 before the branch
7581;; instruction for the shortest sequence, and 4 before the branch instruction
7582;; if we have to jump around an unconditional branch.
7583;; To the basic branch range the PC offset must be added (this is +4).
7584;; So for forward branches we have
7585;; (pos_range - pos_base_offs + pc_offs) = (pos_range - 2 + 4).
7586;; And for backward branches we have
7587;; (neg_range - neg_base_offs + pc_offs) = (neg_range - (-2 or -4) + 4).
7588;;
7589;; For a 'b' pos_range = 2046, neg_range = -2048 giving (-2040->2048).
7590;; For a 'b<cond>' pos_range = 254, neg_range = -256 giving (-250 ->256).
cffb2a26 7591
aeac46d4 7592(define_expand "cbranchsi4"
7593 [(set (pc) (if_then_else
aa06947a 7594 (match_operator 0 "expandable_comparison_operator"
aeac46d4 7595 [(match_operand:SI 1 "s_register_operand" "")
7596 (match_operand:SI 2 "nonmemory_operand" "")])
7597 (label_ref (match_operand 3 "" ""))
7598 (pc)))]
f9aa4160 7599 "TARGET_EITHER"
aeac46d4 7600 "
74f4459c 7601 if (!TARGET_THUMB1)
7602 {
f9aa4160 7603 if (!arm_validize_comparison (&operands[0], &operands[1], &operands[2]))
7604 FAIL;
74f4459c 7605 emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
7606 operands[3]));
7607 DONE;
7608 }
25f905c2 7609 if (thumb1_cmpneg_operand (operands[2], SImode))
aeac46d4 7610 {
7611 emit_jump_insn (gen_cbranchsi4_scratch (NULL, operands[1], operands[2],
7612 operands[3], operands[0]));
7613 DONE;
7614 }
25f905c2 7615 if (!thumb1_cmp_operand (operands[2], SImode))
aeac46d4 7616 operands[2] = force_reg (SImode, operands[2]);
7617 ")
7618
a8e6c15d 7619;; A pattern to recognize a special situation and optimize for it.
7620;; On the thumb, zero-extension from memory is preferrable to sign-extension
7621;; due to the available addressing modes. Hence, convert a signed comparison
7622;; with zero into an unsigned comparison with 127 if possible.
7623(define_expand "cbranchqi4"
7624 [(set (pc) (if_then_else
7625 (match_operator 0 "lt_ge_comparison_operator"
7626 [(match_operand:QI 1 "memory_operand" "")
7627 (match_operand:QI 2 "const0_operand" "")])
7628 (label_ref (match_operand 3 "" ""))
7629 (pc)))]
7630 "TARGET_THUMB1"
7631{
d0f6c30d 7632 rtx xops[4];
a8e6c15d 7633 xops[1] = gen_reg_rtx (SImode);
7634 emit_insn (gen_zero_extendqisi2 (xops[1], operands[1]));
7635 xops[2] = GEN_INT (127);
7636 xops[0] = gen_rtx_fmt_ee (GET_CODE (operands[0]) == GE ? LEU : GTU,
7637 VOIDmode, xops[1], xops[2]);
7638 xops[3] = operands[3];
7639 emit_insn (gen_cbranchsi4 (xops[0], xops[1], xops[2], xops[3]));
7640 DONE;
7641})
7642
74f4459c 7643(define_expand "cbranchsf4"
7644 [(set (pc) (if_then_else
aa06947a 7645 (match_operator 0 "expandable_comparison_operator"
74f4459c 7646 [(match_operand:SF 1 "s_register_operand" "")
7647 (match_operand:SF 2 "arm_float_compare_operand" "")])
7648 (label_ref (match_operand 3 "" ""))
7649 (pc)))]
7650 "TARGET_32BIT && TARGET_HARD_FLOAT"
7651 "emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
7652 operands[3])); DONE;"
7653)
7654
7655(define_expand "cbranchdf4"
7656 [(set (pc) (if_then_else
aa06947a 7657 (match_operator 0 "expandable_comparison_operator"
74f4459c 7658 [(match_operand:DF 1 "s_register_operand" "")
7659 (match_operand:DF 2 "arm_float_compare_operand" "")])
7660 (label_ref (match_operand 3 "" ""))
7661 (pc)))]
a50d7267 7662 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
74f4459c 7663 "emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
7664 operands[3])); DONE;"
7665)
7666
74f4459c 7667(define_expand "cbranchdi4"
7668 [(set (pc) (if_then_else
aa06947a 7669 (match_operator 0 "expandable_comparison_operator"
b8eae306 7670 [(match_operand:DI 1 "s_register_operand" "")
a8045a4f 7671 (match_operand:DI 2 "cmpdi_operand" "")])
74f4459c 7672 (label_ref (match_operand 3 "" ""))
7673 (pc)))]
a8045a4f 7674 "TARGET_32BIT"
7675 "{
0438d37f 7676 if (!arm_validize_comparison (&operands[0], &operands[1], &operands[2]))
f9aa4160 7677 FAIL;
7678 emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
a8045a4f 7679 operands[3]));
7680 DONE;
7681 }"
74f4459c 7682)
7683
d60047aa 7684(define_insn "cbranchsi4_insn"
aeac46d4 7685 [(set (pc) (if_then_else
7686 (match_operator 0 "arm_comparison_operator"
747b7458 7687 [(match_operand:SI 1 "s_register_operand" "l,l*h")
25f905c2 7688 (match_operand:SI 2 "thumb1_cmp_operand" "lI*h,*r")])
aeac46d4 7689 (label_ref (match_operand 3 "" ""))
7690 (pc)))]
25f905c2 7691 "TARGET_THUMB1"
747b7458 7692{
7693 rtx t = cfun->machine->thumb1_cc_insn;
7694 if (t != NULL_RTX)
d60047aa 7695 {
747b7458 7696 if (!rtx_equal_p (cfun->machine->thumb1_cc_op0, operands[1])
7697 || !rtx_equal_p (cfun->machine->thumb1_cc_op1, operands[2]))
7698 t = NULL_RTX;
7699 if (cfun->machine->thumb1_cc_mode == CC_NOOVmode)
7700 {
7701 if (!noov_comparison_operator (operands[0], VOIDmode))
7702 t = NULL_RTX;
7703 }
7704 else if (cfun->machine->thumb1_cc_mode != CCmode)
d60047aa 7705 t = NULL_RTX;
7706 }
d60047aa 7707 if (t == NULL_RTX)
747b7458 7708 {
7709 output_asm_insn ("cmp\t%1, %2", operands);
7710 cfun->machine->thumb1_cc_insn = insn;
7711 cfun->machine->thumb1_cc_op0 = operands[1];
7712 cfun->machine->thumb1_cc_op1 = operands[2];
7713 cfun->machine->thumb1_cc_mode = CCmode;
7714 }
7715 else
7716 /* Ensure we emit the right type of condition code on the jump. */
7717 XEXP (operands[0], 0) = gen_rtx_REG (cfun->machine->thumb1_cc_mode,
7718 CC_REGNUM);
aeac46d4 7719
cffb2a26 7720 switch (get_attr_length (insn))
7721 {
7722 case 4: return \"b%d0\\t%l3\";
7723 case 6: return \"b%D0\\t.LCB%=\;b\\t%l3\\t%@long jump\\n.LCB%=:\";
7724 default: return \"b%D0\\t.LCB%=\;bl\\t%l3\\t%@far jump\\n.LCB%=:\";
7725 }
747b7458 7726}
cffb2a26 7727 [(set (attr "far_jump")
7728 (if_then_else
7729 (eq_attr "length" "8")
7730 (const_string "yes")
7731 (const_string "no")))
7732 (set (attr "length")
7733 (if_then_else
7734 (and (ge (minus (match_dup 3) (pc)) (const_int -250))
7735 (le (minus (match_dup 3) (pc)) (const_int 256)))
7736 (const_int 4)
7737 (if_then_else
7738 (and (ge (minus (match_dup 3) (pc)) (const_int -2040))
341940e8 7739 (le (minus (match_dup 3) (pc)) (const_int 2048)))
cffb2a26 7740 (const_int 6)
7741 (const_int 8))))]
7742)
7743
aeac46d4 7744(define_insn "cbranchsi4_scratch"
7745 [(set (pc) (if_then_else
7746 (match_operator 4 "arm_comparison_operator"
7747 [(match_operand:SI 1 "s_register_operand" "l,0")
25f905c2 7748 (match_operand:SI 2 "thumb1_cmpneg_operand" "L,J")])
aeac46d4 7749 (label_ref (match_operand 3 "" ""))
7750 (pc)))
7751 (clobber (match_scratch:SI 0 "=l,l"))]
25f905c2 7752 "TARGET_THUMB1"
aeac46d4 7753 "*
7754 output_asm_insn (\"add\\t%0, %1, #%n2\", operands);
7755
7756 switch (get_attr_length (insn))
7757 {
7758 case 4: return \"b%d4\\t%l3\";
7759 case 6: return \"b%D4\\t.LCB%=\;b\\t%l3\\t%@long jump\\n.LCB%=:\";
7760 default: return \"b%D4\\t.LCB%=\;bl\\t%l3\\t%@far jump\\n.LCB%=:\";
7761 }
7762 "
7763 [(set (attr "far_jump")
7764 (if_then_else
7765 (eq_attr "length" "8")
7766 (const_string "yes")
7767 (const_string "no")))
7768 (set (attr "length")
7769 (if_then_else
7770 (and (ge (minus (match_dup 3) (pc)) (const_int -250))
7771 (le (minus (match_dup 3) (pc)) (const_int 256)))
7772 (const_int 4)
7773 (if_then_else
7774 (and (ge (minus (match_dup 3) (pc)) (const_int -2040))
7775 (le (minus (match_dup 3) (pc)) (const_int 2048)))
7776 (const_int 6)
7777 (const_int 8))))]
7778)
446a1e96 7779
cffb2a26 7780(define_insn "*negated_cbranchsi4"
7781 [(set (pc)
7782 (if_then_else
aed179ae 7783 (match_operator 0 "equality_operator"
aeac46d4 7784 [(match_operand:SI 1 "s_register_operand" "l")
7785 (neg:SI (match_operand:SI 2 "s_register_operand" "l"))])
7786 (label_ref (match_operand 3 "" ""))
215b30b3 7787 (pc)))]
25f905c2 7788 "TARGET_THUMB1"
cffb2a26 7789 "*
7790 output_asm_insn (\"cmn\\t%1, %2\", operands);
7791 switch (get_attr_length (insn))
7792 {
7793 case 4: return \"b%d0\\t%l3\";
7794 case 6: return \"b%D0\\t.LCB%=\;b\\t%l3\\t%@long jump\\n.LCB%=:\";
7795 default: return \"b%D0\\t.LCB%=\;bl\\t%l3\\t%@far jump\\n.LCB%=:\";
7796 }
7797 "
7798 [(set (attr "far_jump")
7799 (if_then_else
7800 (eq_attr "length" "8")
7801 (const_string "yes")
7802 (const_string "no")))
7803 (set (attr "length")
7804 (if_then_else
7805 (and (ge (minus (match_dup 3) (pc)) (const_int -250))
341940e8 7806 (le (minus (match_dup 3) (pc)) (const_int 256)))
cffb2a26 7807 (const_int 4)
7808 (if_then_else
341940e8 7809 (and (ge (minus (match_dup 3) (pc)) (const_int -2040))
7810 (le (minus (match_dup 3) (pc)) (const_int 2048)))
cffb2a26 7811 (const_int 6)
7812 (const_int 8))))]
7813)
7814
58d6528b 7815(define_insn "*tbit_cbranch"
7816 [(set (pc)
7817 (if_then_else
7818 (match_operator 0 "equality_operator"
7819 [(zero_extract:SI (match_operand:SI 1 "s_register_operand" "l")
7820 (const_int 1)
7821 (match_operand:SI 2 "const_int_operand" "i"))
7822 (const_int 0)])
7823 (label_ref (match_operand 3 "" ""))
7824 (pc)))
7825 (clobber (match_scratch:SI 4 "=l"))]
25f905c2 7826 "TARGET_THUMB1"
58d6528b 7827 "*
7828 {
7829 rtx op[3];
7830 op[0] = operands[4];
7831 op[1] = operands[1];
7832 op[2] = GEN_INT (32 - 1 - INTVAL (operands[2]));
7833
86efa74d 7834 output_asm_insn (\"lsl\\t%0, %1, %2\", op);
7835 switch (get_attr_length (insn))
7836 {
7837 case 4: return \"b%d0\\t%l3\";
7838 case 6: return \"b%D0\\t.LCB%=\;b\\t%l3\\t%@long jump\\n.LCB%=:\";
7839 default: return \"b%D0\\t.LCB%=\;bl\\t%l3\\t%@far jump\\n.LCB%=:\";
7840 }
7841 }"
7842 [(set (attr "far_jump")
7843 (if_then_else
7844 (eq_attr "length" "8")
7845 (const_string "yes")
7846 (const_string "no")))
7847 (set (attr "length")
7848 (if_then_else
7849 (and (ge (minus (match_dup 3) (pc)) (const_int -250))
7850 (le (minus (match_dup 3) (pc)) (const_int 256)))
7851 (const_int 4)
7852 (if_then_else
7853 (and (ge (minus (match_dup 3) (pc)) (const_int -2040))
7854 (le (minus (match_dup 3) (pc)) (const_int 2048)))
7855 (const_int 6)
7856 (const_int 8))))]
7857)
7858
7859(define_insn "*tlobits_cbranch"
7860 [(set (pc)
7861 (if_then_else
7862 (match_operator 0 "equality_operator"
7863 [(zero_extract:SI (match_operand:SI 1 "s_register_operand" "l")
7864 (match_operand:SI 2 "const_int_operand" "i")
7865 (const_int 0))
7866 (const_int 0)])
7867 (label_ref (match_operand 3 "" ""))
7868 (pc)))
7869 (clobber (match_scratch:SI 4 "=l"))]
25f905c2 7870 "TARGET_THUMB1"
86efa74d 7871 "*
7872 {
7873 rtx op[3];
7874 op[0] = operands[4];
7875 op[1] = operands[1];
7876 op[2] = GEN_INT (32 - INTVAL (operands[2]));
7877
58d6528b 7878 output_asm_insn (\"lsl\\t%0, %1, %2\", op);
7879 switch (get_attr_length (insn))
7880 {
7881 case 4: return \"b%d0\\t%l3\";
7882 case 6: return \"b%D0\\t.LCB%=\;b\\t%l3\\t%@long jump\\n.LCB%=:\";
7883 default: return \"b%D0\\t.LCB%=\;bl\\t%l3\\t%@far jump\\n.LCB%=:\";
7884 }
7885 }"
7886 [(set (attr "far_jump")
7887 (if_then_else
7888 (eq_attr "length" "8")
7889 (const_string "yes")
7890 (const_string "no")))
7891 (set (attr "length")
7892 (if_then_else
7893 (and (ge (minus (match_dup 3) (pc)) (const_int -250))
7894 (le (minus (match_dup 3) (pc)) (const_int 256)))
7895 (const_int 4)
7896 (if_then_else
7897 (and (ge (minus (match_dup 3) (pc)) (const_int -2040))
7898 (le (minus (match_dup 3) (pc)) (const_int 2048)))
7899 (const_int 6)
7900 (const_int 8))))]
7901)
747b7458 7902
aeac46d4 7903(define_insn "*tstsi3_cbranch"
58d6528b 7904 [(set (pc)
7905 (if_then_else
aeac46d4 7906 (match_operator 3 "equality_operator"
7907 [(and:SI (match_operand:SI 0 "s_register_operand" "%l")
7908 (match_operand:SI 1 "s_register_operand" "l"))
58d6528b 7909 (const_int 0)])
aeac46d4 7910 (label_ref (match_operand 2 "" ""))
7911 (pc)))]
25f905c2 7912 "TARGET_THUMB1"
58d6528b 7913 "*
7914 {
aeac46d4 7915 output_asm_insn (\"tst\\t%0, %1\", operands);
58d6528b 7916 switch (get_attr_length (insn))
7917 {
aeac46d4 7918 case 4: return \"b%d3\\t%l2\";
7919 case 6: return \"b%D3\\t.LCB%=\;b\\t%l2\\t%@long jump\\n.LCB%=:\";
7920 default: return \"b%D3\\t.LCB%=\;bl\\t%l2\\t%@far jump\\n.LCB%=:\";
58d6528b 7921 }
7922 }"
7923 [(set (attr "far_jump")
7924 (if_then_else
7925 (eq_attr "length" "8")
7926 (const_string "yes")
7927 (const_string "no")))
7928 (set (attr "length")
7929 (if_then_else
aeac46d4 7930 (and (ge (minus (match_dup 2) (pc)) (const_int -250))
7931 (le (minus (match_dup 2) (pc)) (const_int 256)))
58d6528b 7932 (const_int 4)
7933 (if_then_else
aeac46d4 7934 (and (ge (minus (match_dup 2) (pc)) (const_int -2040))
7935 (le (minus (match_dup 2) (pc)) (const_int 2048)))
58d6528b 7936 (const_int 6)
7937 (const_int 8))))]
7938)
7939
203c488f 7940(define_insn "*cbranchne_decr1"
7941 [(set (pc)
7942 (if_then_else (match_operator 3 "equality_operator"
7943 [(match_operand:SI 2 "s_register_operand" "l,l,1,l")
7944 (const_int 0)])
7945 (label_ref (match_operand 4 "" ""))
7946 (pc)))
aeac46d4 7947 (set (match_operand:SI 0 "thumb_cbrch_target_operand" "=l,*?h,*?m,*?m")
203c488f 7948 (plus:SI (match_dup 2) (const_int -1)))
7949 (clobber (match_scratch:SI 1 "=X,l,&l,&l"))]
25f905c2 7950 "TARGET_THUMB1"
203c488f 7951 "*
7952 {
7953 rtx cond[2];
7954 cond[0] = gen_rtx_fmt_ee ((GET_CODE (operands[3]) == NE
7955 ? GEU : LTU),
58d6528b 7956 VOIDmode, operands[2], const1_rtx);
203c488f 7957 cond[1] = operands[4];
7958
7959 if (which_alternative == 0)
7960 output_asm_insn (\"sub\\t%0, %2, #1\", operands);
7961 else if (which_alternative == 1)
7962 {
7963 /* We must provide an alternative for a hi reg because reload
7964 cannot handle output reloads on a jump instruction, but we
7965 can't subtract into that. Fortunately a mov from lo to hi
7966 does not clobber the condition codes. */
7967 output_asm_insn (\"sub\\t%1, %2, #1\", operands);
7968 output_asm_insn (\"mov\\t%0, %1\", operands);
7969 }
7970 else
7971 {
7972 /* Similarly, but the target is memory. */
7973 output_asm_insn (\"sub\\t%1, %2, #1\", operands);
7974 output_asm_insn (\"str\\t%1, %0\", operands);
7975 }
7976
7977 switch (get_attr_length (insn) - (which_alternative ? 2 : 0))
7978 {
7979 case 4:
8aea555f 7980 output_asm_insn (\"b%d0\\t%l1\", cond);
203c488f 7981 return \"\";
7982 case 6:
8aea555f 7983 output_asm_insn (\"b%D0\\t.LCB%=\", cond);
203c488f 7984 return \"b\\t%l4\\t%@long jump\\n.LCB%=:\";
7985 default:
8aea555f 7986 output_asm_insn (\"b%D0\\t.LCB%=\", cond);
203c488f 7987 return \"bl\\t%l4\\t%@far jump\\n.LCB%=:\";
7988 }
7989 }
7990 "
7991 [(set (attr "far_jump")
7992 (if_then_else
7993 (ior (and (eq (symbol_ref ("which_alternative"))
7994 (const_int 0))
7995 (eq_attr "length" "8"))
7996 (eq_attr "length" "10"))
7997 (const_string "yes")
7998 (const_string "no")))
7999 (set_attr_alternative "length"
8000 [
8001 ;; Alternative 0
8002 (if_then_else
8003 (and (ge (minus (match_dup 4) (pc)) (const_int -250))
8004 (le (minus (match_dup 4) (pc)) (const_int 256)))
8005 (const_int 4)
8006 (if_then_else
8007 (and (ge (minus (match_dup 4) (pc)) (const_int -2040))
8008 (le (minus (match_dup 4) (pc)) (const_int 2048)))
8009 (const_int 6)
8010 (const_int 8)))
8011 ;; Alternative 1
8012 (if_then_else
8013 (and (ge (minus (match_dup 4) (pc)) (const_int -248))
8014 (le (minus (match_dup 4) (pc)) (const_int 256)))
8015 (const_int 6)
8016 (if_then_else
8017 (and (ge (minus (match_dup 4) (pc)) (const_int -2038))
8018 (le (minus (match_dup 4) (pc)) (const_int 2048)))
8019 (const_int 8)
8020 (const_int 10)))
8021 ;; Alternative 2
8022 (if_then_else
8023 (and (ge (minus (match_dup 4) (pc)) (const_int -248))
8024 (le (minus (match_dup 4) (pc)) (const_int 256)))
8025 (const_int 6)
8026 (if_then_else
8027 (and (ge (minus (match_dup 4) (pc)) (const_int -2038))
8028 (le (minus (match_dup 4) (pc)) (const_int 2048)))
8029 (const_int 8)
8030 (const_int 10)))
8031 ;; Alternative 3
8032 (if_then_else
8033 (and (ge (minus (match_dup 4) (pc)) (const_int -248))
8034 (le (minus (match_dup 4) (pc)) (const_int 256)))
8035 (const_int 6)
8036 (if_then_else
8037 (and (ge (minus (match_dup 4) (pc)) (const_int -2038))
8038 (le (minus (match_dup 4) (pc)) (const_int 2048)))
8039 (const_int 8)
8040 (const_int 10)))])]
8041)
cffb2a26 8042
58d6528b 8043(define_insn "*addsi3_cbranch"
8044 [(set (pc)
8045 (if_then_else
b0694be0 8046 (match_operator 4 "arm_comparison_operator"
58d6528b 8047 [(plus:SI
e54011cb 8048 (match_operand:SI 2 "s_register_operand" "%0,l,*l,1,1,1")
8049 (match_operand:SI 3 "reg_or_int_operand" "IJ,lL,*l,lIJ,lIJ,lIJ"))
58d6528b 8050 (const_int 0)])
8051 (label_ref (match_operand 5 "" ""))
8052 (pc)))
aeac46d4 8053 (set
8054 (match_operand:SI 0 "thumb_cbrch_target_operand" "=l,l,*!h,*?h,*?m,*?m")
8055 (plus:SI (match_dup 2) (match_dup 3)))
956a6170 8056 (clobber (match_scratch:SI 1 "=X,X,l,l,&l,&l"))]
25f905c2 8057 "TARGET_THUMB1
58d6528b 8058 && (GET_CODE (operands[4]) == EQ
8059 || GET_CODE (operands[4]) == NE
8060 || GET_CODE (operands[4]) == GE
8061 || GET_CODE (operands[4]) == LT)"
8062 "*
8063 {
8064 rtx cond[3];
8065
956a6170 8066 cond[0] = (which_alternative < 2) ? operands[0] : operands[1];
58d6528b 8067 cond[1] = operands[2];
8068 cond[2] = operands[3];
8069
0438d37f 8070 if (CONST_INT_P (cond[2]) && INTVAL (cond[2]) < 0)
58d6528b 8071 output_asm_insn (\"sub\\t%0, %1, #%n2\", cond);
8072 else
8073 output_asm_insn (\"add\\t%0, %1, %2\", cond);
8074
956a6170 8075 if (which_alternative >= 2
58d6528b 8076 && which_alternative < 4)
8077 output_asm_insn (\"mov\\t%0, %1\", operands);
8078 else if (which_alternative >= 4)
8079 output_asm_insn (\"str\\t%1, %0\", operands);
8080
d0f6c30d 8081 switch (get_attr_length (insn) - ((which_alternative >= 2) ? 2 : 0))
58d6528b 8082 {
8083 case 4:
8084 return \"b%d4\\t%l5\";
8085 case 6:
8086 return \"b%D4\\t.LCB%=\;b\\t%l5\\t%@long jump\\n.LCB%=:\";
8087 default:
8088 return \"b%D4\\t.LCB%=\;bl\\t%l5\\t%@far jump\\n.LCB%=:\";
8089 }
8090 }
8091 "
8092 [(set (attr "far_jump")
8093 (if_then_else
8094 (ior (and (lt (symbol_ref ("which_alternative"))
d0f6c30d 8095 (const_int 2))
58d6528b 8096 (eq_attr "length" "8"))
8097 (eq_attr "length" "10"))
8098 (const_string "yes")
8099 (const_string "no")))
8100 (set (attr "length")
8101 (if_then_else
8102 (lt (symbol_ref ("which_alternative"))
d0f6c30d 8103 (const_int 2))
58d6528b 8104 (if_then_else
8105 (and (ge (minus (match_dup 5) (pc)) (const_int -250))
8106 (le (minus (match_dup 5) (pc)) (const_int 256)))
8107 (const_int 4)
8108 (if_then_else
8109 (and (ge (minus (match_dup 5) (pc)) (const_int -2040))
8110 (le (minus (match_dup 5) (pc)) (const_int 2048)))
8111 (const_int 6)
8112 (const_int 8)))
8113 (if_then_else
8114 (and (ge (minus (match_dup 5) (pc)) (const_int -248))
8115 (le (minus (match_dup 5) (pc)) (const_int 256)))
8116 (const_int 6)
8117 (if_then_else
8118 (and (ge (minus (match_dup 5) (pc)) (const_int -2038))
8119 (le (minus (match_dup 5) (pc)) (const_int 2048)))
8120 (const_int 8)
8121 (const_int 10)))))]
8122)
8123
8124(define_insn "*addsi3_cbranch_scratch"
8125 [(set (pc)
8126 (if_then_else
b0694be0 8127 (match_operator 3 "arm_comparison_operator"
58d6528b 8128 [(plus:SI
8129 (match_operand:SI 1 "s_register_operand" "%l,l,l,0")
3a445a04 8130 (match_operand:SI 2 "reg_or_int_operand" "J,l,L,IJ"))
58d6528b 8131 (const_int 0)])
8132 (label_ref (match_operand 4 "" ""))
8133 (pc)))
8134 (clobber (match_scratch:SI 0 "=X,X,l,l"))]
25f905c2 8135 "TARGET_THUMB1
58d6528b 8136 && (GET_CODE (operands[3]) == EQ
8137 || GET_CODE (operands[3]) == NE
8138 || GET_CODE (operands[3]) == GE
8139 || GET_CODE (operands[3]) == LT)"
8140 "*
8141 {
8142 switch (which_alternative)
8143 {
8144 case 0:
8145 output_asm_insn (\"cmp\t%1, #%n2\", operands);
8146 break;
8147 case 1:
8148 output_asm_insn (\"cmn\t%1, %2\", operands);
8149 break;
0f5e9701 8150 case 2:
3a445a04 8151 if (INTVAL (operands[2]) < 0)
8152 output_asm_insn (\"sub\t%0, %1, %2\", operands);
8153 else
8154 output_asm_insn (\"add\t%0, %1, %2\", operands);
58d6528b 8155 break;
0f5e9701 8156 case 3:
3a445a04 8157 if (INTVAL (operands[2]) < 0)
8158 output_asm_insn (\"sub\t%0, %0, %2\", operands);
8159 else
8160 output_asm_insn (\"add\t%0, %0, %2\", operands);
58d6528b 8161 break;
8162 }
8163
8164 switch (get_attr_length (insn))
8165 {
8166 case 4:
8167 return \"b%d3\\t%l4\";
8168 case 6:
8169 return \"b%D3\\t.LCB%=\;b\\t%l4\\t%@long jump\\n.LCB%=:\";
8170 default:
8171 return \"b%D3\\t.LCB%=\;bl\\t%l4\\t%@far jump\\n.LCB%=:\";
8172 }
8173 }
8174 "
8175 [(set (attr "far_jump")
8176 (if_then_else
8177 (eq_attr "length" "8")
8178 (const_string "yes")
8179 (const_string "no")))
8180 (set (attr "length")
8181 (if_then_else
8182 (and (ge (minus (match_dup 4) (pc)) (const_int -250))
8183 (le (minus (match_dup 4) (pc)) (const_int 256)))
8184 (const_int 4)
8185 (if_then_else
8186 (and (ge (minus (match_dup 4) (pc)) (const_int -2040))
8187 (le (minus (match_dup 4) (pc)) (const_int 2048)))
8188 (const_int 6)
8189 (const_int 8))))]
8190)
8191
58d6528b 8192
9c08d1fa 8193;; Comparison and test insns
8194
cffb2a26 8195(define_insn "*arm_cmpsi_insn"
bd5b4116 8196 [(set (reg:CC CC_REGNUM)
a6864a24 8197 (compare:CC (match_operand:SI 0 "s_register_operand" "l,r,r,r")
8198 (match_operand:SI 1 "arm_add_operand" "Py,r,rI,L")))]
25f905c2 8199 "TARGET_32BIT"
5565501b 8200 "@
a6864a24 8201 cmp%?\\t%0, %1
8202 cmp%?\\t%0, %1
aea4c774 8203 cmp%?\\t%0, %1
8204 cmn%?\\t%0, #%n1"
a6864a24 8205 [(set_attr "conds" "set")
8206 (set_attr "arch" "t2,t2,any,any")
596e5e8f 8207 (set_attr "length" "2,2,4,4")
65f68e55 8208 (set_attr "predicable" "yes")
6b6abc9c 8209 (set_attr "type" "*,*,*,arlo_imm")]
cffb2a26 8210)
b11cae9e 8211
d5d4dc8d 8212(define_insn "*cmpsi_shiftsi"
bd5b4116 8213 [(set (reg:CC CC_REGNUM)
d5d4dc8d 8214 (compare:CC (match_operand:SI 0 "s_register_operand" "r,r")
cffb2a26 8215 (match_operator:SI 3 "shift_operator"
d5d4dc8d 8216 [(match_operand:SI 1 "s_register_operand" "r,r")
8217 (match_operand:SI 2 "shift_amount_operand" "M,rM")])))]
8218 "TARGET_32BIT"
aea4c774 8219 "cmp%?\\t%0, %1%S3"
344495ea 8220 [(set_attr "conds" "set")
331beb1a 8221 (set_attr "shift" "1")
d5d4dc8d 8222 (set_attr "arch" "32,a")
6b6abc9c 8223 (set_attr "type" "arlo_shift,arlo_shift_reg")])
b11cae9e 8224
d5d4dc8d 8225(define_insn "*cmpsi_shiftsi_swp"
bd5b4116 8226 [(set (reg:CC_SWP CC_REGNUM)
aea4c774 8227 (compare:CC_SWP (match_operator:SI 3 "shift_operator"
d5d4dc8d 8228 [(match_operand:SI 1 "s_register_operand" "r,r")
8229 (match_operand:SI 2 "shift_amount_operand" "M,rM")])
8230 (match_operand:SI 0 "s_register_operand" "r,r")))]
8231 "TARGET_32BIT"
aea4c774 8232 "cmp%?\\t%0, %1%S3"
344495ea 8233 [(set_attr "conds" "set")
331beb1a 8234 (set_attr "shift" "1")
d5d4dc8d 8235 (set_attr "arch" "32,a")
6b6abc9c 8236 (set_attr "type" "arlo_shift,arlo_shift_reg")])
b11cae9e 8237
25f905c2 8238(define_insn "*arm_cmpsi_negshiftsi_si"
aed179ae 8239 [(set (reg:CC_Z CC_REGNUM)
8240 (compare:CC_Z
8241 (neg:SI (match_operator:SI 1 "shift_operator"
8242 [(match_operand:SI 2 "s_register_operand" "r")
8243 (match_operand:SI 3 "reg_or_int_operand" "rM")]))
8244 (match_operand:SI 0 "s_register_operand" "r")))]
cffb2a26 8245 "TARGET_ARM"
aed179ae 8246 "cmn%?\\t%0, %2%S1"
344495ea 8247 [(set_attr "conds" "set")
aed179ae 8248 (set (attr "type") (if_then_else (match_operand 3 "const_int_operand" "")
6b6abc9c 8249 (const_string "arlo_shift")
8250 (const_string "arlo_shift_reg")))
596e5e8f 8251 (set_attr "predicable" "yes")]
0d66636f 8252)
b11cae9e 8253
a8045a4f 8254;; DImode comparisons. The generic code generates branches that
8255;; if-conversion can not reduce to a conditional compare, so we do
8256;; that directly.
8257
ba6a3b2f 8258(define_insn_and_split "*arm_cmpdi_insn"
a8045a4f 8259 [(set (reg:CC_NCV CC_REGNUM)
8260 (compare:CC_NCV (match_operand:DI 0 "s_register_operand" "r")
8261 (match_operand:DI 1 "arm_di_operand" "rDi")))
8262 (clobber (match_scratch:SI 2 "=r"))]
b805622c 8263 "TARGET_32BIT"
ba6a3b2f 8264 "#" ; "cmp\\t%Q0, %Q1\;sbcs\\t%2, %R0, %R1"
8265 "&& reload_completed"
8266 [(set (reg:CC CC_REGNUM)
8267 (compare:CC (match_dup 0) (match_dup 1)))
8268 (parallel [(set (reg:CC CC_REGNUM)
8269 (compare:CC (match_dup 3) (match_dup 4)))
8270 (set (match_dup 2)
8271 (minus:SI (match_dup 5)
8272 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))])]
8273 {
8274 operands[3] = gen_highpart (SImode, operands[0]);
8275 operands[0] = gen_lowpart (SImode, operands[0]);
8276 if (CONST_INT_P (operands[1]))
8277 {
8278 operands[4] = GEN_INT (~INTVAL (gen_highpart_mode (SImode,
8279 DImode,
8280 operands[1])));
8281 operands[5] = gen_rtx_PLUS (SImode, operands[3], operands[4]);
8282 }
8283 else
8284 {
8285 operands[4] = gen_highpart (SImode, operands[1]);
8286 operands[5] = gen_rtx_MINUS (SImode, operands[3], operands[4]);
8287 }
8288 operands[1] = gen_lowpart (SImode, operands[1]);
8289 operands[2] = gen_lowpart (SImode, operands[2]);
8290 }
a8045a4f 8291 [(set_attr "conds" "set")
8292 (set_attr "length" "8")]
8293)
8294
ba6a3b2f 8295(define_insn_and_split "*arm_cmpdi_unsigned"
a8045a4f 8296 [(set (reg:CC_CZ CC_REGNUM)
7c36fe71 8297 (compare:CC_CZ (match_operand:DI 0 "s_register_operand" "l,r,r")
8298 (match_operand:DI 1 "arm_di_operand" "Py,r,rDi")))]
8299
48a98053 8300 "TARGET_32BIT"
ba6a3b2f 8301 "#" ; "cmp\\t%R0, %R1\;it eq\;cmpeq\\t%Q0, %Q1"
8302 "&& reload_completed"
8303 [(set (reg:CC CC_REGNUM)
8304 (compare:CC (match_dup 2) (match_dup 3)))
8305 (cond_exec (eq:SI (reg:CC CC_REGNUM) (const_int 0))
8306 (set (reg:CC CC_REGNUM)
8307 (compare:CC (match_dup 0) (match_dup 1))))]
8308 {
8309 operands[2] = gen_highpart (SImode, operands[0]);
8310 operands[0] = gen_lowpart (SImode, operands[0]);
8311 if (CONST_INT_P (operands[1]))
8312 operands[3] = gen_highpart_mode (SImode, DImode, operands[1]);
8313 else
8314 operands[3] = gen_highpart (SImode, operands[1]);
8315 operands[1] = gen_lowpart (SImode, operands[1]);
8316 }
a8045a4f 8317 [(set_attr "conds" "set")
7c36fe71 8318 (set_attr "enabled_for_depr_it" "yes,yes,no")
8319 (set_attr "arch" "t2,t2,*")
8320 (set_attr "length" "6,6,8")]
a8045a4f 8321)
8322
8323(define_insn "*arm_cmpdi_zero"
8324 [(set (reg:CC_Z CC_REGNUM)
8325 (compare:CC_Z (match_operand:DI 0 "s_register_operand" "r")
8326 (const_int 0)))
8327 (clobber (match_scratch:SI 1 "=r"))]
8328 "TARGET_32BIT"
8329 "orr%.\\t%1, %Q0, %R0"
8330 [(set_attr "conds" "set")]
8331)
8332
8333(define_insn "*thumb_cmpdi_zero"
8334 [(set (reg:CC_Z CC_REGNUM)
8335 (compare:CC_Z (match_operand:DI 0 "s_register_operand" "l")
8336 (const_int 0)))
8337 (clobber (match_scratch:SI 1 "=l"))]
8338 "TARGET_THUMB1"
8339 "orr\\t%1, %Q0, %R0"
8340 [(set_attr "conds" "set")
8341 (set_attr "length" "2")]
8342)
8343
9c08d1fa 8344; This insn allows redundant compares to be removed by cse, nothing should
8345; ever appear in the output file since (set (reg x) (reg x)) is a no-op that
8346; is deleted later on. The match_dup will match the mode here, so that
8347; mode changes of the condition codes aren't lost by this even though we don't
8348; specify what they are.
8349
8a18b90c 8350(define_insn "*deleted_compare"
9c08d1fa 8351 [(set (match_operand 0 "cc_register" "") (match_dup 0))]
25f905c2 8352 "TARGET_32BIT"
40dbec34 8353 "\\t%@ deleted compare"
cffb2a26 8354 [(set_attr "conds" "set")
8355 (set_attr "length" "0")]
8356)
9c08d1fa 8357
8358\f
8359;; Conditional branch insns
8360
74f4459c 8361(define_expand "cbranch_cc"
9c08d1fa 8362 [(set (pc)
74f4459c 8363 (if_then_else (match_operator 0 "" [(match_operand 1 "" "")
8364 (match_operand 2 "" "")])
8365 (label_ref (match_operand 3 "" ""))
9c08d1fa 8366 (pc)))]
25f905c2 8367 "TARGET_32BIT"
74f4459c 8368 "operands[1] = arm_gen_compare_reg (GET_CODE (operands[0]),
e1b93706 8369 operands[1], operands[2], NULL_RTX);
74f4459c 8370 operands[2] = const0_rtx;"
8fa3ba89 8371)
8372
8373;;
8374;; Patterns to match conditional branch insns.
8375;;
8376
ffcc986d 8377(define_insn "arm_cond_branch"
9c08d1fa 8378 [(set (pc)
8fa3ba89 8379 (if_then_else (match_operator 1 "arm_comparison_operator"
8a18b90c 8380 [(match_operand 2 "cc_register" "") (const_int 0)])
9c08d1fa 8381 (label_ref (match_operand 0 "" ""))
8382 (pc)))]
25f905c2 8383 "TARGET_32BIT"
d75350ce 8384 "*
9c08d1fa 8385 if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
cffb2a26 8386 {
8387 arm_ccfsm_state += 2;
8388 return \"\";
8389 }
e2348bcb 8390 return \"b%d1\\t%l0\";
cffb2a26 8391 "
a2cd141b 8392 [(set_attr "conds" "use")
a6864a24 8393 (set_attr "type" "branch")
8394 (set (attr "length")
8395 (if_then_else
0bf497f5 8396 (and (match_test "TARGET_THUMB2")
a6864a24 8397 (and (ge (minus (match_dup 0) (pc)) (const_int -250))
8398 (le (minus (match_dup 0) (pc)) (const_int 256))))
8399 (const_int 2)
8400 (const_int 4)))]
cffb2a26 8401)
d75350ce 8402
cffb2a26 8403(define_insn "*arm_cond_branch_reversed"
9c08d1fa 8404 [(set (pc)
8fa3ba89 8405 (if_then_else (match_operator 1 "arm_comparison_operator"
8a18b90c 8406 [(match_operand 2 "cc_register" "") (const_int 0)])
9c08d1fa 8407 (pc)
8408 (label_ref (match_operand 0 "" ""))))]
25f905c2 8409 "TARGET_32BIT"
d75350ce 8410 "*
9c08d1fa 8411 if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
cffb2a26 8412 {
8413 arm_ccfsm_state += 2;
8414 return \"\";
8415 }
e2348bcb 8416 return \"b%D1\\t%l0\";
cffb2a26 8417 "
a2cd141b 8418 [(set_attr "conds" "use")
a6864a24 8419 (set_attr "type" "branch")
8420 (set (attr "length")
8421 (if_then_else
0bf497f5 8422 (and (match_test "TARGET_THUMB2")
a6864a24 8423 (and (ge (minus (match_dup 0) (pc)) (const_int -250))
8424 (le (minus (match_dup 0) (pc)) (const_int 256))))
8425 (const_int 2)
8426 (const_int 4)))]
cffb2a26 8427)
8428
b11cae9e 8429\f
9c08d1fa 8430
8431; scc insns
8432
74f4459c 8433(define_expand "cstore_cc"
7db9af5d 8434 [(set (match_operand:SI 0 "s_register_operand" "")
74f4459c 8435 (match_operator:SI 1 "" [(match_operand 2 "" "")
8436 (match_operand 3 "" "")]))]
25f905c2 8437 "TARGET_32BIT"
74f4459c 8438 "operands[2] = arm_gen_compare_reg (GET_CODE (operands[1]),
e1b93706 8439 operands[2], operands[3], NULL_RTX);
74f4459c 8440 operands[3] = const0_rtx;"
8fa3ba89 8441)
8442
a3b84066 8443(define_insn_and_split "*mov_scc"
9c08d1fa 8444 [(set (match_operand:SI 0 "s_register_operand" "=r")
8fa3ba89 8445 (match_operator:SI 1 "arm_comparison_operator"
8a18b90c 8446 [(match_operand 2 "cc_register" "") (const_int 0)]))]
cffb2a26 8447 "TARGET_ARM"
a3b84066 8448 "#" ; "mov%D1\\t%0, #0\;mov%d1\\t%0, #1"
8449 "TARGET_ARM"
8450 [(set (match_dup 0)
8451 (if_then_else:SI (match_dup 1)
8452 (const_int 1)
8453 (const_int 0)))]
8454 ""
cffb2a26 8455 [(set_attr "conds" "use")
8456 (set_attr "length" "8")]
8457)
9c08d1fa 8458
a3b84066 8459(define_insn_and_split "*mov_negscc"
9c08d1fa 8460 [(set (match_operand:SI 0 "s_register_operand" "=r")
8fa3ba89 8461 (neg:SI (match_operator:SI 1 "arm_comparison_operator"
8a18b90c 8462 [(match_operand 2 "cc_register" "") (const_int 0)])))]
cffb2a26 8463 "TARGET_ARM"
a3b84066 8464 "#" ; "mov%D1\\t%0, #0\;mvn%d1\\t%0, #0"
8465 "TARGET_ARM"
8466 [(set (match_dup 0)
8467 (if_then_else:SI (match_dup 1)
8468 (match_dup 3)
8469 (const_int 0)))]
8470 {
8471 operands[3] = GEN_INT (~0);
8472 }
cffb2a26 8473 [(set_attr "conds" "use")
8474 (set_attr "length" "8")]
8475)
9c08d1fa 8476
a3b84066 8477(define_insn_and_split "*mov_notscc"
9c08d1fa 8478 [(set (match_operand:SI 0 "s_register_operand" "=r")
8fa3ba89 8479 (not:SI (match_operator:SI 1 "arm_comparison_operator"
8a18b90c 8480 [(match_operand 2 "cc_register" "") (const_int 0)])))]
cffb2a26 8481 "TARGET_ARM"
a3b84066 8482 "#" ; "mvn%D1\\t%0, #0\;mvn%d1\\t%0, #1"
8483 "TARGET_ARM"
8484 [(set (match_dup 0)
8485 (if_then_else:SI (match_dup 1)
8486 (match_dup 3)
8487 (match_dup 4)))]
8488 {
8489 operands[3] = GEN_INT (~1);
8490 operands[4] = GEN_INT (~0);
8491 }
cffb2a26 8492 [(set_attr "conds" "use")
8493 (set_attr "length" "8")]
8494)
9c08d1fa 8495
595d88b5 8496(define_expand "cstoresi4"
8497 [(set (match_operand:SI 0 "s_register_operand" "")
aa06947a 8498 (match_operator:SI 1 "expandable_comparison_operator"
595d88b5 8499 [(match_operand:SI 2 "s_register_operand" "")
8500 (match_operand:SI 3 "reg_or_int_operand" "")]))]
74f4459c 8501 "TARGET_32BIT || TARGET_THUMB1"
595d88b5 8502 "{
8503 rtx op3, scratch, scratch2;
8504
74f4459c 8505 if (!TARGET_THUMB1)
8506 {
8507 if (!arm_add_operand (operands[3], SImode))
8508 operands[3] = force_reg (SImode, operands[3]);
8509 emit_insn (gen_cstore_cc (operands[0], operands[1],
8510 operands[2], operands[3]));
8511 DONE;
8512 }
8513
595d88b5 8514 if (operands[3] == const0_rtx)
8515 {
8516 switch (GET_CODE (operands[1]))
8517 {
8518 case EQ:
25f905c2 8519 emit_insn (gen_cstoresi_eq0_thumb1 (operands[0], operands[2]));
595d88b5 8520 break;
8521
8522 case NE:
25f905c2 8523 emit_insn (gen_cstoresi_ne0_thumb1 (operands[0], operands[2]));
595d88b5 8524 break;
8525
8526 case LE:
8527 scratch = expand_binop (SImode, add_optab, operands[2], constm1_rtx,
8528 NULL_RTX, 0, OPTAB_WIDEN);
8529 scratch = expand_binop (SImode, ior_optab, operands[2], scratch,
8530 NULL_RTX, 0, OPTAB_WIDEN);
8531 expand_binop (SImode, lshr_optab, scratch, GEN_INT (31),
8532 operands[0], 1, OPTAB_WIDEN);
8533 break;
8534
8535 case GE:
8536 scratch = expand_unop (SImode, one_cmpl_optab, operands[2],
8537 NULL_RTX, 1);
8538 expand_binop (SImode, lshr_optab, scratch, GEN_INT (31),
8539 NULL_RTX, 1, OPTAB_WIDEN);
8540 break;
8541
8542 case GT:
8543 scratch = expand_binop (SImode, ashr_optab, operands[2],
8544 GEN_INT (31), NULL_RTX, 0, OPTAB_WIDEN);
8545 scratch = expand_binop (SImode, sub_optab, scratch, operands[2],
8546 NULL_RTX, 0, OPTAB_WIDEN);
8547 expand_binop (SImode, lshr_optab, scratch, GEN_INT (31), operands[0],
8548 0, OPTAB_WIDEN);
8549 break;
8550
8551 /* LT is handled by generic code. No need for unsigned with 0. */
8552 default:
8553 FAIL;
8554 }
8555 DONE;
8556 }
8557
8558 switch (GET_CODE (operands[1]))
8559 {
8560 case EQ:
8561 scratch = expand_binop (SImode, sub_optab, operands[2], operands[3],
8562 NULL_RTX, 0, OPTAB_WIDEN);
25f905c2 8563 emit_insn (gen_cstoresi_eq0_thumb1 (operands[0], scratch));
595d88b5 8564 break;
8565
8566 case NE:
8567 scratch = expand_binop (SImode, sub_optab, operands[2], operands[3],
8568 NULL_RTX, 0, OPTAB_WIDEN);
25f905c2 8569 emit_insn (gen_cstoresi_ne0_thumb1 (operands[0], scratch));
595d88b5 8570 break;
8571
8572 case LE:
8573 op3 = force_reg (SImode, operands[3]);
8574
8575 scratch = expand_binop (SImode, lshr_optab, operands[2], GEN_INT (31),
8576 NULL_RTX, 1, OPTAB_WIDEN);
8577 scratch2 = expand_binop (SImode, ashr_optab, op3, GEN_INT (31),
8578 NULL_RTX, 0, OPTAB_WIDEN);
25f905c2 8579 emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch2,
595d88b5 8580 op3, operands[2]));
8581 break;
8582
8583 case GE:
8584 op3 = operands[3];
25f905c2 8585 if (!thumb1_cmp_operand (op3, SImode))
595d88b5 8586 op3 = force_reg (SImode, op3);
8587 scratch = expand_binop (SImode, ashr_optab, operands[2], GEN_INT (31),
8588 NULL_RTX, 0, OPTAB_WIDEN);
8589 scratch2 = expand_binop (SImode, lshr_optab, op3, GEN_INT (31),
8590 NULL_RTX, 1, OPTAB_WIDEN);
25f905c2 8591 emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch2,
595d88b5 8592 operands[2], op3));
8593 break;
8594
8595 case LEU:
8596 op3 = force_reg (SImode, operands[3]);
8597 scratch = force_reg (SImode, const0_rtx);
25f905c2 8598 emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch,
595d88b5 8599 op3, operands[2]));
8600 break;
8601
8602 case GEU:
8603 op3 = operands[3];
25f905c2 8604 if (!thumb1_cmp_operand (op3, SImode))
595d88b5 8605 op3 = force_reg (SImode, op3);
8606 scratch = force_reg (SImode, const0_rtx);
25f905c2 8607 emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch,
595d88b5 8608 operands[2], op3));
8609 break;
8610
8611 case LTU:
8612 op3 = operands[3];
25f905c2 8613 if (!thumb1_cmp_operand (op3, SImode))
595d88b5 8614 op3 = force_reg (SImode, op3);
8615 scratch = gen_reg_rtx (SImode);
408b7ae5 8616 emit_insn (gen_cstoresi_ltu_thumb1 (operands[0], operands[2], op3));
595d88b5 8617 break;
8618
8619 case GTU:
8620 op3 = force_reg (SImode, operands[3]);
8621 scratch = gen_reg_rtx (SImode);
408b7ae5 8622 emit_insn (gen_cstoresi_ltu_thumb1 (operands[0], op3, operands[2]));
595d88b5 8623 break;
8624
8625 /* No good sequences for GT, LT. */
8626 default:
8627 FAIL;
8628 }
8629 DONE;
8630}")
8631
74f4459c 8632(define_expand "cstoresf4"
8633 [(set (match_operand:SI 0 "s_register_operand" "")
aa06947a 8634 (match_operator:SI 1 "expandable_comparison_operator"
74f4459c 8635 [(match_operand:SF 2 "s_register_operand" "")
8636 (match_operand:SF 3 "arm_float_compare_operand" "")]))]
8637 "TARGET_32BIT && TARGET_HARD_FLOAT"
8638 "emit_insn (gen_cstore_cc (operands[0], operands[1],
8639 operands[2], operands[3])); DONE;"
8640)
8641
8642(define_expand "cstoredf4"
8643 [(set (match_operand:SI 0 "s_register_operand" "")
aa06947a 8644 (match_operator:SI 1 "expandable_comparison_operator"
74f4459c 8645 [(match_operand:DF 2 "s_register_operand" "")
8646 (match_operand:DF 3 "arm_float_compare_operand" "")]))]
d63ed457 8647 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
74f4459c 8648 "emit_insn (gen_cstore_cc (operands[0], operands[1],
8649 operands[2], operands[3])); DONE;"
8650)
8651
74f4459c 8652(define_expand "cstoredi4"
8653 [(set (match_operand:SI 0 "s_register_operand" "")
aa06947a 8654 (match_operator:SI 1 "expandable_comparison_operator"
b8eae306 8655 [(match_operand:DI 2 "s_register_operand" "")
a8045a4f 8656 (match_operand:DI 3 "cmpdi_operand" "")]))]
8657 "TARGET_32BIT"
8658 "{
f9aa4160 8659 if (!arm_validize_comparison (&operands[1],
8660 &operands[2],
8661 &operands[3]))
8662 FAIL;
8663 emit_insn (gen_cstore_cc (operands[0], operands[1], operands[2],
a8045a4f 8664 operands[3]));
8665 DONE;
8666 }"
74f4459c 8667)
8668
25f905c2 8669(define_expand "cstoresi_eq0_thumb1"
595d88b5 8670 [(parallel
8671 [(set (match_operand:SI 0 "s_register_operand" "")
8672 (eq:SI (match_operand:SI 1 "s_register_operand" "")
8673 (const_int 0)))
8674 (clobber (match_dup:SI 2))])]
25f905c2 8675 "TARGET_THUMB1"
595d88b5 8676 "operands[2] = gen_reg_rtx (SImode);"
8677)
8678
25f905c2 8679(define_expand "cstoresi_ne0_thumb1"
595d88b5 8680 [(parallel
8681 [(set (match_operand:SI 0 "s_register_operand" "")
8682 (ne:SI (match_operand:SI 1 "s_register_operand" "")
8683 (const_int 0)))
8684 (clobber (match_dup:SI 2))])]
25f905c2 8685 "TARGET_THUMB1"
595d88b5 8686 "operands[2] = gen_reg_rtx (SImode);"
8687)
8688
25f905c2 8689(define_insn "*cstoresi_eq0_thumb1_insn"
595d88b5 8690 [(set (match_operand:SI 0 "s_register_operand" "=&l,l")
8691 (eq:SI (match_operand:SI 1 "s_register_operand" "l,0")
8692 (const_int 0)))
8693 (clobber (match_operand:SI 2 "s_register_operand" "=X,l"))]
25f905c2 8694 "TARGET_THUMB1"
595d88b5 8695 "@
8696 neg\\t%0, %1\;adc\\t%0, %0, %1
8697 neg\\t%2, %1\;adc\\t%0, %1, %2"
8698 [(set_attr "length" "4")]
8699)
8700
25f905c2 8701(define_insn "*cstoresi_ne0_thumb1_insn"
595d88b5 8702 [(set (match_operand:SI 0 "s_register_operand" "=l")
8703 (ne:SI (match_operand:SI 1 "s_register_operand" "0")
8704 (const_int 0)))
8705 (clobber (match_operand:SI 2 "s_register_operand" "=l"))]
25f905c2 8706 "TARGET_THUMB1"
595d88b5 8707 "sub\\t%2, %1, #1\;sbc\\t%0, %1, %2"
8708 [(set_attr "length" "4")]
8709)
8710
408b7ae5 8711;; Used as part of the expansion of thumb ltu and gtu sequences
25f905c2 8712(define_insn "cstoresi_nltu_thumb1"
595d88b5 8713 [(set (match_operand:SI 0 "s_register_operand" "=l,l")
a277ddf3 8714 (neg:SI (ltu:SI (match_operand:SI 1 "s_register_operand" "l,*h")
25f905c2 8715 (match_operand:SI 2 "thumb1_cmp_operand" "lI*h,*r"))))]
8716 "TARGET_THUMB1"
595d88b5 8717 "cmp\\t%1, %2\;sbc\\t%0, %0, %0"
8718 [(set_attr "length" "4")]
8719)
8720
408b7ae5 8721(define_insn_and_split "cstoresi_ltu_thumb1"
8722 [(set (match_operand:SI 0 "s_register_operand" "=l,l")
8723 (ltu:SI (match_operand:SI 1 "s_register_operand" "l,*h")
8724 (match_operand:SI 2 "thumb1_cmp_operand" "lI*h,*r")))]
8725 "TARGET_THUMB1"
8726 "#"
8727 "TARGET_THUMB1"
8728 [(set (match_dup 3)
8729 (neg:SI (ltu:SI (match_dup 1) (match_dup 2))))
8730 (set (match_dup 0) (neg:SI (match_dup 3)))]
8731 "operands[3] = gen_reg_rtx (SImode);"
8732 [(set_attr "length" "4")]
8733)
8734
595d88b5 8735;; Used as part of the expansion of thumb les sequence.
25f905c2 8736(define_insn "thumb1_addsi3_addgeu"
595d88b5 8737 [(set (match_operand:SI 0 "s_register_operand" "=l")
8738 (plus:SI (plus:SI (match_operand:SI 1 "s_register_operand" "%0")
8739 (match_operand:SI 2 "s_register_operand" "l"))
8740 (geu:SI (match_operand:SI 3 "s_register_operand" "l")
25f905c2 8741 (match_operand:SI 4 "thumb1_cmp_operand" "lI"))))]
8742 "TARGET_THUMB1"
595d88b5 8743 "cmp\\t%3, %4\;adc\\t%0, %1, %2"
8744 [(set_attr "length" "4")]
8745)
8746
9c08d1fa 8747\f
39b5e676 8748;; Conditional move insns
8749
8750(define_expand "movsicc"
8a18b90c 8751 [(set (match_operand:SI 0 "s_register_operand" "")
aa06947a 8752 (if_then_else:SI (match_operand 1 "expandable_comparison_operator" "")
aea4c774 8753 (match_operand:SI 2 "arm_not_operand" "")
8a18b90c 8754 (match_operand:SI 3 "arm_not_operand" "")))]
25f905c2 8755 "TARGET_32BIT"
39b5e676 8756 "
215b30b3 8757 {
f9aa4160 8758 enum rtx_code code;
278b301d 8759 rtx ccreg;
8760
f9aa4160 8761 if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0),
8762 &XEXP (operands[1], 1)))
278b301d 8763 FAIL;
f9aa4160 8764
8765 code = GET_CODE (operands[1]);
74f4459c 8766 ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
e1b93706 8767 XEXP (operands[1], 1), NULL_RTX);
29bb088d 8768 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
215b30b3 8769 }"
8770)
39b5e676 8771
8772(define_expand "movsfcc"
8a18b90c 8773 [(set (match_operand:SF 0 "s_register_operand" "")
4df97ffc 8774 (if_then_else:SF (match_operand 1 "arm_cond_move_operator" "")
8a18b90c 8775 (match_operand:SF 2 "s_register_operand" "")
d86c91f6 8776 (match_operand:SF 3 "s_register_operand" "")))]
19f6bf8d 8777 "TARGET_32BIT && TARGET_HARD_FLOAT"
39b5e676 8778 "
215b30b3 8779 {
8780 enum rtx_code code = GET_CODE (operands[1]);
8781 rtx ccreg;
f082f1c4 8782
f9aa4160 8783 if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0),
8784 &XEXP (operands[1], 1)))
8785 FAIL;
39b5e676 8786
f9aa4160 8787 code = GET_CODE (operands[1]);
74f4459c 8788 ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
e1b93706 8789 XEXP (operands[1], 1), NULL_RTX);
29bb088d 8790 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
215b30b3 8791 }"
8792)
39b5e676 8793
8794(define_expand "movdfcc"
8a18b90c 8795 [(set (match_operand:DF 0 "s_register_operand" "")
4df97ffc 8796 (if_then_else:DF (match_operand 1 "arm_cond_move_operator" "")
8a18b90c 8797 (match_operand:DF 2 "s_register_operand" "")
d86c91f6 8798 (match_operand:DF 3 "s_register_operand" "")))]
994606f8 8799 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
39b5e676 8800 "
215b30b3 8801 {
8802 enum rtx_code code = GET_CODE (operands[1]);
278b301d 8803 rtx ccreg;
39b5e676 8804
f9aa4160 8805 if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0),
8806 &XEXP (operands[1], 1)))
8807 FAIL;
8808 code = GET_CODE (operands[1]);
74f4459c 8809 ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
e1b93706 8810 XEXP (operands[1], 1), NULL_RTX);
29bb088d 8811 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
215b30b3 8812 }"
8813)
39b5e676 8814
91cb50d2 8815(define_insn "*cmov<mode>"
8816 [(set (match_operand:SDF 0 "s_register_operand" "=<F_constraint>")
8817 (if_then_else:SDF (match_operator 1 "arm_vsel_comparison_operator"
8818 [(match_operand 2 "cc_register" "") (const_int 0)])
8819 (match_operand:SDF 3 "s_register_operand"
8820 "<F_constraint>")
8821 (match_operand:SDF 4 "s_register_operand"
8822 "<F_constraint>")))]
8823 "TARGET_HARD_FLOAT && TARGET_FPU_ARMV8 <vfp_double_cond>"
8824 "*
8825 {
8826 enum arm_cond_code code = maybe_get_arm_condition_code (operands[1]);
8827 switch (code)
8828 {
8829 case ARM_GE:
8830 case ARM_GT:
8831 case ARM_EQ:
8832 case ARM_VS:
8833 return \"vsel%d1.<V_if_elem>\\t%<V_reg>0, %<V_reg>3, %<V_reg>4\";
8834 case ARM_LT:
8835 case ARM_LE:
8836 case ARM_NE:
8837 case ARM_VC:
8838 return \"vsel%D1.<V_if_elem>\\t%<V_reg>0, %<V_reg>4, %<V_reg>3\";
8839 default:
8840 gcc_unreachable ();
8841 }
8842 return \"\";
8843 }"
8844 [(set_attr "conds" "use")
8845 (set_attr "type" "f_sel<vfp_type>")]
8846)
8847
190efb17 8848(define_insn_and_split "*movsicc_insn"
f082f1c4 8849 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r,r,r,r,r")
8a18b90c 8850 (if_then_else:SI
8fa3ba89 8851 (match_operator 3 "arm_comparison_operator"
8a18b90c 8852 [(match_operand 4 "cc_register" "") (const_int 0)])
f082f1c4 8853 (match_operand:SI 1 "arm_not_operand" "0,0,rI,K,rI,rI,K,K")
8854 (match_operand:SI 2 "arm_not_operand" "rI,K,0,0,rI,K,rI,K")))]
cffb2a26 8855 "TARGET_ARM"
39b5e676 8856 "@
8a18b90c 8857 mov%D3\\t%0, %2
8858 mvn%D3\\t%0, #%B2
f082f1c4 8859 mov%d3\\t%0, %1
8860 mvn%d3\\t%0, #%B1
190efb17 8861 #
8862 #
8863 #
8864 #"
8865 ; alt4: mov%d3\\t%0, %1\;mov%D3\\t%0, %2
8866 ; alt5: mov%d3\\t%0, %1\;mvn%D3\\t%0, #%B2
8867 ; alt6: mvn%d3\\t%0, #%B1\;mov%D3\\t%0, %2
8868 ; alt7: mvn%d3\\t%0, #%B1\;mvn%D3\\t%0, #%B2"
8869 "&& reload_completed"
8870 [(const_int 0)]
8871 {
8872 enum rtx_code rev_code;
8873 enum machine_mode mode;
8874 rtx rev_cond;
8875
8876 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
8877 operands[3],
8878 gen_rtx_SET (VOIDmode,
8879 operands[0],
8880 operands[1])));
8881
8882 rev_code = GET_CODE (operands[3]);
8883 mode = GET_MODE (operands[4]);
8884 if (mode == CCFPmode || mode == CCFPEmode)
8885 rev_code = reverse_condition_maybe_unordered (rev_code);
8886 else
8887 rev_code = reverse_condition (rev_code);
8888
8889 rev_cond = gen_rtx_fmt_ee (rev_code,
8890 VOIDmode,
8891 operands[4],
8892 const0_rtx);
8893 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
8894 rev_cond,
8895 gen_rtx_SET (VOIDmode,
8896 operands[0],
8897 operands[2])));
8898 DONE;
8899 }
f082f1c4 8900 [(set_attr "length" "4,4,4,4,8,8,8,8")
d2a518d1 8901 (set_attr "conds" "use")
65f68e55 8902 (set_attr_alternative "type"
8903 [(if_then_else (match_operand 2 "const_int_operand" "")
1aed5204 8904 (const_string "mov_imm")
8905 (const_string "mov_reg"))
8906 (const_string "mvn_imm")
65f68e55 8907 (if_then_else (match_operand 1 "const_int_operand" "")
1aed5204 8908 (const_string "mov_imm")
8909 (const_string "mov_reg"))
8910 (const_string "mvn_imm")
8911 (const_string "mov_reg")
8912 (const_string "mov_reg")
8913 (const_string "mov_reg")
8914 (const_string "mov_reg")])]
215b30b3 8915)
39b5e676 8916
39b5e676 8917(define_insn "*movsfcc_soft_insn"
f082f1c4 8918 [(set (match_operand:SF 0 "s_register_operand" "=r,r")
8fa3ba89 8919 (if_then_else:SF (match_operator 3 "arm_comparison_operator"
8a18b90c 8920 [(match_operand 4 "cc_register" "") (const_int 0)])
f082f1c4 8921 (match_operand:SF 1 "s_register_operand" "0,r")
8922 (match_operand:SF 2 "s_register_operand" "r,0")))]
cffb2a26 8923 "TARGET_ARM && TARGET_SOFT_FLOAT"
f082f1c4 8924 "@
8925 mov%D3\\t%0, %2
8926 mov%d3\\t%0, %1"
d2a518d1 8927 [(set_attr "conds" "use")
1aed5204 8928 (set_attr "type" "mov_reg")]
8fa3ba89 8929)
39b5e676 8930
39b5e676 8931\f
9c08d1fa 8932;; Jump and linkage insns
8933
cffb2a26 8934(define_expand "jump"
9c08d1fa 8935 [(set (pc)
8936 (label_ref (match_operand 0 "" "")))]
cffb2a26 8937 "TARGET_EITHER"
9c08d1fa 8938 ""
cffb2a26 8939)
8940
8941(define_insn "*arm_jump"
8942 [(set (pc)
8943 (label_ref (match_operand 0 "" "")))]
25f905c2 8944 "TARGET_32BIT"
9c08d1fa 8945 "*
0d66636f 8946 {
8947 if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
8948 {
8949 arm_ccfsm_state += 2;
8950 return \"\";
8951 }
8952 return \"b%?\\t%l0\";
8953 }
8954 "
a6864a24 8955 [(set_attr "predicable" "yes")
8956 (set (attr "length")
8957 (if_then_else
0bf497f5 8958 (and (match_test "TARGET_THUMB2")
a6864a24 8959 (and (ge (minus (match_dup 0) (pc)) (const_int -2044))
8960 (le (minus (match_dup 0) (pc)) (const_int 2048))))
8961 (const_int 2)
8962 (const_int 4)))]
0d66636f 8963)
9c08d1fa 8964
cffb2a26 8965(define_insn "*thumb_jump"
8966 [(set (pc)
8967 (label_ref (match_operand 0 "" "")))]
25f905c2 8968 "TARGET_THUMB1"
cffb2a26 8969 "*
8970 if (get_attr_length (insn) == 2)
8971 return \"b\\t%l0\";
8972 return \"bl\\t%l0\\t%@ far jump\";
8973 "
8974 [(set (attr "far_jump")
8975 (if_then_else
8976 (eq_attr "length" "4")
8977 (const_string "yes")
8978 (const_string "no")))
8979 (set (attr "length")
8980 (if_then_else
911ed8af 8981 (and (ge (minus (match_dup 0) (pc)) (const_int -2044))
8982 (le (minus (match_dup 0) (pc)) (const_int 2048)))
cffb2a26 8983 (const_int 2)
8984 (const_int 4)))]
8985)
8986
d3373b54 8987(define_expand "call"
8988 [(parallel [(call (match_operand 0 "memory_operand" "")
8989 (match_operand 1 "general_operand" ""))
cffb2a26 8990 (use (match_operand 2 "" ""))
bd5b4116 8991 (clobber (reg:SI LR_REGNUM))])]
cffb2a26 8992 "TARGET_EITHER"
6c4c2133 8993 "
8994 {
bac7fc85 8995 rtx callee, pat;
bbe777ea 8996
bbe777ea 8997 /* In an untyped call, we can get NULL for operand 2. */
8998 if (operands[2] == NULL_RTX)
8999 operands[2] = const0_rtx;
9000
de55252a 9001 /* Decide if we should generate indirect calls by loading the
85c36fd1 9002 32-bit address of the callee into a register before performing the
de55252a 9003 branch and link. */
9004 callee = XEXP (operands[0], 0);
9005 if (GET_CODE (callee) == SYMBOL_REF
9006 ? arm_is_long_call_p (SYMBOL_REF_DECL (callee))
9007 : !REG_P (callee))
bbe777ea 9008 XEXP (operands[0], 0) = force_reg (Pmode, callee);
bac7fc85 9009
9010 pat = gen_call_internal (operands[0], operands[1], operands[2]);
9011 arm_emit_call_insn (pat, XEXP (operands[0], 0));
9012 DONE;
6c4c2133 9013 }"
9014)
d3373b54 9015
bac7fc85 9016(define_expand "call_internal"
9017 [(parallel [(call (match_operand 0 "memory_operand" "")
9018 (match_operand 1 "general_operand" ""))
9019 (use (match_operand 2 "" ""))
9020 (clobber (reg:SI LR_REGNUM))])])
9021
f1039640 9022(define_insn "*call_reg_armv5"
d3373b54 9023 [(call (mem:SI (match_operand:SI 0 "s_register_operand" "r"))
cffb2a26 9024 (match_operand 1 "" ""))
9025 (use (match_operand 2 "" ""))
bd5b4116 9026 (clobber (reg:SI LR_REGNUM))]
33ae7c4b 9027 "TARGET_ARM && arm_arch5 && !SIBLING_CALL_P (insn)"
f1039640 9028 "blx%?\\t%0"
9029 [(set_attr "type" "call")]
9030)
9031
9032(define_insn "*call_reg_arm"
9033 [(call (mem:SI (match_operand:SI 0 "s_register_operand" "r"))
9034 (match_operand 1 "" ""))
9035 (use (match_operand 2 "" ""))
9036 (clobber (reg:SI LR_REGNUM))]
33ae7c4b 9037 "TARGET_ARM && !arm_arch5 && !SIBLING_CALL_P (insn)"
9c08d1fa 9038 "*
5565501b 9039 return output_call (operands);
cffb2a26 9040 "
9041 ;; length is worst case, normally it is only two
9042 [(set_attr "length" "12")
9043 (set_attr "type" "call")]
9044)
9c08d1fa 9045
89504fc1 9046
9047;; Note: not used for armv5+ because the sequence used (ldr pc, ...) is not
9048;; considered a function call by the branch predictor of some cores (PR40887).
9049;; Falls back to blx rN (*call_reg_armv5).
9050
f7fbdd4a 9051(define_insn "*call_mem"
a3c63a9d 9052 [(call (mem:SI (match_operand:SI 0 "call_memory_operand" "m"))
cffb2a26 9053 (match_operand 1 "" ""))
9054 (use (match_operand 2 "" ""))
bd5b4116 9055 (clobber (reg:SI LR_REGNUM))]
33ae7c4b 9056 "TARGET_ARM && !arm_arch5 && !SIBLING_CALL_P (insn)"
9c08d1fa 9057 "*
5565501b 9058 return output_call_mem (operands);
cffb2a26 9059 "
9060 [(set_attr "length" "12")
9061 (set_attr "type" "call")]
9062)
9063
25f905c2 9064(define_insn "*call_reg_thumb1_v5"
cffb2a26 9065 [(call (mem:SI (match_operand:SI 0 "register_operand" "l*r"))
9066 (match_operand 1 "" ""))
9067 (use (match_operand 2 "" ""))
bd5b4116 9068 (clobber (reg:SI LR_REGNUM))]
33ae7c4b 9069 "TARGET_THUMB1 && arm_arch5 && !SIBLING_CALL_P (insn)"
f1039640 9070 "blx\\t%0"
9071 [(set_attr "length" "2")
9072 (set_attr "type" "call")]
cffb2a26 9073)
9074
25f905c2 9075(define_insn "*call_reg_thumb1"
f1039640 9076 [(call (mem:SI (match_operand:SI 0 "register_operand" "l*r"))
9077 (match_operand 1 "" ""))
9078 (use (match_operand 2 "" ""))
bd5b4116 9079 (clobber (reg:SI LR_REGNUM))]
33ae7c4b 9080 "TARGET_THUMB1 && !arm_arch5 && !SIBLING_CALL_P (insn)"
cffb2a26 9081 "*
9082 {
150502c9 9083 if (!TARGET_CALLER_INTERWORKING)
afe27f3b 9084 return thumb_call_via_reg (operands[0]);
150502c9 9085 else if (operands[1] == const0_rtx)
f1039640 9086 return \"bl\\t%__interwork_call_via_%0\";
150502c9 9087 else if (frame_pointer_needed)
9088 return \"bl\\t%__interwork_r7_call_via_%0\";
cffb2a26 9089 else
150502c9 9090 return \"bl\\t%__interwork_r11_call_via_%0\";
cffb2a26 9091 }"
9092 [(set_attr "type" "call")]
9093)
9c08d1fa 9094
d3373b54 9095(define_expand "call_value"
e0698af7 9096 [(parallel [(set (match_operand 0 "" "")
9097 (call (match_operand 1 "memory_operand" "")
9098 (match_operand 2 "general_operand" "")))
cffb2a26 9099 (use (match_operand 3 "" ""))
bd5b4116 9100 (clobber (reg:SI LR_REGNUM))])]
cffb2a26 9101 "TARGET_EITHER"
6c4c2133 9102 "
9103 {
bac7fc85 9104 rtx pat, callee;
bbe777ea 9105
9106 /* In an untyped call, we can get NULL for operand 2. */
9107 if (operands[3] == 0)
9108 operands[3] = const0_rtx;
9109
de55252a 9110 /* Decide if we should generate indirect calls by loading the
9111 32-bit address of the callee into a register before performing the
9112 branch and link. */
9113 callee = XEXP (operands[1], 0);
9114 if (GET_CODE (callee) == SYMBOL_REF
9115 ? arm_is_long_call_p (SYMBOL_REF_DECL (callee))
9116 : !REG_P (callee))
78fe751b 9117 XEXP (operands[1], 0) = force_reg (Pmode, callee);
bac7fc85 9118
9119 pat = gen_call_value_internal (operands[0], operands[1],
9120 operands[2], operands[3]);
9121 arm_emit_call_insn (pat, XEXP (operands[1], 0));
9122 DONE;
6c4c2133 9123 }"
9124)
d3373b54 9125
bac7fc85 9126(define_expand "call_value_internal"
9127 [(parallel [(set (match_operand 0 "" "")
9128 (call (match_operand 1 "memory_operand" "")
9129 (match_operand 2 "general_operand" "")))
9130 (use (match_operand 3 "" ""))
9131 (clobber (reg:SI LR_REGNUM))])])
9132
f1039640 9133(define_insn "*call_value_reg_armv5"
27ed6835 9134 [(set (match_operand 0 "" "")
755eb2b4 9135 (call (mem:SI (match_operand:SI 1 "s_register_operand" "r"))
cffb2a26 9136 (match_operand 2 "" "")))
bbe777ea 9137 (use (match_operand 3 "" ""))
bd5b4116 9138 (clobber (reg:SI LR_REGNUM))]
33ae7c4b 9139 "TARGET_ARM && arm_arch5 && !SIBLING_CALL_P (insn)"
f1039640 9140 "blx%?\\t%1"
9141 [(set_attr "type" "call")]
9142)
9143
9144(define_insn "*call_value_reg_arm"
9145 [(set (match_operand 0 "" "")
9146 (call (mem:SI (match_operand:SI 1 "s_register_operand" "r"))
9147 (match_operand 2 "" "")))
9148 (use (match_operand 3 "" ""))
9149 (clobber (reg:SI LR_REGNUM))]
33ae7c4b 9150 "TARGET_ARM && !arm_arch5 && !SIBLING_CALL_P (insn)"
9c08d1fa 9151 "*
215b30b3 9152 return output_call (&operands[1]);
cffb2a26 9153 "
9154 [(set_attr "length" "12")
9155 (set_attr "type" "call")]
9156)
9c08d1fa 9157
89504fc1 9158;; Note: see *call_mem
9159
f7fbdd4a 9160(define_insn "*call_value_mem"
27ed6835 9161 [(set (match_operand 0 "" "")
a3c63a9d 9162 (call (mem:SI (match_operand:SI 1 "call_memory_operand" "m"))
cffb2a26 9163 (match_operand 2 "" "")))
bbe777ea 9164 (use (match_operand 3 "" ""))
bd5b4116 9165 (clobber (reg:SI LR_REGNUM))]
33ae7c4b 9166 "TARGET_ARM && !arm_arch5 && (!CONSTANT_ADDRESS_P (XEXP (operands[1], 0)))
9167 && !SIBLING_CALL_P (insn)"
9c08d1fa 9168 "*
215b30b3 9169 return output_call_mem (&operands[1]);
cffb2a26 9170 "
9171 [(set_attr "length" "12")
9172 (set_attr "type" "call")]
9173)
9c08d1fa 9174
25f905c2 9175(define_insn "*call_value_reg_thumb1_v5"
f1039640 9176 [(set (match_operand 0 "" "")
9177 (call (mem:SI (match_operand:SI 1 "register_operand" "l*r"))
9178 (match_operand 2 "" "")))
9179 (use (match_operand 3 "" ""))
9180 (clobber (reg:SI LR_REGNUM))]
25f905c2 9181 "TARGET_THUMB1 && arm_arch5"
f1039640 9182 "blx\\t%1"
9183 [(set_attr "length" "2")
9184 (set_attr "type" "call")]
9185)
9186
25f905c2 9187(define_insn "*call_value_reg_thumb1"
f1039640 9188 [(set (match_operand 0 "" "")
9189 (call (mem:SI (match_operand:SI 1 "register_operand" "l*r"))
9190 (match_operand 2 "" "")))
9191 (use (match_operand 3 "" ""))
9192 (clobber (reg:SI LR_REGNUM))]
25f905c2 9193 "TARGET_THUMB1 && !arm_arch5"
f1039640 9194 "*
9195 {
150502c9 9196 if (!TARGET_CALLER_INTERWORKING)
afe27f3b 9197 return thumb_call_via_reg (operands[1]);
150502c9 9198 else if (operands[2] == const0_rtx)
f1039640 9199 return \"bl\\t%__interwork_call_via_%1\";
150502c9 9200 else if (frame_pointer_needed)
9201 return \"bl\\t%__interwork_r7_call_via_%1\";
f1039640 9202 else
150502c9 9203 return \"bl\\t%__interwork_r11_call_via_%1\";
f1039640 9204 }"
9205 [(set_attr "type" "call")]
9206)
9207
9c08d1fa 9208;; Allow calls to SYMBOL_REFs specially as they are not valid general addresses
9209;; The 'a' causes the operand to be treated as an address, i.e. no '#' output.
9210
f7fbdd4a 9211(define_insn "*call_symbol"
27ed6835 9212 [(call (mem:SI (match_operand:SI 0 "" ""))
cffb2a26 9213 (match_operand 1 "" ""))
bbe777ea 9214 (use (match_operand 2 "" ""))
bd5b4116 9215 (clobber (reg:SI LR_REGNUM))]
d68c2c10 9216 "TARGET_32BIT
33ae7c4b 9217 && !SIBLING_CALL_P (insn)
cffb2a26 9218 && (GET_CODE (operands[0]) == SYMBOL_REF)
de55252a 9219 && !arm_is_long_call_p (SYMBOL_REF_DECL (operands[0]))"
6ebaa29d 9220 "*
9221 {
55c1e470 9222 return NEED_PLT_RELOC ? \"bl%?\\t%a0(PLT)\" : \"bl%?\\t%a0\";
6ebaa29d 9223 }"
cffb2a26 9224 [(set_attr "type" "call")]
9225)
9c08d1fa 9226
f7fbdd4a 9227(define_insn "*call_value_symbol"
ccd90aaa 9228 [(set (match_operand 0 "" "")
27ed6835 9229 (call (mem:SI (match_operand:SI 1 "" ""))
dd6d7504 9230 (match_operand:SI 2 "" "")))
bbe777ea 9231 (use (match_operand 3 "" ""))
bd5b4116 9232 (clobber (reg:SI LR_REGNUM))]
d68c2c10 9233 "TARGET_32BIT
33ae7c4b 9234 && !SIBLING_CALL_P (insn)
cffb2a26 9235 && (GET_CODE (operands[1]) == SYMBOL_REF)
de55252a 9236 && !arm_is_long_call_p (SYMBOL_REF_DECL (operands[1]))"
6ebaa29d 9237 "*
9238 {
55c1e470 9239 return NEED_PLT_RELOC ? \"bl%?\\t%a1(PLT)\" : \"bl%?\\t%a1\";
6ebaa29d 9240 }"
cffb2a26 9241 [(set_attr "type" "call")]
9242)
9243
9244(define_insn "*call_insn"
27ed6835 9245 [(call (mem:SI (match_operand:SI 0 "" ""))
cffb2a26 9246 (match_operand:SI 1 "" ""))
9247 (use (match_operand 2 "" ""))
bd5b4116 9248 (clobber (reg:SI LR_REGNUM))]
d68c2c10 9249 "TARGET_THUMB1
1675c6e9 9250 && GET_CODE (operands[0]) == SYMBOL_REF
de55252a 9251 && !arm_is_long_call_p (SYMBOL_REF_DECL (operands[0]))"
cffb2a26 9252 "bl\\t%a0"
9253 [(set_attr "length" "4")
9254 (set_attr "type" "call")]
9255)
9256
9257(define_insn "*call_value_insn"
ccd90aaa 9258 [(set (match_operand 0 "" "")
27ed6835 9259 (call (mem:SI (match_operand 1 "" ""))
cffb2a26 9260 (match_operand 2 "" "")))
9261 (use (match_operand 3 "" ""))
bd5b4116 9262 (clobber (reg:SI LR_REGNUM))]
d68c2c10 9263 "TARGET_THUMB1
1675c6e9 9264 && GET_CODE (operands[1]) == SYMBOL_REF
de55252a 9265 && !arm_is_long_call_p (SYMBOL_REF_DECL (operands[1]))"
cffb2a26 9266 "bl\\t%a1"
9267 [(set_attr "length" "4")
9268 (set_attr "type" "call")]
9269)
9c08d1fa 9270
1c494086 9271;; We may also be able to do sibcalls for Thumb, but it's much harder...
9272(define_expand "sibcall"
9273 [(parallel [(call (match_operand 0 "memory_operand" "")
9274 (match_operand 1 "general_operand" ""))
2ba80634 9275 (return)
9276 (use (match_operand 2 "" ""))])]
d68c2c10 9277 "TARGET_32BIT"
1c494086 9278 "
9279 {
33ae7c4b 9280 if (!REG_P (XEXP (operands[0], 0))
9281 && (GET_CODE (XEXP (operands[0], 0)) != SYMBOL_REF))
9282 XEXP (operands[0], 0) = force_reg (SImode, XEXP (operands[0], 0));
9283
1c494086 9284 if (operands[2] == NULL_RTX)
9285 operands[2] = const0_rtx;
1c494086 9286 }"
9287)
9288
9289(define_expand "sibcall_value"
ccd90aaa 9290 [(parallel [(set (match_operand 0 "" "")
1c494086 9291 (call (match_operand 1 "memory_operand" "")
9292 (match_operand 2 "general_operand" "")))
2ba80634 9293 (return)
9294 (use (match_operand 3 "" ""))])]
d68c2c10 9295 "TARGET_32BIT"
1c494086 9296 "
9297 {
33ae7c4b 9298 if (!REG_P (XEXP (operands[1], 0)) &&
9299 (GET_CODE (XEXP (operands[1],0)) != SYMBOL_REF))
9300 XEXP (operands[1], 0) = force_reg (SImode, XEXP (operands[1], 0));
9301
1c494086 9302 if (operands[3] == NULL_RTX)
9303 operands[3] = const0_rtx;
1c494086 9304 }"
9305)
9306
9307(define_insn "*sibcall_insn"
84ce8e5c 9308 [(call (mem:SI (match_operand:SI 0 "call_insn_operand" "Cs, US"))
1c494086 9309 (match_operand 1 "" ""))
2ba80634 9310 (return)
9311 (use (match_operand 2 "" ""))]
33ae7c4b 9312 "TARGET_32BIT && SIBLING_CALL_P (insn)"
1c494086 9313 "*
33ae7c4b 9314 if (which_alternative == 1)
9315 return NEED_PLT_RELOC ? \"b%?\\t%a0(PLT)\" : \"b%?\\t%a0\";
9316 else
9317 {
9318 if (arm_arch5 || arm_arch4t)
947d113e 9319 return \"bx%?\\t%0\\t%@ indirect register sibling call\";
33ae7c4b 9320 else
9321 return \"mov%?\\t%|pc, %0\\t%@ indirect register sibling call\";
9322 }
1c494086 9323 "
9324 [(set_attr "type" "call")]
9325)
9326
9327(define_insn "*sibcall_value_insn"
84ce8e5c 9328 [(set (match_operand 0 "" "")
9329 (call (mem:SI (match_operand:SI 1 "call_insn_operand" "Cs,US"))
1c494086 9330 (match_operand 2 "" "")))
2ba80634 9331 (return)
9332 (use (match_operand 3 "" ""))]
33ae7c4b 9333 "TARGET_32BIT && SIBLING_CALL_P (insn)"
1c494086 9334 "*
33ae7c4b 9335 if (which_alternative == 1)
9336 return NEED_PLT_RELOC ? \"b%?\\t%a1(PLT)\" : \"b%?\\t%a1\";
9337 else
9338 {
9339 if (arm_arch5 || arm_arch4t)
84ce8e5c 9340 return \"bx%?\\t%1\";
33ae7c4b 9341 else
9342 return \"mov%?\\t%|pc, %1\\t@ indirect sibling call \";
9343 }
1c494086 9344 "
9345 [(set_attr "type" "call")]
9346)
9347
0686440e 9348(define_expand "<return_str>return"
9349 [(returns)]
8cba51a5 9350 "(TARGET_ARM || (TARGET_THUMB2
9351 && ARM_FUNC_TYPE (arm_current_func_type ()) == ARM_FT_NORMAL
9352 && !IS_STACKALIGN (arm_current_func_type ())))
0686440e 9353 <return_cond_false>"
8cba51a5 9354 "
9355 {
9356 if (TARGET_THUMB2)
9357 {
0686440e 9358 thumb2_expand_return (<return_simple_p>);
8cba51a5 9359 DONE;
9360 }
9361 }
9362 "
9363)
d68c2c10 9364
9c08d1fa 9365;; Often the return insn will be the same as loading from memory, so set attr
d68c2c10 9366(define_insn "*arm_return"
9c08d1fa 9367 [(return)]
cffb2a26 9368 "TARGET_ARM && USE_RETURN_INSN (FALSE)"
9c08d1fa 9369 "*
9c08d1fa 9370 {
cffb2a26 9371 if (arm_ccfsm_state == 2)
9372 {
9373 arm_ccfsm_state += 2;
9374 return \"\";
9375 }
e2549f81 9376 return output_return_instruction (const_true_rtx, true, false, false);
cffb2a26 9377 }"
a2cd141b 9378 [(set_attr "type" "load1")
755eb2b4 9379 (set_attr "length" "12")
0d66636f 9380 (set_attr "predicable" "yes")]
cffb2a26 9381)
9c08d1fa 9382
0686440e 9383(define_insn "*cond_<return_str>return"
9c08d1fa 9384 [(set (pc)
8fa3ba89 9385 (if_then_else (match_operator 0 "arm_comparison_operator"
8a18b90c 9386 [(match_operand 1 "cc_register" "") (const_int 0)])
0686440e 9387 (returns)
9c08d1fa 9388 (pc)))]
0686440e 9389 "TARGET_ARM <return_cond_true>"
9c08d1fa 9390 "*
8fa3ba89 9391 {
9392 if (arm_ccfsm_state == 2)
9393 {
9394 arm_ccfsm_state += 2;
9395 return \"\";
9396 }
0686440e 9397 return output_return_instruction (operands[0], true, false,
9398 <return_simple_p>);
8fa3ba89 9399 }"
9400 [(set_attr "conds" "use")
755eb2b4 9401 (set_attr "length" "12")
a2cd141b 9402 (set_attr "type" "load1")]
8fa3ba89 9403)
9c08d1fa 9404
0686440e 9405(define_insn "*cond_<return_str>return_inverted"
9c08d1fa 9406 [(set (pc)
8fa3ba89 9407 (if_then_else (match_operator 0 "arm_comparison_operator"
8a18b90c 9408 [(match_operand 1 "cc_register" "") (const_int 0)])
9c08d1fa 9409 (pc)
0686440e 9410 (returns)))]
9411 "TARGET_ARM <return_cond_true>"
9c08d1fa 9412 "*
8fa3ba89 9413 {
9414 if (arm_ccfsm_state == 2)
9415 {
9416 arm_ccfsm_state += 2;
9417 return \"\";
9418 }
0686440e 9419 return output_return_instruction (operands[0], true, true,
9420 <return_simple_p>);
8fa3ba89 9421 }"
9422 [(set_attr "conds" "use")
37a1317b 9423 (set_attr "length" "12")
a2cd141b 9424 (set_attr "type" "load1")]
8fa3ba89 9425)
9c08d1fa 9426
e2549f81 9427(define_insn "*arm_simple_return"
9428 [(simple_return)]
9429 "TARGET_ARM"
9430 "*
9431 {
9432 if (arm_ccfsm_state == 2)
9433 {
9434 arm_ccfsm_state += 2;
9435 return \"\";
9436 }
9437 return output_return_instruction (const_true_rtx, true, false, true);
9438 }"
9439 [(set_attr "type" "branch")
9440 (set_attr "length" "4")
9441 (set_attr "predicable" "yes")]
9442)
9443
68121397 9444;; Generate a sequence of instructions to determine if the processor is
9445;; in 26-bit or 32-bit mode, and return the appropriate return address
9446;; mask.
9447
9448(define_expand "return_addr_mask"
9449 [(set (match_dup 1)
9450 (compare:CC_NOOV (unspec [(const_int 0)] UNSPEC_CHECK_ARCH)
9451 (const_int 0)))
9452 (set (match_operand:SI 0 "s_register_operand" "")
9453 (if_then_else:SI (eq (match_dup 1) (const_int 0))
9454 (const_int -1)
9455 (const_int 67108860)))] ; 0x03fffffc
9456 "TARGET_ARM"
9457 "
62eddbd4 9458 operands[1] = gen_rtx_REG (CC_NOOVmode, CC_REGNUM);
68121397 9459 ")
9460
9461(define_insn "*check_arch2"
9462 [(set (match_operand:CC_NOOV 0 "cc_register" "")
9463 (compare:CC_NOOV (unspec [(const_int 0)] UNSPEC_CHECK_ARCH)
9464 (const_int 0)))]
9465 "TARGET_ARM"
9466 "teq\\t%|r0, %|r0\;teq\\t%|pc, %|pc"
9467 [(set_attr "length" "8")
9468 (set_attr "conds" "set")]
9469)
9470
9c08d1fa 9471;; Call subroutine returning any type.
9472
9473(define_expand "untyped_call"
9474 [(parallel [(call (match_operand 0 "" "")
9475 (const_int 0))
9476 (match_operand 1 "" "")
9477 (match_operand 2 "" "")])]
ccd90aaa 9478 "TARGET_EITHER"
9c08d1fa 9479 "
215b30b3 9480 {
9481 int i;
ccd90aaa 9482 rtx par = gen_rtx_PARALLEL (VOIDmode,
9483 rtvec_alloc (XVECLEN (operands[2], 0)));
9484 rtx addr = gen_reg_rtx (Pmode);
9485 rtx mem;
9486 int size = 0;
9c08d1fa 9487
ccd90aaa 9488 emit_move_insn (addr, XEXP (operands[1], 0));
9489 mem = change_address (operands[1], BLKmode, addr);
9c08d1fa 9490
215b30b3 9491 for (i = 0; i < XVECLEN (operands[2], 0); i++)
9492 {
ccd90aaa 9493 rtx src = SET_SRC (XVECEXP (operands[2], 0, i));
9c08d1fa 9494
ccd90aaa 9495 /* Default code only uses r0 as a return value, but we could
9496 be using anything up to 4 registers. */
9497 if (REGNO (src) == R0_REGNUM)
9498 src = gen_rtx_REG (TImode, R0_REGNUM);
9499
9500 XVECEXP (par, 0, i) = gen_rtx_EXPR_LIST (VOIDmode, src,
9501 GEN_INT (size));
9502 size += GET_MODE_SIZE (GET_MODE (src));
9503 }
9504
9505 emit_call_insn (GEN_CALL_VALUE (par, operands[0], const0_rtx, NULL,
9506 const0_rtx));
9507
9508 size = 0;
9509
9510 for (i = 0; i < XVECLEN (par, 0); i++)
9511 {
9512 HOST_WIDE_INT offset = 0;
9513 rtx reg = XEXP (XVECEXP (par, 0, i), 0);
9514
9515 if (size != 0)
29c05e22 9516 emit_move_insn (addr, plus_constant (Pmode, addr, size));
ccd90aaa 9517
9518 mem = change_address (mem, GET_MODE (reg), NULL);
9519 if (REGNO (reg) == R0_REGNUM)
9520 {
9521 /* On thumb we have to use a write-back instruction. */
320ea44d 9522 emit_insn (arm_gen_store_multiple (arm_regs_in_sequence, 4, addr,
9523 TARGET_THUMB ? TRUE : FALSE, mem, &offset));
ccd90aaa 9524 size = TARGET_ARM ? 16 : 0;
9525 }
9526 else
9527 {
9528 emit_move_insn (mem, reg);
9529 size = GET_MODE_SIZE (GET_MODE (reg));
9530 }
215b30b3 9531 }
9c08d1fa 9532
215b30b3 9533 /* The optimizer does not know that the call sets the function value
9534 registers we stored in the result block. We avoid problems by
9535 claiming that all hard registers are used and clobbered at this
9536 point. */
9537 emit_insn (gen_blockage ());
9538
9539 DONE;
9540 }"
9541)
9c08d1fa 9542
ccd90aaa 9543(define_expand "untyped_return"
9544 [(match_operand:BLK 0 "memory_operand" "")
9545 (match_operand 1 "" "")]
9546 "TARGET_EITHER"
9547 "
9548 {
9549 int i;
9550 rtx addr = gen_reg_rtx (Pmode);
9551 rtx mem;
9552 int size = 0;
9553
9554 emit_move_insn (addr, XEXP (operands[0], 0));
9555 mem = change_address (operands[0], BLKmode, addr);
9556
9557 for (i = 0; i < XVECLEN (operands[1], 0); i++)
9558 {
9559 HOST_WIDE_INT offset = 0;
9560 rtx reg = SET_DEST (XVECEXP (operands[1], 0, i));
9561
9562 if (size != 0)
29c05e22 9563 emit_move_insn (addr, plus_constant (Pmode, addr, size));
ccd90aaa 9564
9565 mem = change_address (mem, GET_MODE (reg), NULL);
9566 if (REGNO (reg) == R0_REGNUM)
9567 {
9568 /* On thumb we have to use a write-back instruction. */
320ea44d 9569 emit_insn (arm_gen_load_multiple (arm_regs_in_sequence, 4, addr,
9570 TARGET_THUMB ? TRUE : FALSE, mem, &offset));
ccd90aaa 9571 size = TARGET_ARM ? 16 : 0;
9572 }
9573 else
9574 {
9575 emit_move_insn (reg, mem);
9576 size = GET_MODE_SIZE (GET_MODE (reg));
9577 }
9578 }
9579
9580 /* Emit USE insns before the return. */
9581 for (i = 0; i < XVECLEN (operands[1], 0); i++)
18b42941 9582 emit_use (SET_DEST (XVECEXP (operands[1], 0, i)));
ccd90aaa 9583
9584 /* Construct the return. */
9585 expand_naked_return ();
9586
9587 DONE;
9588 }"
9589)
9590
9c08d1fa 9591;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
9592;; all of memory. This blocks insns from being moved across this point.
9593
9594(define_insn "blockage"
e1159bbe 9595 [(unspec_volatile [(const_int 0)] VUNSPEC_BLOCKAGE)]
cffb2a26 9596 "TARGET_EITHER"
9c08d1fa 9597 ""
cffb2a26 9598 [(set_attr "length" "0")
9599 (set_attr "type" "block")]
9600)
9c08d1fa 9601
f7fbdd4a 9602(define_expand "casesi"
9603 [(match_operand:SI 0 "s_register_operand" "") ; index to jump on
aea4c774 9604 (match_operand:SI 1 "const_int_operand" "") ; lower bound
9605 (match_operand:SI 2 "const_int_operand" "") ; total range
f7fbdd4a 9606 (match_operand:SI 3 "" "") ; table label
9607 (match_operand:SI 4 "" "")] ; Out of range label
e6ac8414 9608 "TARGET_32BIT || optimize_size || flag_pic"
f7fbdd4a 9609 "
215b30b3 9610 {
e6ac8414 9611 enum insn_code code;
215b30b3 9612 if (operands[1] != const0_rtx)
9613 {
e6ac8414 9614 rtx reg = gen_reg_rtx (SImode);
f7fbdd4a 9615
215b30b3 9616 emit_insn (gen_addsi3 (reg, operands[0],
d022fa24 9617 gen_int_mode (-INTVAL (operands[1]),
9618 SImode)));
215b30b3 9619 operands[0] = reg;
9620 }
9c08d1fa 9621
25f905c2 9622 if (TARGET_ARM)
e6ac8414 9623 code = CODE_FOR_arm_casesi_internal;
3db2019b 9624 else if (TARGET_THUMB1)
e6ac8414 9625 code = CODE_FOR_thumb1_casesi_internal_pic;
25f905c2 9626 else if (flag_pic)
e6ac8414 9627 code = CODE_FOR_thumb2_casesi_internal_pic;
25f905c2 9628 else
e6ac8414 9629 code = CODE_FOR_thumb2_casesi_internal;
9630
9631 if (!insn_data[(int) code].operand[1].predicate(operands[2], SImode))
9632 operands[2] = force_reg (SImode, operands[2]);
9633
9634 emit_jump_insn (GEN_FCN ((int) code) (operands[0], operands[2],
9635 operands[3], operands[4]));
215b30b3 9636 DONE;
9637 }"
9638)
f7fbdd4a 9639
f082f1c4 9640;; The USE in this pattern is needed to tell flow analysis that this is
9641;; a CASESI insn. It has no other purpose.
25f905c2 9642(define_insn "arm_casesi_internal"
f082f1c4 9643 [(parallel [(set (pc)
9644 (if_then_else
9645 (leu (match_operand:SI 0 "s_register_operand" "r")
9646 (match_operand:SI 1 "arm_rhs_operand" "rI"))
9647 (mem:SI (plus:SI (mult:SI (match_dup 0) (const_int 4))
9648 (label_ref (match_operand 2 "" ""))))
9649 (label_ref (match_operand 3 "" ""))))
bd5b4116 9650 (clobber (reg:CC CC_REGNUM))
f082f1c4 9651 (use (label_ref (match_dup 2)))])]
cffb2a26 9652 "TARGET_ARM"
f7fbdd4a 9653 "*
0d66636f 9654 if (flag_pic)
9655 return \"cmp\\t%0, %1\;addls\\t%|pc, %|pc, %0, asl #2\;b\\t%l3\";
9656 return \"cmp\\t%0, %1\;ldrls\\t%|pc, [%|pc, %0, asl #2]\;b\\t%l3\";
9657 "
9658 [(set_attr "conds" "clob")
9659 (set_attr "length" "12")]
9660)
9c08d1fa 9661
e6ac8414 9662(define_expand "thumb1_casesi_internal_pic"
9663 [(match_operand:SI 0 "s_register_operand" "")
9664 (match_operand:SI 1 "thumb1_cmp_operand" "")
9665 (match_operand 2 "" "")
9666 (match_operand 3 "" "")]
3db2019b 9667 "TARGET_THUMB1"
e6ac8414 9668 {
9669 rtx reg0;
9670 rtx test = gen_rtx_GTU (VOIDmode, operands[0], operands[1]);
9671 emit_jump_insn (gen_cbranchsi4 (test, operands[0], operands[1],
9672 operands[3]));
9673 reg0 = gen_rtx_REG (SImode, 0);
9674 emit_move_insn (reg0, operands[0]);
9675 emit_jump_insn (gen_thumb1_casesi_dispatch (operands[2]/*, operands[3]*/));
9676 DONE;
9677 }
9678)
9679
9680(define_insn "thumb1_casesi_dispatch"
9681 [(parallel [(set (pc) (unspec [(reg:SI 0)
9682 (label_ref (match_operand 0 "" ""))
9683;; (label_ref (match_operand 1 "" ""))
9684]
9685 UNSPEC_THUMB1_CASESI))
9686 (clobber (reg:SI IP_REGNUM))
9687 (clobber (reg:SI LR_REGNUM))])]
3db2019b 9688 "TARGET_THUMB1"
e6ac8414 9689 "* return thumb1_output_casesi(operands);"
9690 [(set_attr "length" "4")]
9691)
9692
cffb2a26 9693(define_expand "indirect_jump"
9c08d1fa 9694 [(set (pc)
cffb2a26 9695 (match_operand:SI 0 "s_register_operand" ""))]
9696 "TARGET_EITHER"
25f905c2 9697 "
9698 /* Thumb-2 doesn't have mov pc, reg. Explicitly set the low bit of the
9699 address and use bx. */
9700 if (TARGET_THUMB2)
9701 {
9702 rtx tmp;
9703 tmp = gen_reg_rtx (SImode);
9704 emit_insn (gen_iorsi3 (tmp, operands[0], GEN_INT(1)));
9705 operands[0] = tmp;
9706 }
9707 "
cffb2a26 9708)
9709
f1039640 9710;; NB Never uses BX.
cffb2a26 9711(define_insn "*arm_indirect_jump"
9712 [(set (pc)
9713 (match_operand:SI 0 "s_register_operand" "r"))]
9714 "TARGET_ARM"
9715 "mov%?\\t%|pc, %0\\t%@ indirect register jump"
0d66636f 9716 [(set_attr "predicable" "yes")]
cffb2a26 9717)
9c08d1fa 9718
f7fbdd4a 9719(define_insn "*load_indirect_jump"
9c08d1fa 9720 [(set (pc)
9721 (match_operand:SI 0 "memory_operand" "m"))]
cffb2a26 9722 "TARGET_ARM"
9723 "ldr%?\\t%|pc, %0\\t%@ indirect memory jump"
a2cd141b 9724 [(set_attr "type" "load1")
61a2d04c 9725 (set_attr "pool_range" "4096")
9726 (set_attr "neg_pool_range" "4084")
0d66636f 9727 (set_attr "predicable" "yes")]
cffb2a26 9728)
9729
f1039640 9730;; NB Never uses BX.
25f905c2 9731(define_insn "*thumb1_indirect_jump"
cffb2a26 9732 [(set (pc)
9733 (match_operand:SI 0 "register_operand" "l*r"))]
25f905c2 9734 "TARGET_THUMB1"
cffb2a26 9735 "mov\\tpc, %0"
9736 [(set_attr "conds" "clob")
9737 (set_attr "length" "2")]
9738)
9739
9c08d1fa 9740\f
9741;; Misc insns
9742
9743(define_insn "nop"
9744 [(const_int 0)]
cffb2a26 9745 "TARGET_EITHER"
9746 "*
25f905c2 9747 if (TARGET_UNIFIED_ASM)
9748 return \"nop\";
cffb2a26 9749 if (TARGET_ARM)
9750 return \"mov%?\\t%|r0, %|r0\\t%@ nop\";
9751 return \"mov\\tr8, r8\";
9752 "
9753 [(set (attr "length")
9754 (if_then_else (eq_attr "is_thumb" "yes")
9755 (const_int 2)
9756 (const_int 4)))]
9757)
9758
9c08d1fa 9759\f
9760;; Patterns to allow combination of arithmetic, cond code and shifts
9761
f7fbdd4a 9762(define_insn "*arith_shiftsi"
7392680c 9763 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r")
9c08d1fa 9764 (match_operator:SI 1 "shiftable_operator"
9765 [(match_operator:SI 3 "shift_operator"
7392680c 9766 [(match_operand:SI 4 "s_register_operand" "r,r,r,r")
9767 (match_operand:SI 5 "shift_amount_operand" "M,M,M,r")])
9768 (match_operand:SI 2 "s_register_operand" "rk,rk,r,rk")]))]
d5d4dc8d 9769 "TARGET_32BIT"
6c4c2133 9770 "%i1%?\\t%0, %2, %4%S3"
344495ea 9771 [(set_attr "predicable" "yes")
331beb1a 9772 (set_attr "shift" "4")
7392680c 9773 (set_attr "arch" "a,t2,t2,a")
9774 ;; Thumb2 doesn't allow the stack pointer to be used for
9775 ;; operand1 for all operations other than add and sub. In this case
9776 ;; the minus operation is a candidate for an rsub and hence needs
9777 ;; to be disabled.
9778 ;; We have to make sure to disable the fourth alternative if
d5d4dc8d 9779 ;; the shift_operator is MULT, since otherwise the insn will
9780 ;; also match a multiply_accumulate pattern and validate_change
9781 ;; will allow a replacement of the constant with a register
9782 ;; despite the checks done in shift_operator.
9783 (set_attr_alternative "insn_enabled"
9784 [(const_string "yes")
7392680c 9785 (if_then_else
9786 (match_operand:SI 1 "add_operator" "")
9787 (const_string "yes") (const_string "no"))
9788 (const_string "yes")
d5d4dc8d 9789 (if_then_else
9790 (match_operand:SI 3 "mult_operator" "")
9791 (const_string "no") (const_string "yes"))])
6b6abc9c 9792 (set_attr "type" "arlo_shift,arlo_shift,arlo_shift,arlo_shift_reg")])
9c08d1fa 9793
d7863cfe 9794(define_split
9795 [(set (match_operand:SI 0 "s_register_operand" "")
9796 (match_operator:SI 1 "shiftable_operator"
9797 [(match_operator:SI 2 "shiftable_operator"
9798 [(match_operator:SI 3 "shift_operator"
9799 [(match_operand:SI 4 "s_register_operand" "")
9800 (match_operand:SI 5 "reg_or_int_operand" "")])
9801 (match_operand:SI 6 "s_register_operand" "")])
9802 (match_operand:SI 7 "arm_rhs_operand" "")]))
9803 (clobber (match_operand:SI 8 "s_register_operand" ""))]
d5d4dc8d 9804 "TARGET_32BIT"
d7863cfe 9805 [(set (match_dup 8)
9806 (match_op_dup 2 [(match_op_dup 3 [(match_dup 4) (match_dup 5)])
9807 (match_dup 6)]))
9808 (set (match_dup 0)
9809 (match_op_dup 1 [(match_dup 8) (match_dup 7)]))]
9810 "")
9811
f7fbdd4a 9812(define_insn "*arith_shiftsi_compare0"
bd5b4116 9813 [(set (reg:CC_NOOV CC_REGNUM)
d5d4dc8d 9814 (compare:CC_NOOV
9815 (match_operator:SI 1 "shiftable_operator"
9816 [(match_operator:SI 3 "shift_operator"
9817 [(match_operand:SI 4 "s_register_operand" "r,r")
9818 (match_operand:SI 5 "shift_amount_operand" "M,r")])
9819 (match_operand:SI 2 "s_register_operand" "r,r")])
9820 (const_int 0)))
9821 (set (match_operand:SI 0 "s_register_operand" "=r,r")
9c08d1fa 9822 (match_op_dup 1 [(match_op_dup 3 [(match_dup 4) (match_dup 5)])
9823 (match_dup 2)]))]
d5d4dc8d 9824 "TARGET_32BIT"
25f905c2 9825 "%i1%.\\t%0, %2, %4%S3"
344495ea 9826 [(set_attr "conds" "set")
331beb1a 9827 (set_attr "shift" "4")
d5d4dc8d 9828 (set_attr "arch" "32,a")
6b6abc9c 9829 (set_attr "type" "arlo_shift,arlo_shift_reg")])
9c08d1fa 9830
f7fbdd4a 9831(define_insn "*arith_shiftsi_compare0_scratch"
bd5b4116 9832 [(set (reg:CC_NOOV CC_REGNUM)
d5d4dc8d 9833 (compare:CC_NOOV
9834 (match_operator:SI 1 "shiftable_operator"
9835 [(match_operator:SI 3 "shift_operator"
9836 [(match_operand:SI 4 "s_register_operand" "r,r")
9837 (match_operand:SI 5 "shift_amount_operand" "M,r")])
9838 (match_operand:SI 2 "s_register_operand" "r,r")])
9839 (const_int 0)))
9840 (clobber (match_scratch:SI 0 "=r,r"))]
9841 "TARGET_32BIT"
25f905c2 9842 "%i1%.\\t%0, %2, %4%S3"
344495ea 9843 [(set_attr "conds" "set")
331beb1a 9844 (set_attr "shift" "4")
d5d4dc8d 9845 (set_attr "arch" "32,a")
6b6abc9c 9846 (set_attr "type" "arlo_shift,arlo_shift_reg")])
9c08d1fa 9847
f7fbdd4a 9848(define_insn "*sub_shiftsi"
d5d4dc8d 9849 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9850 (minus:SI (match_operand:SI 1 "s_register_operand" "r,r")
9c08d1fa 9851 (match_operator:SI 2 "shift_operator"
d5d4dc8d 9852 [(match_operand:SI 3 "s_register_operand" "r,r")
9853 (match_operand:SI 4 "shift_amount_operand" "M,r")])))]
9854 "TARGET_32BIT"
6c4c2133 9855 "sub%?\\t%0, %1, %3%S2"
344495ea 9856 [(set_attr "predicable" "yes")
331beb1a 9857 (set_attr "shift" "3")
d5d4dc8d 9858 (set_attr "arch" "32,a")
6b6abc9c 9859 (set_attr "type" "arlo_shift,arlo_shift_reg")])
9c08d1fa 9860
f7fbdd4a 9861(define_insn "*sub_shiftsi_compare0"
bd5b4116 9862 [(set (reg:CC_NOOV CC_REGNUM)
40dbec34 9863 (compare:CC_NOOV
d5d4dc8d 9864 (minus:SI (match_operand:SI 1 "s_register_operand" "r,r")
40dbec34 9865 (match_operator:SI 2 "shift_operator"
d5d4dc8d 9866 [(match_operand:SI 3 "s_register_operand" "r,r")
9867 (match_operand:SI 4 "shift_amount_operand" "M,rM")]))
40dbec34 9868 (const_int 0)))
d5d4dc8d 9869 (set (match_operand:SI 0 "s_register_operand" "=r,r")
9870 (minus:SI (match_dup 1)
9871 (match_op_dup 2 [(match_dup 3) (match_dup 4)])))]
9872 "TARGET_32BIT"
25f905c2 9873 "sub%.\\t%0, %1, %3%S2"
344495ea 9874 [(set_attr "conds" "set")
a2cd141b 9875 (set_attr "shift" "3")
d5d4dc8d 9876 (set_attr "arch" "32,a")
6b6abc9c 9877 (set_attr "type" "arlo_shift,arlo_shift_reg")])
9c08d1fa 9878
f7fbdd4a 9879(define_insn "*sub_shiftsi_compare0_scratch"
bd5b4116 9880 [(set (reg:CC_NOOV CC_REGNUM)
40dbec34 9881 (compare:CC_NOOV
d5d4dc8d 9882 (minus:SI (match_operand:SI 1 "s_register_operand" "r,r")
40dbec34 9883 (match_operator:SI 2 "shift_operator"
d5d4dc8d 9884 [(match_operand:SI 3 "s_register_operand" "r,r")
9885 (match_operand:SI 4 "shift_amount_operand" "M,rM")]))
40dbec34 9886 (const_int 0)))
d5d4dc8d 9887 (clobber (match_scratch:SI 0 "=r,r"))]
9888 "TARGET_32BIT"
25f905c2 9889 "sub%.\\t%0, %1, %3%S2"
344495ea 9890 [(set_attr "conds" "set")
a2cd141b 9891 (set_attr "shift" "3")
d5d4dc8d 9892 (set_attr "arch" "32,a")
6b6abc9c 9893 (set_attr "type" "arlo_shift,arlo_shift_reg")])
9c08d1fa 9894\f
9895
190efb17 9896(define_insn_and_split "*and_scc"
9c08d1fa 9897 [(set (match_operand:SI 0 "s_register_operand" "=r")
8fa3ba89 9898 (and:SI (match_operator:SI 1 "arm_comparison_operator"
190efb17 9899 [(match_operand 2 "cc_register" "") (const_int 0)])
9900 (match_operand:SI 3 "s_register_operand" "r")))]
cffb2a26 9901 "TARGET_ARM"
190efb17 9902 "#" ; "mov%D1\\t%0, #0\;and%d1\\t%0, %3, #1"
9903 "&& reload_completed"
9904 [(cond_exec (match_dup 5) (set (match_dup 0) (const_int 0)))
9905 (cond_exec (match_dup 4) (set (match_dup 0)
9906 (and:SI (match_dup 3) (const_int 1))))]
9907 {
9908 enum machine_mode mode = GET_MODE (operands[2]);
9909 enum rtx_code rc = GET_CODE (operands[1]);
9910
9911 /* Note that operands[4] is the same as operands[1],
9912 but with VOIDmode as the result. */
9913 operands[4] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
9914 if (mode == CCFPmode || mode == CCFPEmode)
9915 rc = reverse_condition_maybe_unordered (rc);
9916 else
9917 rc = reverse_condition (rc);
9918 operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
9919 }
8fa3ba89 9920 [(set_attr "conds" "use")
1aed5204 9921 (set_attr "type" "mov_reg")
8fa3ba89 9922 (set_attr "length" "8")]
9923)
9c08d1fa 9924
190efb17 9925(define_insn_and_split "*ior_scc"
9c08d1fa 9926 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
190efb17 9927 (ior:SI (match_operator:SI 1 "arm_comparison_operator"
9928 [(match_operand 2 "cc_register" "") (const_int 0)])
9929 (match_operand:SI 3 "s_register_operand" "0,?r")))]
cffb2a26 9930 "TARGET_ARM"
e2348bcb 9931 "@
190efb17 9932 orr%d1\\t%0, %3, #1
9933 #"
9934 "&& reload_completed
9935 && REGNO (operands [0]) != REGNO (operands[3])"
9936 ;; && which_alternative == 1
9937 ; mov%D1\\t%0, %3\;orr%d1\\t%0, %3, #1
9938 [(cond_exec (match_dup 5) (set (match_dup 0) (match_dup 3)))
9939 (cond_exec (match_dup 4) (set (match_dup 0)
9940 (ior:SI (match_dup 3) (const_int 1))))]
9941 {
9942 enum machine_mode mode = GET_MODE (operands[2]);
9943 enum rtx_code rc = GET_CODE (operands[1]);
9944
9945 /* Note that operands[4] is the same as operands[1],
9946 but with VOIDmode as the result. */
9947 operands[4] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
9948 if (mode == CCFPmode || mode == CCFPEmode)
9949 rc = reverse_condition_maybe_unordered (rc);
9950 else
9951 rc = reverse_condition (rc);
9952 operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
9953 }
8fa3ba89 9954 [(set_attr "conds" "use")
9955 (set_attr "length" "4,8")]
9956)
9c08d1fa 9957
2df9477b 9958; A series of splitters for the compare_scc pattern below. Note that
9959; order is important.
9960(define_split
9961 [(set (match_operand:SI 0 "s_register_operand" "")
9962 (lt:SI (match_operand:SI 1 "s_register_operand" "")
9963 (const_int 0)))
9964 (clobber (reg:CC CC_REGNUM))]
9965 "TARGET_32BIT && reload_completed"
9966 [(set (match_dup 0) (lshiftrt:SI (match_dup 1) (const_int 31)))])
9967
9968(define_split
9969 [(set (match_operand:SI 0 "s_register_operand" "")
9970 (ge:SI (match_operand:SI 1 "s_register_operand" "")
9971 (const_int 0)))
9972 (clobber (reg:CC CC_REGNUM))]
9973 "TARGET_32BIT && reload_completed"
9974 [(set (match_dup 0) (not:SI (match_dup 1)))
9975 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 31)))])
9976
98562479 9977(define_split
9978 [(set (match_operand:SI 0 "s_register_operand" "")
9979 (eq:SI (match_operand:SI 1 "s_register_operand" "")
9980 (const_int 0)))
9981 (clobber (reg:CC CC_REGNUM))]
9982 "arm_arch5 && TARGET_32BIT"
9983 [(set (match_dup 0) (clz:SI (match_dup 1)))
9984 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 5)))]
9985)
9986
2df9477b 9987(define_split
9988 [(set (match_operand:SI 0 "s_register_operand" "")
9989 (eq:SI (match_operand:SI 1 "s_register_operand" "")
9990 (const_int 0)))
9991 (clobber (reg:CC CC_REGNUM))]
9992 "TARGET_32BIT && reload_completed"
9993 [(parallel
080c0b9a 9994 [(set (reg:CC CC_REGNUM)
9995 (compare:CC (const_int 1) (match_dup 1)))
2df9477b 9996 (set (match_dup 0)
9997 (minus:SI (const_int 1) (match_dup 1)))])
080c0b9a 9998 (cond_exec (ltu:CC (reg:CC CC_REGNUM) (const_int 0))
2df9477b 9999 (set (match_dup 0) (const_int 0)))])
10000
10001(define_split
10002 [(set (match_operand:SI 0 "s_register_operand" "")
10003 (ne:SI (match_operand:SI 1 "s_register_operand" "")
10004 (match_operand:SI 2 "const_int_operand" "")))
10005 (clobber (reg:CC CC_REGNUM))]
10006 "TARGET_32BIT && reload_completed"
10007 [(parallel
10008 [(set (reg:CC CC_REGNUM)
10009 (compare:CC (match_dup 1) (match_dup 2)))
10010 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 3)))])
10011 (cond_exec (ne:CC (reg:CC CC_REGNUM) (const_int 0))
10012 (set (match_dup 0) (const_int 1)))]
10013{
10014 operands[3] = GEN_INT (-INTVAL (operands[2]));
10015})
10016
10017(define_split
10018 [(set (match_operand:SI 0 "s_register_operand" "")
10019 (ne:SI (match_operand:SI 1 "s_register_operand" "")
10020 (match_operand:SI 2 "arm_add_operand" "")))
10021 (clobber (reg:CC CC_REGNUM))]
10022 "TARGET_32BIT && reload_completed"
10023 [(parallel
10024 [(set (reg:CC_NOOV CC_REGNUM)
10025 (compare:CC_NOOV (minus:SI (match_dup 1) (match_dup 2))
10026 (const_int 0)))
10027 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
10028 (cond_exec (ne:CC_NOOV (reg:CC_NOOV CC_REGNUM) (const_int 0))
10029 (set (match_dup 0) (const_int 1)))])
10030
10031(define_insn_and_split "*compare_scc"
fd711051 10032 [(set (match_operand:SI 0 "s_register_operand" "=Ts,Ts")
8fa3ba89 10033 (match_operator:SI 1 "arm_comparison_operator"
5565501b 10034 [(match_operand:SI 2 "s_register_operand" "r,r")
10035 (match_operand:SI 3 "arm_add_operand" "rI,L")]))
bd5b4116 10036 (clobber (reg:CC CC_REGNUM))]
2df9477b 10037 "TARGET_32BIT"
10038 "#"
10039 "&& reload_completed"
10040 [(set (reg:CC CC_REGNUM) (compare:CC (match_dup 2) (match_dup 3)))
10041 (cond_exec (match_dup 4) (set (match_dup 0) (const_int 0)))
10042 (cond_exec (match_dup 5) (set (match_dup 0) (const_int 1)))]
10043{
10044 rtx tmp1;
10045 enum machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
10046 operands[2], operands[3]);
10047 enum rtx_code rc = GET_CODE (operands[1]);
e2348bcb 10048
2df9477b 10049 tmp1 = gen_rtx_REG (mode, CC_REGNUM);
080c0b9a 10050
2df9477b 10051 operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, tmp1, const0_rtx);
10052 if (mode == CCFPmode || mode == CCFPEmode)
10053 rc = reverse_condition_maybe_unordered (rc);
10054 else
10055 rc = reverse_condition (rc);
10056 operands[4] = gen_rtx_fmt_ee (rc, VOIDmode, tmp1, const0_rtx);
10057})
9c08d1fa 10058
080c0b9a 10059;; Attempt to improve the sequence generated by the compare_scc splitters
10060;; not to use conditional execution.
98562479 10061
10062;; Rd = (eq (reg1) (const_int0)) // ARMv5
10063;; clz Rd, reg1
10064;; lsr Rd, Rd, #5
080c0b9a 10065(define_peephole2
10066 [(set (reg:CC CC_REGNUM)
10067 (compare:CC (match_operand:SI 1 "register_operand" "")
98562479 10068 (const_int 0)))
10069 (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
10070 (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
10071 (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
10072 (set (match_dup 0) (const_int 1)))]
10073 "arm_arch5 && TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)"
10074 [(set (match_dup 0) (clz:SI (match_dup 1)))
10075 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 5)))]
10076)
10077
10078;; Rd = (eq (reg1) (const_int0)) // !ARMv5
10079;; negs Rd, reg1
10080;; adc Rd, Rd, reg1
10081(define_peephole2
10082 [(set (reg:CC CC_REGNUM)
10083 (compare:CC (match_operand:SI 1 "register_operand" "")
10084 (const_int 0)))
080c0b9a 10085 (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
10086 (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
10087 (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
10088 (set (match_dup 0) (const_int 1)))
98562479 10089 (match_scratch:SI 2 "r")]
10090 "TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)"
922b6913 10091 [(parallel
10092 [(set (reg:CC CC_REGNUM)
98562479 10093 (compare:CC (const_int 0) (match_dup 1)))
10094 (set (match_dup 2) (minus:SI (const_int 0) (match_dup 1)))])
10095 (set (match_dup 0)
10096 (plus:SI (plus:SI (match_dup 1) (match_dup 2))
10097 (geu:SI (reg:CC CC_REGNUM) (const_int 0))))]
10098)
10099
31991287 10100;; Rd = (eq (reg1) (reg2/imm)) // ARMv5 and optimising for speed.
98562479 10101;; sub Rd, Reg1, reg2
10102;; clz Rd, Rd
10103;; lsr Rd, Rd, #5
10104(define_peephole2
10105 [(set (reg:CC CC_REGNUM)
10106 (compare:CC (match_operand:SI 1 "register_operand" "")
10107 (match_operand:SI 2 "arm_rhs_operand" "")))
10108 (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
10109 (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
10110 (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
10111 (set (match_dup 0) (const_int 1)))]
31991287 10112 "arm_arch5 && TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)
10113 && !(TARGET_THUMB2 && optimize_insn_for_size_p ())"
98562479 10114 [(set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))
10115 (set (match_dup 0) (clz:SI (match_dup 0)))
10116 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 5)))]
10117)
10118
10119
31991287 10120;; Rd = (eq (reg1) (reg2)) // ! ARMv5 or optimising for size.
98562479 10121;; sub T1, Reg1, reg2
10122;; negs Rd, T1
10123;; adc Rd, Rd, T1
10124(define_peephole2
10125 [(set (reg:CC CC_REGNUM)
10126 (compare:CC (match_operand:SI 1 "register_operand" "")
10127 (match_operand:SI 2 "arm_rhs_operand" "")))
10128 (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
10129 (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
10130 (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
10131 (set (match_dup 0) (const_int 1)))
10132 (match_scratch:SI 3 "r")]
10133 "TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)"
31991287 10134 [(set (match_dup 3) (match_dup 4))
080c0b9a 10135 (parallel
10136 [(set (reg:CC CC_REGNUM)
10137 (compare:CC (const_int 0) (match_dup 3)))
10138 (set (match_dup 0) (minus:SI (const_int 0) (match_dup 3)))])
98562479 10139 (set (match_dup 0)
10140 (plus:SI (plus:SI (match_dup 0) (match_dup 3))
10141 (geu:SI (reg:CC CC_REGNUM) (const_int 0))))]
31991287 10142 "
10143 if (CONST_INT_P (operands[2]))
10144 operands[4] = plus_constant (SImode, operands[1], -INTVAL (operands[2]));
10145 else
10146 operands[4] = gen_rtx_MINUS (SImode, operands[1], operands[2]);
10147 ")
080c0b9a 10148
f7fbdd4a 10149(define_insn "*cond_move"
9c08d1fa 10150 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
aea4c774 10151 (if_then_else:SI (match_operator 3 "equality_operator"
8fa3ba89 10152 [(match_operator 4 "arm_comparison_operator"
8a18b90c 10153 [(match_operand 5 "cc_register" "") (const_int 0)])
aea4c774 10154 (const_int 0)])
10155 (match_operand:SI 1 "arm_rhs_operand" "0,rI,?rI")
10156 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))]
cffb2a26 10157 "TARGET_ARM"
9c08d1fa 10158 "*
8fa3ba89 10159 if (GET_CODE (operands[3]) == NE)
10160 {
10161 if (which_alternative != 1)
10162 output_asm_insn (\"mov%D4\\t%0, %2\", operands);
10163 if (which_alternative != 0)
10164 output_asm_insn (\"mov%d4\\t%0, %1\", operands);
10165 return \"\";
10166 }
10167 if (which_alternative != 0)
10168 output_asm_insn (\"mov%D4\\t%0, %1\", operands);
10169 if (which_alternative != 1)
10170 output_asm_insn (\"mov%d4\\t%0, %2\", operands);
10171 return \"\";
10172 "
10173 [(set_attr "conds" "use")
1aed5204 10174 (set_attr "type" "mov_reg")
8fa3ba89 10175 (set_attr "length" "4,4,8")]
10176)
9c08d1fa 10177
f7fbdd4a 10178(define_insn "*cond_arith"
9c08d1fa 10179 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10180 (match_operator:SI 5 "shiftable_operator"
8fa3ba89 10181 [(match_operator:SI 4 "arm_comparison_operator"
9c08d1fa 10182 [(match_operand:SI 2 "s_register_operand" "r,r")
10183 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
10184 (match_operand:SI 1 "s_register_operand" "0,?r")]))
bd5b4116 10185 (clobber (reg:CC CC_REGNUM))]
cffb2a26 10186 "TARGET_ARM"
9c08d1fa 10187 "*
8fa3ba89 10188 if (GET_CODE (operands[4]) == LT && operands[3] == const0_rtx)
10189 return \"%i5\\t%0, %1, %2, lsr #31\";
40dbec34 10190
8fa3ba89 10191 output_asm_insn (\"cmp\\t%2, %3\", operands);
10192 if (GET_CODE (operands[5]) == AND)
10193 output_asm_insn (\"mov%D4\\t%0, #0\", operands);
10194 else if (GET_CODE (operands[5]) == MINUS)
10195 output_asm_insn (\"rsb%D4\\t%0, %1, #0\", operands);
10196 else if (which_alternative != 0)
10197 output_asm_insn (\"mov%D4\\t%0, %1\", operands);
10198 return \"%i5%d4\\t%0, %1, #1\";
10199 "
10200 [(set_attr "conds" "clob")
10201 (set_attr "length" "12")]
10202)
9c08d1fa 10203
f7fbdd4a 10204(define_insn "*cond_sub"
9c08d1fa 10205 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10206 (minus:SI (match_operand:SI 1 "s_register_operand" "0,?r")
8fa3ba89 10207 (match_operator:SI 4 "arm_comparison_operator"
9c08d1fa 10208 [(match_operand:SI 2 "s_register_operand" "r,r")
10209 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))
bd5b4116 10210 (clobber (reg:CC CC_REGNUM))]
cffb2a26 10211 "TARGET_ARM"
9c08d1fa 10212 "*
8fa3ba89 10213 output_asm_insn (\"cmp\\t%2, %3\", operands);
10214 if (which_alternative != 0)
10215 output_asm_insn (\"mov%D4\\t%0, %1\", operands);
10216 return \"sub%d4\\t%0, %1, #1\";
10217 "
10218 [(set_attr "conds" "clob")
10219 (set_attr "length" "8,12")]
10220)
9c08d1fa 10221
aea4c774 10222(define_insn "*cmp_ite0"
cffb2a26 10223 [(set (match_operand 6 "dominant_cc_register" "")
aea4c774 10224 (compare
10225 (if_then_else:SI
8fa3ba89 10226 (match_operator 4 "arm_comparison_operator"
2ff91fec 10227 [(match_operand:SI 0 "s_register_operand"
10228 "l,l,l,r,r,r,r,r,r")
10229 (match_operand:SI 1 "arm_add_operand"
10230 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
8fa3ba89 10231 (match_operator:SI 5 "arm_comparison_operator"
2ff91fec 10232 [(match_operand:SI 2 "s_register_operand"
10233 "l,r,r,l,l,r,r,r,r")
10234 (match_operand:SI 3 "arm_add_operand"
10235 "lPy,rI,L,lPy,lPy,rI,rI,L,L")])
aea4c774 10236 (const_int 0))
10237 (const_int 0)))]
2ff91fec 10238 "TARGET_32BIT"
9c08d1fa 10239 "*
aea4c774 10240 {
2ff91fec 10241 static const char * const cmp1[NUM_OF_COND_CMP][2] =
10242 {
10243 {\"cmp%d5\\t%0, %1\",
10244 \"cmp%d4\\t%2, %3\"},
10245 {\"cmn%d5\\t%0, #%n1\",
10246 \"cmp%d4\\t%2, %3\"},
10247 {\"cmp%d5\\t%0, %1\",
10248 \"cmn%d4\\t%2, #%n3\"},
10249 {\"cmn%d5\\t%0, #%n1\",
10250 \"cmn%d4\\t%2, #%n3\"}
10251 };
10252 static const char * const cmp2[NUM_OF_COND_CMP][2] =
10253 {
10254 {\"cmp\\t%2, %3\",
10255 \"cmp\\t%0, %1\"},
10256 {\"cmp\\t%2, %3\",
10257 \"cmn\\t%0, #%n1\"},
10258 {\"cmn\\t%2, #%n3\",
10259 \"cmp\\t%0, %1\"},
10260 {\"cmn\\t%2, #%n3\",
10261 \"cmn\\t%0, #%n1\"}
10262 };
10263 static const char * const ite[2] =
8fa3ba89 10264 {
2ff91fec 10265 \"it\\t%d5\",
10266 \"it\\t%d4\"
8fa3ba89 10267 };
2ff91fec 10268 static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
10269 CMP_CMP, CMN_CMP, CMP_CMP,
10270 CMN_CMP, CMP_CMN, CMN_CMN};
8fa3ba89 10271 int swap =
10272 comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4]));
10273
2ff91fec 10274 output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
10275 if (TARGET_THUMB2) {
10276 output_asm_insn (ite[swap], operands);
10277 }
10278 output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
10279 return \"\";
8fa3ba89 10280 }"
10281 [(set_attr "conds" "set")
2ff91fec 10282 (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
10283 (set_attr_alternative "length"
10284 [(const_int 6)
10285 (const_int 8)
10286 (const_int 8)
10287 (const_int 8)
10288 (const_int 8)
10289 (if_then_else (eq_attr "is_thumb" "no")
10290 (const_int 8)
10291 (const_int 10))
10292 (if_then_else (eq_attr "is_thumb" "no")
10293 (const_int 8)
10294 (const_int 10))
10295 (if_then_else (eq_attr "is_thumb" "no")
10296 (const_int 8)
10297 (const_int 10))
10298 (if_then_else (eq_attr "is_thumb" "no")
10299 (const_int 8)
10300 (const_int 10))])]
8fa3ba89 10301)
9c08d1fa 10302
aea4c774 10303(define_insn "*cmp_ite1"
cffb2a26 10304 [(set (match_operand 6 "dominant_cc_register" "")
aea4c774 10305 (compare
10306 (if_then_else:SI
8fa3ba89 10307 (match_operator 4 "arm_comparison_operator"
2ff91fec 10308 [(match_operand:SI 0 "s_register_operand"
10309 "l,l,l,r,r,r,r,r,r")
10310 (match_operand:SI 1 "arm_add_operand"
10311 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
8fa3ba89 10312 (match_operator:SI 5 "arm_comparison_operator"
2ff91fec 10313 [(match_operand:SI 2 "s_register_operand"
10314 "l,r,r,l,l,r,r,r,r")
10315 (match_operand:SI 3 "arm_add_operand"
10316 "lPy,rI,L,lPy,lPy,rI,rI,L,L")])
aea4c774 10317 (const_int 1))
10318 (const_int 0)))]
2ff91fec 10319 "TARGET_32BIT"
9c08d1fa 10320 "*
9c08d1fa 10321 {
2ff91fec 10322 static const char * const cmp1[NUM_OF_COND_CMP][2] =
10323 {
10324 {\"cmp\\t%0, %1\",
10325 \"cmp\\t%2, %3\"},
10326 {\"cmn\\t%0, #%n1\",
10327 \"cmp\\t%2, %3\"},
10328 {\"cmp\\t%0, %1\",
10329 \"cmn\\t%2, #%n3\"},
10330 {\"cmn\\t%0, #%n1\",
10331 \"cmn\\t%2, #%n3\"}
10332 };
10333 static const char * const cmp2[NUM_OF_COND_CMP][2] =
215b30b3 10334 {
2ff91fec 10335 {\"cmp%d4\\t%2, %3\",
10336 \"cmp%D5\\t%0, %1\"},
10337 {\"cmp%d4\\t%2, %3\",
10338 \"cmn%D5\\t%0, #%n1\"},
10339 {\"cmn%d4\\t%2, #%n3\",
10340 \"cmp%D5\\t%0, %1\"},
10341 {\"cmn%d4\\t%2, #%n3\",
10342 \"cmn%D5\\t%0, #%n1\"}
215b30b3 10343 };
2ff91fec 10344 static const char * const ite[2] =
10345 {
10346 \"it\\t%d4\",
10347 \"it\\t%D5\"
10348 };
10349 static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
10350 CMP_CMP, CMN_CMP, CMP_CMP,
10351 CMN_CMP, CMP_CMN, CMN_CMN};
215b30b3 10352 int swap =
10353 comparison_dominates_p (GET_CODE (operands[5]),
10354 reverse_condition (GET_CODE (operands[4])));
10355
2ff91fec 10356 output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
10357 if (TARGET_THUMB2) {
10358 output_asm_insn (ite[swap], operands);
10359 }
10360 output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
10361 return \"\";
215b30b3 10362 }"
8fa3ba89 10363 [(set_attr "conds" "set")
2ff91fec 10364 (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
10365 (set_attr_alternative "length"
10366 [(const_int 6)
10367 (const_int 8)
10368 (const_int 8)
10369 (const_int 8)
10370 (const_int 8)
10371 (if_then_else (eq_attr "is_thumb" "no")
10372 (const_int 8)
10373 (const_int 10))
10374 (if_then_else (eq_attr "is_thumb" "no")
10375 (const_int 8)
10376 (const_int 10))
10377 (if_then_else (eq_attr "is_thumb" "no")
10378 (const_int 8)
10379 (const_int 10))
10380 (if_then_else (eq_attr "is_thumb" "no")
10381 (const_int 8)
10382 (const_int 10))])]
8fa3ba89 10383)
9c08d1fa 10384
f6c53574 10385(define_insn "*cmp_and"
10386 [(set (match_operand 6 "dominant_cc_register" "")
10387 (compare
10388 (and:SI
10389 (match_operator 4 "arm_comparison_operator"
2ff91fec 10390 [(match_operand:SI 0 "s_register_operand"
10391 "l,l,l,r,r,r,r,r,r")
10392 (match_operand:SI 1 "arm_add_operand"
10393 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
f6c53574 10394 (match_operator:SI 5 "arm_comparison_operator"
2ff91fec 10395 [(match_operand:SI 2 "s_register_operand"
10396 "l,r,r,l,l,r,r,r,r")
10397 (match_operand:SI 3 "arm_add_operand"
10398 "lPy,rI,L,lPy,lPy,rI,rI,L,L")]))
f6c53574 10399 (const_int 0)))]
2ff91fec 10400 "TARGET_32BIT"
f6c53574 10401 "*
10402 {
2ff91fec 10403 static const char *const cmp1[NUM_OF_COND_CMP][2] =
f6c53574 10404 {
2ff91fec 10405 {\"cmp%d5\\t%0, %1\",
10406 \"cmp%d4\\t%2, %3\"},
10407 {\"cmn%d5\\t%0, #%n1\",
10408 \"cmp%d4\\t%2, %3\"},
10409 {\"cmp%d5\\t%0, %1\",
10410 \"cmn%d4\\t%2, #%n3\"},
10411 {\"cmn%d5\\t%0, #%n1\",
10412 \"cmn%d4\\t%2, #%n3\"}
f6c53574 10413 };
2ff91fec 10414 static const char *const cmp2[NUM_OF_COND_CMP][2] =
10415 {
10416 {\"cmp\\t%2, %3\",
10417 \"cmp\\t%0, %1\"},
10418 {\"cmp\\t%2, %3\",
10419 \"cmn\\t%0, #%n1\"},
10420 {\"cmn\\t%2, #%n3\",
10421 \"cmp\\t%0, %1\"},
10422 {\"cmn\\t%2, #%n3\",
10423 \"cmn\\t%0, #%n1\"}
10424 };
10425 static const char *const ite[2] =
10426 {
10427 \"it\\t%d5\",
10428 \"it\\t%d4\"
10429 };
10430 static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
10431 CMP_CMP, CMN_CMP, CMP_CMP,
10432 CMN_CMP, CMP_CMN, CMN_CMN};
f6c53574 10433 int swap =
10434 comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4]));
10435
2ff91fec 10436 output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
10437 if (TARGET_THUMB2) {
10438 output_asm_insn (ite[swap], operands);
10439 }
10440 output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
10441 return \"\";
f6c53574 10442 }"
10443 [(set_attr "conds" "set")
10444 (set_attr "predicable" "no")
2ff91fec 10445 (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
10446 (set_attr_alternative "length"
10447 [(const_int 6)
10448 (const_int 8)
10449 (const_int 8)
10450 (const_int 8)
10451 (const_int 8)
10452 (if_then_else (eq_attr "is_thumb" "no")
10453 (const_int 8)
10454 (const_int 10))
10455 (if_then_else (eq_attr "is_thumb" "no")
10456 (const_int 8)
10457 (const_int 10))
10458 (if_then_else (eq_attr "is_thumb" "no")
10459 (const_int 8)
10460 (const_int 10))
10461 (if_then_else (eq_attr "is_thumb" "no")
10462 (const_int 8)
10463 (const_int 10))])]
f6c53574 10464)
10465
10466(define_insn "*cmp_ior"
10467 [(set (match_operand 6 "dominant_cc_register" "")
10468 (compare
10469 (ior:SI
10470 (match_operator 4 "arm_comparison_operator"
2ff91fec 10471 [(match_operand:SI 0 "s_register_operand"
10472 "l,l,l,r,r,r,r,r,r")
10473 (match_operand:SI 1 "arm_add_operand"
10474 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
f6c53574 10475 (match_operator:SI 5 "arm_comparison_operator"
2ff91fec 10476 [(match_operand:SI 2 "s_register_operand"
10477 "l,r,r,l,l,r,r,r,r")
10478 (match_operand:SI 3 "arm_add_operand"
10479 "lPy,rI,L,lPy,lPy,rI,rI,L,L")]))
f6c53574 10480 (const_int 0)))]
2ff91fec 10481 "TARGET_32BIT"
f6c53574 10482 "*
f6c53574 10483 {
2ff91fec 10484 static const char *const cmp1[NUM_OF_COND_CMP][2] =
10485 {
10486 {\"cmp\\t%0, %1\",
10487 \"cmp\\t%2, %3\"},
10488 {\"cmn\\t%0, #%n1\",
10489 \"cmp\\t%2, %3\"},
10490 {\"cmp\\t%0, %1\",
10491 \"cmn\\t%2, #%n3\"},
10492 {\"cmn\\t%0, #%n1\",
10493 \"cmn\\t%2, #%n3\"}
10494 };
10495 static const char *const cmp2[NUM_OF_COND_CMP][2] =
10496 {
10497 {\"cmp%D4\\t%2, %3\",
10498 \"cmp%D5\\t%0, %1\"},
10499 {\"cmp%D4\\t%2, %3\",
10500 \"cmn%D5\\t%0, #%n1\"},
10501 {\"cmn%D4\\t%2, #%n3\",
10502 \"cmp%D5\\t%0, %1\"},
10503 {\"cmn%D4\\t%2, #%n3\",
10504 \"cmn%D5\\t%0, #%n1\"}
10505 };
10506 static const char *const ite[2] =
10507 {
10508 \"it\\t%D4\",
10509 \"it\\t%D5\"
10510 };
10511 static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
10512 CMP_CMP, CMN_CMP, CMP_CMP,
10513 CMN_CMP, CMP_CMN, CMN_CMN};
10514 int swap =
10515 comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4]));
10516
10517 output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
10518 if (TARGET_THUMB2) {
10519 output_asm_insn (ite[swap], operands);
10520 }
10521 output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
10522 return \"\";
10523 }
10524 "
f6c53574 10525 [(set_attr "conds" "set")
2ff91fec 10526 (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
10527 (set_attr_alternative "length"
10528 [(const_int 6)
10529 (const_int 8)
10530 (const_int 8)
10531 (const_int 8)
10532 (const_int 8)
10533 (if_then_else (eq_attr "is_thumb" "no")
10534 (const_int 8)
10535 (const_int 10))
10536 (if_then_else (eq_attr "is_thumb" "no")
10537 (const_int 8)
10538 (const_int 10))
10539 (if_then_else (eq_attr "is_thumb" "no")
10540 (const_int 8)
10541 (const_int 10))
10542 (if_then_else (eq_attr "is_thumb" "no")
10543 (const_int 8)
10544 (const_int 10))])]
f6c53574 10545)
10546
3c5afce6 10547(define_insn_and_split "*ior_scc_scc"
fd711051 10548 [(set (match_operand:SI 0 "s_register_operand" "=Ts")
3c5afce6 10549 (ior:SI (match_operator:SI 3 "arm_comparison_operator"
10550 [(match_operand:SI 1 "s_register_operand" "r")
10551 (match_operand:SI 2 "arm_add_operand" "rIL")])
10552 (match_operator:SI 6 "arm_comparison_operator"
10553 [(match_operand:SI 4 "s_register_operand" "r")
10554 (match_operand:SI 5 "arm_add_operand" "rIL")])))
10555 (clobber (reg:CC CC_REGNUM))]
2ff91fec 10556 "TARGET_32BIT
3c5afce6 10557 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_OR_Y)
10558 != CCmode)"
10559 "#"
2ff91fec 10560 "TARGET_32BIT && reload_completed"
3c5afce6 10561 [(set (match_dup 7)
10562 (compare
10563 (ior:SI
10564 (match_op_dup 3 [(match_dup 1) (match_dup 2)])
10565 (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
10566 (const_int 0)))
10567 (set (match_dup 0) (ne:SI (match_dup 7) (const_int 0)))]
10568 "operands[7]
10569 = gen_rtx_REG (arm_select_dominance_cc_mode (operands[3], operands[6],
10570 DOM_CC_X_OR_Y),
601f584c 10571 CC_REGNUM);"
10572 [(set_attr "conds" "clob")
10573 (set_attr "length" "16")])
10574
10575; If the above pattern is followed by a CMP insn, then the compare is
10576; redundant, since we can rework the conditional instruction that follows.
10577(define_insn_and_split "*ior_scc_scc_cmp"
10578 [(set (match_operand 0 "dominant_cc_register" "")
10579 (compare (ior:SI (match_operator:SI 3 "arm_comparison_operator"
10580 [(match_operand:SI 1 "s_register_operand" "r")
10581 (match_operand:SI 2 "arm_add_operand" "rIL")])
10582 (match_operator:SI 6 "arm_comparison_operator"
10583 [(match_operand:SI 4 "s_register_operand" "r")
10584 (match_operand:SI 5 "arm_add_operand" "rIL")]))
10585 (const_int 0)))
fd711051 10586 (set (match_operand:SI 7 "s_register_operand" "=Ts")
601f584c 10587 (ior:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)])
10588 (match_op_dup 6 [(match_dup 4) (match_dup 5)])))]
2ff91fec 10589 "TARGET_32BIT"
601f584c 10590 "#"
2ff91fec 10591 "TARGET_32BIT && reload_completed"
601f584c 10592 [(set (match_dup 0)
10593 (compare
10594 (ior:SI
10595 (match_op_dup 3 [(match_dup 1) (match_dup 2)])
10596 (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
10597 (const_int 0)))
10598 (set (match_dup 7) (ne:SI (match_dup 0) (const_int 0)))]
10599 ""
10600 [(set_attr "conds" "set")
10601 (set_attr "length" "16")])
3c5afce6 10602
10603(define_insn_and_split "*and_scc_scc"
fd711051 10604 [(set (match_operand:SI 0 "s_register_operand" "=Ts")
3c5afce6 10605 (and:SI (match_operator:SI 3 "arm_comparison_operator"
10606 [(match_operand:SI 1 "s_register_operand" "r")
10607 (match_operand:SI 2 "arm_add_operand" "rIL")])
10608 (match_operator:SI 6 "arm_comparison_operator"
10609 [(match_operand:SI 4 "s_register_operand" "r")
10610 (match_operand:SI 5 "arm_add_operand" "rIL")])))
10611 (clobber (reg:CC CC_REGNUM))]
2ff91fec 10612 "TARGET_32BIT
3c5afce6 10613 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y)
10614 != CCmode)"
10615 "#"
2ff91fec 10616 "TARGET_32BIT && reload_completed
601f584c 10617 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y)
10618 != CCmode)"
3c5afce6 10619 [(set (match_dup 7)
10620 (compare
10621 (and:SI
10622 (match_op_dup 3 [(match_dup 1) (match_dup 2)])
10623 (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
10624 (const_int 0)))
10625 (set (match_dup 0) (ne:SI (match_dup 7) (const_int 0)))]
10626 "operands[7]
10627 = gen_rtx_REG (arm_select_dominance_cc_mode (operands[3], operands[6],
10628 DOM_CC_X_AND_Y),
601f584c 10629 CC_REGNUM);"
10630 [(set_attr "conds" "clob")
10631 (set_attr "length" "16")])
10632
10633; If the above pattern is followed by a CMP insn, then the compare is
10634; redundant, since we can rework the conditional instruction that follows.
10635(define_insn_and_split "*and_scc_scc_cmp"
10636 [(set (match_operand 0 "dominant_cc_register" "")
10637 (compare (and:SI (match_operator:SI 3 "arm_comparison_operator"
10638 [(match_operand:SI 1 "s_register_operand" "r")
10639 (match_operand:SI 2 "arm_add_operand" "rIL")])
10640 (match_operator:SI 6 "arm_comparison_operator"
10641 [(match_operand:SI 4 "s_register_operand" "r")
10642 (match_operand:SI 5 "arm_add_operand" "rIL")]))
10643 (const_int 0)))
fd711051 10644 (set (match_operand:SI 7 "s_register_operand" "=Ts")
601f584c 10645 (and:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)])
10646 (match_op_dup 6 [(match_dup 4) (match_dup 5)])))]
2ff91fec 10647 "TARGET_32BIT"
601f584c 10648 "#"
2ff91fec 10649 "TARGET_32BIT && reload_completed"
601f584c 10650 [(set (match_dup 0)
10651 (compare
10652 (and:SI
10653 (match_op_dup 3 [(match_dup 1) (match_dup 2)])
10654 (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
10655 (const_int 0)))
10656 (set (match_dup 7) (ne:SI (match_dup 0) (const_int 0)))]
10657 ""
10658 [(set_attr "conds" "set")
10659 (set_attr "length" "16")])
10660
10661;; If there is no dominance in the comparison, then we can still save an
10662;; instruction in the AND case, since we can know that the second compare
10663;; need only zero the value if false (if true, then the value is already
10664;; correct).
10665(define_insn_and_split "*and_scc_scc_nodom"
fd711051 10666 [(set (match_operand:SI 0 "s_register_operand" "=&Ts,&Ts,&Ts")
601f584c 10667 (and:SI (match_operator:SI 3 "arm_comparison_operator"
10668 [(match_operand:SI 1 "s_register_operand" "r,r,0")
10669 (match_operand:SI 2 "arm_add_operand" "rIL,0,rIL")])
10670 (match_operator:SI 6 "arm_comparison_operator"
10671 [(match_operand:SI 4 "s_register_operand" "r,r,r")
10672 (match_operand:SI 5 "arm_add_operand" "rIL,rIL,rIL")])))
10673 (clobber (reg:CC CC_REGNUM))]
2ff91fec 10674 "TARGET_32BIT
601f584c 10675 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y)
10676 == CCmode)"
10677 "#"
2ff91fec 10678 "TARGET_32BIT && reload_completed"
601f584c 10679 [(parallel [(set (match_dup 0)
10680 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
10681 (clobber (reg:CC CC_REGNUM))])
10682 (set (match_dup 7) (match_op_dup 8 [(match_dup 4) (match_dup 5)]))
10683 (set (match_dup 0)
10684 (if_then_else:SI (match_op_dup 6 [(match_dup 7) (const_int 0)])
10685 (match_dup 0)
10686 (const_int 0)))]
10687 "operands[7] = gen_rtx_REG (SELECT_CC_MODE (GET_CODE (operands[6]),
10688 operands[4], operands[5]),
10689 CC_REGNUM);
10690 operands[8] = gen_rtx_COMPARE (GET_MODE (operands[7]), operands[4],
10691 operands[5]);"
10692 [(set_attr "conds" "clob")
10693 (set_attr "length" "20")])
3c5afce6 10694
3a0bdee0 10695(define_split
10696 [(set (reg:CC_NOOV CC_REGNUM)
10697 (compare:CC_NOOV (ior:SI
10698 (and:SI (match_operand:SI 0 "s_register_operand" "")
10699 (const_int 1))
b0694be0 10700 (match_operator:SI 1 "arm_comparison_operator"
3a0bdee0 10701 [(match_operand:SI 2 "s_register_operand" "")
10702 (match_operand:SI 3 "arm_add_operand" "")]))
10703 (const_int 0)))
10704 (clobber (match_operand:SI 4 "s_register_operand" ""))]
10705 "TARGET_ARM"
10706 [(set (match_dup 4)
10707 (ior:SI (match_op_dup 1 [(match_dup 2) (match_dup 3)])
10708 (match_dup 0)))
10709 (set (reg:CC_NOOV CC_REGNUM)
10710 (compare:CC_NOOV (and:SI (match_dup 4) (const_int 1))
10711 (const_int 0)))]
10712 "")
10713
10714(define_split
10715 [(set (reg:CC_NOOV CC_REGNUM)
10716 (compare:CC_NOOV (ior:SI
b0694be0 10717 (match_operator:SI 1 "arm_comparison_operator"
3a0bdee0 10718 [(match_operand:SI 2 "s_register_operand" "")
10719 (match_operand:SI 3 "arm_add_operand" "")])
10720 (and:SI (match_operand:SI 0 "s_register_operand" "")
10721 (const_int 1)))
10722 (const_int 0)))
10723 (clobber (match_operand:SI 4 "s_register_operand" ""))]
10724 "TARGET_ARM"
10725 [(set (match_dup 4)
10726 (ior:SI (match_op_dup 1 [(match_dup 2) (match_dup 3)])
10727 (match_dup 0)))
10728 (set (reg:CC_NOOV CC_REGNUM)
10729 (compare:CC_NOOV (and:SI (match_dup 4) (const_int 1))
10730 (const_int 0)))]
10731 "")
25f905c2 10732;; ??? The conditional patterns above need checking for Thumb-2 usefulness
3a0bdee0 10733
190efb17 10734(define_insn_and_split "*negscc"
9c08d1fa 10735 [(set (match_operand:SI 0 "s_register_operand" "=r")
8fa3ba89 10736 (neg:SI (match_operator 3 "arm_comparison_operator"
9c08d1fa 10737 [(match_operand:SI 1 "s_register_operand" "r")
10738 (match_operand:SI 2 "arm_rhs_operand" "rI")])))
bd5b4116 10739 (clobber (reg:CC CC_REGNUM))]
cffb2a26 10740 "TARGET_ARM"
190efb17 10741 "#"
10742 "&& reload_completed"
10743 [(const_int 0)]
10744 {
10745 rtx cc_reg = gen_rtx_REG (CCmode, CC_REGNUM);
e2348bcb 10746
190efb17 10747 if (GET_CODE (operands[3]) == LT && operands[2] == const0_rtx)
10748 {
10749 /* Emit mov\\t%0, %1, asr #31 */
10750 emit_insn (gen_rtx_SET (VOIDmode,
10751 operands[0],
10752 gen_rtx_ASHIFTRT (SImode,
10753 operands[1],
10754 GEN_INT (31))));
10755 DONE;
10756 }
10757 else if (GET_CODE (operands[3]) == NE)
10758 {
10759 /* Emit subs\\t%0, %1, %2\;mvnne\\t%0, #0 */
10760 if (CONST_INT_P (operands[2]))
10761 emit_insn (gen_cmpsi2_addneg (operands[0], operands[1], operands[2],
10762 GEN_INT (- INTVAL (operands[2]))));
10763 else
10764 emit_insn (gen_subsi3_compare (operands[0], operands[1], operands[2]));
10765
10766 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
10767 gen_rtx_NE (SImode,
10768 cc_reg,
10769 const0_rtx),
10770 gen_rtx_SET (SImode,
10771 operands[0],
10772 GEN_INT (~0))));
10773 DONE;
10774 }
10775 else
10776 {
10777 /* Emit: cmp\\t%1, %2\;mov%D3\\t%0, #0\;mvn%d3\\t%0, #0 */
10778 emit_insn (gen_rtx_SET (VOIDmode,
10779 cc_reg,
10780 gen_rtx_COMPARE (CCmode, operands[1], operands[2])));
10781 enum rtx_code rc = GET_CODE (operands[3]);
10782
10783 rc = reverse_condition (rc);
10784 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
10785 gen_rtx_fmt_ee (rc,
10786 VOIDmode,
10787 cc_reg,
10788 const0_rtx),
10789 gen_rtx_SET (VOIDmode, operands[0], const0_rtx)));
10790 rc = GET_CODE (operands[3]);
10791 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
10792 gen_rtx_fmt_ee (rc,
10793 VOIDmode,
10794 cc_reg,
10795 const0_rtx),
10796 gen_rtx_SET (VOIDmode,
10797 operands[0],
10798 GEN_INT (~0))));
10799 DONE;
10800 }
10801 FAIL;
10802 }
8fa3ba89 10803 [(set_attr "conds" "clob")
10804 (set_attr "length" "12")]
10805)
9c08d1fa 10806
90404b57 10807(define_insn_and_split "movcond_addsi"
10808 [(set (match_operand:SI 0 "s_register_operand" "=r,l,r")
10809 (if_then_else:SI
10810 (match_operator 5 "comparison_operator"
10811 [(plus:SI (match_operand:SI 3 "s_register_operand" "r,r,r")
10812 (match_operand:SI 4 "arm_add_operand" "rIL,rIL,rIL"))
10813 (const_int 0)])
10814 (match_operand:SI 1 "arm_rhs_operand" "rI,rPy,r")
10815 (match_operand:SI 2 "arm_rhs_operand" "rI,rPy,r")))
10816 (clobber (reg:CC CC_REGNUM))]
10817 "TARGET_32BIT"
10818 "#"
10819 "&& reload_completed"
10820 [(set (reg:CC_NOOV CC_REGNUM)
10821 (compare:CC_NOOV
10822 (plus:SI (match_dup 3)
10823 (match_dup 4))
10824 (const_int 0)))
10825 (set (match_dup 0) (match_dup 1))
10826 (cond_exec (match_dup 6)
10827 (set (match_dup 0) (match_dup 2)))]
10828 "
10829 {
10830 enum machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[5]),
10831 operands[3], operands[4]);
10832 enum rtx_code rc = GET_CODE (operands[5]);
10833
10834 operands[6] = gen_rtx_REG (mode, CC_REGNUM);
10835 gcc_assert (!(mode == CCFPmode || mode == CCFPEmode));
10836 rc = reverse_condition (rc);
10837
10838 operands[6] = gen_rtx_fmt_ee (rc, VOIDmode, operands[6], const0_rtx);
10839 }
10840 "
10841 [(set_attr "conds" "clob")
10842 (set_attr "enabled_for_depr_it" "no,yes,yes")]
10843)
10844
9c08d1fa 10845(define_insn "movcond"
10846 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
5565501b 10847 (if_then_else:SI
8fa3ba89 10848 (match_operator 5 "arm_comparison_operator"
5565501b 10849 [(match_operand:SI 3 "s_register_operand" "r,r,r")
10850 (match_operand:SI 4 "arm_add_operand" "rIL,rIL,rIL")])
10851 (match_operand:SI 1 "arm_rhs_operand" "0,rI,?rI")
10852 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
bd5b4116 10853 (clobber (reg:CC CC_REGNUM))]
cffb2a26 10854 "TARGET_ARM"
9c08d1fa 10855 "*
10856 if (GET_CODE (operands[5]) == LT
10857 && (operands[4] == const0_rtx))
10858 {
0438d37f 10859 if (which_alternative != 1 && REG_P (operands[1]))
9c08d1fa 10860 {
9c08d1fa 10861 if (operands[2] == const0_rtx)
e2348bcb 10862 return \"and\\t%0, %1, %3, asr #31\";
10863 return \"ands\\t%0, %1, %3, asr #32\;movcc\\t%0, %2\";
9c08d1fa 10864 }
0438d37f 10865 else if (which_alternative != 0 && REG_P (operands[2]))
9c08d1fa 10866 {
9c08d1fa 10867 if (operands[1] == const0_rtx)
e2348bcb 10868 return \"bic\\t%0, %2, %3, asr #31\";
10869 return \"bics\\t%0, %2, %3, asr #32\;movcs\\t%0, %1\";
9c08d1fa 10870 }
10871 /* The only case that falls through to here is when both ops 1 & 2
674a8f0b 10872 are constants. */
9c08d1fa 10873 }
e2348bcb 10874
9c08d1fa 10875 if (GET_CODE (operands[5]) == GE
10876 && (operands[4] == const0_rtx))
10877 {
0438d37f 10878 if (which_alternative != 1 && REG_P (operands[1]))
9c08d1fa 10879 {
9c08d1fa 10880 if (operands[2] == const0_rtx)
e2348bcb 10881 return \"bic\\t%0, %1, %3, asr #31\";
10882 return \"bics\\t%0, %1, %3, asr #32\;movcs\\t%0, %2\";
9c08d1fa 10883 }
0438d37f 10884 else if (which_alternative != 0 && REG_P (operands[2]))
9c08d1fa 10885 {
9c08d1fa 10886 if (operands[1] == const0_rtx)
e2348bcb 10887 return \"and\\t%0, %2, %3, asr #31\";
10888 return \"ands\\t%0, %2, %3, asr #32\;movcc\\t%0, %1\";
9c08d1fa 10889 }
10890 /* The only case that falls through to here is when both ops 1 & 2
674a8f0b 10891 are constants. */
9c08d1fa 10892 }
0438d37f 10893 if (CONST_INT_P (operands[4])
9c08d1fa 10894 && !const_ok_for_arm (INTVAL (operands[4])))
e2348bcb 10895 output_asm_insn (\"cmn\\t%3, #%n4\", operands);
9c08d1fa 10896 else
e2348bcb 10897 output_asm_insn (\"cmp\\t%3, %4\", operands);
9c08d1fa 10898 if (which_alternative != 0)
e2348bcb 10899 output_asm_insn (\"mov%d5\\t%0, %1\", operands);
9c08d1fa 10900 if (which_alternative != 1)
e2348bcb 10901 output_asm_insn (\"mov%D5\\t%0, %2\", operands);
9c08d1fa 10902 return \"\";
215b30b3 10903 "
8fa3ba89 10904 [(set_attr "conds" "clob")
10905 (set_attr "length" "8,8,12")]
10906)
9c08d1fa 10907
25f905c2 10908;; ??? The patterns below need checking for Thumb-2 usefulness.
10909
8a18b90c 10910(define_insn "*ifcompare_plus_move"
10911 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8fa3ba89 10912 (if_then_else:SI (match_operator 6 "arm_comparison_operator"
8a18b90c 10913 [(match_operand:SI 4 "s_register_operand" "r,r")
10914 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
10915 (plus:SI
10916 (match_operand:SI 2 "s_register_operand" "r,r")
10917 (match_operand:SI 3 "arm_add_operand" "rIL,rIL"))
129a2fe4 10918 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))
bd5b4116 10919 (clobber (reg:CC CC_REGNUM))]
cffb2a26 10920 "TARGET_ARM"
8a18b90c 10921 "#"
8fa3ba89 10922 [(set_attr "conds" "clob")
10923 (set_attr "length" "8,12")]
10924)
8a18b90c 10925
10926(define_insn "*if_plus_move"
129a2fe4 10927 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r")
8a18b90c 10928 (if_then_else:SI
8fa3ba89 10929 (match_operator 4 "arm_comparison_operator"
8a18b90c 10930 [(match_operand 5 "cc_register" "") (const_int 0)])
10931 (plus:SI
129a2fe4 10932 (match_operand:SI 2 "s_register_operand" "r,r,r,r")
10933 (match_operand:SI 3 "arm_add_operand" "rI,L,rI,L"))
10934 (match_operand:SI 1 "arm_rhs_operand" "0,0,?rI,?rI")))]
cffb2a26 10935 "TARGET_ARM"
8a18b90c 10936 "@
10937 add%d4\\t%0, %2, %3
10938 sub%d4\\t%0, %2, #%n3
10939 add%d4\\t%0, %2, %3\;mov%D4\\t%0, %1
129a2fe4 10940 sub%d4\\t%0, %2, #%n3\;mov%D4\\t%0, %1"
8fa3ba89 10941 [(set_attr "conds" "use")
10942 (set_attr "length" "4,4,8,8")
65f68e55 10943 (set_attr_alternative "type"
10944 [(if_then_else (match_operand 3 "const_int_operand" "")
6b6abc9c 10945 (const_string "arlo_imm" )
65f68e55 10946 (const_string "*"))
6b6abc9c 10947 (const_string "arlo_imm")
65f68e55 10948 (const_string "*")
10949 (const_string "*")])]
8fa3ba89 10950)
8a18b90c 10951
10952(define_insn "*ifcompare_move_plus"
5565501b 10953 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8fa3ba89 10954 (if_then_else:SI (match_operator 6 "arm_comparison_operator"
8a18b90c 10955 [(match_operand:SI 4 "s_register_operand" "r,r")
10956 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
129a2fe4 10957 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
8a18b90c 10958 (plus:SI
10959 (match_operand:SI 2 "s_register_operand" "r,r")
10960 (match_operand:SI 3 "arm_add_operand" "rIL,rIL"))))
bd5b4116 10961 (clobber (reg:CC CC_REGNUM))]
cffb2a26 10962 "TARGET_ARM"
8a18b90c 10963 "#"
8fa3ba89 10964 [(set_attr "conds" "clob")
10965 (set_attr "length" "8,12")]
10966)
8a18b90c 10967
10968(define_insn "*if_move_plus"
129a2fe4 10969 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r")
8a18b90c 10970 (if_then_else:SI
8fa3ba89 10971 (match_operator 4 "arm_comparison_operator"
8a18b90c 10972 [(match_operand 5 "cc_register" "") (const_int 0)])
129a2fe4 10973 (match_operand:SI 1 "arm_rhs_operand" "0,0,?rI,?rI")
8a18b90c 10974 (plus:SI
129a2fe4 10975 (match_operand:SI 2 "s_register_operand" "r,r,r,r")
10976 (match_operand:SI 3 "arm_add_operand" "rI,L,rI,L"))))]
cffb2a26 10977 "TARGET_ARM"
8a18b90c 10978 "@
10979 add%D4\\t%0, %2, %3
10980 sub%D4\\t%0, %2, #%n3
10981 add%D4\\t%0, %2, %3\;mov%d4\\t%0, %1
129a2fe4 10982 sub%D4\\t%0, %2, #%n3\;mov%d4\\t%0, %1"
8fa3ba89 10983 [(set_attr "conds" "use")
10984 (set_attr "length" "4,4,8,8")
65f68e55 10985 (set_attr_alternative "type"
10986 [(if_then_else (match_operand 3 "const_int_operand" "")
6b6abc9c 10987 (const_string "arlo_imm" )
65f68e55 10988 (const_string "*"))
6b6abc9c 10989 (const_string "arlo_imm")
65f68e55 10990 (const_string "*")
10991 (const_string "*")])]
8fa3ba89 10992)
8a18b90c 10993
10994(define_insn "*ifcompare_arith_arith"
10995 [(set (match_operand:SI 0 "s_register_operand" "=r")
8fa3ba89 10996 (if_then_else:SI (match_operator 9 "arm_comparison_operator"
8a18b90c 10997 [(match_operand:SI 5 "s_register_operand" "r")
10998 (match_operand:SI 6 "arm_add_operand" "rIL")])
9c08d1fa 10999 (match_operator:SI 8 "shiftable_operator"
8a18b90c 11000 [(match_operand:SI 1 "s_register_operand" "r")
11001 (match_operand:SI 2 "arm_rhs_operand" "rI")])
9c08d1fa 11002 (match_operator:SI 7 "shiftable_operator"
8a18b90c 11003 [(match_operand:SI 3 "s_register_operand" "r")
11004 (match_operand:SI 4 "arm_rhs_operand" "rI")])))
bd5b4116 11005 (clobber (reg:CC CC_REGNUM))]
cffb2a26 11006 "TARGET_ARM"
8a18b90c 11007 "#"
8fa3ba89 11008 [(set_attr "conds" "clob")
11009 (set_attr "length" "12")]
11010)
9c08d1fa 11011
8a18b90c 11012(define_insn "*if_arith_arith"
11013 [(set (match_operand:SI 0 "s_register_operand" "=r")
8fa3ba89 11014 (if_then_else:SI (match_operator 5 "arm_comparison_operator"
8a18b90c 11015 [(match_operand 8 "cc_register" "") (const_int 0)])
11016 (match_operator:SI 6 "shiftable_operator"
11017 [(match_operand:SI 1 "s_register_operand" "r")
11018 (match_operand:SI 2 "arm_rhs_operand" "rI")])
11019 (match_operator:SI 7 "shiftable_operator"
11020 [(match_operand:SI 3 "s_register_operand" "r")
11021 (match_operand:SI 4 "arm_rhs_operand" "rI")])))]
cffb2a26 11022 "TARGET_ARM"
8a18b90c 11023 "%I6%d5\\t%0, %1, %2\;%I7%D5\\t%0, %3, %4"
8fa3ba89 11024 [(set_attr "conds" "use")
11025 (set_attr "length" "8")]
11026)
8a18b90c 11027
f7fbdd4a 11028(define_insn "*ifcompare_arith_move"
9c08d1fa 11029 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8fa3ba89 11030 (if_then_else:SI (match_operator 6 "arm_comparison_operator"
9c08d1fa 11031 [(match_operand:SI 2 "s_register_operand" "r,r")
5565501b 11032 (match_operand:SI 3 "arm_add_operand" "rIL,rIL")])
9c08d1fa 11033 (match_operator:SI 7 "shiftable_operator"
11034 [(match_operand:SI 4 "s_register_operand" "r,r")
11035 (match_operand:SI 5 "arm_rhs_operand" "rI,rI")])
129a2fe4 11036 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))
bd5b4116 11037 (clobber (reg:CC CC_REGNUM))]
cffb2a26 11038 "TARGET_ARM"
9c08d1fa 11039 "*
9c08d1fa 11040 /* If we have an operation where (op x 0) is the identity operation and
01cc3b75 11041 the conditional operator is LT or GE and we are comparing against zero and
674a8f0b 11042 everything is in registers then we can do this in two instructions. */
9c08d1fa 11043 if (operands[3] == const0_rtx
11044 && GET_CODE (operands[7]) != AND
0438d37f 11045 && REG_P (operands[5])
11046 && REG_P (operands[1])
9c08d1fa 11047 && REGNO (operands[1]) == REGNO (operands[4])
11048 && REGNO (operands[4]) != REGNO (operands[0]))
11049 {
11050 if (GET_CODE (operands[6]) == LT)
40dbec34 11051 return \"and\\t%0, %5, %2, asr #31\;%I7\\t%0, %4, %0\";
9c08d1fa 11052 else if (GET_CODE (operands[6]) == GE)
40dbec34 11053 return \"bic\\t%0, %5, %2, asr #31\;%I7\\t%0, %4, %0\";
9c08d1fa 11054 }
0438d37f 11055 if (CONST_INT_P (operands[3])
9c08d1fa 11056 && !const_ok_for_arm (INTVAL (operands[3])))
e2348bcb 11057 output_asm_insn (\"cmn\\t%2, #%n3\", operands);
9c08d1fa 11058 else
e2348bcb 11059 output_asm_insn (\"cmp\\t%2, %3\", operands);
40dbec34 11060 output_asm_insn (\"%I7%d6\\t%0, %4, %5\", operands);
9c08d1fa 11061 if (which_alternative != 0)
129a2fe4 11062 return \"mov%D6\\t%0, %1\";
9c08d1fa 11063 return \"\";
215b30b3 11064 "
8fa3ba89 11065 [(set_attr "conds" "clob")
11066 (set_attr "length" "8,12")]
11067)
9c08d1fa 11068
8a18b90c 11069(define_insn "*if_arith_move"
129a2fe4 11070 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8fa3ba89 11071 (if_then_else:SI (match_operator 4 "arm_comparison_operator"
8a18b90c 11072 [(match_operand 6 "cc_register" "") (const_int 0)])
11073 (match_operator:SI 5 "shiftable_operator"
129a2fe4 11074 [(match_operand:SI 2 "s_register_operand" "r,r")
11075 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
11076 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))]
cffb2a26 11077 "TARGET_ARM"
8a18b90c 11078 "@
11079 %I5%d4\\t%0, %2, %3
129a2fe4 11080 %I5%d4\\t%0, %2, %3\;mov%D4\\t%0, %1"
8fa3ba89 11081 [(set_attr "conds" "use")
11082 (set_attr "length" "4,8")
11083 (set_attr "type" "*,*")]
11084)
8a18b90c 11085
f7fbdd4a 11086(define_insn "*ifcompare_move_arith"
9c08d1fa 11087 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8fa3ba89 11088 (if_then_else:SI (match_operator 6 "arm_comparison_operator"
9c08d1fa 11089 [(match_operand:SI 4 "s_register_operand" "r,r")
5565501b 11090 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
129a2fe4 11091 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
9c08d1fa 11092 (match_operator:SI 7 "shiftable_operator"
11093 [(match_operand:SI 2 "s_register_operand" "r,r")
11094 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))
bd5b4116 11095 (clobber (reg:CC CC_REGNUM))]
cffb2a26 11096 "TARGET_ARM"
9c08d1fa 11097 "*
9c08d1fa 11098 /* If we have an operation where (op x 0) is the identity operation and
01cc3b75 11099 the conditional operator is LT or GE and we are comparing against zero and
9c08d1fa 11100 everything is in registers then we can do this in two instructions */
11101 if (operands[5] == const0_rtx
11102 && GET_CODE (operands[7]) != AND
0438d37f 11103 && REG_P (operands[3])
11104 && REG_P (operands[1])
9c08d1fa 11105 && REGNO (operands[1]) == REGNO (operands[2])
11106 && REGNO (operands[2]) != REGNO (operands[0]))
11107 {
11108 if (GET_CODE (operands[6]) == GE)
40dbec34 11109 return \"and\\t%0, %3, %4, asr #31\;%I7\\t%0, %2, %0\";
9c08d1fa 11110 else if (GET_CODE (operands[6]) == LT)
40dbec34 11111 return \"bic\\t%0, %3, %4, asr #31\;%I7\\t%0, %2, %0\";
9c08d1fa 11112 }
40dbec34 11113
0438d37f 11114 if (CONST_INT_P (operands[5])
9c08d1fa 11115 && !const_ok_for_arm (INTVAL (operands[5])))
e2348bcb 11116 output_asm_insn (\"cmn\\t%4, #%n5\", operands);
9c08d1fa 11117 else
e2348bcb 11118 output_asm_insn (\"cmp\\t%4, %5\", operands);
40dbec34 11119
9c08d1fa 11120 if (which_alternative != 0)
129a2fe4 11121 output_asm_insn (\"mov%d6\\t%0, %1\", operands);
40dbec34 11122 return \"%I7%D6\\t%0, %2, %3\";
215b30b3 11123 "
8fa3ba89 11124 [(set_attr "conds" "clob")
11125 (set_attr "length" "8,12")]
11126)
9c08d1fa 11127
8a18b90c 11128(define_insn "*if_move_arith"
129a2fe4 11129 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8a18b90c 11130 (if_then_else:SI
8fa3ba89 11131 (match_operator 4 "arm_comparison_operator"
8a18b90c 11132 [(match_operand 6 "cc_register" "") (const_int 0)])
129a2fe4 11133 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
8a18b90c 11134 (match_operator:SI 5 "shiftable_operator"
129a2fe4 11135 [(match_operand:SI 2 "s_register_operand" "r,r")
11136 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))]
cffb2a26 11137 "TARGET_ARM"
8a18b90c 11138 "@
11139 %I5%D4\\t%0, %2, %3
129a2fe4 11140 %I5%D4\\t%0, %2, %3\;mov%d4\\t%0, %1"
8fa3ba89 11141 [(set_attr "conds" "use")
11142 (set_attr "length" "4,8")
11143 (set_attr "type" "*,*")]
11144)
8a18b90c 11145
11146(define_insn "*ifcompare_move_not"
9c08d1fa 11147 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8a18b90c 11148 (if_then_else:SI
8fa3ba89 11149 (match_operator 5 "arm_comparison_operator"
8a18b90c 11150 [(match_operand:SI 3 "s_register_operand" "r,r")
11151 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
11152 (match_operand:SI 1 "arm_not_operand" "0,?rIK")
11153 (not:SI
11154 (match_operand:SI 2 "s_register_operand" "r,r"))))
bd5b4116 11155 (clobber (reg:CC CC_REGNUM))]
cffb2a26 11156 "TARGET_ARM"
8a18b90c 11157 "#"
8fa3ba89 11158 [(set_attr "conds" "clob")
11159 (set_attr "length" "8,12")]
11160)
9c08d1fa 11161
8a18b90c 11162(define_insn "*if_move_not"
11163 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
11164 (if_then_else:SI
8fa3ba89 11165 (match_operator 4 "arm_comparison_operator"
8a18b90c 11166 [(match_operand 3 "cc_register" "") (const_int 0)])
11167 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")
11168 (not:SI (match_operand:SI 2 "s_register_operand" "r,r,r"))))]
cffb2a26 11169 "TARGET_ARM"
8a18b90c 11170 "@
11171 mvn%D4\\t%0, %2
11172 mov%d4\\t%0, %1\;mvn%D4\\t%0, %2
11173 mvn%d4\\t%0, #%B1\;mvn%D4\\t%0, %2"
8fa3ba89 11174 [(set_attr "conds" "use")
1aed5204 11175 (set_attr "type" "mvn_reg")
8fa3ba89 11176 (set_attr "length" "4,8,8")]
11177)
8a18b90c 11178
11179(define_insn "*ifcompare_not_move"
9c08d1fa 11180 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8a18b90c 11181 (if_then_else:SI
8fa3ba89 11182 (match_operator 5 "arm_comparison_operator"
8a18b90c 11183 [(match_operand:SI 3 "s_register_operand" "r,r")
11184 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
11185 (not:SI
11186 (match_operand:SI 2 "s_register_operand" "r,r"))
11187 (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
bd5b4116 11188 (clobber (reg:CC CC_REGNUM))]
cffb2a26 11189 "TARGET_ARM"
8a18b90c 11190 "#"
8fa3ba89 11191 [(set_attr "conds" "clob")
11192 (set_attr "length" "8,12")]
11193)
9c08d1fa 11194
8a18b90c 11195(define_insn "*if_not_move"
11196 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
11197 (if_then_else:SI
8fa3ba89 11198 (match_operator 4 "arm_comparison_operator"
8a18b90c 11199 [(match_operand 3 "cc_register" "") (const_int 0)])
11200 (not:SI (match_operand:SI 2 "s_register_operand" "r,r,r"))
11201 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")))]
cffb2a26 11202 "TARGET_ARM"
8a18b90c 11203 "@
11204 mvn%d4\\t%0, %2
11205 mov%D4\\t%0, %1\;mvn%d4\\t%0, %2
11206 mvn%D4\\t%0, #%B1\;mvn%d4\\t%0, %2"
8fa3ba89 11207 [(set_attr "conds" "use")
1aed5204 11208 (set_attr "type" "mvn_reg")
8fa3ba89 11209 (set_attr "length" "4,8,8")]
11210)
8a18b90c 11211
11212(define_insn "*ifcompare_shift_move"
9c08d1fa 11213 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8a18b90c 11214 (if_then_else:SI
8fa3ba89 11215 (match_operator 6 "arm_comparison_operator"
8a18b90c 11216 [(match_operand:SI 4 "s_register_operand" "r,r")
11217 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
11218 (match_operator:SI 7 "shift_operator"
11219 [(match_operand:SI 2 "s_register_operand" "r,r")
11220 (match_operand:SI 3 "arm_rhs_operand" "rM,rM")])
11221 (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
bd5b4116 11222 (clobber (reg:CC CC_REGNUM))]
cffb2a26 11223 "TARGET_ARM"
9c08d1fa 11224 "#"
8fa3ba89 11225 [(set_attr "conds" "clob")
11226 (set_attr "length" "8,12")]
11227)
9c08d1fa 11228
8a18b90c 11229(define_insn "*if_shift_move"
11230 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
11231 (if_then_else:SI
8fa3ba89 11232 (match_operator 5 "arm_comparison_operator"
8a18b90c 11233 [(match_operand 6 "cc_register" "") (const_int 0)])
11234 (match_operator:SI 4 "shift_operator"
11235 [(match_operand:SI 2 "s_register_operand" "r,r,r")
11236 (match_operand:SI 3 "arm_rhs_operand" "rM,rM,rM")])
11237 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")))]
cffb2a26 11238 "TARGET_ARM"
5565501b 11239 "@
8a18b90c 11240 mov%d5\\t%0, %2%S4
11241 mov%D5\\t%0, %1\;mov%d5\\t%0, %2%S4
11242 mvn%D5\\t%0, #%B1\;mov%d5\\t%0, %2%S4"
8fa3ba89 11243 [(set_attr "conds" "use")
331beb1a 11244 (set_attr "shift" "2")
a2cd141b 11245 (set_attr "length" "4,8,8")
11246 (set (attr "type") (if_then_else (match_operand 3 "const_int_operand" "")
1aed5204 11247 (const_string "mov_shift")
11248 (const_string "mov_shift_reg")))]
8fa3ba89 11249)
5565501b 11250
8a18b90c 11251(define_insn "*ifcompare_move_shift"
11252 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5565501b 11253 (if_then_else:SI
8fa3ba89 11254 (match_operator 6 "arm_comparison_operator"
8a18b90c 11255 [(match_operand:SI 4 "s_register_operand" "r,r")
11256 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
11257 (match_operand:SI 1 "arm_not_operand" "0,?rIK")
5565501b 11258 (match_operator:SI 7 "shift_operator"
8a18b90c 11259 [(match_operand:SI 2 "s_register_operand" "r,r")
11260 (match_operand:SI 3 "arm_rhs_operand" "rM,rM")])))
bd5b4116 11261 (clobber (reg:CC CC_REGNUM))]
cffb2a26 11262 "TARGET_ARM"
8a18b90c 11263 "#"
8fa3ba89 11264 [(set_attr "conds" "clob")
11265 (set_attr "length" "8,12")]
11266)
5565501b 11267
8a18b90c 11268(define_insn "*if_move_shift"
11269 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
5565501b 11270 (if_then_else:SI
8fa3ba89 11271 (match_operator 5 "arm_comparison_operator"
8a18b90c 11272 [(match_operand 6 "cc_register" "") (const_int 0)])
11273 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")
11274 (match_operator:SI 4 "shift_operator"
11275 [(match_operand:SI 2 "s_register_operand" "r,r,r")
11276 (match_operand:SI 3 "arm_rhs_operand" "rM,rM,rM")])))]
cffb2a26 11277 "TARGET_ARM"
5565501b 11278 "@
8a18b90c 11279 mov%D5\\t%0, %2%S4
11280 mov%d5\\t%0, %1\;mov%D5\\t%0, %2%S4
11281 mvn%d5\\t%0, #%B1\;mov%D5\\t%0, %2%S4"
8fa3ba89 11282 [(set_attr "conds" "use")
331beb1a 11283 (set_attr "shift" "2")
a2cd141b 11284 (set_attr "length" "4,8,8")
11285 (set (attr "type") (if_then_else (match_operand 3 "const_int_operand" "")
1aed5204 11286 (const_string "mov_shift")
11287 (const_string "mov_shift_reg")))]
8fa3ba89 11288)
9c08d1fa 11289
f7fbdd4a 11290(define_insn "*ifcompare_shift_shift"
8a18b90c 11291 [(set (match_operand:SI 0 "s_register_operand" "=r")
5565501b 11292 (if_then_else:SI
8fa3ba89 11293 (match_operator 7 "arm_comparison_operator"
8a18b90c 11294 [(match_operand:SI 5 "s_register_operand" "r")
11295 (match_operand:SI 6 "arm_add_operand" "rIL")])
5565501b 11296 (match_operator:SI 8 "shift_operator"
8a18b90c 11297 [(match_operand:SI 1 "s_register_operand" "r")
11298 (match_operand:SI 2 "arm_rhs_operand" "rM")])
5565501b 11299 (match_operator:SI 9 "shift_operator"
8a18b90c 11300 [(match_operand:SI 3 "s_register_operand" "r")
11301 (match_operand:SI 4 "arm_rhs_operand" "rM")])))
bd5b4116 11302 (clobber (reg:CC CC_REGNUM))]
cffb2a26 11303 "TARGET_ARM"
8a18b90c 11304 "#"
8fa3ba89 11305 [(set_attr "conds" "clob")
11306 (set_attr "length" "12")]
11307)
9c08d1fa 11308
8a18b90c 11309(define_insn "*if_shift_shift"
11310 [(set (match_operand:SI 0 "s_register_operand" "=r")
11311 (if_then_else:SI
8fa3ba89 11312 (match_operator 5 "arm_comparison_operator"
8a18b90c 11313 [(match_operand 8 "cc_register" "") (const_int 0)])
11314 (match_operator:SI 6 "shift_operator"
11315 [(match_operand:SI 1 "s_register_operand" "r")
11316 (match_operand:SI 2 "arm_rhs_operand" "rM")])
11317 (match_operator:SI 7 "shift_operator"
11318 [(match_operand:SI 3 "s_register_operand" "r")
11319 (match_operand:SI 4 "arm_rhs_operand" "rM")])))]
cffb2a26 11320 "TARGET_ARM"
8a18b90c 11321 "mov%d5\\t%0, %1%S6\;mov%D5\\t%0, %3%S7"
8fa3ba89 11322 [(set_attr "conds" "use")
331beb1a 11323 (set_attr "shift" "1")
a2cd141b 11324 (set_attr "length" "8")
11325 (set (attr "type") (if_then_else
11326 (and (match_operand 2 "const_int_operand" "")
11327 (match_operand 4 "const_int_operand" ""))
1aed5204 11328 (const_string "mov_shift")
11329 (const_string "mov_shift_reg")))]
8fa3ba89 11330)
8a18b90c 11331
f7fbdd4a 11332(define_insn "*ifcompare_not_arith"
8a18b90c 11333 [(set (match_operand:SI 0 "s_register_operand" "=r")
5565501b 11334 (if_then_else:SI
8fa3ba89 11335 (match_operator 6 "arm_comparison_operator"
8a18b90c 11336 [(match_operand:SI 4 "s_register_operand" "r")
11337 (match_operand:SI 5 "arm_add_operand" "rIL")])
11338 (not:SI (match_operand:SI 1 "s_register_operand" "r"))
5565501b 11339 (match_operator:SI 7 "shiftable_operator"
8a18b90c 11340 [(match_operand:SI 2 "s_register_operand" "r")
11341 (match_operand:SI 3 "arm_rhs_operand" "rI")])))
bd5b4116 11342 (clobber (reg:CC CC_REGNUM))]
cffb2a26 11343 "TARGET_ARM"
8a18b90c 11344 "#"
8fa3ba89 11345 [(set_attr "conds" "clob")
11346 (set_attr "length" "12")]
11347)
9c08d1fa 11348
8a18b90c 11349(define_insn "*if_not_arith"
11350 [(set (match_operand:SI 0 "s_register_operand" "=r")
11351 (if_then_else:SI
8fa3ba89 11352 (match_operator 5 "arm_comparison_operator"
8a18b90c 11353 [(match_operand 4 "cc_register" "") (const_int 0)])
11354 (not:SI (match_operand:SI 1 "s_register_operand" "r"))
11355 (match_operator:SI 6 "shiftable_operator"
11356 [(match_operand:SI 2 "s_register_operand" "r")
11357 (match_operand:SI 3 "arm_rhs_operand" "rI")])))]
cffb2a26 11358 "TARGET_ARM"
8a18b90c 11359 "mvn%d5\\t%0, %1\;%I6%D5\\t%0, %2, %3"
8fa3ba89 11360 [(set_attr "conds" "use")
1aed5204 11361 (set_attr "type" "mvn_reg")
8fa3ba89 11362 (set_attr "length" "8")]
11363)
8a18b90c 11364
11365(define_insn "*ifcompare_arith_not"
11366 [(set (match_operand:SI 0 "s_register_operand" "=r")
5565501b 11367 (if_then_else:SI
8fa3ba89 11368 (match_operator 6 "arm_comparison_operator"
8a18b90c 11369 [(match_operand:SI 4 "s_register_operand" "r")
11370 (match_operand:SI 5 "arm_add_operand" "rIL")])
5565501b 11371 (match_operator:SI 7 "shiftable_operator"
8a18b90c 11372 [(match_operand:SI 2 "s_register_operand" "r")
11373 (match_operand:SI 3 "arm_rhs_operand" "rI")])
11374 (not:SI (match_operand:SI 1 "s_register_operand" "r"))))
bd5b4116 11375 (clobber (reg:CC CC_REGNUM))]
cffb2a26 11376 "TARGET_ARM"
8a18b90c 11377 "#"
8fa3ba89 11378 [(set_attr "conds" "clob")
11379 (set_attr "length" "12")]
11380)
9c08d1fa 11381
8a18b90c 11382(define_insn "*if_arith_not"
11383 [(set (match_operand:SI 0 "s_register_operand" "=r")
11384 (if_then_else:SI
8fa3ba89 11385 (match_operator 5 "arm_comparison_operator"
8a18b90c 11386 [(match_operand 4 "cc_register" "") (const_int 0)])
11387 (match_operator:SI 6 "shiftable_operator"
11388 [(match_operand:SI 2 "s_register_operand" "r")
11389 (match_operand:SI 3 "arm_rhs_operand" "rI")])
11390 (not:SI (match_operand:SI 1 "s_register_operand" "r"))))]
cffb2a26 11391 "TARGET_ARM"
8a18b90c 11392 "mvn%D5\\t%0, %1\;%I6%d5\\t%0, %2, %3"
8fa3ba89 11393 [(set_attr "conds" "use")
1aed5204 11394 (set_attr "type" "mvn_reg")
8fa3ba89 11395 (set_attr "length" "8")]
11396)
8a18b90c 11397
f7fbdd4a 11398(define_insn "*ifcompare_neg_move"
8a18b90c 11399 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5565501b 11400 (if_then_else:SI
8fa3ba89 11401 (match_operator 5 "arm_comparison_operator"
8a18b90c 11402 [(match_operand:SI 3 "s_register_operand" "r,r")
11403 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
11404 (neg:SI (match_operand:SI 2 "s_register_operand" "r,r"))
11405 (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
bd5b4116 11406 (clobber (reg:CC CC_REGNUM))]
cffb2a26 11407 "TARGET_ARM"
8a18b90c 11408 "#"
8fa3ba89 11409 [(set_attr "conds" "clob")
11410 (set_attr "length" "8,12")]
11411)
8a18b90c 11412
11413(define_insn "*if_neg_move"
11414 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
11415 (if_then_else:SI
8fa3ba89 11416 (match_operator 4 "arm_comparison_operator"
8a18b90c 11417 [(match_operand 3 "cc_register" "") (const_int 0)])
11418 (neg:SI (match_operand:SI 2 "s_register_operand" "r,r,r"))
11419 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")))]
cffb2a26 11420 "TARGET_ARM"
8a18b90c 11421 "@
11422 rsb%d4\\t%0, %2, #0
11423 mov%D4\\t%0, %1\;rsb%d4\\t%0, %2, #0
11424 mvn%D4\\t%0, #%B1\;rsb%d4\\t%0, %2, #0"
8fa3ba89 11425 [(set_attr "conds" "use")
11426 (set_attr "length" "4,8,8")]
11427)
9c08d1fa 11428
f7fbdd4a 11429(define_insn "*ifcompare_move_neg"
8a18b90c 11430 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5565501b 11431 (if_then_else:SI
8fa3ba89 11432 (match_operator 5 "arm_comparison_operator"
8a18b90c 11433 [(match_operand:SI 3 "s_register_operand" "r,r")
11434 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
11435 (match_operand:SI 1 "arm_not_operand" "0,?rIK")
11436 (neg:SI (match_operand:SI 2 "s_register_operand" "r,r"))))
bd5b4116 11437 (clobber (reg:CC CC_REGNUM))]
cffb2a26 11438 "TARGET_ARM"
8a18b90c 11439 "#"
8fa3ba89 11440 [(set_attr "conds" "clob")
11441 (set_attr "length" "8,12")]
11442)
8a18b90c 11443
11444(define_insn "*if_move_neg"
11445 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
11446 (if_then_else:SI
8fa3ba89 11447 (match_operator 4 "arm_comparison_operator"
8a18b90c 11448 [(match_operand 3 "cc_register" "") (const_int 0)])
11449 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")
11450 (neg:SI (match_operand:SI 2 "s_register_operand" "r,r,r"))))]
cffb2a26 11451 "TARGET_ARM"
8a18b90c 11452 "@
11453 rsb%D4\\t%0, %2, #0
11454 mov%d4\\t%0, %1\;rsb%D4\\t%0, %2, #0
11455 mvn%d4\\t%0, #%B1\;rsb%D4\\t%0, %2, #0"
0d66636f 11456 [(set_attr "conds" "use")
11457 (set_attr "length" "4,8,8")]
11458)
9c08d1fa 11459
f7fbdd4a 11460(define_insn "*arith_adjacentmem"
9c08d1fa 11461 [(set (match_operand:SI 0 "s_register_operand" "=r")
11462 (match_operator:SI 1 "shiftable_operator"
11463 [(match_operand:SI 2 "memory_operand" "m")
11464 (match_operand:SI 3 "memory_operand" "m")]))
11465 (clobber (match_scratch:SI 4 "=r"))]
cffb2a26 11466 "TARGET_ARM && adjacent_mem_locations (operands[2], operands[3])"
9c08d1fa 11467 "*
215b30b3 11468 {
11469 rtx ldm[3];
11470 rtx arith[4];
94dee231 11471 rtx base_reg;
11472 HOST_WIDE_INT val1 = 0, val2 = 0;
9c08d1fa 11473
215b30b3 11474 if (REGNO (operands[0]) > REGNO (operands[4]))
11475 {
11476 ldm[1] = operands[4];
11477 ldm[2] = operands[0];
11478 }
11479 else
11480 {
11481 ldm[1] = operands[0];
11482 ldm[2] = operands[4];
11483 }
94dee231 11484
11485 base_reg = XEXP (operands[2], 0);
11486
11487 if (!REG_P (base_reg))
11488 {
11489 val1 = INTVAL (XEXP (base_reg, 1));
11490 base_reg = XEXP (base_reg, 0);
11491 }
11492
11493 if (!REG_P (XEXP (operands[3], 0)))
215b30b3 11494 val2 = INTVAL (XEXP (XEXP (operands[3], 0), 1));
94dee231 11495
215b30b3 11496 arith[0] = operands[0];
11497 arith[3] = operands[1];
94dee231 11498
215b30b3 11499 if (val1 < val2)
11500 {
11501 arith[1] = ldm[1];
11502 arith[2] = ldm[2];
11503 }
11504 else
11505 {
11506 arith[1] = ldm[2];
11507 arith[2] = ldm[1];
11508 }
94dee231 11509
11510 ldm[0] = base_reg;
11511 if (val1 !=0 && val2 != 0)
215b30b3 11512 {
cdb1295a 11513 rtx ops[3];
11514
94dee231 11515 if (val1 == 4 || val2 == 4)
11516 /* Other val must be 8, since we know they are adjacent and neither
11517 is zero. */
25f905c2 11518 output_asm_insn (\"ldm%(ib%)\\t%0, {%1, %2}\", ldm);
cdb1295a 11519 else if (const_ok_for_arm (val1) || const_ok_for_arm (-val1))
94dee231 11520 {
94dee231 11521 ldm[0] = ops[0] = operands[4];
11522 ops[1] = base_reg;
11523 ops[2] = GEN_INT (val1);
11524 output_add_immediate (ops);
11525 if (val1 < val2)
25f905c2 11526 output_asm_insn (\"ldm%(ia%)\\t%0, {%1, %2}\", ldm);
94dee231 11527 else
25f905c2 11528 output_asm_insn (\"ldm%(da%)\\t%0, {%1, %2}\", ldm);
94dee231 11529 }
cdb1295a 11530 else
11531 {
11532 /* Offset is out of range for a single add, so use two ldr. */
11533 ops[0] = ldm[1];
11534 ops[1] = base_reg;
11535 ops[2] = GEN_INT (val1);
11536 output_asm_insn (\"ldr%?\\t%0, [%1, %2]\", ops);
11537 ops[0] = ldm[2];
11538 ops[2] = GEN_INT (val2);
11539 output_asm_insn (\"ldr%?\\t%0, [%1, %2]\", ops);
11540 }
215b30b3 11541 }
94dee231 11542 else if (val1 != 0)
215b30b3 11543 {
215b30b3 11544 if (val1 < val2)
25f905c2 11545 output_asm_insn (\"ldm%(da%)\\t%0, {%1, %2}\", ldm);
215b30b3 11546 else
25f905c2 11547 output_asm_insn (\"ldm%(ia%)\\t%0, {%1, %2}\", ldm);
215b30b3 11548 }
11549 else
11550 {
215b30b3 11551 if (val1 < val2)
25f905c2 11552 output_asm_insn (\"ldm%(ia%)\\t%0, {%1, %2}\", ldm);
215b30b3 11553 else
25f905c2 11554 output_asm_insn (\"ldm%(da%)\\t%0, {%1, %2}\", ldm);
215b30b3 11555 }
11556 output_asm_insn (\"%I3%?\\t%0, %1, %2\", arith);
11557 return \"\";
11558 }"
11559 [(set_attr "length" "12")
11560 (set_attr "predicable" "yes")
a2cd141b 11561 (set_attr "type" "load1")]
215b30b3 11562)
9c08d1fa 11563
9c08d1fa 11564; This pattern is never tried by combine, so do it as a peephole
11565
a0f94409 11566(define_peephole2
372575c7 11567 [(set (match_operand:SI 0 "arm_general_register_operand" "")
11568 (match_operand:SI 1 "arm_general_register_operand" ""))
bd5b4116 11569 (set (reg:CC CC_REGNUM)
aea4c774 11570 (compare:CC (match_dup 1) (const_int 0)))]
372575c7 11571 "TARGET_ARM"
a0f94409 11572 [(parallel [(set (reg:CC CC_REGNUM) (compare:CC (match_dup 1) (const_int 0)))
11573 (set (match_dup 0) (match_dup 1))])]
11574 ""
0d66636f 11575)
9c08d1fa 11576
9c08d1fa 11577(define_split
11578 [(set (match_operand:SI 0 "s_register_operand" "")
11579 (and:SI (ge:SI (match_operand:SI 1 "s_register_operand" "")
11580 (const_int 0))
8fa3ba89 11581 (neg:SI (match_operator:SI 2 "arm_comparison_operator"
9c08d1fa 11582 [(match_operand:SI 3 "s_register_operand" "")
11583 (match_operand:SI 4 "arm_rhs_operand" "")]))))
11584 (clobber (match_operand:SI 5 "s_register_operand" ""))]
cffb2a26 11585 "TARGET_ARM"
9c08d1fa 11586 [(set (match_dup 5) (not:SI (ashiftrt:SI (match_dup 1) (const_int 31))))
11587 (set (match_dup 0) (and:SI (match_op_dup 2 [(match_dup 3) (match_dup 4)])
11588 (match_dup 5)))]
215b30b3 11589 ""
11590)
9c08d1fa 11591
aea4c774 11592;; This split can be used because CC_Z mode implies that the following
11593;; branch will be an equality, or an unsigned inequality, so the sign
11594;; extension is not needed.
9c08d1fa 11595
aea4c774 11596(define_split
bd5b4116 11597 [(set (reg:CC_Z CC_REGNUM)
aea4c774 11598 (compare:CC_Z
11599 (ashift:SI (subreg:SI (match_operand:QI 0 "memory_operand" "") 0)
9c08d1fa 11600 (const_int 24))
aea4c774 11601 (match_operand 1 "const_int_operand" "")))
11602 (clobber (match_scratch:SI 2 ""))]
cffb2a26 11603 "TARGET_ARM
11604 && (((unsigned HOST_WIDE_INT) INTVAL (operands[1]))
11605 == (((unsigned HOST_WIDE_INT) INTVAL (operands[1])) >> 24) << 24)"
aea4c774 11606 [(set (match_dup 2) (zero_extend:SI (match_dup 0)))
bd5b4116 11607 (set (reg:CC CC_REGNUM) (compare:CC (match_dup 2) (match_dup 1)))]
aea4c774 11608 "
9c08d1fa 11609 operands[1] = GEN_INT (((unsigned long) INTVAL (operands[1])) >> 24);
215b30b3 11610 "
11611)
25f905c2 11612;; ??? Check the patterns above for Thumb-2 usefulness
9c08d1fa 11613
87b22bf7 11614(define_expand "prologue"
11615 [(clobber (const_int 0))]
cffb2a26 11616 "TARGET_EITHER"
25f905c2 11617 "if (TARGET_32BIT)
cffb2a26 11618 arm_expand_prologue ();
11619 else
25f905c2 11620 thumb1_expand_prologue ();
87b22bf7 11621 DONE;
cffb2a26 11622 "
11623)
87b22bf7 11624
56d27660 11625(define_expand "epilogue"
4c44712e 11626 [(clobber (const_int 0))]
cffb2a26 11627 "TARGET_EITHER"
56d27660 11628 "
18d50ae6 11629 if (crtl->calls_eh_return)
fb94f18b 11630 emit_insn (gen_force_register_use (gen_rtx_REG (Pmode, 2)));
25f905c2 11631 if (TARGET_THUMB1)
c3635784 11632 {
11633 thumb1_expand_epilogue ();
11634 emit_jump_insn (gen_rtx_UNSPEC_VOLATILE (VOIDmode,
11635 gen_rtvec (1, ret_rtx), VUNSPEC_EPILOGUE));
11636 }
11637 else if (HAVE_return)
11638 {
11639 /* HAVE_return is testing for USE_RETURN_INSN (FALSE). Hence,
11640 no need for explicit testing again. */
11641 emit_jump_insn (gen_return ());
11642 }
11643 else if (TARGET_32BIT)
11644 {
11645 arm_expand_epilogue (true);
11646 }
cffb2a26 11647 DONE;
11648 "
11649)
56d27660 11650
7571d3f7 11651(define_insn "prologue_thumb1_interwork"
11652 [(unspec_volatile [(const_int 0)] VUNSPEC_THUMB1_INTERWORK)]
11653 "TARGET_THUMB1"
11654 "* return thumb1_output_interwork ();"
11655 [(set_attr "length" "8")]
11656)
11657
ef5651d0 11658;; Note - although unspec_volatile's USE all hard registers,
11659;; USEs are ignored after relaod has completed. Thus we need
11660;; to add an unspec of the link register to ensure that flow
11661;; does not think that it is unused by the sibcall branch that
11662;; will replace the standard function epilogue.
c3635784 11663(define_expand "sibcall_epilogue"
fb94f18b 11664 [(parallel [(unspec:SI [(reg:SI LR_REGNUM)] UNSPEC_REGISTER_USE)
c3635784 11665 (unspec_volatile [(return)] VUNSPEC_EPILOGUE)])]
11666 "TARGET_32BIT"
11667 "
11668 arm_expand_epilogue (false);
11669 DONE;
11670 "
1c494086 11671)
11672
cffb2a26 11673(define_insn "*epilogue_insns"
e1159bbe 11674 [(unspec_volatile [(return)] VUNSPEC_EPILOGUE)]
b1324f4f 11675 "TARGET_THUMB1"
56d27660 11676 "*
e7fd8dfa 11677 return thumb1_unexpanded_epilogue ();
cffb2a26 11678 "
215b30b3 11679 ; Length is absolute worst case
cffb2a26 11680 [(set_attr "length" "44")
defc47cf 11681 (set_attr "type" "block")
11682 ;; We don't clobber the conditions, but the potential length of this
11683 ;; operation is sufficient to make conditionalizing the sequence
11684 ;; unlikely to be profitable.
11685 (set_attr "conds" "clob")]
cffb2a26 11686)
11687
11688(define_expand "eh_epilogue"
7db9af5d 11689 [(use (match_operand:SI 0 "register_operand" ""))
11690 (use (match_operand:SI 1 "register_operand" ""))
11691 (use (match_operand:SI 2 "register_operand" ""))]
cffb2a26 11692 "TARGET_EITHER"
11693 "
215b30b3 11694 {
11695 cfun->machine->eh_epilogue_sp_ofs = operands[1];
0438d37f 11696 if (!REG_P (operands[2]) || REGNO (operands[2]) != 2)
215b30b3 11697 {
11698 rtx ra = gen_rtx_REG (Pmode, 2);
11699
11700 emit_move_insn (ra, operands[2]);
11701 operands[2] = ra;
11702 }
5cf3595a 11703 /* This is a hack -- we may have crystalized the function type too
11704 early. */
11705 cfun->machine->func_type = 0;
215b30b3 11706 }"
11707)
56d27660 11708
9c08d1fa 11709;; This split is only used during output to reduce the number of patterns
11710;; that need assembler instructions adding to them. We allowed the setting
11711;; of the conditions to be implicit during rtl generation so that
11712;; the conditional compare patterns would work. However this conflicts to
8a18b90c 11713;; some extent with the conditional data operations, so we have to split them
9c08d1fa 11714;; up again here.
11715
25f905c2 11716;; ??? Need to audit these splitters for Thumb-2. Why isn't normal
11717;; conditional execution sufficient?
11718
9c08d1fa 11719(define_split
11720 [(set (match_operand:SI 0 "s_register_operand" "")
8fa3ba89 11721 (if_then_else:SI (match_operator 1 "arm_comparison_operator"
11722 [(match_operand 2 "" "") (match_operand 3 "" "")])
11723 (match_dup 0)
11724 (match_operand 4 "" "")))
bd5b4116 11725 (clobber (reg:CC CC_REGNUM))]
ac8b093b 11726 "TARGET_ARM && reload_completed"
8fa3ba89 11727 [(set (match_dup 5) (match_dup 6))
11728 (cond_exec (match_dup 7)
11729 (set (match_dup 0) (match_dup 4)))]
11730 "
11731 {
11732 enum machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
11733 operands[2], operands[3]);
11734 enum rtx_code rc = GET_CODE (operands[1]);
11735
bd5b4116 11736 operands[5] = gen_rtx_REG (mode, CC_REGNUM);
8fa3ba89 11737 operands[6] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
11738 if (mode == CCFPmode || mode == CCFPEmode)
11739 rc = reverse_condition_maybe_unordered (rc);
11740 else
11741 rc = reverse_condition (rc);
11742
11743 operands[7] = gen_rtx_fmt_ee (rc, VOIDmode, operands[5], const0_rtx);
11744 }"
11745)
11746
11747(define_split
11748 [(set (match_operand:SI 0 "s_register_operand" "")
11749 (if_then_else:SI (match_operator 1 "arm_comparison_operator"
11750 [(match_operand 2 "" "") (match_operand 3 "" "")])
11751 (match_operand 4 "" "")
11752 (match_dup 0)))
bd5b4116 11753 (clobber (reg:CC CC_REGNUM))]
ac8b093b 11754 "TARGET_ARM && reload_completed"
8fa3ba89 11755 [(set (match_dup 5) (match_dup 6))
11756 (cond_exec (match_op_dup 1 [(match_dup 5) (const_int 0)])
11757 (set (match_dup 0) (match_dup 4)))]
11758 "
11759 {
11760 enum machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
11761 operands[2], operands[3]);
11762
bd5b4116 11763 operands[5] = gen_rtx_REG (mode, CC_REGNUM);
8fa3ba89 11764 operands[6] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
11765 }"
11766)
11767
11768(define_split
11769 [(set (match_operand:SI 0 "s_register_operand" "")
11770 (if_then_else:SI (match_operator 1 "arm_comparison_operator"
9c08d1fa 11771 [(match_operand 2 "" "") (match_operand 3 "" "")])
11772 (match_operand 4 "" "")
11773 (match_operand 5 "" "")))
bd5b4116 11774 (clobber (reg:CC CC_REGNUM))]
ac8b093b 11775 "TARGET_ARM && reload_completed"
8fa3ba89 11776 [(set (match_dup 6) (match_dup 7))
11777 (cond_exec (match_op_dup 1 [(match_dup 6) (const_int 0)])
11778 (set (match_dup 0) (match_dup 4)))
11779 (cond_exec (match_dup 8)
11780 (set (match_dup 0) (match_dup 5)))]
11781 "
11782 {
11783 enum machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
11784 operands[2], operands[3]);
11785 enum rtx_code rc = GET_CODE (operands[1]);
11786
bd5b4116 11787 operands[6] = gen_rtx_REG (mode, CC_REGNUM);
8fa3ba89 11788 operands[7] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
11789 if (mode == CCFPmode || mode == CCFPEmode)
11790 rc = reverse_condition_maybe_unordered (rc);
11791 else
11792 rc = reverse_condition (rc);
11793
11794 operands[8] = gen_rtx_fmt_ee (rc, VOIDmode, operands[6], const0_rtx);
11795 }"
11796)
11797
cffb2a26 11798(define_split
11799 [(set (match_operand:SI 0 "s_register_operand" "")
8fa3ba89 11800 (if_then_else:SI (match_operator 1 "arm_comparison_operator"
cffb2a26 11801 [(match_operand:SI 2 "s_register_operand" "")
11802 (match_operand:SI 3 "arm_add_operand" "")])
11803 (match_operand:SI 4 "arm_rhs_operand" "")
11804 (not:SI
11805 (match_operand:SI 5 "s_register_operand" ""))))
bd5b4116 11806 (clobber (reg:CC CC_REGNUM))]
ac8b093b 11807 "TARGET_ARM && reload_completed"
cffb2a26 11808 [(set (match_dup 6) (match_dup 7))
f6c53574 11809 (cond_exec (match_op_dup 1 [(match_dup 6) (const_int 0)])
11810 (set (match_dup 0) (match_dup 4)))
11811 (cond_exec (match_dup 8)
11812 (set (match_dup 0) (not:SI (match_dup 5))))]
cffb2a26 11813 "
215b30b3 11814 {
11815 enum machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
11816 operands[2], operands[3]);
f6c53574 11817 enum rtx_code rc = GET_CODE (operands[1]);
cffb2a26 11818
bd5b4116 11819 operands[6] = gen_rtx_REG (mode, CC_REGNUM);
1a83b3ff 11820 operands[7] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
f6c53574 11821 if (mode == CCFPmode || mode == CCFPEmode)
11822 rc = reverse_condition_maybe_unordered (rc);
11823 else
11824 rc = reverse_condition (rc);
11825
11826 operands[8] = gen_rtx_fmt_ee (rc, VOIDmode, operands[6], const0_rtx);
215b30b3 11827 }"
11828)
cffb2a26 11829
11830(define_insn "*cond_move_not"
11831 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8fa3ba89 11832 (if_then_else:SI (match_operator 4 "arm_comparison_operator"
cffb2a26 11833 [(match_operand 3 "cc_register" "") (const_int 0)])
11834 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
11835 (not:SI
11836 (match_operand:SI 2 "s_register_operand" "r,r"))))]
11837 "TARGET_ARM"
11838 "@
11839 mvn%D4\\t%0, %2
11840 mov%d4\\t%0, %1\;mvn%D4\\t%0, %2"
0d66636f 11841 [(set_attr "conds" "use")
1aed5204 11842 (set_attr "type" "mvn_reg")
0d66636f 11843 (set_attr "length" "4,8")]
11844)
cffb2a26 11845
9c08d1fa 11846;; The next two patterns occur when an AND operation is followed by a
11847;; scc insn sequence
11848
f7fbdd4a 11849(define_insn "*sign_extract_onebit"
9c08d1fa 11850 [(set (match_operand:SI 0 "s_register_operand" "=r")
11851 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
11852 (const_int 1)
ed750274 11853 (match_operand:SI 2 "const_int_operand" "n")))
11854 (clobber (reg:CC CC_REGNUM))]
cffb2a26 11855 "TARGET_ARM"
9c08d1fa 11856 "*
0d66636f 11857 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
11858 output_asm_insn (\"ands\\t%0, %1, %2\", operands);
11859 return \"mvnne\\t%0, #0\";
11860 "
11861 [(set_attr "conds" "clob")
11862 (set_attr "length" "8")]
11863)
9c08d1fa 11864
f7fbdd4a 11865(define_insn "*not_signextract_onebit"
9c08d1fa 11866 [(set (match_operand:SI 0 "s_register_operand" "=r")
11867 (not:SI
11868 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
11869 (const_int 1)
ed750274 11870 (match_operand:SI 2 "const_int_operand" "n"))))
11871 (clobber (reg:CC CC_REGNUM))]
cffb2a26 11872 "TARGET_ARM"
9c08d1fa 11873 "*
0d66636f 11874 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
11875 output_asm_insn (\"tst\\t%1, %2\", operands);
11876 output_asm_insn (\"mvneq\\t%0, #0\", operands);
11877 return \"movne\\t%0, #0\";
11878 "
11879 [(set_attr "conds" "clob")
11880 (set_attr "length" "12")]
11881)
25f905c2 11882;; ??? The above patterns need auditing for Thumb-2
87b22bf7 11883
0d66636f 11884;; Push multiple registers to the stack. Registers are in parallel (use ...)
11885;; expressions. For simplicity, the first register is also in the unspec
11886;; part.
08508cbf 11887;; To avoid the usage of GNU extension, the length attribute is computed
11888;; in a C function arm_attr_length_push_multi.
f7fbdd4a 11889(define_insn "*push_multi"
87b22bf7 11890 [(match_parallel 2 "multi_register_push"
7571d3f7 11891 [(set (match_operand:BLK 0 "push_mult_memory_operand" "")
3cc80a30 11892 (unspec:BLK [(match_operand:SI 1 "s_register_operand" "")]
e1159bbe 11893 UNSPEC_PUSH_MULT))])]
7571d3f7 11894 ""
87b22bf7 11895 "*
215b30b3 11896 {
11897 int num_saves = XVECLEN (operands[2], 0);
ed593f11 11898
215b30b3 11899 /* For the StrongARM at least it is faster to
25f905c2 11900 use STR to store only a single register.
542d5028 11901 In Thumb mode always use push, and the assembler will pick
11902 something appropriate. */
25f905c2 11903 if (num_saves == 1 && TARGET_ARM)
61309563 11904 output_asm_insn (\"str%?\\t%1, [%m0, #-4]!\", operands);
215b30b3 11905 else
11906 {
11907 int i;
11908 char pattern[100];
ed593f11 11909
25f905c2 11910 if (TARGET_ARM)
61309563 11911 strcpy (pattern, \"stm%(fd%)\\t%m0!, {%1\");
11912 else if (TARGET_THUMB2)
11913 strcpy (pattern, \"push%?\\t{%1\");
25f905c2 11914 else
11915 strcpy (pattern, \"push\\t{%1\");
215b30b3 11916
6079f055 11917 for (i = 1; i < num_saves; i++)
215b30b3 11918 {
11919 strcat (pattern, \", %|\");
11920 strcat (pattern,
11921 reg_names[REGNO (XEXP (XVECEXP (operands[2], 0, i), 0))]);
11922 }
11923
11924 strcat (pattern, \"}\");
11925 output_asm_insn (pattern, operands);
11926 }
11927
11928 return \"\";
11929 }"
a6864a24 11930 [(set_attr "type" "store4")
11931 (set (attr "length")
08508cbf 11932 (symbol_ref "arm_attr_length_push_multi (operands[2], operands[1])"))]
215b30b3 11933)
f7fbdd4a 11934
4c58c898 11935(define_insn "stack_tie"
11936 [(set (mem:BLK (scratch))
aaa37ad6 11937 (unspec:BLK [(match_operand:SI 0 "s_register_operand" "rk")
11938 (match_operand:SI 1 "s_register_operand" "rk")]
4c58c898 11939 UNSPEC_PRLG_STK))]
11940 ""
11941 ""
11942 [(set_attr "length" "0")]
11943)
11944
426be8c5 11945;; Pop (as used in epilogue RTL)
11946;;
11947(define_insn "*load_multiple_with_writeback"
11948 [(match_parallel 0 "load_multiple_operation"
11949 [(set (match_operand:SI 1 "s_register_operand" "+rk")
11950 (plus:SI (match_dup 1)
11951 (match_operand:SI 2 "const_int_operand" "I")))
11952 (set (match_operand:SI 3 "s_register_operand" "=rk")
11953 (mem:SI (match_dup 1)))
11954 ])]
11955 "TARGET_32BIT && (reload_in_progress || reload_completed)"
11956 "*
11957 {
11958 arm_output_multireg_pop (operands, /*return_pc=*/false,
11959 /*cond=*/const_true_rtx,
11960 /*reverse=*/false,
11961 /*update=*/true);
11962 return \"\";
11963 }
11964 "
11965 [(set_attr "type" "load4")
11966 (set_attr "predicable" "yes")]
11967)
11968
11969;; Pop with return (as used in epilogue RTL)
11970;;
11971;; This instruction is generated when the registers are popped at the end of
11972;; epilogue. Here, instead of popping the value into LR and then generating
11973;; jump to LR, value is popped into PC directly. Hence, the pattern is combined
11974;; with (return).
11975(define_insn "*pop_multiple_with_writeback_and_return"
11976 [(match_parallel 0 "pop_multiple_return"
11977 [(return)
11978 (set (match_operand:SI 1 "s_register_operand" "+rk")
11979 (plus:SI (match_dup 1)
11980 (match_operand:SI 2 "const_int_operand" "I")))
11981 (set (match_operand:SI 3 "s_register_operand" "=rk")
11982 (mem:SI (match_dup 1)))
11983 ])]
11984 "TARGET_32BIT && (reload_in_progress || reload_completed)"
11985 "*
11986 {
11987 arm_output_multireg_pop (operands, /*return_pc=*/true,
11988 /*cond=*/const_true_rtx,
11989 /*reverse=*/false,
11990 /*update=*/true);
11991 return \"\";
11992 }
11993 "
11994 [(set_attr "type" "load4")
11995 (set_attr "predicable" "yes")]
11996)
11997
11998(define_insn "*pop_multiple_with_return"
11999 [(match_parallel 0 "pop_multiple_return"
12000 [(return)
12001 (set (match_operand:SI 2 "s_register_operand" "=rk")
12002 (mem:SI (match_operand:SI 1 "s_register_operand" "rk")))
12003 ])]
12004 "TARGET_32BIT && (reload_in_progress || reload_completed)"
12005 "*
12006 {
12007 arm_output_multireg_pop (operands, /*return_pc=*/true,
12008 /*cond=*/const_true_rtx,
12009 /*reverse=*/false,
12010 /*update=*/false);
12011 return \"\";
12012 }
12013 "
12014 [(set_attr "type" "load4")
12015 (set_attr "predicable" "yes")]
12016)
12017
12018;; Load into PC and return
12019(define_insn "*ldr_with_return"
12020 [(return)
12021 (set (reg:SI PC_REGNUM)
12022 (mem:SI (post_inc:SI (match_operand:SI 0 "s_register_operand" "+rk"))))]
12023 "TARGET_32BIT && (reload_in_progress || reload_completed)"
12024 "ldr%?\t%|pc, [%0], #4"
12025 [(set_attr "type" "load1")
12026 (set_attr "predicable" "yes")]
12027)
1a0b0f12 12028;; Pop for floating point registers (as used in epilogue RTL)
12029(define_insn "*vfp_pop_multiple_with_writeback"
12030 [(match_parallel 0 "pop_multiple_fp"
12031 [(set (match_operand:SI 1 "s_register_operand" "+rk")
12032 (plus:SI (match_dup 1)
12033 (match_operand:SI 2 "const_int_operand" "I")))
12034 (set (match_operand:DF 3 "arm_hard_register_operand" "")
12035 (mem:DF (match_dup 1)))])]
12036 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
12037 "*
12038 {
12039 int num_regs = XVECLEN (operands[0], 0);
12040 char pattern[100];
12041 rtx op_list[2];
12042 strcpy (pattern, \"fldmfdd\\t\");
12043 strcat (pattern, reg_names[REGNO (SET_DEST (XVECEXP (operands[0], 0, 0)))]);
12044 strcat (pattern, \"!, {\");
12045 op_list[0] = XEXP (XVECEXP (operands[0], 0, 1), 0);
12046 strcat (pattern, \"%P0\");
12047 if ((num_regs - 1) > 1)
12048 {
12049 strcat (pattern, \"-%P1\");
12050 op_list [1] = XEXP (XVECEXP (operands[0], 0, num_regs - 1), 0);
12051 }
12052
12053 strcat (pattern, \"}\");
12054 output_asm_insn (pattern, op_list);
12055 return \"\";
12056 }
12057 "
12058 [(set_attr "type" "load4")
12059 (set_attr "conds" "unconditional")
12060 (set_attr "predicable" "no")]
12061)
12062
f7fbdd4a 12063;; Special patterns for dealing with the constant pool
12064
cffb2a26 12065(define_insn "align_4"
e1159bbe 12066 [(unspec_volatile [(const_int 0)] VUNSPEC_ALIGN)]
cffb2a26 12067 "TARGET_EITHER"
f7fbdd4a 12068 "*
cffb2a26 12069 assemble_align (32);
f7fbdd4a 12070 return \"\";
cffb2a26 12071 "
12072)
f7fbdd4a 12073
755eb2b4 12074(define_insn "align_8"
12075 [(unspec_volatile [(const_int 0)] VUNSPEC_ALIGN8)]
f9273c43 12076 "TARGET_EITHER"
755eb2b4 12077 "*
12078 assemble_align (64);
12079 return \"\";
12080 "
12081)
12082
cffb2a26 12083(define_insn "consttable_end"
e1159bbe 12084 [(unspec_volatile [(const_int 0)] VUNSPEC_POOL_END)]
cffb2a26 12085 "TARGET_EITHER"
f7fbdd4a 12086 "*
cffb2a26 12087 making_const_table = FALSE;
f7fbdd4a 12088 return \"\";
cffb2a26 12089 "
12090)
f7fbdd4a 12091
cffb2a26 12092(define_insn "consttable_1"
e1159bbe 12093 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_1)]
25f905c2 12094 "TARGET_THUMB1"
f7fbdd4a 12095 "*
cffb2a26 12096 making_const_table = TRUE;
09d688ff 12097 assemble_integer (operands[0], 1, BITS_PER_WORD, 1);
cffb2a26 12098 assemble_zeros (3);
f7fbdd4a 12099 return \"\";
cffb2a26 12100 "
12101 [(set_attr "length" "4")]
12102)
f7fbdd4a 12103
cffb2a26 12104(define_insn "consttable_2"
e1159bbe 12105 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_2)]
25f905c2 12106 "TARGET_THUMB1"
f7fbdd4a 12107 "*
cffb2a26 12108 making_const_table = TRUE;
9b8516be 12109 gcc_assert (GET_MODE_CLASS (GET_MODE (operands[0])) != MODE_FLOAT);
09d688ff 12110 assemble_integer (operands[0], 2, BITS_PER_WORD, 1);
cffb2a26 12111 assemble_zeros (2);
f7fbdd4a 12112 return \"\";
cffb2a26 12113 "
12114 [(set_attr "length" "4")]
12115)
12116
12117(define_insn "consttable_4"
e1159bbe 12118 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_4)]
cffb2a26 12119 "TARGET_EITHER"
12120 "*
12121 {
9b8516be 12122 rtx x = operands[0];
cffb2a26 12123 making_const_table = TRUE;
9b8516be 12124 switch (GET_MODE_CLASS (GET_MODE (x)))
cffb2a26 12125 {
12126 case MODE_FLOAT:
9b8516be 12127 if (GET_MODE (x) == HFmode)
12128 arm_emit_fp16_const (x);
12129 else
12130 {
12131 REAL_VALUE_TYPE r;
12132 REAL_VALUE_FROM_CONST_DOUBLE (r, x);
12133 assemble_real (r, GET_MODE (x), BITS_PER_WORD);
12134 }
12135 break;
cffb2a26 12136 default:
7b04c5d5 12137 /* XXX: Sometimes gcc does something really dumb and ends up with
12138 a HIGH in a constant pool entry, usually because it's trying to
12139 load into a VFP register. We know this will always be used in
12140 combination with a LO_SUM which ignores the high bits, so just
12141 strip off the HIGH. */
12142 if (GET_CODE (x) == HIGH)
12143 x = XEXP (x, 0);
9b8516be 12144 assemble_integer (x, 4, BITS_PER_WORD, 1);
12145 mark_symbol_refs_as_used (x);
cffb2a26 12146 break;
12147 }
12148 return \"\";
12149 }"
12150 [(set_attr "length" "4")]
12151)
12152
12153(define_insn "consttable_8"
e1159bbe 12154 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_8)]
cffb2a26 12155 "TARGET_EITHER"
12156 "*
12157 {
12158 making_const_table = TRUE;
12159 switch (GET_MODE_CLASS (GET_MODE (operands[0])))
12160 {
12161 case MODE_FLOAT:
12162 {
badfe841 12163 REAL_VALUE_TYPE r;
12164 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[0]);
12165 assemble_real (r, GET_MODE (operands[0]), BITS_PER_WORD);
cffb2a26 12166 break;
12167 }
12168 default:
09d688ff 12169 assemble_integer (operands[0], 8, BITS_PER_WORD, 1);
cffb2a26 12170 break;
12171 }
12172 return \"\";
12173 }"
12174 [(set_attr "length" "8")]
12175)
12176
d98a3884 12177(define_insn "consttable_16"
12178 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_16)]
12179 "TARGET_EITHER"
12180 "*
12181 {
12182 making_const_table = TRUE;
12183 switch (GET_MODE_CLASS (GET_MODE (operands[0])))
12184 {
12185 case MODE_FLOAT:
12186 {
12187 REAL_VALUE_TYPE r;
12188 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[0]);
12189 assemble_real (r, GET_MODE (operands[0]), BITS_PER_WORD);
12190 break;
12191 }
12192 default:
12193 assemble_integer (operands[0], 16, BITS_PER_WORD, 1);
12194 break;
12195 }
12196 return \"\";
12197 }"
12198 [(set_attr "length" "16")]
12199)
12200
cffb2a26 12201;; Miscellaneous Thumb patterns
12202
fd957ef3 12203(define_expand "tablejump"
7db9af5d 12204 [(parallel [(set (pc) (match_operand:SI 0 "register_operand" ""))
fd957ef3 12205 (use (label_ref (match_operand 1 "" "")))])]
25f905c2 12206 "TARGET_THUMB1"
fd957ef3 12207 "
12208 if (flag_pic)
12209 {
12210 /* Hopefully, CSE will eliminate this copy. */
12211 rtx reg1 = copy_addr_to_reg (gen_rtx_LABEL_REF (Pmode, operands[1]));
12212 rtx reg2 = gen_reg_rtx (SImode);
12213
12214 emit_insn (gen_addsi3 (reg2, operands[0], reg1));
12215 operands[0] = reg2;
12216 }
12217 "
12218)
12219
f1039640 12220;; NB never uses BX.
25f905c2 12221(define_insn "*thumb1_tablejump"
cffb2a26 12222 [(set (pc) (match_operand:SI 0 "register_operand" "l*r"))
12223 (use (label_ref (match_operand 1 "" "")))]
25f905c2 12224 "TARGET_THUMB1"
fd957ef3 12225 "mov\\t%|pc, %0"
cffb2a26 12226 [(set_attr "length" "2")]
12227)
0d66636f 12228
331beb1a 12229;; V5 Instructions,
12230
8f4be2be 12231(define_insn "clzsi2"
12232 [(set (match_operand:SI 0 "s_register_operand" "=r")
12233 (clz:SI (match_operand:SI 1 "s_register_operand" "r")))]
25f905c2 12234 "TARGET_32BIT && arm_arch5"
ee7cbe0e 12235 "clz%?\\t%0, %1"
bcaec148 12236 [(set_attr "predicable" "yes")
bebe9bbb 12237 (set_attr "type" "clz")])
331beb1a 12238
099ad98b 12239(define_insn "rbitsi2"
12240 [(set (match_operand:SI 0 "s_register_operand" "=r")
12241 (unspec:SI [(match_operand:SI 1 "s_register_operand" "r")] UNSPEC_RBIT))]
12242 "TARGET_32BIT && arm_arch_thumb2"
12243 "rbit%?\\t%0, %1"
12244 [(set_attr "predicable" "yes")
bebe9bbb 12245 (set_attr "type" "clz")])
099ad98b 12246
12247(define_expand "ctzsi2"
12248 [(set (match_operand:SI 0 "s_register_operand" "")
12249 (ctz:SI (match_operand:SI 1 "s_register_operand" "")))]
12250 "TARGET_32BIT && arm_arch_thumb2"
12251 "
30191172 12252 {
12253 rtx tmp = gen_reg_rtx (SImode);
12254 emit_insn (gen_rbitsi2 (tmp, operands[1]));
12255 emit_insn (gen_clzsi2 (operands[0], tmp));
12256 }
099ad98b 12257 DONE;
12258 "
12259)
12260
e1159bbe 12261;; V5E instructions.
331beb1a 12262
12263(define_insn "prefetch"
f4e79814 12264 [(prefetch (match_operand:SI 0 "address_operand" "p")
12265 (match_operand:SI 1 "" "")
12266 (match_operand:SI 2 "" ""))]
25f905c2 12267 "TARGET_32BIT && arm_arch5e"
bcb7a8f6 12268 "pld\\t%a0")
331beb1a 12269
0d66636f 12270;; General predication pattern
12271
12272(define_cond_exec
12273 [(match_operator 0 "arm_comparison_operator"
12274 [(match_operand 1 "cc_register" "")
12275 (const_int 0)])]
25f905c2 12276 "TARGET_32BIT"
0d66636f 12277 ""
c7a58118 12278[(set_attr "predicated" "yes")]
0d66636f 12279)
12280
fb94f18b 12281(define_insn "force_register_use"
12282 [(unspec:SI [(match_operand:SI 0 "register_operand" "")] UNSPEC_REGISTER_USE)]
063a05c7 12283 ""
fb94f18b 12284 "%@ %0 needed"
02cfc9c9 12285 [(set_attr "length" "0")]
063a05c7 12286)
7db9af5d 12287
4c44712e 12288
12289;; Patterns for exception handling
12290
12291(define_expand "eh_return"
12292 [(use (match_operand 0 "general_operand" ""))]
12293 "TARGET_EITHER"
12294 "
12295 {
25f905c2 12296 if (TARGET_32BIT)
4c44712e 12297 emit_insn (gen_arm_eh_return (operands[0]));
12298 else
12299 emit_insn (gen_thumb_eh_return (operands[0]));
12300 DONE;
12301 }"
12302)
12303
12304;; We can't expand this before we know where the link register is stored.
12305(define_insn_and_split "arm_eh_return"
12306 [(unspec_volatile [(match_operand:SI 0 "s_register_operand" "r")]
12307 VUNSPEC_EH_RETURN)
12308 (clobber (match_scratch:SI 1 "=&r"))]
12309 "TARGET_ARM"
12310 "#"
12311 "&& reload_completed"
12312 [(const_int 0)]
12313 "
12314 {
12315 arm_set_return_address (operands[0], operands[1]);
12316 DONE;
12317 }"
12318)
12319
12320(define_insn_and_split "thumb_eh_return"
12321 [(unspec_volatile [(match_operand:SI 0 "s_register_operand" "l")]
12322 VUNSPEC_EH_RETURN)
12323 (clobber (match_scratch:SI 1 "=&l"))]
25f905c2 12324 "TARGET_THUMB1"
4c44712e 12325 "#"
12326 "&& reload_completed"
12327 [(const_int 0)]
12328 "
12329 {
12330 thumb_set_return_address (operands[0], operands[1]);
12331 DONE;
12332 }"
12333)
12334
f655717d 12335\f
12336;; TLS support
12337
12338(define_insn "load_tp_hard"
12339 [(set (match_operand:SI 0 "register_operand" "=r")
12340 (unspec:SI [(const_int 0)] UNSPEC_TLS))]
12341 "TARGET_HARD_TP"
12342 "mrc%?\\tp15, 0, %0, c13, c0, 3\\t@ load_tp_hard"
12343 [(set_attr "predicable" "yes")]
12344)
12345
12346;; Doesn't clobber R1-R3. Must use r0 for the first operand.
12347(define_insn "load_tp_soft"
12348 [(set (reg:SI 0) (unspec:SI [(const_int 0)] UNSPEC_TLS))
12349 (clobber (reg:SI LR_REGNUM))
12350 (clobber (reg:SI IP_REGNUM))
12351 (clobber (reg:CC CC_REGNUM))]
12352 "TARGET_SOFT_TP"
12353 "bl\\t__aeabi_read_tp\\t@ load_tp_soft"
12354 [(set_attr "conds" "clob")]
12355)
12356
f41e4452 12357;; tls descriptor call
12358(define_insn "tlscall"
12359 [(set (reg:SI R0_REGNUM)
12360 (unspec:SI [(reg:SI R0_REGNUM)
12361 (match_operand:SI 0 "" "X")
12362 (match_operand 1 "" "")] UNSPEC_TLS))
12363 (clobber (reg:SI R1_REGNUM))
12364 (clobber (reg:SI LR_REGNUM))
12365 (clobber (reg:SI CC_REGNUM))]
12366 "TARGET_GNU2_TLS"
12367 {
12368 targetm.asm_out.internal_label (asm_out_file, "LPIC",
12369 INTVAL (operands[1]));
12370 return "bl\\t%c0(tlscall)";
12371 }
12372 [(set_attr "conds" "clob")
12373 (set_attr "length" "4")]
12374)
12375
1fe0edab 12376;; For thread pointer builtin
12377(define_expand "get_thread_pointersi"
12378 [(match_operand:SI 0 "s_register_operand" "=r")]
12379 ""
12380 "
12381 {
12382 arm_load_tp (operands[0]);
12383 DONE;
12384 }")
12385
f41e4452 12386;;
12387
aabe09ac 12388;; We only care about the lower 16 bits of the constant
12389;; being inserted into the upper 16 bits of the register.
eca5c984 12390(define_insn "*arm_movtas_ze"
12391 [(set (zero_extract:SI (match_operand:SI 0 "s_register_operand" "+r")
12392 (const_int 16)
12393 (const_int 16))
12394 (match_operand:SI 1 "const_int_operand" ""))]
181ab277 12395 "arm_arch_thumb2"
aabe09ac 12396 "movt%?\t%0, %L1"
eca5c984 12397 [(set_attr "predicable" "yes")
7c36fe71 12398 (set_attr "predicable_short_it" "no")
12399 (set_attr "length" "4")]
eca5c984 12400)
12401
c0fc3696 12402(define_insn "*arm_rev"
a486b499 12403 [(set (match_operand:SI 0 "s_register_operand" "=l,l,r")
12404 (bswap:SI (match_operand:SI 1 "s_register_operand" "l,l,r")))]
12405 "arm_arch6"
12406 "@
12407 rev\t%0, %1
12408 rev%?\t%0, %1
12409 rev%?\t%0, %1"
12410 [(set_attr "arch" "t1,t2,32")
12411 (set_attr "length" "2,2,4")]
ff82f757 12412)
12413
12414(define_expand "arm_legacy_rev"
12415 [(set (match_operand:SI 2 "s_register_operand" "")
12416 (xor:SI (rotatert:SI (match_operand:SI 1 "s_register_operand" "")
12417 (const_int 16))
12418 (match_dup 1)))
12419 (set (match_dup 2)
12420 (lshiftrt:SI (match_dup 2)
12421 (const_int 8)))
12422 (set (match_operand:SI 3 "s_register_operand" "")
12423 (rotatert:SI (match_dup 1)
12424 (const_int 8)))
12425 (set (match_dup 2)
12426 (and:SI (match_dup 2)
12427 (const_int -65281)))
12428 (set (match_operand:SI 0 "s_register_operand" "")
12429 (xor:SI (match_dup 3)
12430 (match_dup 2)))]
12431 "TARGET_32BIT"
12432 ""
12433)
12434
12435;; Reuse temporaries to keep register pressure down.
12436(define_expand "thumb_legacy_rev"
12437 [(set (match_operand:SI 2 "s_register_operand" "")
12438 (ashift:SI (match_operand:SI 1 "s_register_operand" "")
12439 (const_int 24)))
12440 (set (match_operand:SI 3 "s_register_operand" "")
12441 (lshiftrt:SI (match_dup 1)
12442 (const_int 24)))
12443 (set (match_dup 3)
12444 (ior:SI (match_dup 3)
12445 (match_dup 2)))
12446 (set (match_operand:SI 4 "s_register_operand" "")
12447 (const_int 16))
12448 (set (match_operand:SI 5 "s_register_operand" "")
12449 (rotatert:SI (match_dup 1)
12450 (match_dup 4)))
12451 (set (match_dup 2)
12452 (ashift:SI (match_dup 5)
12453 (const_int 24)))
12454 (set (match_dup 5)
12455 (lshiftrt:SI (match_dup 5)
12456 (const_int 24)))
12457 (set (match_dup 5)
12458 (ior:SI (match_dup 5)
12459 (match_dup 2)))
12460 (set (match_dup 5)
12461 (rotatert:SI (match_dup 5)
12462 (match_dup 4)))
12463 (set (match_operand:SI 0 "s_register_operand" "")
12464 (ior:SI (match_dup 5)
12465 (match_dup 3)))]
12466 "TARGET_THUMB"
12467 ""
12468)
12469
12470(define_expand "bswapsi2"
12471 [(set (match_operand:SI 0 "s_register_operand" "=r")
12472 (bswap:SI (match_operand:SI 1 "s_register_operand" "r")))]
8d1af482 12473"TARGET_EITHER && (arm_arch6 || !optimize_size)"
ff82f757 12474"
8d1af482 12475 if (!arm_arch6)
12476 {
12477 rtx op2 = gen_reg_rtx (SImode);
12478 rtx op3 = gen_reg_rtx (SImode);
ff82f757 12479
8d1af482 12480 if (TARGET_THUMB)
12481 {
12482 rtx op4 = gen_reg_rtx (SImode);
12483 rtx op5 = gen_reg_rtx (SImode);
ff82f757 12484
8d1af482 12485 emit_insn (gen_thumb_legacy_rev (operands[0], operands[1],
12486 op2, op3, op4, op5));
12487 }
12488 else
12489 {
12490 emit_insn (gen_arm_legacy_rev (operands[0], operands[1],
12491 op2, op3));
12492 }
ff82f757 12493
8d1af482 12494 DONE;
12495 }
ff82f757 12496 "
12497)
12498
a486b499 12499;; bswap16 patterns: use revsh and rev16 instructions for the signed
12500;; and unsigned variants, respectively. For rev16, expose
12501;; byte-swapping in the lower 16 bits only.
12502(define_insn "*arm_revsh"
12503 [(set (match_operand:SI 0 "s_register_operand" "=l,l,r")
12504 (sign_extend:SI (bswap:HI (match_operand:HI 1 "s_register_operand" "l,l,r"))))]
12505 "arm_arch6"
12506 "@
12507 revsh\t%0, %1
12508 revsh%?\t%0, %1
12509 revsh%?\t%0, %1"
12510 [(set_attr "arch" "t1,t2,32")
12511 (set_attr "length" "2,2,4")]
12512)
12513
12514(define_insn "*arm_rev16"
12515 [(set (match_operand:HI 0 "s_register_operand" "=l,l,r")
12516 (bswap:HI (match_operand:HI 1 "s_register_operand" "l,l,r")))]
12517 "arm_arch6"
12518 "@
12519 rev16\t%0, %1
12520 rev16%?\t%0, %1
12521 rev16%?\t%0, %1"
12522 [(set_attr "arch" "t1,t2,32")
12523 (set_attr "length" "2,2,4")]
12524)
12525
12526(define_expand "bswaphi2"
12527 [(set (match_operand:HI 0 "s_register_operand" "=r")
12528 (bswap:HI (match_operand:HI 1 "s_register_operand" "r")))]
12529"arm_arch6"
12530""
12531)
12532
1653cf17 12533;; Patterns for LDRD/STRD in Thumb2 mode
12534
12535(define_insn "*thumb2_ldrd"
12536 [(set (match_operand:SI 0 "s_register_operand" "=r")
12537 (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "rk")
12538 (match_operand:SI 2 "ldrd_strd_offset_operand" "Do"))))
12539 (set (match_operand:SI 3 "s_register_operand" "=r")
12540 (mem:SI (plus:SI (match_dup 1)
12541 (match_operand:SI 4 "const_int_operand" ""))))]
12542 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
12543 && current_tune->prefer_ldrd_strd
12544 && ((INTVAL (operands[2]) + 4) == INTVAL (operands[4]))
12545 && (operands_ok_ldrd_strd (operands[0], operands[3],
12546 operands[1], INTVAL (operands[2]),
12547 false, true))"
12548 "ldrd%?\t%0, %3, [%1, %2]"
12549 [(set_attr "type" "load2")
d952d547 12550 (set_attr "predicable" "yes")
12551 (set_attr "predicable_short_it" "no")])
1653cf17 12552
12553(define_insn "*thumb2_ldrd_base"
12554 [(set (match_operand:SI 0 "s_register_operand" "=r")
12555 (mem:SI (match_operand:SI 1 "s_register_operand" "rk")))
12556 (set (match_operand:SI 2 "s_register_operand" "=r")
12557 (mem:SI (plus:SI (match_dup 1)
12558 (const_int 4))))]
12559 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
12560 && current_tune->prefer_ldrd_strd
12561 && (operands_ok_ldrd_strd (operands[0], operands[2],
12562 operands[1], 0, false, true))"
12563 "ldrd%?\t%0, %2, [%1]"
12564 [(set_attr "type" "load2")
d952d547 12565 (set_attr "predicable" "yes")
12566 (set_attr "predicable_short_it" "no")])
1653cf17 12567
12568(define_insn "*thumb2_ldrd_base_neg"
12569 [(set (match_operand:SI 0 "s_register_operand" "=r")
12570 (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "rk")
12571 (const_int -4))))
12572 (set (match_operand:SI 2 "s_register_operand" "=r")
12573 (mem:SI (match_dup 1)))]
12574 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
12575 && current_tune->prefer_ldrd_strd
12576 && (operands_ok_ldrd_strd (operands[0], operands[2],
12577 operands[1], -4, false, true))"
12578 "ldrd%?\t%0, %2, [%1, #-4]"
12579 [(set_attr "type" "load2")
d952d547 12580 (set_attr "predicable" "yes")
12581 (set_attr "predicable_short_it" "no")])
1653cf17 12582
12583(define_insn "*thumb2_strd"
12584 [(set (mem:SI (plus:SI (match_operand:SI 0 "s_register_operand" "rk")
12585 (match_operand:SI 1 "ldrd_strd_offset_operand" "Do")))
12586 (match_operand:SI 2 "s_register_operand" "r"))
12587 (set (mem:SI (plus:SI (match_dup 0)
12588 (match_operand:SI 3 "const_int_operand" "")))
12589 (match_operand:SI 4 "s_register_operand" "r"))]
12590 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
12591 && current_tune->prefer_ldrd_strd
12592 && ((INTVAL (operands[1]) + 4) == INTVAL (operands[3]))
12593 && (operands_ok_ldrd_strd (operands[2], operands[4],
12594 operands[0], INTVAL (operands[1]),
12595 false, false))"
12596 "strd%?\t%2, %4, [%0, %1]"
12597 [(set_attr "type" "store2")
d952d547 12598 (set_attr "predicable" "yes")
12599 (set_attr "predicable_short_it" "no")])
1653cf17 12600
12601(define_insn "*thumb2_strd_base"
12602 [(set (mem:SI (match_operand:SI 0 "s_register_operand" "rk"))
12603 (match_operand:SI 1 "s_register_operand" "r"))
12604 (set (mem:SI (plus:SI (match_dup 0)
12605 (const_int 4)))
12606 (match_operand:SI 2 "s_register_operand" "r"))]
12607 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
12608 && current_tune->prefer_ldrd_strd
12609 && (operands_ok_ldrd_strd (operands[1], operands[2],
12610 operands[0], 0, false, false))"
12611 "strd%?\t%1, %2, [%0]"
12612 [(set_attr "type" "store2")
d952d547 12613 (set_attr "predicable" "yes")
12614 (set_attr "predicable_short_it" "no")])
1653cf17 12615
12616(define_insn "*thumb2_strd_base_neg"
12617 [(set (mem:SI (plus:SI (match_operand:SI 0 "s_register_operand" "rk")
12618 (const_int -4)))
12619 (match_operand:SI 1 "s_register_operand" "r"))
12620 (set (mem:SI (match_dup 0))
12621 (match_operand:SI 2 "s_register_operand" "r"))]
12622 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
12623 && current_tune->prefer_ldrd_strd
12624 && (operands_ok_ldrd_strd (operands[1], operands[2],
12625 operands[0], -4, false, false))"
12626 "strd%?\t%1, %2, [%0, #-4]"
12627 [(set_attr "type" "store2")
d952d547 12628 (set_attr "predicable" "yes")
12629 (set_attr "predicable_short_it" "no")])
1653cf17 12630
12631
353cf59a 12632;; Load the load/store double peephole optimizations.
12633(include "ldrdstrd.md")
12634
320ea44d 12635;; Load the load/store multiple patterns
12636(include "ldmstm.md")
426be8c5 12637
12638;; Patterns in ldmstm.md don't cover more than 4 registers. This pattern covers
12639;; large lists without explicit writeback generated for APCS_FRAME epilogue.
12640(define_insn "*load_multiple"
12641 [(match_parallel 0 "load_multiple_operation"
12642 [(set (match_operand:SI 2 "s_register_operand" "=rk")
12643 (mem:SI (match_operand:SI 1 "s_register_operand" "rk")))
12644 ])]
12645 "TARGET_32BIT"
12646 "*
12647 {
12648 arm_output_multireg_pop (operands, /*return_pc=*/false,
12649 /*cond=*/const_true_rtx,
12650 /*reverse=*/false,
12651 /*update=*/false);
12652 return \"\";
12653 }
12654 "
12655 [(set_attr "predicable" "yes")]
12656)
12657
d98a3884 12658;; Vector bits common to IWMMXT and Neon
12659(include "vec-common.md")
755eb2b4 12660;; Load the Intel Wireless Multimedia Extension patterns
12661(include "iwmmxt.md")
a2cd141b 12662;; Load the VFP co-processor patterns
12663(include "vfp.md")
25f905c2 12664;; Thumb-2 patterns
12665(include "thumb2.md")
d98a3884 12666;; Neon patterns
12667(include "neon.md")
06df6b17 12668;; Synchronization Primitives
12669(include "sync.md")
bbbe4599 12670;; Fixed-point patterns
12671(include "arm-fixed.md")