]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/config/arm/arm.md
testsuite: error out with tested condition instead of FOO
[thirdparty/gcc.git] / gcc / config / arm / arm.md
CommitLineData
129a2fe4 1;;- Machine description for ARM for GNU compiler
3aea1f79 2;; Copyright (C) 1991-2014 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
861033d5 85;; Instruction classification types
86(include "types.md")
87
215b30b3 88; IS_THUMB is set to 'yes' when we are generating Thumb code, and 'no' when
89; generating ARM code. This is used to control the length of some insn
90; patterns that share the same RTL in both ARM and Thumb code.
1c494086 91(define_attr "is_thumb" "no,yes" (const (symbol_ref "thumb_code")))
cffb2a26 92
ef51b8e1 93; IS_ARCH6 is set to 'yes' when we are generating code form ARMv6.
94(define_attr "is_arch6" "no,yes" (const (symbol_ref "arm_arch6")))
95
747b7458 96; IS_THUMB1 is set to 'yes' iff we are generating Thumb-1 code.
97(define_attr "is_thumb1" "no,yes" (const (symbol_ref "thumb1_code")))
98
c7a58118 99; We use this attribute to disable alternatives that can produce 32-bit
100; instructions inside an IT-block in Thumb2 state. ARMv8 deprecates IT blocks
101; that contain 32-bit instructions.
102(define_attr "enabled_for_depr_it" "no,yes" (const_string "yes"))
103
104; This attribute is used to disable a predicated alternative when we have
105; arm_restrict_it.
106(define_attr "predicable_short_it" "no,yes" (const_string "yes"))
107
331beb1a 108;; Operand number of an input operand that is shifted. Zero if the
109;; given instruction does not shift one of its input operands.
331beb1a 110(define_attr "shift" "" (const_int 0))
111
3d91c5d6 112; Floating Point Unit. If we only have floating point emulation, then there
113; is no point in scheduling the floating point insns. (Well, for best
114; performance we should try and group them together).
bffbb863 115(define_attr "fpu" "none,vfp"
c7f506fd 116 (const (symbol_ref "arm_fpu_attr")))
3d91c5d6 117
c7a58118 118(define_attr "predicated" "yes,no" (const_string "no"))
119
094e994f 120; LENGTH of an instruction (in bytes)
06df6b17 121(define_attr "length" ""
e1b93706 122 (const_int 4))
9c08d1fa 123
d5d4dc8d 124; The architecture which supports the instruction (or alternative).
125; This can be "a" for ARM, "t" for either of the Thumbs, "32" for
126; TARGET_32BIT, "t1" or "t2" to specify a specific Thumb mode. "v6"
127; for ARM or Thumb-2 with arm_arch6, and nov6 for ARM without
128; arm_arch6. This attribute is used to compute attribute "enabled",
129; use type "any" to enable an alternative in all cases.
21cc9773 130(define_attr "arch" "any,a,t,32,t1,t2,v6,nov6,neon_for_64bits,avoid_neon_for_64bits,iwmmxt,iwmmxt2,armv6_or_vfpv3"
d5d4dc8d 131 (const_string "any"))
132
133(define_attr "arch_enabled" "no,yes"
134 (cond [(eq_attr "arch" "any")
135 (const_string "yes")
136
137 (and (eq_attr "arch" "a")
0bf497f5 138 (match_test "TARGET_ARM"))
d5d4dc8d 139 (const_string "yes")
140
141 (and (eq_attr "arch" "t")
0bf497f5 142 (match_test "TARGET_THUMB"))
d5d4dc8d 143 (const_string "yes")
144
145 (and (eq_attr "arch" "t1")
0bf497f5 146 (match_test "TARGET_THUMB1"))
d5d4dc8d 147 (const_string "yes")
148
149 (and (eq_attr "arch" "t2")
0bf497f5 150 (match_test "TARGET_THUMB2"))
d5d4dc8d 151 (const_string "yes")
152
153 (and (eq_attr "arch" "32")
0bf497f5 154 (match_test "TARGET_32BIT"))
d5d4dc8d 155 (const_string "yes")
156
157 (and (eq_attr "arch" "v6")
0bf497f5 158 (match_test "TARGET_32BIT && arm_arch6"))
d5d4dc8d 159 (const_string "yes")
160
161 (and (eq_attr "arch" "nov6")
0bf497f5 162 (match_test "TARGET_32BIT && !arm_arch6"))
a651f34d 163 (const_string "yes")
164
b6779ddc 165 (and (eq_attr "arch" "avoid_neon_for_64bits")
166 (match_test "TARGET_NEON")
167 (not (match_test "TARGET_PREFER_NEON_64BITS")))
a651f34d 168 (const_string "yes")
169
b6779ddc 170 (and (eq_attr "arch" "neon_for_64bits")
171 (match_test "TARGET_NEON")
172 (match_test "TARGET_PREFER_NEON_64BITS"))
6b8f7c28 173 (const_string "yes")
174
175 (and (eq_attr "arch" "iwmmxt2")
176 (match_test "TARGET_REALLY_IWMMXT2"))
21cc9773 177 (const_string "yes")
178
179 (and (eq_attr "arch" "armv6_or_vfpv3")
180 (match_test "arm_arch6 || TARGET_VFP3"))
181 (const_string "yes")
182 ]
6b8f7c28 183
d5d4dc8d 184 (const_string "no")))
185
aa06c51c 186(define_attr "opt" "any,speed,size"
187 (const_string "any"))
188
189(define_attr "opt_enabled" "no,yes"
190 (cond [(eq_attr "opt" "any")
191 (const_string "yes")
192
193 (and (eq_attr "opt" "speed")
194 (match_test "optimize_function_for_speed_p (cfun)"))
195 (const_string "yes")
196
197 (and (eq_attr "opt" "size")
198 (match_test "optimize_function_for_size_p (cfun)"))
199 (const_string "yes")]
200 (const_string "no")))
201
861033d5 202(define_attr "use_literal_pool" "no,yes"
203 (cond [(and (eq_attr "type" "f_loads,f_loadd")
204 (match_test "CONSTANT_P (operands[1])"))
205 (const_string "yes")]
206 (const_string "no")))
207
d5d4dc8d 208; Enable all alternatives that are both arch_enabled and insn_enabled.
951a3f72 209; FIXME:: opt_enabled has been temporarily removed till the time we have
210; an attribute that allows the use of such alternatives.
211; This depends on caching of speed_p, size_p on a per
212; alternative basis. The problem is that the enabled attribute
213; cannot depend on any state that is not cached or is not constant
214; for a compilation unit. We probably need a generic "hot/cold"
215; alternative which if implemented can help with this. We disable this
216; until such a time as this is implemented and / or the improvements or
217; regressions with removing this attribute are double checked.
218; See ashldi3_neon and <shift>di3_neon in neon.md.
219
93b431d9 220 (define_attr "enabled" "no,yes"
0abea32c 221 (cond [(and (eq_attr "predicable_short_it" "no")
c7a58118 222 (and (eq_attr "predicated" "yes")
223 (match_test "arm_restrict_it")))
224 (const_string "no")
225
226 (and (eq_attr "enabled_for_depr_it" "no")
227 (match_test "arm_restrict_it"))
228 (const_string "no")
229
861033d5 230 (and (eq_attr "use_literal_pool" "yes")
231 (match_test "arm_disable_literal_pool"))
232 (const_string "no")
233
aa06c51c 234 (eq_attr "arch_enabled" "no")
aa06c51c 235 (const_string "no")]
236 (const_string "yes")))
d5d4dc8d 237
56d27660 238; POOL_RANGE is how far away from a constant pool entry that this insn
239; can be placed. If the distance is zero, then this insn will never
240; reference the pool.
42e1de19 241; Note that for Thumb constant pools the PC value is rounded down to the
242; nearest multiple of four. Therefore, THUMB2_POOL_RANGE (and POOL_RANGE for
243; Thumb insns) should be set to <max_range> - 2.
cffb2a26 244; NEG_POOL_RANGE is nonzero for insns that can reference a constant pool entry
8848d797 245; before its address. It is set to <max_range> - (8 + <data_size>).
cde1623a 246(define_attr "arm_pool_range" "" (const_int 0))
247(define_attr "thumb2_pool_range" "" (const_int 0))
248(define_attr "arm_neg_pool_range" "" (const_int 0))
249(define_attr "thumb2_neg_pool_range" "" (const_int 0))
250
251(define_attr "pool_range" ""
252 (cond [(eq_attr "is_thumb" "yes") (attr "thumb2_pool_range")]
253 (attr "arm_pool_range")))
254(define_attr "neg_pool_range" ""
255 (cond [(eq_attr "is_thumb" "yes") (attr "thumb2_neg_pool_range")]
256 (attr "arm_neg_pool_range")))
56d27660 257
215b30b3 258; An assembler sequence may clobber the condition codes without us knowing.
4d7a8451 259; If such an insn references the pool, then we have no way of knowing how,
260; so use the most conservative value for pool_range.
9c08d1fa 261(define_asm_attributes
4d7a8451 262 [(set_attr "conds" "clob")
263 (set_attr "length" "4")
264 (set_attr "pool_range" "250")])
9c08d1fa 265
9888ad6d 266; Load scheduling, set from the arm_ld_sched variable
4c834714 267; initialized by arm_option_override()
9888ad6d 268(define_attr "ldsched" "no,yes" (const (symbol_ref "arm_ld_sched")))
849170fd 269
f7fbdd4a 270; condition codes: this one is used by final_prescan_insn to speed up
271; conditionalizing instructions. It saves having to scan the rtl to see if
272; it uses or alters the condition codes.
215b30b3 273;
f7fbdd4a 274; USE means that the condition codes are used by the insn in the process of
215b30b3 275; outputting code, this means (at present) that we can't use the insn in
276; inlined branches
277;
f7fbdd4a 278; SET means that the purpose of the insn is to set the condition codes in a
215b30b3 279; well defined manner.
280;
f7fbdd4a 281; CLOB means that the condition codes are altered in an undefined manner, if
215b30b3 282; they are altered at all
283;
ad6d3e2a 284; UNCONDITIONAL means the instruction can not be conditionally executed and
285; that the instruction does not use or alter the condition codes.
c52acdd2 286;
ad6d3e2a 287; NOCOND means that the instruction does not use or alter the condition
288; codes but can be converted into a conditionally exectuted instruction.
f7fbdd4a 289
b0694be0 290(define_attr "conds" "use,set,clob,unconditional,nocond"
747b7458 291 (if_then_else
292 (ior (eq_attr "is_thumb1" "yes")
293 (eq_attr "type" "call"))
c1a66faf 294 (const_string "clob")
32093010 295 (if_then_else (eq_attr "is_neon_type" "no")
52432540 296 (const_string "nocond")
297 (const_string "unconditional"))))
f7fbdd4a 298
215b30b3 299; Predicable means that the insn can be conditionally executed based on
300; an automatically added predicate (additional patterns are generated by
301; gen...). We default to 'no' because no Thumb patterns match this rule
302; and not all ARM patterns do.
0d66636f 303(define_attr "predicable" "no,yes" (const_string "no"))
304
129a2fe4 305; Only model the write buffer for ARM6 and ARM7. Earlier processors don't
306; have one. Later ones, such as StrongARM, have write-back caches, so don't
8d232dc7 307; suffer blockages enough to warrant modelling this (and it can adversely
129a2fe4 308; affect the schedule).
74a71f7d 309(define_attr "model_wbuf" "no,yes" (const (symbol_ref "arm_tune_wbuf")))
129a2fe4 310
215b30b3 311; WRITE_CONFLICT implies that a read following an unrelated write is likely
312; to stall the processor. Used with model_wbuf above.
9c08d1fa 313(define_attr "write_conflict" "no,yes"
314 (if_then_else (eq_attr "type"
96854199 315 "block,call,load1")
9c08d1fa 316 (const_string "yes")
317 (const_string "no")))
318
215b30b3 319; Classify the insns into those that take one cycle and those that take more
320; than one on the main cpu execution unit.
f7fbdd4a 321(define_attr "core_cycles" "single,multi"
322 (if_then_else (eq_attr "type"
112eda6f 323 "adc_imm, adc_reg, adcs_imm, adcs_reg, adr, alu_ext, alu_imm, alu_sreg,\
324 alu_shift_imm, alu_shift_reg, alu_dsp_reg, alus_ext, alus_imm, alus_sreg,\
d82e788e 325 alus_shift_imm, alus_shift_reg, bfm, csel, rev, logic_imm, logic_reg,\
326 logic_shift_imm, logic_shift_reg, logics_imm, logics_reg,\
327 logics_shift_imm, logics_shift_reg, extend, shift_imm, float, fcsel,\
7cb6c048 328 wmmx_wor, wmmx_wxor, wmmx_wand, wmmx_wandn, wmmx_wmov, wmmx_tmcrr,\
329 wmmx_tmrrc, wmmx_wldr, wmmx_wstr, wmmx_tmcr, wmmx_tmrc, wmmx_wadd,\
330 wmmx_wsub, wmmx_wmul, wmmx_wmac, wmmx_wavg2, wmmx_tinsr, wmmx_textrm,\
331 wmmx_wshufh, wmmx_wcmpeq, wmmx_wcmpgt, wmmx_wmax, wmmx_wmin, wmmx_wpack,\
332 wmmx_wunpckih, wmmx_wunpckil, wmmx_wunpckeh, wmmx_wunpckel, wmmx_wror,\
333 wmmx_wsra, wmmx_wsrl, wmmx_wsll, wmmx_wmadd, wmmx_tmia, wmmx_tmiaph,\
334 wmmx_tmiaxy, wmmx_tbcst, wmmx_tmovmsk, wmmx_wacc, wmmx_waligni,\
335 wmmx_walignr, wmmx_tandc, wmmx_textrc, wmmx_torc, wmmx_torvsc, wmmx_wsad,\
336 wmmx_wabs, wmmx_wabsdiff, wmmx_waddsubhx, wmmx_wsubaddhx, wmmx_wavg4,\
337 wmmx_wmulw, wmmx_wqmulm, wmmx_wqmulwm, wmmx_waddbhus, wmmx_wqmiaxy,\
338 wmmx_wmiaxy, wmmx_wmiawxy, wmmx_wmerge")
f7fbdd4a 339 (const_string "single")
340 (const_string "multi")))
341
cffb2a26 342;; FAR_JUMP is "yes" if a BL instruction is used to generate a branch to a
215b30b3 343;; distant label. Only applicable to Thumb code.
cffb2a26 344(define_attr "far_jump" "yes,no" (const_string "no"))
345
d51f92df 346
25f905c2 347;; The number of machine instructions this pattern expands to.
348;; Used for Thumb-2 conditional execution.
349(define_attr "ce_count" "" (const_int 1))
350
4182b724 351;;---------------------------------------------------------------------------
352;; Unspecs
353
354(include "unspecs.md")
355
d51f92df 356;;---------------------------------------------------------------------------
fd781bb2 357;; Mode iterators
d51f92df 358
3de0dec6 359(include "iterators.md")
03770691 360
d51f92df 361;;---------------------------------------------------------------------------
362;; Predicates
363
9c9db025 364(include "predicates.md")
234f6557 365(include "constraints.md")
9c9db025 366
a2cd141b 367;;---------------------------------------------------------------------------
368;; Pipeline descriptions
215b30b3 369
e3879fd0 370(define_attr "tune_cortexr4" "yes,no"
371 (const (if_then_else
7d3cda8c 372 (eq_attr "tune" "cortexr4,cortexr4f,cortexr5")
e3879fd0 373 (const_string "yes")
374 (const_string "no"))))
375
a2cd141b 376;; True if the generic scheduling description should be used.
377
378(define_attr "generic_sched" "yes,no"
2546d93a 379 (const (if_then_else
25b10f06 380 (ior (eq_attr "tune" "fa526,fa626,fa606te,fa626te,fmp626,fa726te,arm926ejs,arm1020e,arm1026ejs,arm1136js,arm1136jfs,cortexa5,cortexa7,cortexa8,cortexa9,cortexa12,cortexa15,cortexa53,cortexm4,marvell_pj4")
2546d93a 381 (eq_attr "tune_cortexr4" "yes"))
4d5cb40d 382 (const_string "no")
383 (const_string "yes"))))
384
c0e1af52 385(define_attr "generic_vfp" "yes,no"
386 (const (if_then_else
387 (and (eq_attr "fpu" "vfp")
43e4f6e8 388 (eq_attr "tune" "!arm1020e,arm1022e,cortexa5,cortexa7,cortexa8,cortexa9,cortexa53,cortexm4,marvell_pj4")
e3879fd0 389 (eq_attr "tune_cortexr4" "no"))
c0e1af52 390 (const_string "yes")
391 (const_string "no"))))
392
6b8f7c28 393(include "marvell-f-iwmmxt.md")
a2cd141b 394(include "arm-generic.md")
395(include "arm926ejs.md")
c0e1af52 396(include "arm1020e.md")
a2cd141b 397(include "arm1026ejs.md")
398(include "arm1136jfs.md")
0e266d06 399(include "fa526.md")
400(include "fa606te.md")
401(include "fa626te.md")
402(include "fmp626.md")
403(include "fa726te.md")
3f1e069f 404(include "cortex-a5.md")
d6b7f019 405(include "cortex-a7.md")
bcaec148 406(include "cortex-a8.md")
036068af 407(include "cortex-a9.md")
65f2f758 408(include "cortex-a15.md")
da10bc87 409(include "cortex-a53.md")
934a1e72 410(include "cortex-r4.md")
e3879fd0 411(include "cortex-r4f.md")
2546d93a 412(include "cortex-m4.md")
413(include "cortex-m4-fpu.md")
55e3ada8 414(include "vfp11.md")
ea7d210b 415(include "marvell-pj4.md")
3586df96 416
9c08d1fa 417\f
215b30b3 418;;---------------------------------------------------------------------------
e1159bbe 419;; Insn patterns
420;;
a0f94409 421;; Addition insns.
215b30b3 422
9c08d1fa 423;; Note: For DImode insns, there is normally no reason why operands should
424;; not be in the same register, what we don't want is for something being
425;; written to partially overlap something that is an input.
426
cffb2a26 427(define_expand "adddi3"
428 [(parallel
215b30b3 429 [(set (match_operand:DI 0 "s_register_operand" "")
cffb2a26 430 (plus:DI (match_operand:DI 1 "s_register_operand" "")
10e5ccd5 431 (match_operand:DI 2 "arm_adddi_operand" "")))
bd5b4116 432 (clobber (reg:CC CC_REGNUM))])]
cffb2a26 433 "TARGET_EITHER"
434 "
25f905c2 435 if (TARGET_THUMB1)
cffb2a26 436 {
0438d37f 437 if (!REG_P (operands[1]))
bc5a93af 438 operands[1] = force_reg (DImode, operands[1]);
0438d37f 439 if (!REG_P (operands[2]))
bc5a93af 440 operands[2] = force_reg (DImode, operands[2]);
cffb2a26 441 }
442 "
443)
444
a0f94409 445(define_insn_and_split "*arm_adddi3"
10e5ccd5 446 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r,&r,&r,&r")
447 (plus:DI (match_operand:DI 1 "s_register_operand" "%0, 0, r, 0, r")
448 (match_operand:DI 2 "arm_adddi_operand" "r, 0, r, Dd, Dd")))
bd5b4116 449 (clobber (reg:CC CC_REGNUM))]
b805622c 450 "TARGET_32BIT && !TARGET_NEON"
33782ec7 451 "#"
94829feb 452 "TARGET_32BIT && reload_completed
453 && ! (TARGET_NEON && IS_VFP_REGNUM (REGNO (operands[0])))"
a0f94409 454 [(parallel [(set (reg:CC_C CC_REGNUM)
455 (compare:CC_C (plus:SI (match_dup 1) (match_dup 2))
456 (match_dup 1)))
457 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
080c0b9a 458 (set (match_dup 3) (plus:SI (plus:SI (match_dup 4) (match_dup 5))
459 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
a0f94409 460 "
461 {
462 operands[3] = gen_highpart (SImode, operands[0]);
463 operands[0] = gen_lowpart (SImode, operands[0]);
464 operands[4] = gen_highpart (SImode, operands[1]);
465 operands[1] = gen_lowpart (SImode, operands[1]);
10e5ccd5 466 operands[5] = gen_highpart_mode (SImode, DImode, operands[2]);
a0f94409 467 operands[2] = gen_lowpart (SImode, operands[2]);
468 }"
cffb2a26 469 [(set_attr "conds" "clob")
1b7da4ac 470 (set_attr "length" "8")
471 (set_attr "type" "multiple")]
cffb2a26 472)
9c08d1fa 473
a0f94409 474(define_insn_and_split "*adddi_sesidi_di"
9c08d1fa 475 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
476 (plus:DI (sign_extend:DI
97499065 477 (match_operand:SI 2 "s_register_operand" "r,r"))
e5fea38e 478 (match_operand:DI 1 "s_register_operand" "0,r")))
bd5b4116 479 (clobber (reg:CC CC_REGNUM))]
b805622c 480 "TARGET_32BIT"
33782ec7 481 "#"
25f905c2 482 "TARGET_32BIT && reload_completed"
a0f94409 483 [(parallel [(set (reg:CC_C CC_REGNUM)
484 (compare:CC_C (plus:SI (match_dup 1) (match_dup 2))
485 (match_dup 1)))
486 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
080c0b9a 487 (set (match_dup 3) (plus:SI (plus:SI (ashiftrt:SI (match_dup 2)
a0f94409 488 (const_int 31))
080c0b9a 489 (match_dup 4))
490 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
a0f94409 491 "
492 {
493 operands[3] = gen_highpart (SImode, operands[0]);
494 operands[0] = gen_lowpart (SImode, operands[0]);
495 operands[4] = gen_highpart (SImode, operands[1]);
496 operands[1] = gen_lowpart (SImode, operands[1]);
497 operands[2] = gen_lowpart (SImode, operands[2]);
498 }"
215b30b3 499 [(set_attr "conds" "clob")
1b7da4ac 500 (set_attr "length" "8")
501 (set_attr "type" "multiple")]
215b30b3 502)
9c08d1fa 503
a0f94409 504(define_insn_and_split "*adddi_zesidi_di"
9c08d1fa 505 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
506 (plus:DI (zero_extend:DI
97499065 507 (match_operand:SI 2 "s_register_operand" "r,r"))
e5fea38e 508 (match_operand:DI 1 "s_register_operand" "0,r")))
a0f94409 509 (clobber (reg:CC CC_REGNUM))]
b805622c 510 "TARGET_32BIT"
33782ec7 511 "#"
25f905c2 512 "TARGET_32BIT && reload_completed"
a0f94409 513 [(parallel [(set (reg:CC_C CC_REGNUM)
514 (compare:CC_C (plus:SI (match_dup 1) (match_dup 2))
515 (match_dup 1)))
516 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
080c0b9a 517 (set (match_dup 3) (plus:SI (plus:SI (match_dup 4) (const_int 0))
518 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
a0f94409 519 "
520 {
521 operands[3] = gen_highpart (SImode, operands[0]);
522 operands[0] = gen_lowpart (SImode, operands[0]);
523 operands[4] = gen_highpart (SImode, operands[1]);
524 operands[1] = gen_lowpart (SImode, operands[1]);
525 operands[2] = gen_lowpart (SImode, operands[2]);
526 }"
cffb2a26 527 [(set_attr "conds" "clob")
1b7da4ac 528 (set_attr "length" "8")
529 (set_attr "type" "multiple")]
cffb2a26 530)
b11cae9e 531
87b22bf7 532(define_expand "addsi3"
cffb2a26 533 [(set (match_operand:SI 0 "s_register_operand" "")
87b22bf7 534 (plus:SI (match_operand:SI 1 "s_register_operand" "")
535 (match_operand:SI 2 "reg_or_int_operand" "")))]
cffb2a26 536 "TARGET_EITHER"
87b22bf7 537 "
0438d37f 538 if (TARGET_32BIT && CONST_INT_P (operands[2]))
87b22bf7 539 {
96f57e36 540 arm_split_constant (PLUS, SImode, NULL_RTX,
541 INTVAL (operands[2]), operands[0], operands[1],
e1ba4a27 542 optimize && can_create_pseudo_p ());
87b22bf7 543 DONE;
544 }
cffb2a26 545 "
546)
87b22bf7 547
5bd751ff 548; If there is a scratch available, this will be faster than synthesizing the
a0f94409 549; addition.
550(define_peephole2
551 [(match_scratch:SI 3 "r")
372575c7 552 (set (match_operand:SI 0 "arm_general_register_operand" "")
553 (plus:SI (match_operand:SI 1 "arm_general_register_operand" "")
cffb2a26 554 (match_operand:SI 2 "const_int_operand" "")))]
25f905c2 555 "TARGET_32BIT &&
a0f94409 556 !(const_ok_for_arm (INTVAL (operands[2]))
557 || const_ok_for_arm (-INTVAL (operands[2])))
558 && const_ok_for_arm (~INTVAL (operands[2]))"
559 [(set (match_dup 3) (match_dup 2))
560 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 3)))]
561 ""
562)
87b22bf7 563
2f02c19f 564;; The r/r/k alternative is required when reloading the address
565;; (plus (reg rN) (reg sp)) into (reg rN). In this case reload will
566;; put the duplicated register first, and not try the commutative version.
a0f94409 567(define_insn_and_split "*arm_addsi3"
7c36fe71 568 [(set (match_operand:SI 0 "s_register_operand" "=rk,l,l ,l ,r ,k ,r,r ,k ,r ,k,k,r ,k ,r")
569 (plus:SI (match_operand:SI 1 "s_register_operand" "%0 ,l,0 ,l ,rk,k ,r,rk,k ,rk,k,r,rk,k ,rk")
570 (match_operand:SI 2 "reg_or_int_operand" "rk ,l,Py,Pd,rI,rI,k,Pj,Pj,L ,L,L,PJ,PJ,?n")))]
25f905c2 571 "TARGET_32BIT"
5565501b 572 "@
c24d855d 573 add%?\\t%0, %0, %2
5565501b 574 add%?\\t%0, %1, %2
a0b3420a 575 add%?\\t%0, %1, %2
7c36fe71 576 add%?\\t%0, %1, %2
577 add%?\\t%0, %1, %2
aaa37ad6 578 add%?\\t%0, %1, %2
2f02c19f 579 add%?\\t%0, %2, %1
d5cbae34 580 addw%?\\t%0, %1, %2
581 addw%?\\t%0, %1, %2
aaa37ad6 582 sub%?\\t%0, %1, #%n2
87b22bf7 583 sub%?\\t%0, %1, #%n2
d7757711 584 sub%?\\t%0, %1, #%n2
d5cbae34 585 subw%?\\t%0, %1, #%n2
586 subw%?\\t%0, %1, #%n2
87b22bf7 587 #"
a3ffc315 588 "TARGET_32BIT
0438d37f 589 && CONST_INT_P (operands[2])
d5cbae34 590 && !const_ok_for_op (INTVAL (operands[2]), PLUS)
a3ffc315 591 && (reload_completed || !arm_eliminable_register (operands[1]))"
a0f94409 592 [(clobber (const_int 0))]
593 "
96f57e36 594 arm_split_constant (PLUS, SImode, curr_insn,
595 INTVAL (operands[2]), operands[0],
a0f94409 596 operands[1], 0);
597 DONE;
598 "
7c36fe71 599 [(set_attr "length" "2,4,4,4,4,4,4,4,4,4,4,4,4,4,16")
d5cbae34 600 (set_attr "predicable" "yes")
7c36fe71 601 (set_attr "predicable_short_it" "yes,yes,yes,yes,no,no,no,no,no,no,no,no,no,no,no")
602 (set_attr "arch" "t2,t2,t2,t2,*,*,*,t2,t2,*,*,a,t2,t2,*")
65f68e55 603 (set (attr "type") (if_then_else (match_operand 2 "const_int_operand" "")
d82e788e 604 (const_string "alu_imm")
112eda6f 605 (const_string "alu_sreg")))
65f68e55 606 ]
cffb2a26 607)
608
90c2bcf0 609(define_insn "addsi3_compare0"
bd5b4116 610 [(set (reg:CC_NOOV CC_REGNUM)
5565501b 611 (compare:CC_NOOV
65f68e55 612 (plus:SI (match_operand:SI 1 "s_register_operand" "r, r,r")
613 (match_operand:SI 2 "arm_add_operand" "I,L,r"))
5565501b 614 (const_int 0)))
65f68e55 615 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9c08d1fa 616 (plus:SI (match_dup 1) (match_dup 2)))]
ec792a7b 617 "TARGET_ARM"
5565501b 618 "@
25f905c2 619 add%.\\t%0, %1, %2
65f68e55 620 sub%.\\t%0, %1, #%n2
621 add%.\\t%0, %1, %2"
622 [(set_attr "conds" "set")
112eda6f 623 (set_attr "type" "alus_imm,alus_imm,alus_sreg")]
cffb2a26 624)
9c08d1fa 625
aea4c774 626(define_insn "*addsi3_compare0_scratch"
bd5b4116 627 [(set (reg:CC_NOOV CC_REGNUM)
aea4c774 628 (compare:CC_NOOV
65f68e55 629 (plus:SI (match_operand:SI 0 "s_register_operand" "r, r, r")
630 (match_operand:SI 1 "arm_add_operand" "I,L, r"))
aea4c774 631 (const_int 0)))]
ec792a7b 632 "TARGET_ARM"
cffb2a26 633 "@
634 cmn%?\\t%0, %1
65f68e55 635 cmp%?\\t%0, #%n1
636 cmn%?\\t%0, %1"
596e5e8f 637 [(set_attr "conds" "set")
65f68e55 638 (set_attr "predicable" "yes")
112eda6f 639 (set_attr "type" "alus_imm,alus_imm,alus_sreg")]
0d66636f 640)
cffb2a26 641
aed179ae 642(define_insn "*compare_negsi_si"
643 [(set (reg:CC_Z CC_REGNUM)
644 (compare:CC_Z
7c36fe71 645 (neg:SI (match_operand:SI 0 "s_register_operand" "l,r"))
646 (match_operand:SI 1 "s_register_operand" "l,r")))]
25f905c2 647 "TARGET_32BIT"
aed179ae 648 "cmn%?\\t%1, %0"
596e5e8f 649 [(set_attr "conds" "set")
7c36fe71 650 (set_attr "predicable" "yes")
651 (set_attr "arch" "t2,*")
652 (set_attr "length" "2,4")
1b7da4ac 653 (set_attr "predicable_short_it" "yes,no")
112eda6f 654 (set_attr "type" "alus_sreg")]
0d66636f 655)
aea4c774 656
203c488f 657;; This is the canonicalization of addsi3_compare0_for_combiner when the
658;; addend is a constant.
190efb17 659(define_insn "cmpsi2_addneg"
203c488f 660 [(set (reg:CC CC_REGNUM)
661 (compare:CC
662 (match_operand:SI 1 "s_register_operand" "r,r")
2a977b78 663 (match_operand:SI 2 "arm_addimm_operand" "L,I")))
203c488f 664 (set (match_operand:SI 0 "s_register_operand" "=r,r")
665 (plus:SI (match_dup 1)
2a977b78 666 (match_operand:SI 3 "arm_addimm_operand" "I,L")))]
25f905c2 667 "TARGET_32BIT && INTVAL (operands[2]) == -INTVAL (operands[3])"
203c488f 668 "@
2a977b78 669 add%.\\t%0, %1, %3
670 sub%.\\t%0, %1, #%n3"
1b7da4ac 671 [(set_attr "conds" "set")
112eda6f 672 (set_attr "type" "alus_sreg")]
203c488f 673)
674
675;; Convert the sequence
676;; sub rd, rn, #1
677;; cmn rd, #1 (equivalent to cmp rd, #-1)
678;; bne dest
679;; into
680;; subs rd, rn, #1
681;; bcs dest ((unsigned)rn >= 1)
682;; similarly for the beq variant using bcc.
683;; This is a common looping idiom (while (n--))
684(define_peephole2
372575c7 685 [(set (match_operand:SI 0 "arm_general_register_operand" "")
686 (plus:SI (match_operand:SI 1 "arm_general_register_operand" "")
203c488f 687 (const_int -1)))
688 (set (match_operand 2 "cc_register" "")
689 (compare (match_dup 0) (const_int -1)))
690 (set (pc)
691 (if_then_else (match_operator 3 "equality_operator"
692 [(match_dup 2) (const_int 0)])
693 (match_operand 4 "" "")
694 (match_operand 5 "" "")))]
25f905c2 695 "TARGET_32BIT && peep2_reg_dead_p (3, operands[2])"
203c488f 696 [(parallel[
697 (set (match_dup 2)
698 (compare:CC
699 (match_dup 1) (const_int 1)))
700 (set (match_dup 0) (plus:SI (match_dup 1) (const_int -1)))])
701 (set (pc)
702 (if_then_else (match_op_dup 3 [(match_dup 2) (const_int 0)])
703 (match_dup 4)
704 (match_dup 5)))]
705 "operands[2] = gen_rtx_REG (CCmode, CC_REGNUM);
706 operands[3] = gen_rtx_fmt_ee ((GET_CODE (operands[3]) == NE
707 ? GEU : LTU),
708 VOIDmode,
709 operands[2], const0_rtx);"
710)
711
ebcc79bc 712;; The next four insns work because they compare the result with one of
713;; the operands, and we know that the use of the condition code is
714;; either GEU or LTU, so we can use the carry flag from the addition
715;; instead of doing the compare a second time.
716(define_insn "*addsi3_compare_op1"
bd5b4116 717 [(set (reg:CC_C CC_REGNUM)
ebcc79bc 718 (compare:CC_C
65f68e55 719 (plus:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
720 (match_operand:SI 2 "arm_add_operand" "I,L,r"))
ebcc79bc 721 (match_dup 1)))
65f68e55 722 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
ebcc79bc 723 (plus:SI (match_dup 1) (match_dup 2)))]
25f905c2 724 "TARGET_32BIT"
ebcc79bc 725 "@
25f905c2 726 add%.\\t%0, %1, %2
65f68e55 727 sub%.\\t%0, %1, #%n2
728 add%.\\t%0, %1, %2"
729 [(set_attr "conds" "set")
112eda6f 730 (set_attr "type" "alus_imm,alus_imm,alus_sreg")]
0d66636f 731)
ebcc79bc 732
733(define_insn "*addsi3_compare_op2"
bd5b4116 734 [(set (reg:CC_C CC_REGNUM)
ebcc79bc 735 (compare:CC_C
65f68e55 736 (plus:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
737 (match_operand:SI 2 "arm_add_operand" "I,L,r"))
ebcc79bc 738 (match_dup 2)))
65f68e55 739 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9c08d1fa 740 (plus:SI (match_dup 1) (match_dup 2)))]
25f905c2 741 "TARGET_32BIT"
5565501b 742 "@
65f68e55 743 add%.\\t%0, %1, %2
25f905c2 744 add%.\\t%0, %1, %2
745 sub%.\\t%0, %1, #%n2"
65f68e55 746 [(set_attr "conds" "set")
112eda6f 747 (set_attr "type" "alus_imm,alus_imm,alus_sreg")]
0d66636f 748)
9c08d1fa 749
ebcc79bc 750(define_insn "*compare_addsi2_op0"
bd5b4116 751 [(set (reg:CC_C CC_REGNUM)
7c36fe71 752 (compare:CC_C
753 (plus:SI (match_operand:SI 0 "s_register_operand" "l,l,r,r,r")
754 (match_operand:SI 1 "arm_add_operand" "Pv,l,I,L,r"))
755 (match_dup 0)))]
25f905c2 756 "TARGET_32BIT"
ebcc79bc 757 "@
7c36fe71 758 cmp%?\\t%0, #%n1
759 cmn%?\\t%0, %1
ebcc79bc 760 cmn%?\\t%0, %1
65f68e55 761 cmp%?\\t%0, #%n1
762 cmn%?\\t%0, %1"
596e5e8f 763 [(set_attr "conds" "set")
65f68e55 764 (set_attr "predicable" "yes")
7c36fe71 765 (set_attr "arch" "t2,t2,*,*,*")
766 (set_attr "predicable_short_it" "yes,yes,no,no,no")
767 (set_attr "length" "2,2,4,4,4")
112eda6f 768 (set_attr "type" "alus_imm,alus_sreg,alus_imm,alus_imm,alus_sreg")]
0d66636f 769)
ebcc79bc 770
771(define_insn "*compare_addsi2_op1"
bd5b4116 772 [(set (reg:CC_C CC_REGNUM)
7c36fe71 773 (compare:CC_C
774 (plus:SI (match_operand:SI 0 "s_register_operand" "l,l,r,r,r")
775 (match_operand:SI 1 "arm_add_operand" "Pv,l,I,L,r"))
776 (match_dup 1)))]
25f905c2 777 "TARGET_32BIT"
ebcc79bc 778 "@
7c36fe71 779 cmp%?\\t%0, #%n1
780 cmn%?\\t%0, %1
ebcc79bc 781 cmn%?\\t%0, %1
65f68e55 782 cmp%?\\t%0, #%n1
783 cmn%?\\t%0, %1"
596e5e8f 784 [(set_attr "conds" "set")
65f68e55 785 (set_attr "predicable" "yes")
7c36fe71 786 (set_attr "arch" "t2,t2,*,*,*")
787 (set_attr "predicable_short_it" "yes,yes,no,no,no")
788 (set_attr "length" "2,2,4,4,4")
112eda6f 789 (set_attr "type" "alus_imm,alus_sreg,alus_imm,alus_imm,alus_sreg")]
7c36fe71 790 )
ebcc79bc 791
080c0b9a 792(define_insn "*addsi3_carryin_<optab>"
7c36fe71 793 [(set (match_operand:SI 0 "s_register_operand" "=l,r,r")
794 (plus:SI (plus:SI (match_operand:SI 1 "s_register_operand" "%l,r,r")
795 (match_operand:SI 2 "arm_not_operand" "0,rI,K"))
796 (LTUGEU:SI (reg:<cnb> CC_REGNUM) (const_int 0))))]
25f905c2 797 "TARGET_32BIT"
10e5ccd5 798 "@
a0b3420a 799 adc%?\\t%0, %1, %2
10e5ccd5 800 adc%?\\t%0, %1, %2
801 sbc%?\\t%0, %1, #%B2"
a7de272d 802 [(set_attr "conds" "use")
7c36fe71 803 (set_attr "predicable" "yes")
804 (set_attr "arch" "t2,*,*")
805 (set_attr "length" "4")
1b7da4ac 806 (set_attr "predicable_short_it" "yes,no,no")
807 (set_attr "type" "adc_reg,adc_reg,adc_imm")]
cffb2a26 808)
ebcc79bc 809
080c0b9a 810(define_insn "*addsi3_carryin_alt2_<optab>"
7c36fe71 811 [(set (match_operand:SI 0 "s_register_operand" "=l,r,r")
812 (plus:SI (plus:SI (LTUGEU:SI (reg:<cnb> CC_REGNUM) (const_int 0))
813 (match_operand:SI 1 "s_register_operand" "%l,r,r"))
814 (match_operand:SI 2 "arm_rhs_operand" "l,rI,K")))]
25f905c2 815 "TARGET_32BIT"
10e5ccd5 816 "@
a0b3420a 817 adc%?\\t%0, %1, %2
10e5ccd5 818 adc%?\\t%0, %1, %2
819 sbc%?\\t%0, %1, #%B2"
a7de272d 820 [(set_attr "conds" "use")
7c36fe71 821 (set_attr "predicable" "yes")
822 (set_attr "arch" "t2,*,*")
823 (set_attr "length" "4")
1b7da4ac 824 (set_attr "predicable_short_it" "yes,no,no")
825 (set_attr "type" "adc_reg,adc_reg,adc_imm")]
0d66636f 826)
ebcc79bc 827
080c0b9a 828(define_insn "*addsi3_carryin_shift_<optab>"
ebcc79bc 829 [(set (match_operand:SI 0 "s_register_operand" "=r")
080c0b9a 830 (plus:SI (plus:SI
831 (match_operator:SI 2 "shift_operator"
832 [(match_operand:SI 3 "s_register_operand" "r")
833 (match_operand:SI 4 "reg_or_int_operand" "rM")])
834 (match_operand:SI 1 "s_register_operand" "r"))
835 (LTUGEU:SI (reg:<cnb> CC_REGNUM) (const_int 0))))]
25f905c2 836 "TARGET_32BIT"
080c0b9a 837 "adc%?\\t%0, %1, %3%S2"
838 [(set_attr "conds" "use")
a7de272d 839 (set_attr "predicable" "yes")
7c36fe71 840 (set_attr "predicable_short_it" "no")
080c0b9a 841 (set (attr "type") (if_then_else (match_operand 4 "const_int_operand" "")
d82e788e 842 (const_string "alu_shift_imm")
843 (const_string "alu_shift_reg")))]
cffb2a26 844)
ebcc79bc 845
922b6913 846(define_insn "*addsi3_carryin_clobercc_<optab>"
847 [(set (match_operand:SI 0 "s_register_operand" "=r")
848 (plus:SI (plus:SI (match_operand:SI 1 "s_register_operand" "%r")
849 (match_operand:SI 2 "arm_rhs_operand" "rI"))
850 (LTUGEU:SI (reg:<cnb> CC_REGNUM) (const_int 0))))
851 (clobber (reg:CC CC_REGNUM))]
852 "TARGET_32BIT"
853 "adc%.\\t%0, %1, %2"
1b7da4ac 854 [(set_attr "conds" "set")
855 (set_attr "type" "adcs_reg")]
922b6913 856)
857
9154bd82 858(define_insn "*subsi3_carryin"
859 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
860 (minus:SI (minus:SI (match_operand:SI 1 "reg_or_int_operand" "r,I")
861 (match_operand:SI 2 "s_register_operand" "r,r"))
862 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
863 "TARGET_32BIT"
864 "@
865 sbc%?\\t%0, %1, %2
866 rsc%?\\t%0, %2, %1"
867 [(set_attr "conds" "use")
868 (set_attr "arch" "*,a")
7c36fe71 869 (set_attr "predicable" "yes")
1b7da4ac 870 (set_attr "predicable_short_it" "no")
871 (set_attr "type" "adc_reg,adc_imm")]
9154bd82 872)
873
874(define_insn "*subsi3_carryin_const"
875 [(set (match_operand:SI 0 "s_register_operand" "=r")
876 (minus:SI (plus:SI (match_operand:SI 1 "reg_or_int_operand" "r")
877 (match_operand:SI 2 "arm_not_operand" "K"))
878 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
879 "TARGET_32BIT"
880 "sbc\\t%0, %1, #%B2"
1b7da4ac 881 [(set_attr "conds" "use")
882 (set_attr "type" "adc_imm")]
9154bd82 883)
884
885(define_insn "*subsi3_carryin_compare"
886 [(set (reg:CC CC_REGNUM)
887 (compare:CC (match_operand:SI 1 "s_register_operand" "r")
888 (match_operand:SI 2 "s_register_operand" "r")))
889 (set (match_operand:SI 0 "s_register_operand" "=r")
890 (minus:SI (minus:SI (match_dup 1)
891 (match_dup 2))
892 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
893 "TARGET_32BIT"
894 "sbcs\\t%0, %1, %2"
1b7da4ac 895 [(set_attr "conds" "set")
896 (set_attr "type" "adcs_reg")]
9154bd82 897)
898
899(define_insn "*subsi3_carryin_compare_const"
900 [(set (reg:CC CC_REGNUM)
901 (compare:CC (match_operand:SI 1 "reg_or_int_operand" "r")
902 (match_operand:SI 2 "arm_not_operand" "K")))
903 (set (match_operand:SI 0 "s_register_operand" "=r")
904 (minus:SI (plus:SI (match_dup 1)
905 (match_dup 2))
906 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
907 "TARGET_32BIT"
908 "sbcs\\t%0, %1, #%B2"
1b7da4ac 909 [(set_attr "conds" "set")
910 (set_attr "type" "adcs_imm")]
9154bd82 911)
912
913(define_insn "*subsi3_carryin_shift"
914 [(set (match_operand:SI 0 "s_register_operand" "=r")
915 (minus:SI (minus:SI
916 (match_operand:SI 1 "s_register_operand" "r")
917 (match_operator:SI 2 "shift_operator"
918 [(match_operand:SI 3 "s_register_operand" "r")
919 (match_operand:SI 4 "reg_or_int_operand" "rM")]))
920 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
921 "TARGET_32BIT"
922 "sbc%?\\t%0, %1, %3%S2"
923 [(set_attr "conds" "use")
924 (set_attr "predicable" "yes")
925 (set (attr "type") (if_then_else (match_operand 4 "const_int_operand" "")
d82e788e 926 (const_string "alu_shift_imm")
927 (const_string "alu_shift_reg")))]
9154bd82 928)
929
930(define_insn "*rsbsi3_carryin_shift"
931 [(set (match_operand:SI 0 "s_register_operand" "=r")
932 (minus:SI (minus:SI
933 (match_operator:SI 2 "shift_operator"
934 [(match_operand:SI 3 "s_register_operand" "r")
935 (match_operand:SI 4 "reg_or_int_operand" "rM")])
936 (match_operand:SI 1 "s_register_operand" "r"))
937 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
938 "TARGET_ARM"
939 "rsc%?\\t%0, %1, %3%S2"
940 [(set_attr "conds" "use")
941 (set_attr "predicable" "yes")
942 (set (attr "type") (if_then_else (match_operand 4 "const_int_operand" "")
d82e788e 943 (const_string "alu_shift_imm")
944 (const_string "alu_shift_reg")))]
9154bd82 945)
946
d795fb69 947; transform ((x << y) - 1) to ~(~(x-1) << y) Where X is a constant.
948(define_split
949 [(set (match_operand:SI 0 "s_register_operand" "")
950 (plus:SI (ashift:SI (match_operand:SI 1 "const_int_operand" "")
951 (match_operand:SI 2 "s_register_operand" ""))
952 (const_int -1)))
953 (clobber (match_operand:SI 3 "s_register_operand" ""))]
25f905c2 954 "TARGET_32BIT"
d795fb69 955 [(set (match_dup 3) (match_dup 1))
956 (set (match_dup 0) (not:SI (ashift:SI (match_dup 3) (match_dup 2))))]
957 "
958 operands[1] = GEN_INT (~(INTVAL (operands[1]) - 1));
959")
960
604f3a0a 961(define_expand "addsf3"
962 [(set (match_operand:SF 0 "s_register_operand" "")
963 (plus:SF (match_operand:SF 1 "s_register_operand" "")
d86c91f6 964 (match_operand:SF 2 "s_register_operand" "")))]
25f905c2 965 "TARGET_32BIT && TARGET_HARD_FLOAT"
604f3a0a 966 "
604f3a0a 967")
968
604f3a0a 969(define_expand "adddf3"
970 [(set (match_operand:DF 0 "s_register_operand" "")
971 (plus:DF (match_operand:DF 1 "s_register_operand" "")
d86c91f6 972 (match_operand:DF 2 "s_register_operand" "")))]
a50d7267 973 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
604f3a0a 974 "
604f3a0a 975")
976
cffb2a26 977(define_expand "subdi3"
978 [(parallel
979 [(set (match_operand:DI 0 "s_register_operand" "")
980 (minus:DI (match_operand:DI 1 "s_register_operand" "")
981 (match_operand:DI 2 "s_register_operand" "")))
bd5b4116 982 (clobber (reg:CC CC_REGNUM))])]
cffb2a26 983 "TARGET_EITHER"
984 "
25f905c2 985 if (TARGET_THUMB1)
cffb2a26 986 {
0438d37f 987 if (!REG_P (operands[1]))
5aa8c5f0 988 operands[1] = force_reg (DImode, operands[1]);
0438d37f 989 if (!REG_P (operands[2]))
5aa8c5f0 990 operands[2] = force_reg (DImode, operands[2]);
cffb2a26 991 }
992 "
993)
994
2f9b23e3 995(define_insn_and_split "*arm_subdi3"
cffb2a26 996 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r,&r")
9c08d1fa 997 (minus:DI (match_operand:DI 1 "s_register_operand" "0,r,0")
998 (match_operand:DI 2 "s_register_operand" "r,0,0")))
bd5b4116 999 (clobber (reg:CC CC_REGNUM))]
94829feb 1000 "TARGET_32BIT && !TARGET_NEON"
2f9b23e3 1001 "#" ; "subs\\t%Q0, %Q1, %Q2\;sbc\\t%R0, %R1, %R2"
1002 "&& reload_completed"
1003 [(parallel [(set (reg:CC CC_REGNUM)
1004 (compare:CC (match_dup 1) (match_dup 2)))
1005 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
1006 (set (match_dup 3) (minus:SI (minus:SI (match_dup 4) (match_dup 5))
1007 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1008 {
1009 operands[3] = gen_highpart (SImode, operands[0]);
1010 operands[0] = gen_lowpart (SImode, operands[0]);
1011 operands[4] = gen_highpart (SImode, operands[1]);
1012 operands[1] = gen_lowpart (SImode, operands[1]);
1013 operands[5] = gen_highpart (SImode, operands[2]);
1014 operands[2] = gen_lowpart (SImode, operands[2]);
1015 }
cffb2a26 1016 [(set_attr "conds" "clob")
1b7da4ac 1017 (set_attr "length" "8")
1018 (set_attr "type" "multiple")]
cffb2a26 1019)
1020
2f9b23e3 1021(define_insn_and_split "*subdi_di_zesidi"
cffb2a26 1022 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
e5fea38e 1023 (minus:DI (match_operand:DI 1 "s_register_operand" "0,r")
9c08d1fa 1024 (zero_extend:DI
cffb2a26 1025 (match_operand:SI 2 "s_register_operand" "r,r"))))
bd5b4116 1026 (clobber (reg:CC CC_REGNUM))]
25f905c2 1027 "TARGET_32BIT"
2f9b23e3 1028 "#" ; "subs\\t%Q0, %Q1, %2\;sbc\\t%R0, %R1, #0"
1029 "&& reload_completed"
1030 [(parallel [(set (reg:CC CC_REGNUM)
1031 (compare:CC (match_dup 1) (match_dup 2)))
1032 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
1033 (set (match_dup 3) (minus:SI (plus:SI (match_dup 4) (match_dup 5))
1034 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1035 {
1036 operands[3] = gen_highpart (SImode, operands[0]);
1037 operands[0] = gen_lowpart (SImode, operands[0]);
1038 operands[4] = gen_highpart (SImode, operands[1]);
1039 operands[1] = gen_lowpart (SImode, operands[1]);
1040 operands[5] = GEN_INT (~0);
1041 }
cffb2a26 1042 [(set_attr "conds" "clob")
1b7da4ac 1043 (set_attr "length" "8")
1044 (set_attr "type" "multiple")]
cffb2a26 1045)
9c08d1fa 1046
2f9b23e3 1047(define_insn_and_split "*subdi_di_sesidi"
cffb2a26 1048 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
e5fea38e 1049 (minus:DI (match_operand:DI 1 "s_register_operand" "0,r")
9c08d1fa 1050 (sign_extend:DI
cffb2a26 1051 (match_operand:SI 2 "s_register_operand" "r,r"))))
bd5b4116 1052 (clobber (reg:CC CC_REGNUM))]
25f905c2 1053 "TARGET_32BIT"
2f9b23e3 1054 "#" ; "subs\\t%Q0, %Q1, %2\;sbc\\t%R0, %R1, %2, asr #31"
1055 "&& reload_completed"
1056 [(parallel [(set (reg:CC CC_REGNUM)
1057 (compare:CC (match_dup 1) (match_dup 2)))
1058 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
1059 (set (match_dup 3) (minus:SI (minus:SI (match_dup 4)
1060 (ashiftrt:SI (match_dup 2)
1061 (const_int 31)))
1062 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1063 {
1064 operands[3] = gen_highpart (SImode, operands[0]);
1065 operands[0] = gen_lowpart (SImode, operands[0]);
1066 operands[4] = gen_highpart (SImode, operands[1]);
1067 operands[1] = gen_lowpart (SImode, operands[1]);
1068 }
cffb2a26 1069 [(set_attr "conds" "clob")
1b7da4ac 1070 (set_attr "length" "8")
1071 (set_attr "type" "multiple")]
cffb2a26 1072)
9c08d1fa 1073
2f9b23e3 1074(define_insn_and_split "*subdi_zesidi_di"
cffb2a26 1075 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
9c08d1fa 1076 (minus:DI (zero_extend:DI
cffb2a26 1077 (match_operand:SI 2 "s_register_operand" "r,r"))
e5fea38e 1078 (match_operand:DI 1 "s_register_operand" "0,r")))
bd5b4116 1079 (clobber (reg:CC CC_REGNUM))]
cffb2a26 1080 "TARGET_ARM"
2f9b23e3 1081 "#" ; "rsbs\\t%Q0, %Q1, %2\;rsc\\t%R0, %R1, #0"
1082 ; is equivalent to:
1083 ; "subs\\t%Q0, %2, %Q1\;rsc\\t%R0, %R1, #0"
1084 "&& reload_completed"
1085 [(parallel [(set (reg:CC CC_REGNUM)
1086 (compare:CC (match_dup 2) (match_dup 1)))
1087 (set (match_dup 0) (minus:SI (match_dup 2) (match_dup 1)))])
1088 (set (match_dup 3) (minus:SI (minus:SI (const_int 0) (match_dup 4))
1089 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1090 {
1091 operands[3] = gen_highpart (SImode, operands[0]);
1092 operands[0] = gen_lowpart (SImode, operands[0]);
1093 operands[4] = gen_highpart (SImode, operands[1]);
1094 operands[1] = gen_lowpart (SImode, operands[1]);
1095 }
cffb2a26 1096 [(set_attr "conds" "clob")
1b7da4ac 1097 (set_attr "length" "8")
1098 (set_attr "type" "multiple")]
cffb2a26 1099)
9c08d1fa 1100
2f9b23e3 1101(define_insn_and_split "*subdi_sesidi_di"
cffb2a26 1102 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
9c08d1fa 1103 (minus:DI (sign_extend:DI
cffb2a26 1104 (match_operand:SI 2 "s_register_operand" "r,r"))
e5fea38e 1105 (match_operand:DI 1 "s_register_operand" "0,r")))
bd5b4116 1106 (clobber (reg:CC CC_REGNUM))]
cffb2a26 1107 "TARGET_ARM"
2f9b23e3 1108 "#" ; "rsbs\\t%Q0, %Q1, %2\;rsc\\t%R0, %R1, %2, asr #31"
1109 ; is equivalent to:
1110 ; "subs\\t%Q0, %2, %Q1\;rsc\\t%R0, %R1, %2, asr #31"
1111 "&& reload_completed"
1112 [(parallel [(set (reg:CC CC_REGNUM)
1113 (compare:CC (match_dup 2) (match_dup 1)))
1114 (set (match_dup 0) (minus:SI (match_dup 2) (match_dup 1)))])
1115 (set (match_dup 3) (minus:SI (minus:SI
1116 (ashiftrt:SI (match_dup 2)
1117 (const_int 31))
1118 (match_dup 4))
1119 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1120 {
1121 operands[3] = gen_highpart (SImode, operands[0]);
1122 operands[0] = gen_lowpart (SImode, operands[0]);
1123 operands[4] = gen_highpart (SImode, operands[1]);
1124 operands[1] = gen_lowpart (SImode, operands[1]);
1125 }
cffb2a26 1126 [(set_attr "conds" "clob")
1b7da4ac 1127 (set_attr "length" "8")
1128 (set_attr "type" "multiple")]
cffb2a26 1129)
9c08d1fa 1130
2f9b23e3 1131(define_insn_and_split "*subdi_zesidi_zesidi"
cffb2a26 1132 [(set (match_operand:DI 0 "s_register_operand" "=r")
9c08d1fa 1133 (minus:DI (zero_extend:DI
cffb2a26 1134 (match_operand:SI 1 "s_register_operand" "r"))
9c08d1fa 1135 (zero_extend:DI
cffb2a26 1136 (match_operand:SI 2 "s_register_operand" "r"))))
bd5b4116 1137 (clobber (reg:CC CC_REGNUM))]
25f905c2 1138 "TARGET_32BIT"
2f9b23e3 1139 "#" ; "subs\\t%Q0, %1, %2\;sbc\\t%R0, %1, %1"
1140 "&& reload_completed"
1141 [(parallel [(set (reg:CC CC_REGNUM)
1142 (compare:CC (match_dup 1) (match_dup 2)))
1143 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
1144 (set (match_dup 3) (minus:SI (minus:SI (match_dup 1) (match_dup 1))
1145 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1146 {
1147 operands[3] = gen_highpart (SImode, operands[0]);
1148 operands[0] = gen_lowpart (SImode, operands[0]);
1149 }
cffb2a26 1150 [(set_attr "conds" "clob")
1b7da4ac 1151 (set_attr "length" "8")
1152 (set_attr "type" "multiple")]
cffb2a26 1153)
b11cae9e 1154
87b22bf7 1155(define_expand "subsi3"
cffb2a26 1156 [(set (match_operand:SI 0 "s_register_operand" "")
87b22bf7 1157 (minus:SI (match_operand:SI 1 "reg_or_int_operand" "")
1158 (match_operand:SI 2 "s_register_operand" "")))]
cffb2a26 1159 "TARGET_EITHER"
87b22bf7 1160 "
0438d37f 1161 if (CONST_INT_P (operands[1]))
87b22bf7 1162 {
25f905c2 1163 if (TARGET_32BIT)
cffb2a26 1164 {
96f57e36 1165 arm_split_constant (MINUS, SImode, NULL_RTX,
1166 INTVAL (operands[1]), operands[0],
e1ba4a27 1167 operands[2], optimize && can_create_pseudo_p ());
cffb2a26 1168 DONE;
1169 }
25f905c2 1170 else /* TARGET_THUMB1 */
cffb2a26 1171 operands[1] = force_reg (SImode, operands[1]);
87b22bf7 1172 }
cffb2a26 1173 "
1174)
87b22bf7 1175
25f905c2 1176; ??? Check Thumb-2 split length
a0f94409 1177(define_insn_and_split "*arm_subsi3_insn"
7c36fe71 1178 [(set (match_operand:SI 0 "s_register_operand" "=l,l ,l ,l ,r ,r,r,rk,r")
1179 (minus:SI (match_operand:SI 1 "reg_or_int_operand" "l ,0 ,l ,Pz,rI,r,r,k ,?n")
1180 (match_operand:SI 2 "reg_or_int_operand" "l ,Py,Pd,l ,r ,I,r,r ,r")))]
25f905c2 1181 "TARGET_32BIT"
e2348bcb 1182 "@
7c36fe71 1183 sub%?\\t%0, %1, %2
1184 sub%?\\t%0, %2
1185 sub%?\\t%0, %1, %2
1186 rsb%?\\t%0, %2, %1
87b22bf7 1187 rsb%?\\t%0, %2, %1
aaa37ad6 1188 sub%?\\t%0, %1, %2
080c0b9a 1189 sub%?\\t%0, %1, %2
65f68e55 1190 sub%?\\t%0, %1, %2
87b22bf7 1191 #"
0438d37f 1192 "&& (CONST_INT_P (operands[1])
91a5e339 1193 && !const_ok_for_arm (INTVAL (operands[1])))"
87b22bf7 1194 [(clobber (const_int 0))]
1195 "
96f57e36 1196 arm_split_constant (MINUS, SImode, curr_insn,
1197 INTVAL (operands[1]), operands[0], operands[2], 0);
87b22bf7 1198 DONE;
cffb2a26 1199 "
7c36fe71 1200 [(set_attr "length" "4,4,4,4,4,4,4,4,16")
1201 (set_attr "arch" "t2,t2,t2,t2,*,*,*,*,*")
65f68e55 1202 (set_attr "predicable" "yes")
7c36fe71 1203 (set_attr "predicable_short_it" "yes,yes,yes,yes,no,no,no,no,no")
112eda6f 1204 (set_attr "type" "alu_sreg,alu_sreg,alu_sreg,alu_sreg,alu_imm,alu_imm,alu_sreg,alu_sreg,multiple")]
a0f94409 1205)
1206
1207(define_peephole2
1208 [(match_scratch:SI 3 "r")
372575c7 1209 (set (match_operand:SI 0 "arm_general_register_operand" "")
a0f94409 1210 (minus:SI (match_operand:SI 1 "const_int_operand" "")
372575c7 1211 (match_operand:SI 2 "arm_general_register_operand" "")))]
25f905c2 1212 "TARGET_32BIT
a0f94409 1213 && !const_ok_for_arm (INTVAL (operands[1]))
1214 && const_ok_for_arm (~INTVAL (operands[1]))"
1215 [(set (match_dup 3) (match_dup 1))
1216 (set (match_dup 0) (minus:SI (match_dup 3) (match_dup 2)))]
1217 ""
cffb2a26 1218)
b11cae9e 1219
f7fbdd4a 1220(define_insn "*subsi3_compare0"
bd5b4116 1221 [(set (reg:CC_NOOV CC_REGNUM)
215b30b3 1222 (compare:CC_NOOV
65f68e55 1223 (minus:SI (match_operand:SI 1 "arm_rhs_operand" "r,r,I")
1224 (match_operand:SI 2 "arm_rhs_operand" "I,r,r"))
215b30b3 1225 (const_int 0)))
65f68e55 1226 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9c08d1fa 1227 (minus:SI (match_dup 1) (match_dup 2)))]
25f905c2 1228 "TARGET_32BIT"
e2348bcb 1229 "@
65f68e55 1230 sub%.\\t%0, %1, %2
25f905c2 1231 sub%.\\t%0, %1, %2
1232 rsb%.\\t%0, %2, %1"
65f68e55 1233 [(set_attr "conds" "set")
112eda6f 1234 (set_attr "type" "alus_imm,alus_sreg,alus_sreg")]
cffb2a26 1235)
9c08d1fa 1236
190efb17 1237(define_insn "subsi3_compare"
080c0b9a 1238 [(set (reg:CC CC_REGNUM)
65f68e55 1239 (compare:CC (match_operand:SI 1 "arm_rhs_operand" "r,r,I")
1240 (match_operand:SI 2 "arm_rhs_operand" "I,r,r")))
1241 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
2df9477b 1242 (minus:SI (match_dup 1) (match_dup 2)))]
1243 "TARGET_32BIT"
1244 "@
65f68e55 1245 sub%.\\t%0, %1, %2
2df9477b 1246 sub%.\\t%0, %1, %2
1247 rsb%.\\t%0, %2, %1"
65f68e55 1248 [(set_attr "conds" "set")
112eda6f 1249 (set_attr "type" "alus_imm,alus_sreg,alus_sreg")]
2df9477b 1250)
1251
604f3a0a 1252(define_expand "subsf3"
1253 [(set (match_operand:SF 0 "s_register_operand" "")
d86c91f6 1254 (minus:SF (match_operand:SF 1 "s_register_operand" "")
1255 (match_operand:SF 2 "s_register_operand" "")))]
25f905c2 1256 "TARGET_32BIT && TARGET_HARD_FLOAT"
604f3a0a 1257 "
604f3a0a 1258")
1259
604f3a0a 1260(define_expand "subdf3"
1261 [(set (match_operand:DF 0 "s_register_operand" "")
d86c91f6 1262 (minus:DF (match_operand:DF 1 "s_register_operand" "")
1263 (match_operand:DF 2 "s_register_operand" "")))]
a50d7267 1264 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
604f3a0a 1265 "
604f3a0a 1266")
1267
b11cae9e 1268\f
1269;; Multiplication insns
1270
4422d91f 1271(define_expand "mulhi3"
1272 [(set (match_operand:HI 0 "s_register_operand" "")
1273 (mult:HI (match_operand:HI 1 "s_register_operand" "")
1274 (match_operand:HI 2 "s_register_operand" "")))]
1275 "TARGET_DSP_MULTIPLY"
1276 "
1277 {
1278 rtx result = gen_reg_rtx (SImode);
1279 emit_insn (gen_mulhisi3 (result, operands[1], operands[2]));
1280 emit_move_insn (operands[0], gen_lowpart (HImode, result));
1281 DONE;
1282 }"
1283)
1284
cffb2a26 1285(define_expand "mulsi3"
1286 [(set (match_operand:SI 0 "s_register_operand" "")
1287 (mult:SI (match_operand:SI 2 "s_register_operand" "")
1288 (match_operand:SI 1 "s_register_operand" "")))]
1289 "TARGET_EITHER"
1290 ""
1291)
1292
9c08d1fa 1293;; Use `&' and then `0' to prevent the operands 0 and 1 being the same
cffb2a26 1294(define_insn "*arm_mulsi3"
1295 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r")
9c08d1fa 1296 (mult:SI (match_operand:SI 2 "s_register_operand" "r,r")
e5fea38e 1297 (match_operand:SI 1 "s_register_operand" "%0,r")))]
58d7d654 1298 "TARGET_32BIT && !arm_arch6"
f7fbdd4a 1299 "mul%?\\t%0, %2, %1"
9da0ec36 1300 [(set_attr "type" "mul")
0d66636f 1301 (set_attr "predicable" "yes")]
cffb2a26 1302)
1303
58d7d654 1304(define_insn "*arm_mulsi3_v6"
d952d547 1305 [(set (match_operand:SI 0 "s_register_operand" "=l,l,r")
1306 (mult:SI (match_operand:SI 1 "s_register_operand" "0,l,r")
1307 (match_operand:SI 2 "s_register_operand" "l,0,r")))]
58d7d654 1308 "TARGET_32BIT && arm_arch6"
1309 "mul%?\\t%0, %1, %2"
9da0ec36 1310 [(set_attr "type" "mul")
d952d547 1311 (set_attr "predicable" "yes")
1312 (set_attr "arch" "t2,t2,*")
1313 (set_attr "length" "4")
1314 (set_attr "predicable_short_it" "yes,yes,no")]
58d7d654 1315)
1316
f7fbdd4a 1317(define_insn "*mulsi3_compare0"
bd5b4116 1318 [(set (reg:CC_NOOV CC_REGNUM)
9c08d1fa 1319 (compare:CC_NOOV (mult:SI
1320 (match_operand:SI 2 "s_register_operand" "r,r")
e5fea38e 1321 (match_operand:SI 1 "s_register_operand" "%0,r"))
9c08d1fa 1322 (const_int 0)))
1323 (set (match_operand:SI 0 "s_register_operand" "=&r,&r")
1324 (mult:SI (match_dup 2) (match_dup 1)))]
58d7d654 1325 "TARGET_ARM && !arm_arch6"
1326 "mul%.\\t%0, %2, %1"
1327 [(set_attr "conds" "set")
9da0ec36 1328 (set_attr "type" "muls")]
58d7d654 1329)
1330
1331(define_insn "*mulsi3_compare0_v6"
1332 [(set (reg:CC_NOOV CC_REGNUM)
1333 (compare:CC_NOOV (mult:SI
1334 (match_operand:SI 2 "s_register_operand" "r")
1335 (match_operand:SI 1 "s_register_operand" "r"))
1336 (const_int 0)))
1337 (set (match_operand:SI 0 "s_register_operand" "=r")
1338 (mult:SI (match_dup 2) (match_dup 1)))]
1339 "TARGET_ARM && arm_arch6 && optimize_size"
25f905c2 1340 "mul%.\\t%0, %2, %1"
cffb2a26 1341 [(set_attr "conds" "set")
9da0ec36 1342 (set_attr "type" "muls")]
cffb2a26 1343)
9c08d1fa 1344
f7fbdd4a 1345(define_insn "*mulsi_compare0_scratch"
bd5b4116 1346 [(set (reg:CC_NOOV CC_REGNUM)
9c08d1fa 1347 (compare:CC_NOOV (mult:SI
1348 (match_operand:SI 2 "s_register_operand" "r,r")
e5fea38e 1349 (match_operand:SI 1 "s_register_operand" "%0,r"))
9c08d1fa 1350 (const_int 0)))
1351 (clobber (match_scratch:SI 0 "=&r,&r"))]
58d7d654 1352 "TARGET_ARM && !arm_arch6"
1353 "mul%.\\t%0, %2, %1"
1354 [(set_attr "conds" "set")
9da0ec36 1355 (set_attr "type" "muls")]
58d7d654 1356)
1357
1358(define_insn "*mulsi_compare0_scratch_v6"
1359 [(set (reg:CC_NOOV CC_REGNUM)
1360 (compare:CC_NOOV (mult:SI
1361 (match_operand:SI 2 "s_register_operand" "r")
1362 (match_operand:SI 1 "s_register_operand" "r"))
1363 (const_int 0)))
1364 (clobber (match_scratch:SI 0 "=r"))]
1365 "TARGET_ARM && arm_arch6 && optimize_size"
25f905c2 1366 "mul%.\\t%0, %2, %1"
cffb2a26 1367 [(set_attr "conds" "set")
9da0ec36 1368 (set_attr "type" "muls")]
cffb2a26 1369)
9c08d1fa 1370
b11cae9e 1371;; Unnamed templates to match MLA instruction.
1372
f7fbdd4a 1373(define_insn "*mulsi3addsi"
9c08d1fa 1374 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r,&r")
c8f69309 1375 (plus:SI
9c08d1fa 1376 (mult:SI (match_operand:SI 2 "s_register_operand" "r,r,r,r")
e5fea38e 1377 (match_operand:SI 1 "s_register_operand" "%0,r,0,r"))
1378 (match_operand:SI 3 "s_register_operand" "r,r,0,0")))]
58d7d654 1379 "TARGET_32BIT && !arm_arch6"
1380 "mla%?\\t%0, %2, %1, %3"
9da0ec36 1381 [(set_attr "type" "mla")
58d7d654 1382 (set_attr "predicable" "yes")]
1383)
1384
1385(define_insn "*mulsi3addsi_v6"
1386 [(set (match_operand:SI 0 "s_register_operand" "=r")
1387 (plus:SI
1388 (mult:SI (match_operand:SI 2 "s_register_operand" "r")
1389 (match_operand:SI 1 "s_register_operand" "r"))
1390 (match_operand:SI 3 "s_register_operand" "r")))]
1391 "TARGET_32BIT && arm_arch6"
f7fbdd4a 1392 "mla%?\\t%0, %2, %1, %3"
9da0ec36 1393 [(set_attr "type" "mla")
d952d547 1394 (set_attr "predicable" "yes")
1395 (set_attr "predicable_short_it" "no")]
0d66636f 1396)
b11cae9e 1397
f7fbdd4a 1398(define_insn "*mulsi3addsi_compare0"
bd5b4116 1399 [(set (reg:CC_NOOV CC_REGNUM)
215b30b3 1400 (compare:CC_NOOV
1401 (plus:SI (mult:SI
1402 (match_operand:SI 2 "s_register_operand" "r,r,r,r")
e5fea38e 1403 (match_operand:SI 1 "s_register_operand" "%0,r,0,r"))
1404 (match_operand:SI 3 "s_register_operand" "r,r,0,0"))
215b30b3 1405 (const_int 0)))
9c08d1fa 1406 (set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r,&r")
1407 (plus:SI (mult:SI (match_dup 2) (match_dup 1))
1408 (match_dup 3)))]
58d7d654 1409 "TARGET_ARM && arm_arch6"
1410 "mla%.\\t%0, %2, %1, %3"
1411 [(set_attr "conds" "set")
9da0ec36 1412 (set_attr "type" "mlas")]
58d7d654 1413)
1414
1415(define_insn "*mulsi3addsi_compare0_v6"
1416 [(set (reg:CC_NOOV CC_REGNUM)
1417 (compare:CC_NOOV
1418 (plus:SI (mult:SI
1419 (match_operand:SI 2 "s_register_operand" "r")
1420 (match_operand:SI 1 "s_register_operand" "r"))
1421 (match_operand:SI 3 "s_register_operand" "r"))
1422 (const_int 0)))
1423 (set (match_operand:SI 0 "s_register_operand" "=r")
1424 (plus:SI (mult:SI (match_dup 2) (match_dup 1))
1425 (match_dup 3)))]
1426 "TARGET_ARM && arm_arch6 && optimize_size"
25f905c2 1427 "mla%.\\t%0, %2, %1, %3"
0d66636f 1428 [(set_attr "conds" "set")
9da0ec36 1429 (set_attr "type" "mlas")]
0d66636f 1430)
9c08d1fa 1431
f7fbdd4a 1432(define_insn "*mulsi3addsi_compare0_scratch"
bd5b4116 1433 [(set (reg:CC_NOOV CC_REGNUM)
215b30b3 1434 (compare:CC_NOOV
1435 (plus:SI (mult:SI
1436 (match_operand:SI 2 "s_register_operand" "r,r,r,r")
e5fea38e 1437 (match_operand:SI 1 "s_register_operand" "%0,r,0,r"))
215b30b3 1438 (match_operand:SI 3 "s_register_operand" "?r,r,0,0"))
1439 (const_int 0)))
9c08d1fa 1440 (clobber (match_scratch:SI 0 "=&r,&r,&r,&r"))]
58d7d654 1441 "TARGET_ARM && !arm_arch6"
1442 "mla%.\\t%0, %2, %1, %3"
1443 [(set_attr "conds" "set")
9da0ec36 1444 (set_attr "type" "mlas")]
58d7d654 1445)
1446
1447(define_insn "*mulsi3addsi_compare0_scratch_v6"
1448 [(set (reg:CC_NOOV CC_REGNUM)
1449 (compare:CC_NOOV
1450 (plus:SI (mult:SI
1451 (match_operand:SI 2 "s_register_operand" "r")
1452 (match_operand:SI 1 "s_register_operand" "r"))
1453 (match_operand:SI 3 "s_register_operand" "r"))
1454 (const_int 0)))
1455 (clobber (match_scratch:SI 0 "=r"))]
1456 "TARGET_ARM && arm_arch6 && optimize_size"
25f905c2 1457 "mla%.\\t%0, %2, %1, %3"
cffb2a26 1458 [(set_attr "conds" "set")
9da0ec36 1459 (set_attr "type" "mlas")]
cffb2a26 1460)
f7fbdd4a 1461
89545238 1462(define_insn "*mulsi3subsi"
1463 [(set (match_operand:SI 0 "s_register_operand" "=r")
1464 (minus:SI
1465 (match_operand:SI 3 "s_register_operand" "r")
1466 (mult:SI (match_operand:SI 2 "s_register_operand" "r")
1467 (match_operand:SI 1 "s_register_operand" "r"))))]
1468 "TARGET_32BIT && arm_arch_thumb2"
1469 "mls%?\\t%0, %2, %1, %3"
9da0ec36 1470 [(set_attr "type" "mla")
d952d547 1471 (set_attr "predicable" "yes")
1472 (set_attr "predicable_short_it" "no")]
89545238 1473)
1474
5cdca009 1475(define_expand "maddsidi4"
1476 [(set (match_operand:DI 0 "s_register_operand" "")
1477 (plus:DI
1478 (mult:DI
1479 (sign_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1480 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "")))
1481 (match_operand:DI 3 "s_register_operand" "")))]
1482 "TARGET_32BIT && arm_arch3m"
1483 "")
82b85d08 1484
1485(define_insn "*mulsidi3adddi"
fe8dbf85 1486 [(set (match_operand:DI 0 "s_register_operand" "=&r")
82b85d08 1487 (plus:DI
215b30b3 1488 (mult:DI
fe8dbf85 1489 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "%r"))
1490 (sign_extend:DI (match_operand:SI 3 "s_register_operand" "r")))
1491 (match_operand:DI 1 "s_register_operand" "0")))]
58d7d654 1492 "TARGET_32BIT && arm_arch3m && !arm_arch6"
1493 "smlal%?\\t%Q0, %R0, %3, %2"
9da0ec36 1494 [(set_attr "type" "smlal")
58d7d654 1495 (set_attr "predicable" "yes")]
1496)
1497
1498(define_insn "*mulsidi3adddi_v6"
1499 [(set (match_operand:DI 0 "s_register_operand" "=r")
1500 (plus:DI
1501 (mult:DI
1502 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r"))
1503 (sign_extend:DI (match_operand:SI 3 "s_register_operand" "r")))
1504 (match_operand:DI 1 "s_register_operand" "0")))]
1505 "TARGET_32BIT && arm_arch6"
fe8dbf85 1506 "smlal%?\\t%Q0, %R0, %3, %2"
9da0ec36 1507 [(set_attr "type" "smlal")
d952d547 1508 (set_attr "predicable" "yes")
1509 (set_attr "predicable_short_it" "no")]
0d66636f 1510)
82b85d08 1511
957788b0 1512;; 32x32->64 widening multiply.
1513;; As with mulsi3, the only difference between the v3-5 and v6+
1514;; versions of these patterns is the requirement that the output not
1515;; overlap the inputs, but that still means we have to have a named
1516;; expander and two different starred insns.
1517
1518(define_expand "mulsidi3"
1519 [(set (match_operand:DI 0 "s_register_operand" "")
1520 (mult:DI
1521 (sign_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1522 (sign_extend:DI (match_operand:SI 2 "s_register_operand" ""))))]
1523 "TARGET_32BIT && arm_arch3m"
1524 ""
1525)
1526
1527(define_insn "*mulsidi3_nov6"
f7fbdd4a 1528 [(set (match_operand:DI 0 "s_register_operand" "=&r")
215b30b3 1529 (mult:DI
1530 (sign_extend:DI (match_operand:SI 1 "s_register_operand" "%r"))
1531 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))]
58d7d654 1532 "TARGET_32BIT && arm_arch3m && !arm_arch6"
1533 "smull%?\\t%Q0, %R0, %1, %2"
9da0ec36 1534 [(set_attr "type" "smull")
58d7d654 1535 (set_attr "predicable" "yes")]
1536)
1537
957788b0 1538(define_insn "*mulsidi3_v6"
58d7d654 1539 [(set (match_operand:DI 0 "s_register_operand" "=r")
1540 (mult:DI
1541 (sign_extend:DI (match_operand:SI 1 "s_register_operand" "r"))
1542 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))]
1543 "TARGET_32BIT && arm_arch6"
97499065 1544 "smull%?\\t%Q0, %R0, %1, %2"
9da0ec36 1545 [(set_attr "type" "smull")
d952d547 1546 (set_attr "predicable" "yes")
1547 (set_attr "predicable_short_it" "no")]
0d66636f 1548)
f7fbdd4a 1549
957788b0 1550(define_expand "umulsidi3"
1551 [(set (match_operand:DI 0 "s_register_operand" "")
1552 (mult:DI
1553 (zero_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1554 (zero_extend:DI (match_operand:SI 2 "s_register_operand" ""))))]
1555 "TARGET_32BIT && arm_arch3m"
1556 ""
1557)
1558
1559(define_insn "*umulsidi3_nov6"
f7fbdd4a 1560 [(set (match_operand:DI 0 "s_register_operand" "=&r")
215b30b3 1561 (mult:DI
1562 (zero_extend:DI (match_operand:SI 1 "s_register_operand" "%r"))
1563 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))]
58d7d654 1564 "TARGET_32BIT && arm_arch3m && !arm_arch6"
1565 "umull%?\\t%Q0, %R0, %1, %2"
9da0ec36 1566 [(set_attr "type" "umull")
58d7d654 1567 (set_attr "predicable" "yes")]
1568)
1569
957788b0 1570(define_insn "*umulsidi3_v6"
58d7d654 1571 [(set (match_operand:DI 0 "s_register_operand" "=r")
1572 (mult:DI
1573 (zero_extend:DI (match_operand:SI 1 "s_register_operand" "r"))
1574 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))]
1575 "TARGET_32BIT && arm_arch6"
97499065 1576 "umull%?\\t%Q0, %R0, %1, %2"
9da0ec36 1577 [(set_attr "type" "umull")
d952d547 1578 (set_attr "predicable" "yes")
1579 (set_attr "predicable_short_it" "no")]
0d66636f 1580)
b11cae9e 1581
5cdca009 1582(define_expand "umaddsidi4"
1583 [(set (match_operand:DI 0 "s_register_operand" "")
1584 (plus:DI
1585 (mult:DI
1586 (zero_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1587 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "")))
1588 (match_operand:DI 3 "s_register_operand" "")))]
1589 "TARGET_32BIT && arm_arch3m"
1590 "")
82b85d08 1591
1592(define_insn "*umulsidi3adddi"
8ead09f9 1593 [(set (match_operand:DI 0 "s_register_operand" "=&r")
82b85d08 1594 (plus:DI
215b30b3 1595 (mult:DI
fe8dbf85 1596 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "%r"))
1597 (zero_extend:DI (match_operand:SI 3 "s_register_operand" "r")))
1598 (match_operand:DI 1 "s_register_operand" "0")))]
58d7d654 1599 "TARGET_32BIT && arm_arch3m && !arm_arch6"
1600 "umlal%?\\t%Q0, %R0, %3, %2"
9da0ec36 1601 [(set_attr "type" "umlal")
58d7d654 1602 (set_attr "predicable" "yes")]
1603)
1604
1605(define_insn "*umulsidi3adddi_v6"
1606 [(set (match_operand:DI 0 "s_register_operand" "=r")
1607 (plus:DI
1608 (mult:DI
1609 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r"))
1610 (zero_extend:DI (match_operand:SI 3 "s_register_operand" "r")))
1611 (match_operand:DI 1 "s_register_operand" "0")))]
1612 "TARGET_32BIT && arm_arch6"
fe8dbf85 1613 "umlal%?\\t%Q0, %R0, %3, %2"
9da0ec36 1614 [(set_attr "type" "umlal")
d952d547 1615 (set_attr "predicable" "yes")
1616 (set_attr "predicable_short_it" "no")]
0d66636f 1617)
82b85d08 1618
957788b0 1619(define_expand "smulsi3_highpart"
1620 [(parallel
1621 [(set (match_operand:SI 0 "s_register_operand" "")
1622 (truncate:SI
1623 (lshiftrt:DI
1624 (mult:DI
1625 (sign_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1626 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "")))
1627 (const_int 32))))
1628 (clobber (match_scratch:SI 3 ""))])]
1629 "TARGET_32BIT && arm_arch3m"
1630 ""
1631)
1632
1633(define_insn "*smulsi3_highpart_nov6"
f082f1c4 1634 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r")
1635 (truncate:SI
1636 (lshiftrt:DI
215b30b3 1637 (mult:DI
e5fea38e 1638 (sign_extend:DI (match_operand:SI 1 "s_register_operand" "%0,r"))
215b30b3 1639 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r,r")))
f082f1c4 1640 (const_int 32))))
1641 (clobber (match_scratch:SI 3 "=&r,&r"))]
58d7d654 1642 "TARGET_32BIT && arm_arch3m && !arm_arch6"
1643 "smull%?\\t%3, %0, %2, %1"
9da0ec36 1644 [(set_attr "type" "smull")
58d7d654 1645 (set_attr "predicable" "yes")]
1646)
1647
957788b0 1648(define_insn "*smulsi3_highpart_v6"
58d7d654 1649 [(set (match_operand:SI 0 "s_register_operand" "=r")
1650 (truncate:SI
1651 (lshiftrt:DI
1652 (mult:DI
1653 (sign_extend:DI (match_operand:SI 1 "s_register_operand" "r"))
1654 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r")))
1655 (const_int 32))))
1656 (clobber (match_scratch:SI 3 "=r"))]
1657 "TARGET_32BIT && arm_arch6"
f082f1c4 1658 "smull%?\\t%3, %0, %2, %1"
9da0ec36 1659 [(set_attr "type" "smull")
d952d547 1660 (set_attr "predicable" "yes")
1661 (set_attr "predicable_short_it" "no")]
cffb2a26 1662)
f082f1c4 1663
957788b0 1664(define_expand "umulsi3_highpart"
1665 [(parallel
1666 [(set (match_operand:SI 0 "s_register_operand" "")
1667 (truncate:SI
1668 (lshiftrt:DI
1669 (mult:DI
1670 (zero_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1671 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "")))
1672 (const_int 32))))
1673 (clobber (match_scratch:SI 3 ""))])]
1674 "TARGET_32BIT && arm_arch3m"
1675 ""
1676)
1677
1678(define_insn "*umulsi3_highpart_nov6"
f082f1c4 1679 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r")
1680 (truncate:SI
1681 (lshiftrt:DI
215b30b3 1682 (mult:DI
e5fea38e 1683 (zero_extend:DI (match_operand:SI 1 "s_register_operand" "%0,r"))
215b30b3 1684 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r,r")))
f082f1c4 1685 (const_int 32))))
1686 (clobber (match_scratch:SI 3 "=&r,&r"))]
58d7d654 1687 "TARGET_32BIT && arm_arch3m && !arm_arch6"
1688 "umull%?\\t%3, %0, %2, %1"
9da0ec36 1689 [(set_attr "type" "umull")
58d7d654 1690 (set_attr "predicable" "yes")]
1691)
1692
957788b0 1693(define_insn "*umulsi3_highpart_v6"
58d7d654 1694 [(set (match_operand:SI 0 "s_register_operand" "=r")
1695 (truncate:SI
1696 (lshiftrt:DI
1697 (mult:DI
1698 (zero_extend:DI (match_operand:SI 1 "s_register_operand" "r"))
1699 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r")))
1700 (const_int 32))))
1701 (clobber (match_scratch:SI 3 "=r"))]
1702 "TARGET_32BIT && arm_arch6"
f082f1c4 1703 "umull%?\\t%3, %0, %2, %1"
9da0ec36 1704 [(set_attr "type" "umull")
d952d547 1705 (set_attr "predicable" "yes")
1706 (set_attr "predicable_short_it" "no")]
cffb2a26 1707)
f082f1c4 1708
331beb1a 1709(define_insn "mulhisi3"
1710 [(set (match_operand:SI 0 "s_register_operand" "=r")
1711 (mult:SI (sign_extend:SI
1712 (match_operand:HI 1 "s_register_operand" "%r"))
1713 (sign_extend:SI
1714 (match_operand:HI 2 "s_register_operand" "r"))))]
25f905c2 1715 "TARGET_DSP_MULTIPLY"
61a2d04c 1716 "smulbb%?\\t%0, %1, %2"
9da0ec36 1717 [(set_attr "type" "smulxy")
fec538d9 1718 (set_attr "predicable" "yes")]
1719)
1720
1721(define_insn "*mulhisi3tb"
1722 [(set (match_operand:SI 0 "s_register_operand" "=r")
1723 (mult:SI (ashiftrt:SI
1724 (match_operand:SI 1 "s_register_operand" "r")
1725 (const_int 16))
1726 (sign_extend:SI
1727 (match_operand:HI 2 "s_register_operand" "r"))))]
25f905c2 1728 "TARGET_DSP_MULTIPLY"
fec538d9 1729 "smultb%?\\t%0, %1, %2"
9da0ec36 1730 [(set_attr "type" "smulxy")
d952d547 1731 (set_attr "predicable" "yes")
1732 (set_attr "predicable_short_it" "no")]
fec538d9 1733)
1734
1735(define_insn "*mulhisi3bt"
1736 [(set (match_operand:SI 0 "s_register_operand" "=r")
1737 (mult:SI (sign_extend:SI
1738 (match_operand:HI 1 "s_register_operand" "r"))
1739 (ashiftrt:SI
1740 (match_operand:SI 2 "s_register_operand" "r")
1741 (const_int 16))))]
25f905c2 1742 "TARGET_DSP_MULTIPLY"
fec538d9 1743 "smulbt%?\\t%0, %1, %2"
9da0ec36 1744 [(set_attr "type" "smulxy")
d952d547 1745 (set_attr "predicable" "yes")
1746 (set_attr "predicable_short_it" "no")]
fec538d9 1747)
1748
1749(define_insn "*mulhisi3tt"
1750 [(set (match_operand:SI 0 "s_register_operand" "=r")
1751 (mult:SI (ashiftrt:SI
1752 (match_operand:SI 1 "s_register_operand" "r")
1753 (const_int 16))
1754 (ashiftrt:SI
1755 (match_operand:SI 2 "s_register_operand" "r")
1756 (const_int 16))))]
25f905c2 1757 "TARGET_DSP_MULTIPLY"
fec538d9 1758 "smultt%?\\t%0, %1, %2"
9da0ec36 1759 [(set_attr "type" "smulxy")
d952d547 1760 (set_attr "predicable" "yes")
1761 (set_attr "predicable_short_it" "no")]
331beb1a 1762)
1763
5cdca009 1764(define_insn "maddhisi4"
331beb1a 1765 [(set (match_operand:SI 0 "s_register_operand" "=r")
cfa6c608 1766 (plus:SI (mult:SI (sign_extend:SI
1767 (match_operand:HI 1 "s_register_operand" "r"))
331beb1a 1768 (sign_extend:SI
cfa6c608 1769 (match_operand:HI 2 "s_register_operand" "r")))
1770 (match_operand:SI 3 "s_register_operand" "r")))]
25f905c2 1771 "TARGET_DSP_MULTIPLY"
5cdca009 1772 "smlabb%?\\t%0, %1, %2, %3"
9da0ec36 1773 [(set_attr "type" "smlaxy")
d952d547 1774 (set_attr "predicable" "yes")
1775 (set_attr "predicable_short_it" "no")]
331beb1a 1776)
1777
9a92f368 1778;; Note: there is no maddhisi4ibt because this one is canonical form
1779(define_insn "*maddhisi4tb"
1780 [(set (match_operand:SI 0 "s_register_operand" "=r")
1781 (plus:SI (mult:SI (ashiftrt:SI
1782 (match_operand:SI 1 "s_register_operand" "r")
1783 (const_int 16))
1784 (sign_extend:SI
1785 (match_operand:HI 2 "s_register_operand" "r")))
1786 (match_operand:SI 3 "s_register_operand" "r")))]
1787 "TARGET_DSP_MULTIPLY"
1788 "smlatb%?\\t%0, %1, %2, %3"
9da0ec36 1789 [(set_attr "type" "smlaxy")
d952d547 1790 (set_attr "predicable" "yes")
1791 (set_attr "predicable_short_it" "no")]
9a92f368 1792)
1793
1794(define_insn "*maddhisi4tt"
1795 [(set (match_operand:SI 0 "s_register_operand" "=r")
1796 (plus:SI (mult:SI (ashiftrt:SI
1797 (match_operand:SI 1 "s_register_operand" "r")
1798 (const_int 16))
1799 (ashiftrt:SI
1800 (match_operand:SI 2 "s_register_operand" "r")
1801 (const_int 16)))
1802 (match_operand:SI 3 "s_register_operand" "r")))]
1803 "TARGET_DSP_MULTIPLY"
1804 "smlatt%?\\t%0, %1, %2, %3"
9da0ec36 1805 [(set_attr "type" "smlaxy")
d952d547 1806 (set_attr "predicable" "yes")
1807 (set_attr "predicable_short_it" "no")]
9a92f368 1808)
1809
aff5fb4d 1810(define_insn "maddhidi4"
331beb1a 1811 [(set (match_operand:DI 0 "s_register_operand" "=r")
1812 (plus:DI
331beb1a 1813 (mult:DI (sign_extend:DI
d952d547 1814 (match_operand:HI 1 "s_register_operand" "r"))
331beb1a 1815 (sign_extend:DI
cfa6c608 1816 (match_operand:HI 2 "s_register_operand" "r")))
1817 (match_operand:DI 3 "s_register_operand" "0")))]
25f905c2 1818 "TARGET_DSP_MULTIPLY"
5cdca009 1819 "smlalbb%?\\t%Q0, %R0, %1, %2"
9da0ec36 1820 [(set_attr "type" "smlalxy")
d952d547 1821 (set_attr "predicable" "yes")
1822 (set_attr "predicable_short_it" "no")])
331beb1a 1823
9a92f368 1824;; Note: there is no maddhidi4ibt because this one is canonical form
1825(define_insn "*maddhidi4tb"
1826 [(set (match_operand:DI 0 "s_register_operand" "=r")
1827 (plus:DI
1828 (mult:DI (sign_extend:DI
1829 (ashiftrt:SI
1830 (match_operand:SI 1 "s_register_operand" "r")
1831 (const_int 16)))
1832 (sign_extend:DI
1833 (match_operand:HI 2 "s_register_operand" "r")))
1834 (match_operand:DI 3 "s_register_operand" "0")))]
1835 "TARGET_DSP_MULTIPLY"
1836 "smlaltb%?\\t%Q0, %R0, %1, %2"
9da0ec36 1837 [(set_attr "type" "smlalxy")
d952d547 1838 (set_attr "predicable" "yes")
1839 (set_attr "predicable_short_it" "no")])
9a92f368 1840
1841(define_insn "*maddhidi4tt"
1842 [(set (match_operand:DI 0 "s_register_operand" "=r")
1843 (plus:DI
1844 (mult:DI (sign_extend:DI
1845 (ashiftrt:SI
1846 (match_operand:SI 1 "s_register_operand" "r")
1847 (const_int 16)))
1848 (sign_extend:DI
1849 (ashiftrt:SI
1850 (match_operand:SI 2 "s_register_operand" "r")
1851 (const_int 16))))
1852 (match_operand:DI 3 "s_register_operand" "0")))]
1853 "TARGET_DSP_MULTIPLY"
1854 "smlaltt%?\\t%Q0, %R0, %1, %2"
9da0ec36 1855 [(set_attr "type" "smlalxy")
d952d547 1856 (set_attr "predicable" "yes")
1857 (set_attr "predicable_short_it" "no")])
9a92f368 1858
604f3a0a 1859(define_expand "mulsf3"
1860 [(set (match_operand:SF 0 "s_register_operand" "")
1861 (mult:SF (match_operand:SF 1 "s_register_operand" "")
d86c91f6 1862 (match_operand:SF 2 "s_register_operand" "")))]
25f905c2 1863 "TARGET_32BIT && TARGET_HARD_FLOAT"
604f3a0a 1864 "
604f3a0a 1865")
1866
604f3a0a 1867(define_expand "muldf3"
1868 [(set (match_operand:DF 0 "s_register_operand" "")
1869 (mult:DF (match_operand:DF 1 "s_register_operand" "")
d86c91f6 1870 (match_operand:DF 2 "s_register_operand" "")))]
a50d7267 1871 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
604f3a0a 1872 "
604f3a0a 1873")
b11cae9e 1874\f
1875;; Division insns
1876
7db9af5d 1877(define_expand "divsf3"
1878 [(set (match_operand:SF 0 "s_register_operand" "")
d86c91f6 1879 (div:SF (match_operand:SF 1 "s_register_operand" "")
1880 (match_operand:SF 2 "s_register_operand" "")))]
994606f8 1881 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
7db9af5d 1882 "")
9c08d1fa 1883
7db9af5d 1884(define_expand "divdf3"
1885 [(set (match_operand:DF 0 "s_register_operand" "")
d86c91f6 1886 (div:DF (match_operand:DF 1 "s_register_operand" "")
1887 (match_operand:DF 2 "s_register_operand" "")))]
994606f8 1888 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
7db9af5d 1889 "")
b11cae9e 1890\f
1891;; Boolean and,ior,xor insns
1892
f6ebffac 1893;; Split up double word logical operations
1894
1895;; Split up simple DImode logical operations. Simply perform the logical
1896;; operation on the upper and lower halves of the registers.
1897(define_split
1898 [(set (match_operand:DI 0 "s_register_operand" "")
1899 (match_operator:DI 6 "logical_binary_operator"
1900 [(match_operand:DI 1 "s_register_operand" "")
1901 (match_operand:DI 2 "s_register_operand" "")]))]
25f905c2 1902 "TARGET_32BIT && reload_completed
e2669ea7 1903 && ! (TARGET_NEON && IS_VFP_REGNUM (REGNO (operands[0])))
25f905c2 1904 && ! IS_IWMMXT_REGNUM (REGNO (operands[0]))"
f6ebffac 1905 [(set (match_dup 0) (match_op_dup:SI 6 [(match_dup 1) (match_dup 2)]))
1906 (set (match_dup 3) (match_op_dup:SI 6 [(match_dup 4) (match_dup 5)]))]
1907 "
215b30b3 1908 {
1909 operands[3] = gen_highpart (SImode, operands[0]);
1910 operands[0] = gen_lowpart (SImode, operands[0]);
1911 operands[4] = gen_highpart (SImode, operands[1]);
1912 operands[1] = gen_lowpart (SImode, operands[1]);
1913 operands[5] = gen_highpart (SImode, operands[2]);
1914 operands[2] = gen_lowpart (SImode, operands[2]);
1915 }"
1916)
f6ebffac 1917
f6ebffac 1918(define_split
1919 [(set (match_operand:DI 0 "s_register_operand" "")
1920 (match_operator:DI 6 "logical_binary_operator"
1921 [(sign_extend:DI (match_operand:SI 2 "s_register_operand" ""))
1922 (match_operand:DI 1 "s_register_operand" "")]))]
25f905c2 1923 "TARGET_32BIT && reload_completed"
f6ebffac 1924 [(set (match_dup 0) (match_op_dup:SI 6 [(match_dup 1) (match_dup 2)]))
1925 (set (match_dup 3) (match_op_dup:SI 6
1926 [(ashiftrt:SI (match_dup 2) (const_int 31))
1927 (match_dup 4)]))]
1928 "
215b30b3 1929 {
1930 operands[3] = gen_highpart (SImode, operands[0]);
1931 operands[0] = gen_lowpart (SImode, operands[0]);
1932 operands[4] = gen_highpart (SImode, operands[1]);
1933 operands[1] = gen_lowpart (SImode, operands[1]);
1934 operands[5] = gen_highpart (SImode, operands[2]);
1935 operands[2] = gen_lowpart (SImode, operands[2]);
1936 }"
1937)
f6ebffac 1938
f6ebffac 1939;; The zero extend of operand 2 means we can just copy the high part of
1940;; operand1 into operand0.
1941(define_split
1942 [(set (match_operand:DI 0 "s_register_operand" "")
1943 (ior:DI
1944 (zero_extend:DI (match_operand:SI 2 "s_register_operand" ""))
1945 (match_operand:DI 1 "s_register_operand" "")))]
25f905c2 1946 "TARGET_32BIT && operands[0] != operands[1] && reload_completed"
f6ebffac 1947 [(set (match_dup 0) (ior:SI (match_dup 1) (match_dup 2)))
1948 (set (match_dup 3) (match_dup 4))]
1949 "
215b30b3 1950 {
1951 operands[4] = gen_highpart (SImode, operands[1]);
1952 operands[3] = gen_highpart (SImode, operands[0]);
1953 operands[0] = gen_lowpart (SImode, operands[0]);
1954 operands[1] = gen_lowpart (SImode, operands[1]);
1955 }"
1956)
f6ebffac 1957
1958;; The zero extend of operand 2 means we can just copy the high part of
1959;; operand1 into operand0.
1960(define_split
1961 [(set (match_operand:DI 0 "s_register_operand" "")
1962 (xor:DI
1963 (zero_extend:DI (match_operand:SI 2 "s_register_operand" ""))
1964 (match_operand:DI 1 "s_register_operand" "")))]
25f905c2 1965 "TARGET_32BIT && operands[0] != operands[1] && reload_completed"
f6ebffac 1966 [(set (match_dup 0) (xor:SI (match_dup 1) (match_dup 2)))
1967 (set (match_dup 3) (match_dup 4))]
1968 "
215b30b3 1969 {
1970 operands[4] = gen_highpart (SImode, operands[1]);
1971 operands[3] = gen_highpart (SImode, operands[0]);
1972 operands[0] = gen_lowpart (SImode, operands[0]);
1973 operands[1] = gen_lowpart (SImode, operands[1]);
1974 }"
1975)
f6ebffac 1976
e2669ea7 1977(define_expand "anddi3"
1978 [(set (match_operand:DI 0 "s_register_operand" "")
1979 (and:DI (match_operand:DI 1 "s_register_operand" "")
1980 (match_operand:DI 2 "neon_inv_logic_op2" "")))]
1981 "TARGET_32BIT"
1982 ""
1983)
1984
f6bbdcf6 1985(define_insn_and_split "*anddi3_insn"
0a314dcd 1986 [(set (match_operand:DI 0 "s_register_operand" "=w,w ,&r,&r,&r,&r,?w,?w")
1987 (and:DI (match_operand:DI 1 "s_register_operand" "%w,0 ,0 ,r ,0 ,r ,w ,0")
1988 (match_operand:DI 2 "arm_anddi_operand_neon" "w ,DL,r ,r ,De,De,w ,DL")))]
f6bbdcf6 1989 "TARGET_32BIT && !TARGET_IWMMXT"
1990{
1991 switch (which_alternative)
1992 {
0a314dcd 1993 case 0: /* fall through */
1994 case 6: return "vand\t%P0, %P1, %P2";
1995 case 1: /* fall through */
1996 case 7: return neon_output_logic_immediate ("vand", &operands[2],
1997 DImode, 1, VALID_NEON_QREG_MODE (DImode));
f6bbdcf6 1998 case 2:
0a314dcd 1999 case 3:
2000 case 4:
f6bbdcf6 2001 case 5: /* fall through */
0a314dcd 2002 return "#";
f6bbdcf6 2003 default: gcc_unreachable ();
2004 }
2005}
0a314dcd 2006 "TARGET_32BIT && !TARGET_IWMMXT && reload_completed
2007 && !(IS_VFP_REGNUM (REGNO (operands[0])))"
f6bbdcf6 2008 [(set (match_dup 3) (match_dup 4))
2009 (set (match_dup 5) (match_dup 6))]
2010 "
2011 {
2012 operands[3] = gen_lowpart (SImode, operands[0]);
2013 operands[5] = gen_highpart (SImode, operands[0]);
2014
2015 operands[4] = simplify_gen_binary (AND, SImode,
2016 gen_lowpart (SImode, operands[1]),
2017 gen_lowpart (SImode, operands[2]));
2018 operands[6] = simplify_gen_binary (AND, SImode,
2019 gen_highpart (SImode, operands[1]),
2020 gen_highpart_mode (SImode, DImode, operands[2]));
2021
2022 }"
32093010 2023 [(set_attr "type" "neon_logic,neon_logic,multiple,multiple,\
2024 multiple,multiple,neon_logic,neon_logic")
0a314dcd 2025 (set_attr "arch" "neon_for_64bits,neon_for_64bits,*,*,*,*,
f6bbdcf6 2026 avoid_neon_for_64bits,avoid_neon_for_64bits")
0a314dcd 2027 (set_attr "length" "*,*,8,8,8,8,*,*")
2028 ]
215b30b3 2029)
b11cae9e 2030
a0f94409 2031(define_insn_and_split "*anddi_zesidi_di"
9c08d1fa 2032 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2033 (and:DI (zero_extend:DI
2034 (match_operand:SI 2 "s_register_operand" "r,r"))
e5fea38e 2035 (match_operand:DI 1 "s_register_operand" "0,r")))]
25f905c2 2036 "TARGET_32BIT"
f6ebffac 2037 "#"
25f905c2 2038 "TARGET_32BIT && reload_completed"
a0f94409 2039 ; The zero extend of operand 2 clears the high word of the output
2040 ; operand.
2041 [(set (match_dup 0) (and:SI (match_dup 1) (match_dup 2)))
2042 (set (match_dup 3) (const_int 0))]
2043 "
2044 {
2045 operands[3] = gen_highpart (SImode, operands[0]);
2046 operands[0] = gen_lowpart (SImode, operands[0]);
2047 operands[1] = gen_lowpart (SImode, operands[1]);
2048 }"
1b7da4ac 2049 [(set_attr "length" "8")
2050 (set_attr "type" "multiple")]
215b30b3 2051)
b11cae9e 2052
f7fbdd4a 2053(define_insn "*anddi_sesdi_di"
cffb2a26 2054 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
9c08d1fa 2055 (and:DI (sign_extend:DI
2056 (match_operand:SI 2 "s_register_operand" "r,r"))
e5fea38e 2057 (match_operand:DI 1 "s_register_operand" "0,r")))]
25f905c2 2058 "TARGET_32BIT"
f6ebffac 2059 "#"
1b7da4ac 2060 [(set_attr "length" "8")
2061 (set_attr "type" "multiple")]
cffb2a26 2062)
b11cae9e 2063
87b22bf7 2064(define_expand "andsi3"
cffb2a26 2065 [(set (match_operand:SI 0 "s_register_operand" "")
87b22bf7 2066 (and:SI (match_operand:SI 1 "s_register_operand" "")
2067 (match_operand:SI 2 "reg_or_int_operand" "")))]
cffb2a26 2068 "TARGET_EITHER"
87b22bf7 2069 "
25f905c2 2070 if (TARGET_32BIT)
87b22bf7 2071 {
0438d37f 2072 if (CONST_INT_P (operands[2]))
cffb2a26 2073 {
47b5b27b 2074 if (INTVAL (operands[2]) == 255 && arm_arch6)
2075 {
2076 operands[1] = convert_to_mode (QImode, operands[1], 1);
2077 emit_insn (gen_thumb2_zero_extendqisi2_v6 (operands[0],
2078 operands[1]));
2079 }
2080 else
2081 arm_split_constant (AND, SImode, NULL_RTX,
2082 INTVAL (operands[2]), operands[0],
2083 operands[1],
2084 optimize && can_create_pseudo_p ());
615caa51 2085
cffb2a26 2086 DONE;
2087 }
87b22bf7 2088 }
25f905c2 2089 else /* TARGET_THUMB1 */
cffb2a26 2090 {
0438d37f 2091 if (!CONST_INT_P (operands[2]))
923ffadb 2092 {
2093 rtx tmp = force_reg (SImode, operands[2]);
2094 if (rtx_equal_p (operands[0], operands[1]))
2095 operands[2] = tmp;
2096 else
2097 {
2098 operands[2] = operands[1];
2099 operands[1] = tmp;
2100 }
2101 }
cffb2a26 2102 else
2103 {
2104 int i;
2105
215b30b3 2106 if (((unsigned HOST_WIDE_INT) ~INTVAL (operands[2])) < 256)
cffb2a26 2107 {
215b30b3 2108 operands[2] = force_reg (SImode,
2109 GEN_INT (~INTVAL (operands[2])));
cffb2a26 2110
747b7458 2111 emit_insn (gen_thumb1_bicsi3 (operands[0], operands[2], operands[1]));
cffb2a26 2112
2113 DONE;
2114 }
87b22bf7 2115
cffb2a26 2116 for (i = 9; i <= 31; i++)
2117 {
2118 if ((((HOST_WIDE_INT) 1) << i) - 1 == INTVAL (operands[2]))
2119 {
2120 emit_insn (gen_extzv (operands[0], operands[1], GEN_INT (i),
2121 const0_rtx));
2122 DONE;
2123 }
215b30b3 2124 else if ((((HOST_WIDE_INT) 1) << i) - 1
2125 == ~INTVAL (operands[2]))
cffb2a26 2126 {
2127 rtx shift = GEN_INT (i);
2128 rtx reg = gen_reg_rtx (SImode);
2129
2130 emit_insn (gen_lshrsi3 (reg, operands[1], shift));
2131 emit_insn (gen_ashlsi3 (operands[0], reg, shift));
2132
2133 DONE;
2134 }
2135 }
2136
2137 operands[2] = force_reg (SImode, operands[2]);
2138 }
215b30b3 2139 }
2140 "
cffb2a26 2141)
2142
25f905c2 2143; ??? Check split length for Thumb-2
a0f94409 2144(define_insn_and_split "*arm_andsi3_insn"
29e234a3 2145 [(set (match_operand:SI 0 "s_register_operand" "=r,l,r,r,r")
2146 (and:SI (match_operand:SI 1 "s_register_operand" "%r,0,r,r,r")
2147 (match_operand:SI 2 "reg_or_int_operand" "I,l,K,r,?n")))]
25f905c2 2148 "TARGET_32BIT"
5565501b 2149 "@
29e234a3 2150 and%?\\t%0, %1, %2
5565501b 2151 and%?\\t%0, %1, %2
87b22bf7 2152 bic%?\\t%0, %1, #%B2
65f68e55 2153 and%?\\t%0, %1, %2
87b22bf7 2154 #"
25f905c2 2155 "TARGET_32BIT
0438d37f 2156 && CONST_INT_P (operands[2])
a0f94409 2157 && !(const_ok_for_arm (INTVAL (operands[2]))
2158 || const_ok_for_arm (~INTVAL (operands[2])))"
2159 [(clobber (const_int 0))]
2160 "
96f57e36 2161 arm_split_constant (AND, SImode, curr_insn,
2162 INTVAL (operands[2]), operands[0], operands[1], 0);
a0f94409 2163 DONE;
2164 "
29e234a3 2165 [(set_attr "length" "4,4,4,4,16")
65f68e55 2166 (set_attr "predicable" "yes")
29e234a3 2167 (set_attr "predicable_short_it" "no,yes,no,no,no")
d82e788e 2168 (set_attr "type" "logic_imm,logic_imm,logic_reg,logic_reg,logic_imm")]
cffb2a26 2169)
2170
f7fbdd4a 2171(define_insn "*andsi3_compare0"
bd5b4116 2172 [(set (reg:CC_NOOV CC_REGNUM)
5565501b 2173 (compare:CC_NOOV
65f68e55 2174 (and:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
2175 (match_operand:SI 2 "arm_not_operand" "I,K,r"))
5565501b 2176 (const_int 0)))
65f68e55 2177 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9c08d1fa 2178 (and:SI (match_dup 1) (match_dup 2)))]
25f905c2 2179 "TARGET_32BIT"
5565501b 2180 "@
25f905c2 2181 and%.\\t%0, %1, %2
65f68e55 2182 bic%.\\t%0, %1, #%B2
2183 and%.\\t%0, %1, %2"
2184 [(set_attr "conds" "set")
d82e788e 2185 (set_attr "type" "logics_imm,logics_imm,logics_reg")]
cffb2a26 2186)
9c08d1fa 2187
f7fbdd4a 2188(define_insn "*andsi3_compare0_scratch"
bd5b4116 2189 [(set (reg:CC_NOOV CC_REGNUM)
5565501b 2190 (compare:CC_NOOV
65f68e55 2191 (and:SI (match_operand:SI 0 "s_register_operand" "r,r,r")
2192 (match_operand:SI 1 "arm_not_operand" "I,K,r"))
5565501b 2193 (const_int 0)))
65f68e55 2194 (clobber (match_scratch:SI 2 "=X,r,X"))]
25f905c2 2195 "TARGET_32BIT"
5565501b 2196 "@
2197 tst%?\\t%0, %1
65f68e55 2198 bic%.\\t%2, %0, #%B1
2199 tst%?\\t%0, %1"
2200 [(set_attr "conds" "set")
d82e788e 2201 (set_attr "type" "logics_imm,logics_imm,logics_reg")]
0d66636f 2202)
9c08d1fa 2203
f7fbdd4a 2204(define_insn "*zeroextractsi_compare0_scratch"
bd5b4116 2205 [(set (reg:CC_NOOV CC_REGNUM)
9c08d1fa 2206 (compare:CC_NOOV (zero_extract:SI
2207 (match_operand:SI 0 "s_register_operand" "r")
d952d547 2208 (match_operand 1 "const_int_operand" "n")
206ee9a2 2209 (match_operand 2 "const_int_operand" "n"))
9c08d1fa 2210 (const_int 0)))]
25f905c2 2211 "TARGET_32BIT
cffb2a26 2212 && (INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) < 32
2213 && INTVAL (operands[1]) > 0
2214 && INTVAL (operands[1]) + (INTVAL (operands[2]) & 1) <= 8
2215 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32)"
9c08d1fa 2216 "*
5c49a439 2217 operands[1] = GEN_INT (((1 << INTVAL (operands[1])) - 1)
2218 << INTVAL (operands[2]));
40dbec34 2219 output_asm_insn (\"tst%?\\t%0, %1\", operands);
e2348bcb 2220 return \"\";
0d66636f 2221 "
596e5e8f 2222 [(set_attr "conds" "set")
65f68e55 2223 (set_attr "predicable" "yes")
d952d547 2224 (set_attr "predicable_short_it" "no")
d82e788e 2225 (set_attr "type" "logics_imm")]
0d66636f 2226)
9c08d1fa 2227
f4462328 2228(define_insn_and_split "*ne_zeroextractsi"
c4034607 2229 [(set (match_operand:SI 0 "s_register_operand" "=r")
2230 (ne:SI (zero_extract:SI
2231 (match_operand:SI 1 "s_register_operand" "r")
2232 (match_operand:SI 2 "const_int_operand" "n")
2233 (match_operand:SI 3 "const_int_operand" "n"))
3b8c7f7a 2234 (const_int 0)))
2235 (clobber (reg:CC CC_REGNUM))]
25f905c2 2236 "TARGET_32BIT
cffb2a26 2237 && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
2238 && INTVAL (operands[2]) > 0
2239 && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
2240 && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)"
f4462328 2241 "#"
25f905c2 2242 "TARGET_32BIT
f4462328 2243 && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
2244 && INTVAL (operands[2]) > 0
2245 && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
2246 && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)"
2247 [(parallel [(set (reg:CC_NOOV CC_REGNUM)
2248 (compare:CC_NOOV (and:SI (match_dup 1) (match_dup 2))
2249 (const_int 0)))
2250 (set (match_dup 0) (and:SI (match_dup 1) (match_dup 2)))])
2251 (set (match_dup 0)
2252 (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
2253 (match_dup 0) (const_int 1)))]
2254 "
2255 operands[2] = GEN_INT (((1 << INTVAL (operands[2])) - 1)
2256 << INTVAL (operands[3]));
2257 "
2258 [(set_attr "conds" "clob")
25f905c2 2259 (set (attr "length")
2260 (if_then_else (eq_attr "is_thumb" "yes")
2261 (const_int 12)
1b7da4ac 2262 (const_int 8)))
2263 (set_attr "type" "multiple")]
f4462328 2264)
2265
2266(define_insn_and_split "*ne_zeroextractsi_shifted"
2267 [(set (match_operand:SI 0 "s_register_operand" "=r")
2268 (ne:SI (zero_extract:SI
2269 (match_operand:SI 1 "s_register_operand" "r")
2270 (match_operand:SI 2 "const_int_operand" "n")
2271 (const_int 0))
2272 (const_int 0)))
2273 (clobber (reg:CC CC_REGNUM))]
2274 "TARGET_ARM"
2275 "#"
2276 "TARGET_ARM"
2277 [(parallel [(set (reg:CC_NOOV CC_REGNUM)
2278 (compare:CC_NOOV (ashift:SI (match_dup 1) (match_dup 2))
2279 (const_int 0)))
2280 (set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 2)))])
2281 (set (match_dup 0)
2282 (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
2283 (match_dup 0) (const_int 1)))]
2284 "
2285 operands[2] = GEN_INT (32 - INTVAL (operands[2]));
2286 "
2287 [(set_attr "conds" "clob")
1b7da4ac 2288 (set_attr "length" "8")
2289 (set_attr "type" "multiple")]
f4462328 2290)
2291
2292(define_insn_and_split "*ite_ne_zeroextractsi"
2293 [(set (match_operand:SI 0 "s_register_operand" "=r")
2294 (if_then_else:SI (ne (zero_extract:SI
2295 (match_operand:SI 1 "s_register_operand" "r")
2296 (match_operand:SI 2 "const_int_operand" "n")
2297 (match_operand:SI 3 "const_int_operand" "n"))
2298 (const_int 0))
2299 (match_operand:SI 4 "arm_not_operand" "rIK")
2300 (const_int 0)))
2301 (clobber (reg:CC CC_REGNUM))]
2302 "TARGET_ARM
2303 && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
2304 && INTVAL (operands[2]) > 0
2305 && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
f8d7bf2f 2306 && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)
2307 && !reg_overlap_mentioned_p (operands[0], operands[4])"
f4462328 2308 "#"
2309 "TARGET_ARM
2310 && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
2311 && INTVAL (operands[2]) > 0
2312 && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
f8d7bf2f 2313 && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)
2314 && !reg_overlap_mentioned_p (operands[0], operands[4])"
f4462328 2315 [(parallel [(set (reg:CC_NOOV CC_REGNUM)
2316 (compare:CC_NOOV (and:SI (match_dup 1) (match_dup 2))
2317 (const_int 0)))
2318 (set (match_dup 0) (and:SI (match_dup 1) (match_dup 2)))])
2319 (set (match_dup 0)
2320 (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
2321 (match_dup 0) (match_dup 4)))]
2322 "
c4034607 2323 operands[2] = GEN_INT (((1 << INTVAL (operands[2])) - 1)
f4462328 2324 << INTVAL (operands[3]));
2325 "
2326 [(set_attr "conds" "clob")
1b7da4ac 2327 (set_attr "length" "8")
2328 (set_attr "type" "multiple")]
f4462328 2329)
2330
2331(define_insn_and_split "*ite_ne_zeroextractsi_shifted"
2332 [(set (match_operand:SI 0 "s_register_operand" "=r")
2333 (if_then_else:SI (ne (zero_extract:SI
2334 (match_operand:SI 1 "s_register_operand" "r")
2335 (match_operand:SI 2 "const_int_operand" "n")
2336 (const_int 0))
2337 (const_int 0))
2338 (match_operand:SI 3 "arm_not_operand" "rIK")
2339 (const_int 0)))
2340 (clobber (reg:CC CC_REGNUM))]
f8d7bf2f 2341 "TARGET_ARM && !reg_overlap_mentioned_p (operands[0], operands[3])"
f4462328 2342 "#"
f8d7bf2f 2343 "TARGET_ARM && !reg_overlap_mentioned_p (operands[0], operands[3])"
f4462328 2344 [(parallel [(set (reg:CC_NOOV CC_REGNUM)
2345 (compare:CC_NOOV (ashift:SI (match_dup 1) (match_dup 2))
2346 (const_int 0)))
2347 (set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 2)))])
2348 (set (match_dup 0)
2349 (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
2350 (match_dup 0) (match_dup 3)))]
2351 "
2352 operands[2] = GEN_INT (32 - INTVAL (operands[2]));
0d66636f 2353 "
2354 [(set_attr "conds" "clob")
1b7da4ac 2355 (set_attr "length" "8")
2356 (set_attr "type" "multiple")]
215b30b3 2357)
9c08d1fa 2358
25f905c2 2359;; ??? Use Thumb-2 has bitfield insert/extract instructions.
d7863cfe 2360(define_split
2361 [(set (match_operand:SI 0 "s_register_operand" "")
2362 (match_operator:SI 1 "shiftable_operator"
2363 [(zero_extract:SI (match_operand:SI 2 "s_register_operand" "")
2364 (match_operand:SI 3 "const_int_operand" "")
2365 (match_operand:SI 4 "const_int_operand" ""))
2366 (match_operand:SI 5 "s_register_operand" "")]))
2367 (clobber (match_operand:SI 6 "s_register_operand" ""))]
2368 "TARGET_ARM"
2369 [(set (match_dup 6) (ashift:SI (match_dup 2) (match_dup 3)))
2370 (set (match_dup 0)
2371 (match_op_dup 1
2372 [(lshiftrt:SI (match_dup 6) (match_dup 4))
2373 (match_dup 5)]))]
2374 "{
2375 HOST_WIDE_INT temp = INTVAL (operands[3]);
2376
2377 operands[3] = GEN_INT (32 - temp - INTVAL (operands[4]));
2378 operands[4] = GEN_INT (32 - temp);
2379 }"
2380)
2381
d7863cfe 2382(define_split
2383 [(set (match_operand:SI 0 "s_register_operand" "")
2384 (match_operator:SI 1 "shiftable_operator"
2385 [(sign_extract:SI (match_operand:SI 2 "s_register_operand" "")
2386 (match_operand:SI 3 "const_int_operand" "")
2387 (match_operand:SI 4 "const_int_operand" ""))
2388 (match_operand:SI 5 "s_register_operand" "")]))
2389 (clobber (match_operand:SI 6 "s_register_operand" ""))]
2390 "TARGET_ARM"
2391 [(set (match_dup 6) (ashift:SI (match_dup 2) (match_dup 3)))
2392 (set (match_dup 0)
2393 (match_op_dup 1
2394 [(ashiftrt:SI (match_dup 6) (match_dup 4))
2395 (match_dup 5)]))]
2396 "{
2397 HOST_WIDE_INT temp = INTVAL (operands[3]);
2398
2399 operands[3] = GEN_INT (32 - temp - INTVAL (operands[4]));
2400 operands[4] = GEN_INT (32 - temp);
2401 }"
2402)
2403
a42059fd 2404;;; ??? This pattern is bogus. If operand3 has bits outside the range
2405;;; represented by the bitfield, then this will produce incorrect results.
2406;;; Somewhere, the value needs to be truncated. On targets like the m68k,
ceb2fe0f 2407;;; which have a real bit-field insert instruction, the truncation happens
2408;;; in the bit-field insert instruction itself. Since arm does not have a
2409;;; bit-field insert instruction, we would have to emit code here to truncate
a42059fd 2410;;; the value before we insert. This loses some of the advantage of having
2411;;; this insv pattern, so this pattern needs to be reevalutated.
2412
8a18b90c 2413(define_expand "insv"
eb04cafb 2414 [(set (zero_extract (match_operand 0 "nonimmediate_operand" "")
2415 (match_operand 1 "general_operand" "")
2416 (match_operand 2 "general_operand" ""))
2417 (match_operand 3 "reg_or_int_operand" ""))]
8b054d5a 2418 "TARGET_ARM || arm_arch_thumb2"
8a18b90c 2419 "
215b30b3 2420 {
2421 int start_bit = INTVAL (operands[2]);
2422 int width = INTVAL (operands[1]);
2423 HOST_WIDE_INT mask = (((HOST_WIDE_INT)1) << width) - 1;
2424 rtx target, subtarget;
2425
8b054d5a 2426 if (arm_arch_thumb2)
2427 {
eb04cafb 2428 if (unaligned_access && MEM_P (operands[0])
2429 && s_register_operand (operands[3], GET_MODE (operands[3]))
2430 && (width == 16 || width == 32) && (start_bit % BITS_PER_UNIT) == 0)
8b054d5a 2431 {
eb04cafb 2432 rtx base_addr;
2433
2434 if (BYTES_BIG_ENDIAN)
2435 start_bit = GET_MODE_BITSIZE (GET_MODE (operands[3])) - width
2436 - start_bit;
8b054d5a 2437
eb04cafb 2438 if (width == 32)
8b054d5a 2439 {
eb04cafb 2440 base_addr = adjust_address (operands[0], SImode,
2441 start_bit / BITS_PER_UNIT);
2442 emit_insn (gen_unaligned_storesi (base_addr, operands[3]));
8b054d5a 2443 }
eb04cafb 2444 else
2445 {
2446 rtx tmp = gen_reg_rtx (HImode);
8b054d5a 2447
eb04cafb 2448 base_addr = adjust_address (operands[0], HImode,
2449 start_bit / BITS_PER_UNIT);
2450 emit_move_insn (tmp, gen_lowpart (HImode, operands[3]));
2451 emit_insn (gen_unaligned_storehi (base_addr, tmp));
2452 }
2453 DONE;
8b054d5a 2454 }
eb04cafb 2455 else if (s_register_operand (operands[0], GET_MODE (operands[0])))
8b054d5a 2456 {
eb04cafb 2457 bool use_bfi = TRUE;
8b054d5a 2458
0438d37f 2459 if (CONST_INT_P (operands[3]))
eb04cafb 2460 {
2461 HOST_WIDE_INT val = INTVAL (operands[3]) & mask;
2462
2463 if (val == 0)
2464 {
2465 emit_insn (gen_insv_zero (operands[0], operands[1],
2466 operands[2]));
2467 DONE;
2468 }
2469
2470 /* See if the set can be done with a single orr instruction. */
2471 if (val == mask && const_ok_for_arm (val << start_bit))
2472 use_bfi = FALSE;
2473 }
2474
2475 if (use_bfi)
2476 {
0438d37f 2477 if (!REG_P (operands[3]))
eb04cafb 2478 operands[3] = force_reg (SImode, operands[3]);
2479
2480 emit_insn (gen_insv_t2 (operands[0], operands[1], operands[2],
2481 operands[3]));
2482 DONE;
2483 }
8b054d5a 2484 }
eb04cafb 2485 else
2486 FAIL;
8b054d5a 2487 }
2488
eb04cafb 2489 if (!s_register_operand (operands[0], GET_MODE (operands[0])))
2490 FAIL;
2491
3f8fde42 2492 target = copy_rtx (operands[0]);
215b30b3 2493 /* Avoid using a subreg as a subtarget, and avoid writing a paradoxical
2494 subreg as the final target. */
2495 if (GET_CODE (target) == SUBREG)
2496 {
2497 subtarget = gen_reg_rtx (SImode);
2498 if (GET_MODE_SIZE (GET_MODE (SUBREG_REG (target)))
2499 < GET_MODE_SIZE (SImode))
2500 target = SUBREG_REG (target);
2501 }
2502 else
2503 subtarget = target;
8a18b90c 2504
0438d37f 2505 if (CONST_INT_P (operands[3]))
215b30b3 2506 {
2507 /* Since we are inserting a known constant, we may be able to
2508 reduce the number of bits that we have to clear so that
2509 the mask becomes simple. */
2510 /* ??? This code does not check to see if the new mask is actually
2511 simpler. It may not be. */
2512 rtx op1 = gen_reg_rtx (SImode);
2513 /* ??? Truncate operand3 to fit in the bitfield. See comment before
2514 start of this pattern. */
2515 HOST_WIDE_INT op3_value = mask & INTVAL (operands[3]);
2516 HOST_WIDE_INT mask2 = ((mask & ~op3_value) << start_bit);
2517
c5b3a71b 2518 emit_insn (gen_andsi3 (op1, operands[0],
2519 gen_int_mode (~mask2, SImode)));
215b30b3 2520 emit_insn (gen_iorsi3 (subtarget, op1,
4292ca6b 2521 gen_int_mode (op3_value << start_bit, SImode)));
215b30b3 2522 }
2523 else if (start_bit == 0
2524 && !(const_ok_for_arm (mask)
2525 || const_ok_for_arm (~mask)))
2526 {
2527 /* A Trick, since we are setting the bottom bits in the word,
2528 we can shift operand[3] up, operand[0] down, OR them together
2529 and rotate the result back again. This takes 3 insns, and
5910bb95 2530 the third might be mergeable into another op. */
215b30b3 2531 /* The shift up copes with the possibility that operand[3] is
2532 wider than the bitfield. */
2533 rtx op0 = gen_reg_rtx (SImode);
2534 rtx op1 = gen_reg_rtx (SImode);
2535
2536 emit_insn (gen_ashlsi3 (op0, operands[3], GEN_INT (32 - width)));
2537 emit_insn (gen_lshrsi3 (op1, operands[0], operands[1]));
2538 emit_insn (gen_iorsi3 (op1, op1, op0));
2539 emit_insn (gen_rotlsi3 (subtarget, op1, operands[1]));
2540 }
2541 else if ((width + start_bit == 32)
2542 && !(const_ok_for_arm (mask)
2543 || const_ok_for_arm (~mask)))
2544 {
2545 /* Similar trick, but slightly less efficient. */
8a18b90c 2546
215b30b3 2547 rtx op0 = gen_reg_rtx (SImode);
2548 rtx op1 = gen_reg_rtx (SImode);
8a18b90c 2549
215b30b3 2550 emit_insn (gen_ashlsi3 (op0, operands[3], GEN_INT (32 - width)));
2551 emit_insn (gen_ashlsi3 (op1, operands[0], operands[1]));
2552 emit_insn (gen_lshrsi3 (op1, op1, operands[1]));
2553 emit_insn (gen_iorsi3 (subtarget, op1, op0));
2554 }
2555 else
2556 {
c5b3a71b 2557 rtx op0 = gen_int_mode (mask, SImode);
215b30b3 2558 rtx op1 = gen_reg_rtx (SImode);
2559 rtx op2 = gen_reg_rtx (SImode);
8a18b90c 2560
215b30b3 2561 if (!(const_ok_for_arm (mask) || const_ok_for_arm (~mask)))
2562 {
2563 rtx tmp = gen_reg_rtx (SImode);
8a18b90c 2564
215b30b3 2565 emit_insn (gen_movsi (tmp, op0));
2566 op0 = tmp;
2567 }
8a18b90c 2568
215b30b3 2569 /* Mask out any bits in operand[3] that are not needed. */
2570 emit_insn (gen_andsi3 (op1, operands[3], op0));
8a18b90c 2571
0438d37f 2572 if (CONST_INT_P (op0)
215b30b3 2573 && (const_ok_for_arm (mask << start_bit)
2574 || const_ok_for_arm (~(mask << start_bit))))
2575 {
c5b3a71b 2576 op0 = gen_int_mode (~(mask << start_bit), SImode);
215b30b3 2577 emit_insn (gen_andsi3 (op2, operands[0], op0));
2578 }
2579 else
2580 {
0438d37f 2581 if (CONST_INT_P (op0))
215b30b3 2582 {
2583 rtx tmp = gen_reg_rtx (SImode);
8a18b90c 2584
215b30b3 2585 emit_insn (gen_movsi (tmp, op0));
2586 op0 = tmp;
2587 }
2588
2589 if (start_bit != 0)
2590 emit_insn (gen_ashlsi3 (op0, op0, operands[2]));
a42059fd 2591
215b30b3 2592 emit_insn (gen_andsi_notsi_si (op2, operands[0], op0));
2593 }
8a18b90c 2594
215b30b3 2595 if (start_bit != 0)
2596 emit_insn (gen_ashlsi3 (op1, op1, operands[2]));
8a18b90c 2597
215b30b3 2598 emit_insn (gen_iorsi3 (subtarget, op1, op2));
2599 }
f082f1c4 2600
215b30b3 2601 if (subtarget != target)
2602 {
2603 /* If TARGET is still a SUBREG, then it must be wider than a word,
2604 so we must be careful only to set the subword we were asked to. */
2605 if (GET_CODE (target) == SUBREG)
2606 emit_move_insn (target, subtarget);
2607 else
2608 emit_move_insn (target, gen_lowpart (GET_MODE (target), subtarget));
2609 }
8a18b90c 2610
215b30b3 2611 DONE;
2612 }"
2613)
8a18b90c 2614
8b054d5a 2615(define_insn "insv_zero"
2616 [(set (zero_extract:SI (match_operand:SI 0 "s_register_operand" "+r")
809003b3 2617 (match_operand:SI 1 "const_int_M_operand" "M")
2618 (match_operand:SI 2 "const_int_M_operand" "M"))
8b054d5a 2619 (const_int 0))]
2620 "arm_arch_thumb2"
2621 "bfc%?\t%0, %2, %1"
2622 [(set_attr "length" "4")
d952d547 2623 (set_attr "predicable" "yes")
d82e788e 2624 (set_attr "predicable_short_it" "no")
2625 (set_attr "type" "bfm")]
8b054d5a 2626)
2627
2628(define_insn "insv_t2"
2629 [(set (zero_extract:SI (match_operand:SI 0 "s_register_operand" "+r")
809003b3 2630 (match_operand:SI 1 "const_int_M_operand" "M")
2631 (match_operand:SI 2 "const_int_M_operand" "M"))
8b054d5a 2632 (match_operand:SI 3 "s_register_operand" "r"))]
2633 "arm_arch_thumb2"
2634 "bfi%?\t%0, %3, %2, %1"
2635 [(set_attr "length" "4")
d952d547 2636 (set_attr "predicable" "yes")
d82e788e 2637 (set_attr "predicable_short_it" "no")
2638 (set_attr "type" "bfm")]
8b054d5a 2639)
2640
215b30b3 2641; constants for op 2 will never be given to these patterns.
a0f94409 2642(define_insn_and_split "*anddi_notdi_di"
9c08d1fa 2643 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
e5fea38e 2644 (and:DI (not:DI (match_operand:DI 1 "s_register_operand" "0,r"))
2645 (match_operand:DI 2 "s_register_operand" "r,0")))]
25f905c2 2646 "TARGET_32BIT"
f6ebffac 2647 "#"
e2669ea7 2648 "TARGET_32BIT && reload_completed
2649 && ! (TARGET_NEON && IS_VFP_REGNUM (REGNO (operands[0])))
2650 && ! IS_IWMMXT_REGNUM (REGNO (operands[0]))"
a0f94409 2651 [(set (match_dup 0) (and:SI (not:SI (match_dup 1)) (match_dup 2)))
2652 (set (match_dup 3) (and:SI (not:SI (match_dup 4)) (match_dup 5)))]
2653 "
2654 {
2655 operands[3] = gen_highpart (SImode, operands[0]);
2656 operands[0] = gen_lowpart (SImode, operands[0]);
2657 operands[4] = gen_highpart (SImode, operands[1]);
2658 operands[1] = gen_lowpart (SImode, operands[1]);
2659 operands[5] = gen_highpart (SImode, operands[2]);
2660 operands[2] = gen_lowpart (SImode, operands[2]);
2661 }"
0d66636f 2662 [(set_attr "length" "8")
1b7da4ac 2663 (set_attr "predicable" "yes")
2664 (set_attr "type" "multiple")]
0d66636f 2665)
d952d547 2666
a0f94409 2667(define_insn_and_split "*anddi_notzesidi_di"
9c08d1fa 2668 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2669 (and:DI (not:DI (zero_extend:DI
2670 (match_operand:SI 2 "s_register_operand" "r,r")))
e2348bcb 2671 (match_operand:DI 1 "s_register_operand" "0,?r")))]
25f905c2 2672 "TARGET_32BIT"
e2348bcb 2673 "@
97499065 2674 bic%?\\t%Q0, %Q1, %2
f6ebffac 2675 #"
a0f94409 2676 ; (not (zero_extend ...)) allows us to just copy the high word from
2677 ; operand1 to operand0.
25f905c2 2678 "TARGET_32BIT
a0f94409 2679 && reload_completed
2680 && operands[0] != operands[1]"
5a097f7d 2681 [(set (match_dup 0) (and:SI (not:SI (match_dup 2)) (match_dup 1)))
a0f94409 2682 (set (match_dup 3) (match_dup 4))]
2683 "
2684 {
2685 operands[3] = gen_highpart (SImode, operands[0]);
2686 operands[0] = gen_lowpart (SImode, operands[0]);
2687 operands[4] = gen_highpart (SImode, operands[1]);
2688 operands[1] = gen_lowpart (SImode, operands[1]);
2689 }"
0d66636f 2690 [(set_attr "length" "4,8")
d952d547 2691 (set_attr "predicable" "yes")
1b7da4ac 2692 (set_attr "predicable_short_it" "no")
2693 (set_attr "type" "multiple")]
0d66636f 2694)
d952d547 2695
d8cd5fa0 2696(define_insn_and_split "*anddi_notdi_zesidi"
2697 [(set (match_operand:DI 0 "s_register_operand" "=r")
2698 (and:DI (not:DI (match_operand:DI 2 "s_register_operand" "r"))
2699 (zero_extend:DI
2700 (match_operand:SI 1 "s_register_operand" "r"))))]
2701 "TARGET_32BIT"
2702 "#"
2703 "TARGET_32BIT && reload_completed"
2704 [(set (match_dup 0) (and:SI (not:SI (match_dup 2)) (match_dup 1)))
2705 (set (match_dup 3) (const_int 0))]
2706 "
2707 {
2708 operands[3] = gen_highpart (SImode, operands[0]);
2709 operands[0] = gen_lowpart (SImode, operands[0]);
2710 operands[2] = gen_lowpart (SImode, operands[2]);
2711 }"
2712 [(set_attr "length" "8")
2713 (set_attr "predicable" "yes")
2714 (set_attr "predicable_short_it" "no")
2715 (set_attr "type" "multiple")]
2716)
2717
a0f94409 2718(define_insn_and_split "*anddi_notsesidi_di"
9c08d1fa 2719 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2720 (and:DI (not:DI (sign_extend:DI
2721 (match_operand:SI 2 "s_register_operand" "r,r")))
5a097f7d 2722 (match_operand:DI 1 "s_register_operand" "0,r")))]
25f905c2 2723 "TARGET_32BIT"
f6ebffac 2724 "#"
25f905c2 2725 "TARGET_32BIT && reload_completed"
5a097f7d 2726 [(set (match_dup 0) (and:SI (not:SI (match_dup 2)) (match_dup 1)))
a0f94409 2727 (set (match_dup 3) (and:SI (not:SI
2728 (ashiftrt:SI (match_dup 2) (const_int 31)))
2729 (match_dup 4)))]
2730 "
2731 {
2732 operands[3] = gen_highpart (SImode, operands[0]);
2733 operands[0] = gen_lowpart (SImode, operands[0]);
2734 operands[4] = gen_highpart (SImode, operands[1]);
2735 operands[1] = gen_lowpart (SImode, operands[1]);
2736 }"
0d66636f 2737 [(set_attr "length" "8")
d952d547 2738 (set_attr "predicable" "yes")
1b7da4ac 2739 (set_attr "predicable_short_it" "no")
2740 (set_attr "type" "multiple")]
0d66636f 2741)
d952d547 2742
8a18b90c 2743(define_insn "andsi_notsi_si"
9c08d1fa 2744 [(set (match_operand:SI 0 "s_register_operand" "=r")
2745 (and:SI (not:SI (match_operand:SI 2 "s_register_operand" "r"))
2746 (match_operand:SI 1 "s_register_operand" "r")))]
25f905c2 2747 "TARGET_32BIT"
0d66636f 2748 "bic%?\\t%0, %1, %2"
d952d547 2749 [(set_attr "predicable" "yes")
1b7da4ac 2750 (set_attr "predicable_short_it" "no")
2751 (set_attr "type" "logic_reg")]
0d66636f 2752)
b11cae9e 2753
8a18b90c 2754(define_insn "andsi_not_shiftsi_si"
a2cd141b 2755 [(set (match_operand:SI 0 "s_register_operand" "=r")
2756 (and:SI (not:SI (match_operator:SI 4 "shift_operator"
2757 [(match_operand:SI 2 "s_register_operand" "r")
2758 (match_operand:SI 3 "arm_rhs_operand" "rM")]))
2759 (match_operand:SI 1 "s_register_operand" "r")))]
cffb2a26 2760 "TARGET_ARM"
6c4c2133 2761 "bic%?\\t%0, %1, %2%S4"
344495ea 2762 [(set_attr "predicable" "yes")
331beb1a 2763 (set_attr "shift" "2")
a2cd141b 2764 (set (attr "type") (if_then_else (match_operand 3 "const_int_operand" "")
d82e788e 2765 (const_string "logic_shift_imm")
2766 (const_string "logic_shift_reg")))]
6c4c2133 2767)
8a18b90c 2768
f7fbdd4a 2769(define_insn "*andsi_notsi_si_compare0"
bd5b4116 2770 [(set (reg:CC_NOOV CC_REGNUM)
e2348bcb 2771 (compare:CC_NOOV
2772 (and:SI (not:SI (match_operand:SI 2 "s_register_operand" "r"))
2773 (match_operand:SI 1 "s_register_operand" "r"))
2774 (const_int 0)))
9c08d1fa 2775 (set (match_operand:SI 0 "s_register_operand" "=r")
2776 (and:SI (not:SI (match_dup 2)) (match_dup 1)))]
25f905c2 2777 "TARGET_32BIT"
2778 "bic%.\\t%0, %1, %2"
d82e788e 2779 [(set_attr "conds" "set")
2780 (set_attr "type" "logics_shift_reg")]
0d66636f 2781)
9c08d1fa 2782
f7fbdd4a 2783(define_insn "*andsi_notsi_si_compare0_scratch"
bd5b4116 2784 [(set (reg:CC_NOOV CC_REGNUM)
e2348bcb 2785 (compare:CC_NOOV
2786 (and:SI (not:SI (match_operand:SI 2 "s_register_operand" "r"))
2787 (match_operand:SI 1 "s_register_operand" "r"))
2788 (const_int 0)))
9c08d1fa 2789 (clobber (match_scratch:SI 0 "=r"))]
25f905c2 2790 "TARGET_32BIT"
2791 "bic%.\\t%0, %1, %2"
d82e788e 2792 [(set_attr "conds" "set")
2793 (set_attr "type" "logics_shift_reg")]
0d66636f 2794)
9c08d1fa 2795
e2669ea7 2796(define_expand "iordi3"
2797 [(set (match_operand:DI 0 "s_register_operand" "")
2798 (ior:DI (match_operand:DI 1 "s_register_operand" "")
2799 (match_operand:DI 2 "neon_logic_op2" "")))]
2800 "TARGET_32BIT"
2801 ""
2802)
2803
74d6113f 2804(define_insn_and_split "*iordi3_insn"
2805 [(set (match_operand:DI 0 "s_register_operand" "=w,w ,&r,&r,&r,&r,?w,?w")
2806 (ior:DI (match_operand:DI 1 "s_register_operand" "%w,0 ,0 ,r ,0 ,r ,w ,0")
e0fe6977 2807 (match_operand:DI 2 "arm_iordi_operand_neon" "w ,Dl,r ,r ,Df,Df,w ,Dl")))]
74d6113f 2808 "TARGET_32BIT && !TARGET_IWMMXT"
2809 {
2810 switch (which_alternative)
2811 {
2812 case 0: /* fall through */
2813 case 6: return "vorr\t%P0, %P1, %P2";
2814 case 1: /* fall through */
2815 case 7: return neon_output_logic_immediate ("vorr", &operands[2],
2816 DImode, 0, VALID_NEON_QREG_MODE (DImode));
2817 case 2:
2818 case 3:
2819 case 4:
2820 case 5:
2821 return "#";
2822 default: gcc_unreachable ();
2823 }
2824 }
2825 "TARGET_32BIT && !TARGET_IWMMXT && reload_completed
2826 && !(IS_VFP_REGNUM (REGNO (operands[0])))"
2827 [(set (match_dup 3) (match_dup 4))
2828 (set (match_dup 5) (match_dup 6))]
2829 "
2830 {
2831 operands[3] = gen_lowpart (SImode, operands[0]);
2832 operands[5] = gen_highpart (SImode, operands[0]);
2833
2834 operands[4] = simplify_gen_binary (IOR, SImode,
2835 gen_lowpart (SImode, operands[1]),
2836 gen_lowpart (SImode, operands[2]));
2837 operands[6] = simplify_gen_binary (IOR, SImode,
2838 gen_highpart (SImode, operands[1]),
2839 gen_highpart_mode (SImode, DImode, operands[2]));
2840
2841 }"
32093010 2842 [(set_attr "type" "neon_logic,neon_logic,multiple,multiple,multiple,\
2843 multiple,neon_logic,neon_logic")
e0fe6977 2844 (set_attr "length" "*,*,8,8,8,8,*,*")
74d6113f 2845 (set_attr "arch" "neon_for_64bits,neon_for_64bits,*,*,*,*,avoid_neon_for_64bits,avoid_neon_for_64bits")]
cffb2a26 2846)
9c08d1fa 2847
f7fbdd4a 2848(define_insn "*iordi_zesidi_di"
9c08d1fa 2849 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2850 (ior:DI (zero_extend:DI
2851 (match_operand:SI 2 "s_register_operand" "r,r"))
e2348bcb 2852 (match_operand:DI 1 "s_register_operand" "0,?r")))]
25f905c2 2853 "TARGET_32BIT"
e2348bcb 2854 "@
97499065 2855 orr%?\\t%Q0, %Q1, %2
f6ebffac 2856 #"
0d66636f 2857 [(set_attr "length" "4,8")
d952d547 2858 (set_attr "predicable" "yes")
1b7da4ac 2859 (set_attr "predicable_short_it" "no")
2860 (set_attr "type" "logic_reg,multiple")]
cffb2a26 2861)
9c08d1fa 2862
f7fbdd4a 2863(define_insn "*iordi_sesidi_di"
9c08d1fa 2864 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2865 (ior:DI (sign_extend:DI
2866 (match_operand:SI 2 "s_register_operand" "r,r"))
e5fea38e 2867 (match_operand:DI 1 "s_register_operand" "0,r")))]
25f905c2 2868 "TARGET_32BIT"
f6ebffac 2869 "#"
0d66636f 2870 [(set_attr "length" "8")
1b7da4ac 2871 (set_attr "predicable" "yes")
2872 (set_attr "type" "multiple")]
cffb2a26 2873)
9c08d1fa 2874
87b22bf7 2875(define_expand "iorsi3"
cffb2a26 2876 [(set (match_operand:SI 0 "s_register_operand" "")
87b22bf7 2877 (ior:SI (match_operand:SI 1 "s_register_operand" "")
2878 (match_operand:SI 2 "reg_or_int_operand" "")))]
cffb2a26 2879 "TARGET_EITHER"
87b22bf7 2880 "
0438d37f 2881 if (CONST_INT_P (operands[2]))
87b22bf7 2882 {
25f905c2 2883 if (TARGET_32BIT)
cffb2a26 2884 {
96f57e36 2885 arm_split_constant (IOR, SImode, NULL_RTX,
2886 INTVAL (operands[2]), operands[0], operands[1],
e1ba4a27 2887 optimize && can_create_pseudo_p ());
cffb2a26 2888 DONE;
2889 }
25f905c2 2890 else /* TARGET_THUMB1 */
923ffadb 2891 {
2892 rtx tmp = force_reg (SImode, operands[2]);
2893 if (rtx_equal_p (operands[0], operands[1]))
2894 operands[2] = tmp;
2895 else
2896 {
2897 operands[2] = operands[1];
2898 operands[1] = tmp;
2899 }
2900 }
87b22bf7 2901 }
cffb2a26 2902 "
2903)
87b22bf7 2904
d5d4dc8d 2905(define_insn_and_split "*iorsi3_insn"
29e234a3 2906 [(set (match_operand:SI 0 "s_register_operand" "=r,l,r,r,r")
2907 (ior:SI (match_operand:SI 1 "s_register_operand" "%r,0,r,r,r")
2908 (match_operand:SI 2 "reg_or_int_operand" "I,l,K,r,?n")))]
d5d4dc8d 2909 "TARGET_32BIT"
87b22bf7 2910 "@
29e234a3 2911 orr%?\\t%0, %1, %2
87b22bf7 2912 orr%?\\t%0, %1, %2
d5d4dc8d 2913 orn%?\\t%0, %1, #%B2
65f68e55 2914 orr%?\\t%0, %1, %2
87b22bf7 2915 #"
d5d4dc8d 2916 "TARGET_32BIT
0438d37f 2917 && CONST_INT_P (operands[2])
d5d4dc8d 2918 && !(const_ok_for_arm (INTVAL (operands[2]))
2919 || (TARGET_THUMB2 && const_ok_for_arm (~INTVAL (operands[2]))))"
a0f94409 2920 [(clobber (const_int 0))]
d5d4dc8d 2921{
29e234a3 2922 arm_split_constant (IOR, SImode, curr_insn,
96f57e36 2923 INTVAL (operands[2]), operands[0], operands[1], 0);
a0f94409 2924 DONE;
d5d4dc8d 2925}
29e234a3 2926 [(set_attr "length" "4,4,4,4,16")
2927 (set_attr "arch" "32,t2,t2,32,32")
65f68e55 2928 (set_attr "predicable" "yes")
29e234a3 2929 (set_attr "predicable_short_it" "no,yes,no,no,no")
d82e788e 2930 (set_attr "type" "logic_imm,logic_reg,logic_imm,logic_reg,logic_reg")]
65f68e55 2931)
cffb2a26 2932
a0f94409 2933(define_peephole2
2934 [(match_scratch:SI 3 "r")
372575c7 2935 (set (match_operand:SI 0 "arm_general_register_operand" "")
2936 (ior:SI (match_operand:SI 1 "arm_general_register_operand" "")
87b22bf7 2937 (match_operand:SI 2 "const_int_operand" "")))]
90560cad 2938 "TARGET_ARM
a0f94409 2939 && !const_ok_for_arm (INTVAL (operands[2]))
2940 && const_ok_for_arm (~INTVAL (operands[2]))"
2941 [(set (match_dup 3) (match_dup 2))
2942 (set (match_dup 0) (ior:SI (match_dup 1) (match_dup 3)))]
2943 ""
215b30b3 2944)
a0f94409 2945
f7fbdd4a 2946(define_insn "*iorsi3_compare0"
bd5b4116 2947 [(set (reg:CC_NOOV CC_REGNUM)
65f68e55 2948 (compare:CC_NOOV (ior:SI (match_operand:SI 1 "s_register_operand" "%r,r")
2949 (match_operand:SI 2 "arm_rhs_operand" "I,r"))
9c08d1fa 2950 (const_int 0)))
65f68e55 2951 (set (match_operand:SI 0 "s_register_operand" "=r,r")
9c08d1fa 2952 (ior:SI (match_dup 1) (match_dup 2)))]
25f905c2 2953 "TARGET_32BIT"
2954 "orr%.\\t%0, %1, %2"
65f68e55 2955 [(set_attr "conds" "set")
d82e788e 2956 (set_attr "type" "logics_imm,logics_reg")]
cffb2a26 2957)
9c08d1fa 2958
f7fbdd4a 2959(define_insn "*iorsi3_compare0_scratch"
bd5b4116 2960 [(set (reg:CC_NOOV CC_REGNUM)
65f68e55 2961 (compare:CC_NOOV (ior:SI (match_operand:SI 1 "s_register_operand" "%r,r")
2962 (match_operand:SI 2 "arm_rhs_operand" "I,r"))
9c08d1fa 2963 (const_int 0)))
65f68e55 2964 (clobber (match_scratch:SI 0 "=r,r"))]
25f905c2 2965 "TARGET_32BIT"
2966 "orr%.\\t%0, %1, %2"
65f68e55 2967 [(set_attr "conds" "set")
d82e788e 2968 (set_attr "type" "logics_imm,logics_reg")]
0d66636f 2969)
9c08d1fa 2970
e2669ea7 2971(define_expand "xordi3"
2972 [(set (match_operand:DI 0 "s_register_operand" "")
2973 (xor:DI (match_operand:DI 1 "s_register_operand" "")
8ee7dc6f 2974 (match_operand:DI 2 "arm_xordi_operand" "")))]
e2669ea7 2975 "TARGET_32BIT"
2976 ""
2977)
2978
8ee7dc6f 2979(define_insn_and_split "*xordi3_insn"
2980 [(set (match_operand:DI 0 "s_register_operand" "=w,&r,&r,&r,&r,?w")
205c3b0a 2981 (xor:DI (match_operand:DI 1 "s_register_operand" "%w ,0,r ,0 ,r ,w")
8ee7dc6f 2982 (match_operand:DI 2 "arm_xordi_operand" "w ,r ,r ,Dg,Dg,w")))]
2983 "TARGET_32BIT && !TARGET_IWMMXT"
2984{
2985 switch (which_alternative)
2986 {
2987 case 1:
2988 case 2:
2989 case 3:
2990 case 4: /* fall through */
2991 return "#";
2992 case 0: /* fall through */
2993 case 5: return "veor\t%P0, %P1, %P2";
2994 default: gcc_unreachable ();
2995 }
2996}
2997 "TARGET_32BIT && !TARGET_IWMMXT && reload_completed
2998 && !(IS_VFP_REGNUM (REGNO (operands[0])))"
2999 [(set (match_dup 3) (match_dup 4))
3000 (set (match_dup 5) (match_dup 6))]
3001 "
3002 {
3003 operands[3] = gen_lowpart (SImode, operands[0]);
3004 operands[5] = gen_highpart (SImode, operands[0]);
3005
3006 operands[4] = simplify_gen_binary (XOR, SImode,
3007 gen_lowpart (SImode, operands[1]),
3008 gen_lowpart (SImode, operands[2]));
3009 operands[6] = simplify_gen_binary (XOR, SImode,
3010 gen_highpart (SImode, operands[1]),
3011 gen_highpart_mode (SImode, DImode, operands[2]));
3012
3013 }"
3014 [(set_attr "length" "*,8,8,8,8,*")
32093010 3015 (set_attr "type" "neon_logic,multiple,multiple,multiple,multiple,neon_logic")
8ee7dc6f 3016 (set_attr "arch" "neon_for_64bits,*,*,*,*,avoid_neon_for_64bits")]
cffb2a26 3017)
9c08d1fa 3018
f7fbdd4a 3019(define_insn "*xordi_zesidi_di"
9c08d1fa 3020 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
3021 (xor:DI (zero_extend:DI
3022 (match_operand:SI 2 "s_register_operand" "r,r"))
e2348bcb 3023 (match_operand:DI 1 "s_register_operand" "0,?r")))]
25f905c2 3024 "TARGET_32BIT"
e2348bcb 3025 "@
97499065 3026 eor%?\\t%Q0, %Q1, %2
f6ebffac 3027 #"
0d66636f 3028 [(set_attr "length" "4,8")
d952d547 3029 (set_attr "predicable" "yes")
1b7da4ac 3030 (set_attr "predicable_short_it" "no")
3031 (set_attr "type" "logic_reg")]
cffb2a26 3032)
9c08d1fa 3033
f7fbdd4a 3034(define_insn "*xordi_sesidi_di"
9c08d1fa 3035 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
3036 (xor:DI (sign_extend:DI
3037 (match_operand:SI 2 "s_register_operand" "r,r"))
e5fea38e 3038 (match_operand:DI 1 "s_register_operand" "0,r")))]
25f905c2 3039 "TARGET_32BIT"
f6ebffac 3040 "#"
0d66636f 3041 [(set_attr "length" "8")
1b7da4ac 3042 (set_attr "predicable" "yes")
3043 (set_attr "type" "multiple")]
cffb2a26 3044)
9c08d1fa 3045
cffb2a26 3046(define_expand "xorsi3"
3047 [(set (match_operand:SI 0 "s_register_operand" "")
3048 (xor:SI (match_operand:SI 1 "s_register_operand" "")
923ffadb 3049 (match_operand:SI 2 "reg_or_int_operand" "")))]
cffb2a26 3050 "TARGET_EITHER"
0438d37f 3051 "if (CONST_INT_P (operands[2]))
923ffadb 3052 {
3053 if (TARGET_32BIT)
3054 {
3055 arm_split_constant (XOR, SImode, NULL_RTX,
3056 INTVAL (operands[2]), operands[0], operands[1],
3057 optimize && can_create_pseudo_p ());
3058 DONE;
3059 }
3060 else /* TARGET_THUMB1 */
3061 {
3062 rtx tmp = force_reg (SImode, operands[2]);
3063 if (rtx_equal_p (operands[0], operands[1]))
3064 operands[2] = tmp;
3065 else
3066 {
3067 operands[2] = operands[1];
3068 operands[1] = tmp;
3069 }
3070 }
3071 }"
cffb2a26 3072)
3073
5dcb35d9 3074(define_insn_and_split "*arm_xorsi3"
29e234a3 3075 [(set (match_operand:SI 0 "s_register_operand" "=r,l,r,r")
3076 (xor:SI (match_operand:SI 1 "s_register_operand" "%r,0,r,r")
3077 (match_operand:SI 2 "reg_or_int_operand" "I,l,r,?n")))]
25f905c2 3078 "TARGET_32BIT"
5dcb35d9 3079 "@
29e234a3 3080 eor%?\\t%0, %1, %2
65f68e55 3081 eor%?\\t%0, %1, %2
5dcb35d9 3082 eor%?\\t%0, %1, %2
3083 #"
3084 "TARGET_32BIT
0438d37f 3085 && CONST_INT_P (operands[2])
5dcb35d9 3086 && !const_ok_for_arm (INTVAL (operands[2]))"
3087 [(clobber (const_int 0))]
3088{
3089 arm_split_constant (XOR, SImode, curr_insn,
3090 INTVAL (operands[2]), operands[0], operands[1], 0);
3091 DONE;
3092}
29e234a3 3093 [(set_attr "length" "4,4,4,16")
65f68e55 3094 (set_attr "predicable" "yes")
29e234a3 3095 (set_attr "predicable_short_it" "no,yes,no,no")
1b7da4ac 3096 (set_attr "type" "logic_imm,logic_reg,logic_reg,multiple")]
cffb2a26 3097)
3098
f7fbdd4a 3099(define_insn "*xorsi3_compare0"
bd5b4116 3100 [(set (reg:CC_NOOV CC_REGNUM)
65f68e55 3101 (compare:CC_NOOV (xor:SI (match_operand:SI 1 "s_register_operand" "r,r")
3102 (match_operand:SI 2 "arm_rhs_operand" "I,r"))
9c08d1fa 3103 (const_int 0)))
65f68e55 3104 (set (match_operand:SI 0 "s_register_operand" "=r,r")
9c08d1fa 3105 (xor:SI (match_dup 1) (match_dup 2)))]
25f905c2 3106 "TARGET_32BIT"
3107 "eor%.\\t%0, %1, %2"
65f68e55 3108 [(set_attr "conds" "set")
d82e788e 3109 (set_attr "type" "logics_imm,logics_reg")]
0d66636f 3110)
9c08d1fa 3111
f7fbdd4a 3112(define_insn "*xorsi3_compare0_scratch"
bd5b4116 3113 [(set (reg:CC_NOOV CC_REGNUM)
65f68e55 3114 (compare:CC_NOOV (xor:SI (match_operand:SI 0 "s_register_operand" "r,r")
3115 (match_operand:SI 1 "arm_rhs_operand" "I,r"))
9c08d1fa 3116 (const_int 0)))]
25f905c2 3117 "TARGET_32BIT"
40dbec34 3118 "teq%?\\t%0, %1"
65f68e55 3119 [(set_attr "conds" "set")
d82e788e 3120 (set_attr "type" "logics_imm,logics_reg")]
cffb2a26 3121)
9c08d1fa 3122
215b30b3 3123; By splitting (IOR (AND (NOT A) (NOT B)) C) as D = AND (IOR A B) (NOT C),
3124; (NOT D) we can sometimes merge the final NOT into one of the following
3125; insns.
9c08d1fa 3126
3127(define_split
a058e94a 3128 [(set (match_operand:SI 0 "s_register_operand" "")
3129 (ior:SI (and:SI (not:SI (match_operand:SI 1 "s_register_operand" ""))
3130 (not:SI (match_operand:SI 2 "arm_rhs_operand" "")))
3131 (match_operand:SI 3 "arm_rhs_operand" "")))
3132 (clobber (match_operand:SI 4 "s_register_operand" ""))]
25f905c2 3133 "TARGET_32BIT"
9c08d1fa 3134 [(set (match_dup 4) (and:SI (ior:SI (match_dup 1) (match_dup 2))
3135 (not:SI (match_dup 3))))
3136 (set (match_dup 0) (not:SI (match_dup 4)))]
3137 ""
3138)
3139
ba6a3b2f 3140(define_insn_and_split "*andsi_iorsi3_notsi"
9c08d1fa 3141 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r")
e5fea38e 3142 (and:SI (ior:SI (match_operand:SI 1 "s_register_operand" "%0,r,r")
9c08d1fa 3143 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI"))
3144 (not:SI (match_operand:SI 3 "arm_rhs_operand" "rI,rI,rI"))))]
25f905c2 3145 "TARGET_32BIT"
ba6a3b2f 3146 "#" ; "orr%?\\t%0, %1, %2\;bic%?\\t%0, %0, %3"
3147 "&& reload_completed"
3148 [(set (match_dup 0) (ior:SI (match_dup 1) (match_dup 2)))
3149 (set (match_dup 0) (and:SI (not:SI (match_dup 3)) (match_dup 0)))]
3150 ""
0d66636f 3151 [(set_attr "length" "8")
25f905c2 3152 (set_attr "ce_count" "2")
d952d547 3153 (set_attr "predicable" "yes")
1b7da4ac 3154 (set_attr "predicable_short_it" "no")
3155 (set_attr "type" "multiple")]
cffb2a26 3156)
9c08d1fa 3157
25f905c2 3158; ??? Are these four splitters still beneficial when the Thumb-2 bitfield
3159; insns are available?
d7863cfe 3160(define_split
3161 [(set (match_operand:SI 0 "s_register_operand" "")
3162 (match_operator:SI 1 "logical_binary_operator"
3163 [(zero_extract:SI (match_operand:SI 2 "s_register_operand" "")
3164 (match_operand:SI 3 "const_int_operand" "")
3165 (match_operand:SI 4 "const_int_operand" ""))
3166 (match_operator:SI 9 "logical_binary_operator"
3167 [(lshiftrt:SI (match_operand:SI 5 "s_register_operand" "")
3168 (match_operand:SI 6 "const_int_operand" ""))
3169 (match_operand:SI 7 "s_register_operand" "")])]))
3170 (clobber (match_operand:SI 8 "s_register_operand" ""))]
25f905c2 3171 "TARGET_32BIT
d7863cfe 3172 && GET_CODE (operands[1]) == GET_CODE (operands[9])
3173 && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
3174 [(set (match_dup 8)
3175 (match_op_dup 1
3176 [(ashift:SI (match_dup 2) (match_dup 4))
3177 (match_dup 5)]))
3178 (set (match_dup 0)
3179 (match_op_dup 1
3180 [(lshiftrt:SI (match_dup 8) (match_dup 6))
3181 (match_dup 7)]))]
3182 "
3183 operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
3184")
3185
3186(define_split
3187 [(set (match_operand:SI 0 "s_register_operand" "")
3188 (match_operator:SI 1 "logical_binary_operator"
3189 [(match_operator:SI 9 "logical_binary_operator"
3190 [(lshiftrt:SI (match_operand:SI 5 "s_register_operand" "")
3191 (match_operand:SI 6 "const_int_operand" ""))
3192 (match_operand:SI 7 "s_register_operand" "")])
3193 (zero_extract:SI (match_operand:SI 2 "s_register_operand" "")
3194 (match_operand:SI 3 "const_int_operand" "")
3195 (match_operand:SI 4 "const_int_operand" ""))]))
3196 (clobber (match_operand:SI 8 "s_register_operand" ""))]
25f905c2 3197 "TARGET_32BIT
d7863cfe 3198 && GET_CODE (operands[1]) == GET_CODE (operands[9])
3199 && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
3200 [(set (match_dup 8)
3201 (match_op_dup 1
3202 [(ashift:SI (match_dup 2) (match_dup 4))
3203 (match_dup 5)]))
3204 (set (match_dup 0)
3205 (match_op_dup 1
3206 [(lshiftrt:SI (match_dup 8) (match_dup 6))
3207 (match_dup 7)]))]
3208 "
3209 operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
3210")
3211
3212(define_split
3213 [(set (match_operand:SI 0 "s_register_operand" "")
3214 (match_operator:SI 1 "logical_binary_operator"
3215 [(sign_extract:SI (match_operand:SI 2 "s_register_operand" "")
3216 (match_operand:SI 3 "const_int_operand" "")
3217 (match_operand:SI 4 "const_int_operand" ""))
3218 (match_operator:SI 9 "logical_binary_operator"
3219 [(ashiftrt:SI (match_operand:SI 5 "s_register_operand" "")
3220 (match_operand:SI 6 "const_int_operand" ""))
3221 (match_operand:SI 7 "s_register_operand" "")])]))
3222 (clobber (match_operand:SI 8 "s_register_operand" ""))]
25f905c2 3223 "TARGET_32BIT
d7863cfe 3224 && GET_CODE (operands[1]) == GET_CODE (operands[9])
3225 && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
3226 [(set (match_dup 8)
3227 (match_op_dup 1
3228 [(ashift:SI (match_dup 2) (match_dup 4))
3229 (match_dup 5)]))
3230 (set (match_dup 0)
3231 (match_op_dup 1
3232 [(ashiftrt:SI (match_dup 8) (match_dup 6))
3233 (match_dup 7)]))]
3234 "
3235 operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
3236")
3237
3238(define_split
3239 [(set (match_operand:SI 0 "s_register_operand" "")
3240 (match_operator:SI 1 "logical_binary_operator"
3241 [(match_operator:SI 9 "logical_binary_operator"
3242 [(ashiftrt:SI (match_operand:SI 5 "s_register_operand" "")
3243 (match_operand:SI 6 "const_int_operand" ""))
3244 (match_operand:SI 7 "s_register_operand" "")])
3245 (sign_extract:SI (match_operand:SI 2 "s_register_operand" "")
3246 (match_operand:SI 3 "const_int_operand" "")
3247 (match_operand:SI 4 "const_int_operand" ""))]))
3248 (clobber (match_operand:SI 8 "s_register_operand" ""))]
25f905c2 3249 "TARGET_32BIT
d7863cfe 3250 && GET_CODE (operands[1]) == GET_CODE (operands[9])
3251 && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
3252 [(set (match_dup 8)
3253 (match_op_dup 1
3254 [(ashift:SI (match_dup 2) (match_dup 4))
3255 (match_dup 5)]))
3256 (set (match_dup 0)
3257 (match_op_dup 1
3258 [(ashiftrt:SI (match_dup 8) (match_dup 6))
3259 (match_dup 7)]))]
3260 "
3261 operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
3262")
9c08d1fa 3263\f
3264
3265;; Minimum and maximum insns
3266
8b9dc177 3267(define_expand "smaxsi3"
3268 [(parallel [
3269 (set (match_operand:SI 0 "s_register_operand" "")
3270 (smax:SI (match_operand:SI 1 "s_register_operand" "")
3271 (match_operand:SI 2 "arm_rhs_operand" "")))
3272 (clobber (reg:CC CC_REGNUM))])]
25f905c2 3273 "TARGET_32BIT"
8b9dc177 3274 "
8774928b 3275 if (operands[2] == const0_rtx || operands[2] == constm1_rtx)
8b9dc177 3276 {
3277 /* No need for a clobber of the condition code register here. */
3278 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
3279 gen_rtx_SMAX (SImode, operands[1],
3280 operands[2])));
3281 DONE;
3282 }
3283")
3284
3285(define_insn "*smax_0"
3286 [(set (match_operand:SI 0 "s_register_operand" "=r")
3287 (smax:SI (match_operand:SI 1 "s_register_operand" "r")
3288 (const_int 0)))]
25f905c2 3289 "TARGET_32BIT"
8b9dc177 3290 "bic%?\\t%0, %1, %1, asr #31"
d952d547 3291 [(set_attr "predicable" "yes")
1b7da4ac 3292 (set_attr "predicable_short_it" "no")
3293 (set_attr "type" "logic_shift_reg")]
8b9dc177 3294)
3295
8774928b 3296(define_insn "*smax_m1"
3297 [(set (match_operand:SI 0 "s_register_operand" "=r")
3298 (smax:SI (match_operand:SI 1 "s_register_operand" "r")
3299 (const_int -1)))]
25f905c2 3300 "TARGET_32BIT"
8774928b 3301 "orr%?\\t%0, %1, %1, asr #31"
d952d547 3302 [(set_attr "predicable" "yes")
1b7da4ac 3303 (set_attr "predicable_short_it" "no")
3304 (set_attr "type" "logic_shift_reg")]
8774928b 3305)
3306
3dc953f2 3307(define_insn_and_split "*arm_smax_insn"
8b9dc177 3308 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
3309 (smax:SI (match_operand:SI 1 "s_register_operand" "%0,?r")
3310 (match_operand:SI 2 "arm_rhs_operand" "rI,rI")))
bd5b4116 3311 (clobber (reg:CC CC_REGNUM))]
cffb2a26 3312 "TARGET_ARM"
3dc953f2 3313 "#"
3314 ; cmp\\t%1, %2\;movlt\\t%0, %2
3315 ; cmp\\t%1, %2\;movge\\t%0, %1\;movlt\\t%0, %2"
3316 "TARGET_ARM"
3317 [(set (reg:CC CC_REGNUM)
3318 (compare:CC (match_dup 1) (match_dup 2)))
3319 (set (match_dup 0)
3320 (if_then_else:SI (ge:SI (reg:CC CC_REGNUM) (const_int 0))
3321 (match_dup 1)
3322 (match_dup 2)))]
3323 ""
cffb2a26 3324 [(set_attr "conds" "clob")
1b7da4ac 3325 (set_attr "length" "8,12")
3326 (set_attr "type" "multiple")]
cffb2a26 3327)
9c08d1fa 3328
8b9dc177 3329(define_expand "sminsi3"
3330 [(parallel [
3331 (set (match_operand:SI 0 "s_register_operand" "")
3332 (smin:SI (match_operand:SI 1 "s_register_operand" "")
3333 (match_operand:SI 2 "arm_rhs_operand" "")))
3334 (clobber (reg:CC CC_REGNUM))])]
25f905c2 3335 "TARGET_32BIT"
8b9dc177 3336 "
3337 if (operands[2] == const0_rtx)
3338 {
3339 /* No need for a clobber of the condition code register here. */
3340 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
3341 gen_rtx_SMIN (SImode, operands[1],
3342 operands[2])));
3343 DONE;
3344 }
3345")
3346
3347(define_insn "*smin_0"
3348 [(set (match_operand:SI 0 "s_register_operand" "=r")
3349 (smin:SI (match_operand:SI 1 "s_register_operand" "r")
3350 (const_int 0)))]
25f905c2 3351 "TARGET_32BIT"
8b9dc177 3352 "and%?\\t%0, %1, %1, asr #31"
d952d547 3353 [(set_attr "predicable" "yes")
1b7da4ac 3354 (set_attr "predicable_short_it" "no")
3355 (set_attr "type" "logic_shift_reg")]
8b9dc177 3356)
3357
3dc953f2 3358(define_insn_and_split "*arm_smin_insn"
8b9dc177 3359 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
3360 (smin:SI (match_operand:SI 1 "s_register_operand" "%0,?r")
3361 (match_operand:SI 2 "arm_rhs_operand" "rI,rI")))
bd5b4116 3362 (clobber (reg:CC CC_REGNUM))]
cffb2a26 3363 "TARGET_ARM"
3dc953f2 3364 "#"
3365 ; cmp\\t%1, %2\;movge\\t%0, %2
3366 ; cmp\\t%1, %2\;movlt\\t%0, %1\;movge\\t%0, %2"
3367 "TARGET_ARM"
3368 [(set (reg:CC CC_REGNUM)
3369 (compare:CC (match_dup 1) (match_dup 2)))
3370 (set (match_dup 0)
3371 (if_then_else:SI (lt:SI (reg:CC CC_REGNUM) (const_int 0))
3372 (match_dup 1)
3373 (match_dup 2)))]
3374 ""
0d66636f 3375 [(set_attr "conds" "clob")
1b7da4ac 3376 (set_attr "length" "8,12")
3377 (set_attr "type" "multiple,multiple")]
0d66636f 3378)
9c08d1fa 3379
25f905c2 3380(define_expand "umaxsi3"
3381 [(parallel [
3382 (set (match_operand:SI 0 "s_register_operand" "")
3383 (umax:SI (match_operand:SI 1 "s_register_operand" "")
3384 (match_operand:SI 2 "arm_rhs_operand" "")))
3385 (clobber (reg:CC CC_REGNUM))])]
3386 "TARGET_32BIT"
3387 ""
3388)
3389
3dc953f2 3390(define_insn_and_split "*arm_umaxsi3"
9c08d1fa 3391 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
3392 (umax:SI (match_operand:SI 1 "s_register_operand" "0,r,?r")
3393 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
bd5b4116 3394 (clobber (reg:CC CC_REGNUM))]
cffb2a26 3395 "TARGET_ARM"
3dc953f2 3396 "#"
3397 ; cmp\\t%1, %2\;movcc\\t%0, %2
3398 ; cmp\\t%1, %2\;movcs\\t%0, %1
3399 ; cmp\\t%1, %2\;movcs\\t%0, %1\;movcc\\t%0, %2"
3400 "TARGET_ARM"
3401 [(set (reg:CC CC_REGNUM)
3402 (compare:CC (match_dup 1) (match_dup 2)))
3403 (set (match_dup 0)
3404 (if_then_else:SI (geu:SI (reg:CC CC_REGNUM) (const_int 0))
3405 (match_dup 1)
3406 (match_dup 2)))]
3407 ""
0d66636f 3408 [(set_attr "conds" "clob")
1b7da4ac 3409 (set_attr "length" "8,8,12")
3410 (set_attr "type" "store1")]
0d66636f 3411)
9c08d1fa 3412
25f905c2 3413(define_expand "uminsi3"
3414 [(parallel [
3415 (set (match_operand:SI 0 "s_register_operand" "")
3416 (umin:SI (match_operand:SI 1 "s_register_operand" "")
3417 (match_operand:SI 2 "arm_rhs_operand" "")))
3418 (clobber (reg:CC CC_REGNUM))])]
3419 "TARGET_32BIT"
3420 ""
3421)
3422
3dc953f2 3423(define_insn_and_split "*arm_uminsi3"
9c08d1fa 3424 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
3425 (umin:SI (match_operand:SI 1 "s_register_operand" "0,r,?r")
3426 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
bd5b4116 3427 (clobber (reg:CC CC_REGNUM))]
cffb2a26 3428 "TARGET_ARM"
3dc953f2 3429 "#"
3430 ; cmp\\t%1, %2\;movcs\\t%0, %2
3431 ; cmp\\t%1, %2\;movcc\\t%0, %1
3432 ; cmp\\t%1, %2\;movcc\\t%0, %1\;movcs\\t%0, %2"
3433 "TARGET_ARM"
3434 [(set (reg:CC CC_REGNUM)
3435 (compare:CC (match_dup 1) (match_dup 2)))
3436 (set (match_dup 0)
3437 (if_then_else:SI (ltu:SI (reg:CC CC_REGNUM) (const_int 0))
3438 (match_dup 1)
3439 (match_dup 2)))]
3440 ""
0d66636f 3441 [(set_attr "conds" "clob")
1b7da4ac 3442 (set_attr "length" "8,8,12")
3443 (set_attr "type" "store1")]
0d66636f 3444)
9c08d1fa 3445
8a18b90c 3446(define_insn "*store_minmaxsi"
9c08d1fa 3447 [(set (match_operand:SI 0 "memory_operand" "=m")
3448 (match_operator:SI 3 "minmax_operator"
3449 [(match_operand:SI 1 "s_register_operand" "r")
3450 (match_operand:SI 2 "s_register_operand" "r")]))
bd5b4116 3451 (clobber (reg:CC CC_REGNUM))]
5ce0ce9b 3452 "TARGET_32BIT && optimize_function_for_size_p (cfun)"
9c08d1fa 3453 "*
dc55b8a9 3454 operands[3] = gen_rtx_fmt_ee (minmax_code (operands[3]), SImode,
3455 operands[1], operands[2]);
e2348bcb 3456 output_asm_insn (\"cmp\\t%1, %2\", operands);
25f905c2 3457 if (TARGET_THUMB2)
3458 output_asm_insn (\"ite\t%d3\", operands);
e2348bcb 3459 output_asm_insn (\"str%d3\\t%1, %0\", operands);
3460 output_asm_insn (\"str%D3\\t%2, %0\", operands);
3461 return \"\";
0d66636f 3462 "
3463 [(set_attr "conds" "clob")
25f905c2 3464 (set (attr "length")
3465 (if_then_else (eq_attr "is_thumb" "yes")
3466 (const_int 14)
3467 (const_int 12)))
0d66636f 3468 (set_attr "type" "store1")]
3469)
9c08d1fa 3470
8a18b90c 3471; Reject the frame pointer in operand[1], since reloading this after
3472; it has been eliminated can cause carnage.
f7fbdd4a 3473(define_insn "*minmax_arithsi"
9c08d1fa 3474 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
3475 (match_operator:SI 4 "shiftable_operator"
3476 [(match_operator:SI 5 "minmax_operator"
3477 [(match_operand:SI 2 "s_register_operand" "r,r")
3478 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
3479 (match_operand:SI 1 "s_register_operand" "0,?r")]))
bd5b4116 3480 (clobber (reg:CC CC_REGNUM))]
7c36fe71 3481 "TARGET_32BIT && !arm_eliminable_register (operands[1]) && !arm_restrict_it"
9c08d1fa 3482 "*
0d66636f 3483 {
3484 enum rtx_code code = GET_CODE (operands[4]);
25f905c2 3485 bool need_else;
3486
3487 if (which_alternative != 0 || operands[3] != const0_rtx
ca0fc5a2 3488 || (code != PLUS && code != IOR && code != XOR))
25f905c2 3489 need_else = true;
3490 else
3491 need_else = false;
0d66636f 3492
dc55b8a9 3493 operands[5] = gen_rtx_fmt_ee (minmax_code (operands[5]), SImode,
3494 operands[2], operands[3]);
0d66636f 3495 output_asm_insn (\"cmp\\t%2, %3\", operands);
25f905c2 3496 if (TARGET_THUMB2)
3497 {
3498 if (need_else)
3499 output_asm_insn (\"ite\\t%d5\", operands);
3500 else
3501 output_asm_insn (\"it\\t%d5\", operands);
3502 }
0d66636f 3503 output_asm_insn (\"%i4%d5\\t%0, %1, %2\", operands);
25f905c2 3504 if (need_else)
0d66636f 3505 output_asm_insn (\"%i4%D5\\t%0, %1, %3\", operands);
3506 return \"\";
215b30b3 3507 }"
0d66636f 3508 [(set_attr "conds" "clob")
25f905c2 3509 (set (attr "length")
3510 (if_then_else (eq_attr "is_thumb" "yes")
3511 (const_int 14)
1b7da4ac 3512 (const_int 12)))
3513 (set_attr "type" "multiple")]
0d66636f 3514)
9c08d1fa 3515
4164bca1 3516; Reject the frame pointer in operand[1], since reloading this after
3517; it has been eliminated can cause carnage.
3518(define_insn_and_split "*minmax_arithsi_non_canon"
7c36fe71 3519 [(set (match_operand:SI 0 "s_register_operand" "=Ts,Ts")
4164bca1 3520 (minus:SI
7c36fe71 3521 (match_operand:SI 1 "s_register_operand" "0,?Ts")
4164bca1 3522 (match_operator:SI 4 "minmax_operator"
7c36fe71 3523 [(match_operand:SI 2 "s_register_operand" "Ts,Ts")
3524 (match_operand:SI 3 "arm_rhs_operand" "TsI,TsI")])))
4164bca1 3525 (clobber (reg:CC CC_REGNUM))]
7c36fe71 3526 "TARGET_32BIT && !arm_eliminable_register (operands[1])
3527 && !(arm_restrict_it && CONST_INT_P (operands[3]))"
4164bca1 3528 "#"
3529 "TARGET_32BIT && !arm_eliminable_register (operands[1]) && reload_completed"
3530 [(set (reg:CC CC_REGNUM)
3531 (compare:CC (match_dup 2) (match_dup 3)))
3532
3533 (cond_exec (match_op_dup 4 [(reg:CC CC_REGNUM) (const_int 0)])
3534 (set (match_dup 0)
3535 (minus:SI (match_dup 1)
3536 (match_dup 2))))
3537 (cond_exec (match_op_dup 5 [(reg:CC CC_REGNUM) (const_int 0)])
3538 (set (match_dup 0)
36ee0cde 3539 (match_dup 6)))]
4164bca1 3540 {
3541 enum machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
3542 operands[2], operands[3]);
3543 enum rtx_code rc = minmax_code (operands[4]);
3544 operands[4] = gen_rtx_fmt_ee (rc, VOIDmode,
3545 operands[2], operands[3]);
3546
3547 if (mode == CCFPmode || mode == CCFPEmode)
3548 rc = reverse_condition_maybe_unordered (rc);
3549 else
3550 rc = reverse_condition (rc);
3551 operands[5] = gen_rtx_fmt_ee (rc, SImode, operands[2], operands[3]);
36ee0cde 3552 if (CONST_INT_P (operands[3]))
3553 operands[6] = plus_constant (SImode, operands[1], -INTVAL (operands[3]));
3554 else
3555 operands[6] = gen_rtx_MINUS (SImode, operands[1], operands[3]);
4164bca1 3556 }
3557 [(set_attr "conds" "clob")
3558 (set (attr "length")
3559 (if_then_else (eq_attr "is_thumb" "yes")
3560 (const_int 14)
1b7da4ac 3561 (const_int 12)))
3562 (set_attr "type" "multiple")]
4164bca1 3563)
3564
b49e3742 3565(define_code_iterator SAT [smin smax])
3566(define_code_iterator SATrev [smin smax])
3567(define_code_attr SATlo [(smin "1") (smax "2")])
3568(define_code_attr SAThi [(smin "2") (smax "1")])
3569
3570(define_insn "*satsi_<SAT:code>"
3571 [(set (match_operand:SI 0 "s_register_operand" "=r")
3572 (SAT:SI (SATrev:SI (match_operand:SI 3 "s_register_operand" "r")
3573 (match_operand:SI 1 "const_int_operand" "i"))
3574 (match_operand:SI 2 "const_int_operand" "i")))]
3575 "TARGET_32BIT && arm_arch6 && <SAT:CODE> != <SATrev:CODE>
3576 && arm_sat_operator_match (operands[<SAT:SATlo>], operands[<SAT:SAThi>], NULL, NULL)"
3577{
3578 int mask;
3579 bool signed_sat;
3580 if (!arm_sat_operator_match (operands[<SAT:SATlo>], operands[<SAT:SAThi>],
3581 &mask, &signed_sat))
3582 gcc_unreachable ();
3583
3584 operands[1] = GEN_INT (mask);
3585 if (signed_sat)
3586 return "ssat%?\t%0, %1, %3";
3587 else
3588 return "usat%?\t%0, %1, %3";
3589}
7c36fe71 3590 [(set_attr "predicable" "yes")
1b7da4ac 3591 (set_attr "predicable_short_it" "no")
3592 (set_attr "type" "alus_imm")]
bebe9bbb 3593)
b49e3742 3594
3595(define_insn "*satsi_<SAT:code>_shift"
3596 [(set (match_operand:SI 0 "s_register_operand" "=r")
3597 (SAT:SI (SATrev:SI (match_operator:SI 3 "sat_shift_operator"
3598 [(match_operand:SI 4 "s_register_operand" "r")
3599 (match_operand:SI 5 "const_int_operand" "i")])
3600 (match_operand:SI 1 "const_int_operand" "i"))
3601 (match_operand:SI 2 "const_int_operand" "i")))]
3602 "TARGET_32BIT && arm_arch6 && <SAT:CODE> != <SATrev:CODE>
3603 && arm_sat_operator_match (operands[<SAT:SATlo>], operands[<SAT:SAThi>], NULL, NULL)"
3604{
3605 int mask;
3606 bool signed_sat;
3607 if (!arm_sat_operator_match (operands[<SAT:SATlo>], operands[<SAT:SAThi>],
3608 &mask, &signed_sat))
3609 gcc_unreachable ();
3610
3611 operands[1] = GEN_INT (mask);
3612 if (signed_sat)
3613 return "ssat%?\t%0, %1, %4%S3";
3614 else
3615 return "usat%?\t%0, %1, %4%S3";
3616}
3617 [(set_attr "predicable" "yes")
7c36fe71 3618 (set_attr "predicable_short_it" "no")
b49e3742 3619 (set_attr "shift" "3")
d82e788e 3620 (set_attr "type" "logic_shift_reg")])
b11cae9e 3621\f
3622;; Shift and rotation insns
3623
a2cd141b 3624(define_expand "ashldi3"
3625 [(set (match_operand:DI 0 "s_register_operand" "")
3626 (ashift:DI (match_operand:DI 1 "s_register_operand" "")
aa06c51c 3627 (match_operand:SI 2 "general_operand" "")))]
25f905c2 3628 "TARGET_32BIT"
a2cd141b 3629 "
aa06c51c 3630 if (TARGET_NEON)
3631 {
3632 /* Delay the decision whether to use NEON or core-regs until
3633 register allocation. */
3634 emit_insn (gen_ashldi3_neon (operands[0], operands[1], operands[2]));
3635 DONE;
3636 }
3637 else
3638 {
3639 /* Only the NEON case can handle in-memory shift counts. */
3640 if (!reg_or_int_operand (operands[2], SImode))
3641 operands[2] = force_reg (SImode, operands[2]);
3642 }
3643
b805622c 3644 if (!CONST_INT_P (operands[2]) && TARGET_REALLY_IWMMXT)
ffcc986d 3645 ; /* No special preparation statements; expand pattern as above. */
3646 else
a2cd141b 3647 {
ffcc986d 3648 rtx scratch1, scratch2;
3649
3650 if (CONST_INT_P (operands[2])
3651 && (HOST_WIDE_INT) INTVAL (operands[2]) == 1)
a2cd141b 3652 {
3653 emit_insn (gen_arm_ashldi3_1bit (operands[0], operands[1]));
3654 DONE;
3655 }
ffcc986d 3656
3657 /* Ideally we should use iwmmxt here if we could know that operands[1]
3658 ends up already living in an iwmmxt register. Otherwise it's
3659 cheaper to have the alternate code being generated than moving
3660 values to iwmmxt regs and back. */
3661
3662 /* If we're optimizing for size, we prefer the libgcc calls. */
3663 if (optimize_function_for_size_p (cfun))
3664 FAIL;
3665
3666 /* Expand operation using core-registers.
3667 'FAIL' would achieve the same thing, but this is a bit smarter. */
3668 scratch1 = gen_reg_rtx (SImode);
3669 scratch2 = gen_reg_rtx (SImode);
3670 arm_emit_coreregs_64bit_shift (ASHIFT, operands[0], operands[1],
3671 operands[2], scratch1, scratch2);
3672 DONE;
a2cd141b 3673 }
a2cd141b 3674 "
3675)
3676
2837e3fb 3677(define_insn "arm_ashldi3_1bit"
50ad1bf9 3678 [(set (match_operand:DI 0 "s_register_operand" "=r,&r")
e5fea38e 3679 (ashift:DI (match_operand:DI 1 "s_register_operand" "0,r")
a2cd141b 3680 (const_int 1)))
3681 (clobber (reg:CC CC_REGNUM))]
25f905c2 3682 "TARGET_32BIT"
2837e3fb 3683 "movs\\t%Q0, %Q1, asl #1\;adc\\t%R0, %R1, %R1"
a2cd141b 3684 [(set_attr "conds" "clob")
1b7da4ac 3685 (set_attr "length" "8")
3686 (set_attr "type" "multiple")]
a2cd141b 3687)
3688
87b22bf7 3689(define_expand "ashlsi3"
cffb2a26 3690 [(set (match_operand:SI 0 "s_register_operand" "")
87b22bf7 3691 (ashift:SI (match_operand:SI 1 "s_register_operand" "")
3692 (match_operand:SI 2 "arm_rhs_operand" "")))]
cffb2a26 3693 "TARGET_EITHER"
87b22bf7 3694 "
0438d37f 3695 if (CONST_INT_P (operands[2])
87b22bf7 3696 && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) > 31)
3697 {
3698 emit_insn (gen_movsi (operands[0], const0_rtx));
3699 DONE;
3700 }
cffb2a26 3701 "
3702)
3703
a2cd141b 3704(define_expand "ashrdi3"
3705 [(set (match_operand:DI 0 "s_register_operand" "")
3706 (ashiftrt:DI (match_operand:DI 1 "s_register_operand" "")
3707 (match_operand:SI 2 "reg_or_int_operand" "")))]
25f905c2 3708 "TARGET_32BIT"
a2cd141b 3709 "
aa06c51c 3710 if (TARGET_NEON)
3711 {
3712 /* Delay the decision whether to use NEON or core-regs until
3713 register allocation. */
3714 emit_insn (gen_ashrdi3_neon (operands[0], operands[1], operands[2]));
3715 DONE;
3716 }
3717
b805622c 3718 if (!CONST_INT_P (operands[2]) && TARGET_REALLY_IWMMXT)
ffcc986d 3719 ; /* No special preparation statements; expand pattern as above. */
3720 else
a2cd141b 3721 {
ffcc986d 3722 rtx scratch1, scratch2;
3723
3724 if (CONST_INT_P (operands[2])
3725 && (HOST_WIDE_INT) INTVAL (operands[2]) == 1)
a2cd141b 3726 {
3727 emit_insn (gen_arm_ashrdi3_1bit (operands[0], operands[1]));
3728 DONE;
3729 }
ffcc986d 3730
3731 /* Ideally we should use iwmmxt here if we could know that operands[1]
3732 ends up already living in an iwmmxt register. Otherwise it's
3733 cheaper to have the alternate code being generated than moving
3734 values to iwmmxt regs and back. */
3735
3736 /* If we're optimizing for size, we prefer the libgcc calls. */
3737 if (optimize_function_for_size_p (cfun))
3738 FAIL;
3739
3740 /* Expand operation using core-registers.
3741 'FAIL' would achieve the same thing, but this is a bit smarter. */
3742 scratch1 = gen_reg_rtx (SImode);
3743 scratch2 = gen_reg_rtx (SImode);
3744 arm_emit_coreregs_64bit_shift (ASHIFTRT, operands[0], operands[1],
3745 operands[2], scratch1, scratch2);
3746 DONE;
a2cd141b 3747 }
a2cd141b 3748 "
3749)
3750
2837e3fb 3751(define_insn "arm_ashrdi3_1bit"
50ad1bf9 3752 [(set (match_operand:DI 0 "s_register_operand" "=r,&r")
e5fea38e 3753 (ashiftrt:DI (match_operand:DI 1 "s_register_operand" "0,r")
a2cd141b 3754 (const_int 1)))
3755 (clobber (reg:CC CC_REGNUM))]
25f905c2 3756 "TARGET_32BIT"
2837e3fb 3757 "movs\\t%R0, %R1, asr #1\;mov\\t%Q0, %Q1, rrx"
a2cd141b 3758 [(set_attr "conds" "clob")
1b7da4ac 3759 (set_attr "length" "8")
3760 (set_attr "type" "multiple")]
a2cd141b 3761)
3762
87b22bf7 3763(define_expand "ashrsi3"
cffb2a26 3764 [(set (match_operand:SI 0 "s_register_operand" "")
87b22bf7 3765 (ashiftrt:SI (match_operand:SI 1 "s_register_operand" "")
3766 (match_operand:SI 2 "arm_rhs_operand" "")))]
cffb2a26 3767 "TARGET_EITHER"
87b22bf7 3768 "
0438d37f 3769 if (CONST_INT_P (operands[2])
87b22bf7 3770 && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) > 31)
3771 operands[2] = GEN_INT (31);
cffb2a26 3772 "
3773)
3774
a2cd141b 3775(define_expand "lshrdi3"
3776 [(set (match_operand:DI 0 "s_register_operand" "")
3777 (lshiftrt:DI (match_operand:DI 1 "s_register_operand" "")
3778 (match_operand:SI 2 "reg_or_int_operand" "")))]
25f905c2 3779 "TARGET_32BIT"
a2cd141b 3780 "
aa06c51c 3781 if (TARGET_NEON)
3782 {
3783 /* Delay the decision whether to use NEON or core-regs until
3784 register allocation. */
3785 emit_insn (gen_lshrdi3_neon (operands[0], operands[1], operands[2]));
3786 DONE;
3787 }
3788
b805622c 3789 if (!CONST_INT_P (operands[2]) && TARGET_REALLY_IWMMXT)
ffcc986d 3790 ; /* No special preparation statements; expand pattern as above. */
3791 else
a2cd141b 3792 {
ffcc986d 3793 rtx scratch1, scratch2;
3794
3795 if (CONST_INT_P (operands[2])
3796 && (HOST_WIDE_INT) INTVAL (operands[2]) == 1)
a2cd141b 3797 {
3798 emit_insn (gen_arm_lshrdi3_1bit (operands[0], operands[1]));
3799 DONE;
3800 }
ffcc986d 3801
3802 /* Ideally we should use iwmmxt here if we could know that operands[1]
3803 ends up already living in an iwmmxt register. Otherwise it's
3804 cheaper to have the alternate code being generated than moving
3805 values to iwmmxt regs and back. */
3806
3807 /* If we're optimizing for size, we prefer the libgcc calls. */
3808 if (optimize_function_for_size_p (cfun))
3809 FAIL;
3810
3811 /* Expand operation using core-registers.
3812 'FAIL' would achieve the same thing, but this is a bit smarter. */
3813 scratch1 = gen_reg_rtx (SImode);
3814 scratch2 = gen_reg_rtx (SImode);
3815 arm_emit_coreregs_64bit_shift (LSHIFTRT, operands[0], operands[1],
3816 operands[2], scratch1, scratch2);
3817 DONE;
a2cd141b 3818 }
a2cd141b 3819 "
3820)
3821
2837e3fb 3822(define_insn "arm_lshrdi3_1bit"
50ad1bf9 3823 [(set (match_operand:DI 0 "s_register_operand" "=r,&r")
e5fea38e 3824 (lshiftrt:DI (match_operand:DI 1 "s_register_operand" "0,r")
a2cd141b 3825 (const_int 1)))
3826 (clobber (reg:CC CC_REGNUM))]
25f905c2 3827 "TARGET_32BIT"
2837e3fb 3828 "movs\\t%R0, %R1, lsr #1\;mov\\t%Q0, %Q1, rrx"
a2cd141b 3829 [(set_attr "conds" "clob")
1b7da4ac 3830 (set_attr "length" "8")
3831 (set_attr "type" "multiple")]
a2cd141b 3832)
3833
87b22bf7 3834(define_expand "lshrsi3"
cffb2a26 3835 [(set (match_operand:SI 0 "s_register_operand" "")
87b22bf7 3836 (lshiftrt:SI (match_operand:SI 1 "s_register_operand" "")
3837 (match_operand:SI 2 "arm_rhs_operand" "")))]
cffb2a26 3838 "TARGET_EITHER"
87b22bf7 3839 "
0438d37f 3840 if (CONST_INT_P (operands[2])
87b22bf7 3841 && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) > 31)
3842 {
3843 emit_insn (gen_movsi (operands[0], const0_rtx));
3844 DONE;
3845 }
cffb2a26 3846 "
3847)
3848
87b22bf7 3849(define_expand "rotlsi3"
cffb2a26 3850 [(set (match_operand:SI 0 "s_register_operand" "")
87b22bf7 3851 (rotatert:SI (match_operand:SI 1 "s_register_operand" "")
3852 (match_operand:SI 2 "reg_or_int_operand" "")))]
25f905c2 3853 "TARGET_32BIT"
87b22bf7 3854 "
0438d37f 3855 if (CONST_INT_P (operands[2]))
87b22bf7 3856 operands[2] = GEN_INT ((32 - INTVAL (operands[2])) % 32);
3857 else
b11cae9e 3858 {
87b22bf7 3859 rtx reg = gen_reg_rtx (SImode);
3860 emit_insn (gen_subsi3 (reg, GEN_INT (32), operands[2]));
3861 operands[2] = reg;
b11cae9e 3862 }
cffb2a26 3863 "
3864)
9c08d1fa 3865
87b22bf7 3866(define_expand "rotrsi3"
cffb2a26 3867 [(set (match_operand:SI 0 "s_register_operand" "")
87b22bf7 3868 (rotatert:SI (match_operand:SI 1 "s_register_operand" "")
3869 (match_operand:SI 2 "arm_rhs_operand" "")))]
cffb2a26 3870 "TARGET_EITHER"
87b22bf7 3871 "
25f905c2 3872 if (TARGET_32BIT)
cffb2a26 3873 {
0438d37f 3874 if (CONST_INT_P (operands[2])
cffb2a26 3875 && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) > 31)
3876 operands[2] = GEN_INT (INTVAL (operands[2]) % 32);
3877 }
25f905c2 3878 else /* TARGET_THUMB1 */
cffb2a26 3879 {
0438d37f 3880 if (CONST_INT_P (operands [2]))
cffb2a26 3881 operands [2] = force_reg (SImode, operands[2]);
3882 }
3883 "
3884)
87b22bf7 3885
cffb2a26 3886(define_insn "*arm_shiftsi3"
88c29385 3887 [(set (match_operand:SI 0 "s_register_operand" "=l,l,r,r")
cffb2a26 3888 (match_operator:SI 3 "shift_operator"
88c29385 3889 [(match_operand:SI 1 "s_register_operand" "0,l,r,r")
3890 (match_operand:SI 2 "reg_or_int_operand" "l,M,M,r")]))]
25f905c2 3891 "TARGET_32BIT"
3892 "* return arm_output_shift(operands, 0);"
344495ea 3893 [(set_attr "predicable" "yes")
88c29385 3894 (set_attr "arch" "t2,t2,*,*")
3895 (set_attr "predicable_short_it" "yes,yes,no,no")
7c36fe71 3896 (set_attr "length" "4")
331beb1a 3897 (set_attr "shift" "1")
88c29385 3898 (set_attr "type" "alu_shift_reg,alu_shift_imm,alu_shift_imm,alu_shift_reg")]
6c4c2133 3899)
87b22bf7 3900
f7fbdd4a 3901(define_insn "*shiftsi3_compare0"
bd5b4116 3902 [(set (reg:CC_NOOV CC_REGNUM)
87b22bf7 3903 (compare:CC_NOOV (match_operator:SI 3 "shift_operator"
6b6abc9c 3904 [(match_operand:SI 1 "s_register_operand" "r,r")
3905 (match_operand:SI 2 "arm_rhs_operand" "M,r")])
9c08d1fa 3906 (const_int 0)))
6b6abc9c 3907 (set (match_operand:SI 0 "s_register_operand" "=r,r")
87b22bf7 3908 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))]
25f905c2 3909 "TARGET_32BIT"
3910 "* return arm_output_shift(operands, 1);"
344495ea 3911 [(set_attr "conds" "set")
331beb1a 3912 (set_attr "shift" "1")
d82e788e 3913 (set_attr "type" "alus_shift_imm,alus_shift_reg")]
0d66636f 3914)
9c08d1fa 3915
f7fbdd4a 3916(define_insn "*shiftsi3_compare0_scratch"
bd5b4116 3917 [(set (reg:CC_NOOV CC_REGNUM)
87b22bf7 3918 (compare:CC_NOOV (match_operator:SI 3 "shift_operator"
6b6abc9c 3919 [(match_operand:SI 1 "s_register_operand" "r,r")
3920 (match_operand:SI 2 "arm_rhs_operand" "M,r")])
9c08d1fa 3921 (const_int 0)))
6b6abc9c 3922 (clobber (match_scratch:SI 0 "=r,r"))]
25f905c2 3923 "TARGET_32BIT"
3924 "* return arm_output_shift(operands, 1);"
344495ea 3925 [(set_attr "conds" "set")
6b6abc9c 3926 (set_attr "shift" "1")
d82e788e 3927 (set_attr "type" "shift_imm,shift_reg")]
0d66636f 3928)
9c08d1fa 3929
d5d4dc8d 3930(define_insn "*not_shiftsi"
3931 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
87b22bf7 3932 (not:SI (match_operator:SI 3 "shift_operator"
d5d4dc8d 3933 [(match_operand:SI 1 "s_register_operand" "r,r")
3934 (match_operand:SI 2 "shift_amount_operand" "M,rM")])))]
3935 "TARGET_32BIT"
6c4c2133 3936 "mvn%?\\t%0, %1%S3"
344495ea 3937 [(set_attr "predicable" "yes")
d952d547 3938 (set_attr "predicable_short_it" "no")
331beb1a 3939 (set_attr "shift" "1")
d5d4dc8d 3940 (set_attr "arch" "32,a")
1aed5204 3941 (set_attr "type" "mvn_shift,mvn_shift_reg")])
9c08d1fa 3942
d5d4dc8d 3943(define_insn "*not_shiftsi_compare0"
bd5b4116 3944 [(set (reg:CC_NOOV CC_REGNUM)
d5d4dc8d 3945 (compare:CC_NOOV
3946 (not:SI (match_operator:SI 3 "shift_operator"
3947 [(match_operand:SI 1 "s_register_operand" "r,r")
3948 (match_operand:SI 2 "shift_amount_operand" "M,rM")]))
3949 (const_int 0)))
3950 (set (match_operand:SI 0 "s_register_operand" "=r,r")
87b22bf7 3951 (not:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)])))]
d5d4dc8d 3952 "TARGET_32BIT"
25f905c2 3953 "mvn%.\\t%0, %1%S3"
344495ea 3954 [(set_attr "conds" "set")
331beb1a 3955 (set_attr "shift" "1")
d5d4dc8d 3956 (set_attr "arch" "32,a")
1aed5204 3957 (set_attr "type" "mvn_shift,mvn_shift_reg")])
9c08d1fa 3958
d5d4dc8d 3959(define_insn "*not_shiftsi_compare0_scratch"
bd5b4116 3960 [(set (reg:CC_NOOV CC_REGNUM)
d5d4dc8d 3961 (compare:CC_NOOV
3962 (not:SI (match_operator:SI 3 "shift_operator"
3963 [(match_operand:SI 1 "s_register_operand" "r,r")
3964 (match_operand:SI 2 "shift_amount_operand" "M,rM")]))
3965 (const_int 0)))
3966 (clobber (match_scratch:SI 0 "=r,r"))]
3967 "TARGET_32BIT"
25f905c2 3968 "mvn%.\\t%0, %1%S3"
344495ea 3969 [(set_attr "conds" "set")
331beb1a 3970 (set_attr "shift" "1")
d5d4dc8d 3971 (set_attr "arch" "32,a")
1aed5204 3972 (set_attr "type" "mvn_shift,mvn_shift_reg")])
9c08d1fa 3973
cffb2a26 3974;; We don't really have extzv, but defining this using shifts helps
3975;; to reduce register pressure later on.
3976
3977(define_expand "extzv"
eb04cafb 3978 [(set (match_operand 0 "s_register_operand" "")
3979 (zero_extract (match_operand 1 "nonimmediate_operand" "")
3980 (match_operand 2 "const_int_operand" "")
3981 (match_operand 3 "const_int_operand" "")))]
8b054d5a 3982 "TARGET_THUMB1 || arm_arch_thumb2"
cffb2a26 3983 "
3984 {
3985 HOST_WIDE_INT lshift = 32 - INTVAL (operands[2]) - INTVAL (operands[3]);
3986 HOST_WIDE_INT rshift = 32 - INTVAL (operands[2]);
3987
8b054d5a 3988 if (arm_arch_thumb2)
3989 {
eb04cafb 3990 HOST_WIDE_INT width = INTVAL (operands[2]);
3991 HOST_WIDE_INT bitpos = INTVAL (operands[3]);
3992
3993 if (unaligned_access && MEM_P (operands[1])
3994 && (width == 16 || width == 32) && (bitpos % BITS_PER_UNIT) == 0)
3995 {
3996 rtx base_addr;
3997
3998 if (BYTES_BIG_ENDIAN)
3999 bitpos = GET_MODE_BITSIZE (GET_MODE (operands[0])) - width
4000 - bitpos;
4001
4002 if (width == 32)
4003 {
4004 base_addr = adjust_address (operands[1], SImode,
4005 bitpos / BITS_PER_UNIT);
4006 emit_insn (gen_unaligned_loadsi (operands[0], base_addr));
4007 }
4008 else
4009 {
4010 rtx dest = operands[0];
4011 rtx tmp = gen_reg_rtx (SImode);
4012
4013 /* We may get a paradoxical subreg here. Strip it off. */
4014 if (GET_CODE (dest) == SUBREG
4015 && GET_MODE (dest) == SImode
4016 && GET_MODE (SUBREG_REG (dest)) == HImode)
4017 dest = SUBREG_REG (dest);
4018
4019 if (GET_MODE_BITSIZE (GET_MODE (dest)) != width)
4020 FAIL;
4021
4022 base_addr = adjust_address (operands[1], HImode,
4023 bitpos / BITS_PER_UNIT);
4024 emit_insn (gen_unaligned_loadhiu (tmp, base_addr));
4025 emit_move_insn (gen_lowpart (SImode, dest), tmp);
4026 }
4027 DONE;
4028 }
4029 else if (s_register_operand (operands[1], GET_MODE (operands[1])))
4030 {
4031 emit_insn (gen_extzv_t2 (operands[0], operands[1], operands[2],
4032 operands[3]));
4033 DONE;
4034 }
4035 else
4036 FAIL;
8b054d5a 4037 }
eb04cafb 4038
4039 if (!s_register_operand (operands[1], GET_MODE (operands[1])))
4040 FAIL;
8b054d5a 4041
cffb2a26 4042 operands[3] = GEN_INT (rshift);
4043
4044 if (lshift == 0)
4045 {
4046 emit_insn (gen_lshrsi3 (operands[0], operands[1], operands[3]));
4047 DONE;
4048 }
4049
eb04cafb 4050 emit_insn (gen_extzv_t1 (operands[0], operands[1], GEN_INT (lshift),
4051 operands[3], gen_reg_rtx (SImode)));
4052 DONE;
215b30b3 4053 }"
cffb2a26 4054)
4055
eb04cafb 4056;; Helper for extzv, for the Thumb-1 register-shifts case.
4057
4058(define_expand "extzv_t1"
4059 [(set (match_operand:SI 4 "s_register_operand" "")
4060 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
4061 (match_operand:SI 2 "const_int_operand" "")))
4062 (set (match_operand:SI 0 "s_register_operand" "")
4063 (lshiftrt:SI (match_dup 4)
4064 (match_operand:SI 3 "const_int_operand" "")))]
4065 "TARGET_THUMB1"
4066 "")
4067
4068(define_expand "extv"
4069 [(set (match_operand 0 "s_register_operand" "")
4070 (sign_extract (match_operand 1 "nonimmediate_operand" "")
4071 (match_operand 2 "const_int_operand" "")
4072 (match_operand 3 "const_int_operand" "")))]
4073 "arm_arch_thumb2"
4074{
4075 HOST_WIDE_INT width = INTVAL (operands[2]);
4076 HOST_WIDE_INT bitpos = INTVAL (operands[3]);
4077
4078 if (unaligned_access && MEM_P (operands[1]) && (width == 16 || width == 32)
4079 && (bitpos % BITS_PER_UNIT) == 0)
4080 {
4081 rtx base_addr;
4082
4083 if (BYTES_BIG_ENDIAN)
4084 bitpos = GET_MODE_BITSIZE (GET_MODE (operands[0])) - width - bitpos;
4085
4086 if (width == 32)
4087 {
4088 base_addr = adjust_address (operands[1], SImode,
4089 bitpos / BITS_PER_UNIT);
4090 emit_insn (gen_unaligned_loadsi (operands[0], base_addr));
4091 }
4092 else
4093 {
4094 rtx dest = operands[0];
4095 rtx tmp = gen_reg_rtx (SImode);
4096
4097 /* We may get a paradoxical subreg here. Strip it off. */
4098 if (GET_CODE (dest) == SUBREG
4099 && GET_MODE (dest) == SImode
4100 && GET_MODE (SUBREG_REG (dest)) == HImode)
4101 dest = SUBREG_REG (dest);
4102
4103 if (GET_MODE_BITSIZE (GET_MODE (dest)) != width)
4104 FAIL;
4105
4106 base_addr = adjust_address (operands[1], HImode,
4107 bitpos / BITS_PER_UNIT);
4108 emit_insn (gen_unaligned_loadhis (tmp, base_addr));
4109 emit_move_insn (gen_lowpart (SImode, dest), tmp);
4110 }
4111
4112 DONE;
4113 }
4114 else if (!s_register_operand (operands[1], GET_MODE (operands[1])))
4115 FAIL;
4116 else if (GET_MODE (operands[0]) == SImode
4117 && GET_MODE (operands[1]) == SImode)
4118 {
4119 emit_insn (gen_extv_regsi (operands[0], operands[1], operands[2],
4120 operands[3]));
4121 DONE;
4122 }
4123
4124 FAIL;
4125})
4126
4127; Helper to expand register forms of extv with the proper modes.
4128
4129(define_expand "extv_regsi"
4130 [(set (match_operand:SI 0 "s_register_operand" "")
4131 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "")
4132 (match_operand 2 "const_int_operand" "")
4133 (match_operand 3 "const_int_operand" "")))]
4134 ""
4135{
4136})
4137
4138; ARMv6+ unaligned load/store instructions (used for packed structure accesses).
4139
4140(define_insn "unaligned_loadsi"
4141 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
4142 (unspec:SI [(match_operand:SI 1 "memory_operand" "Uw,m")]
4143 UNSPEC_UNALIGNED_LOAD))]
4144 "unaligned_access && TARGET_32BIT"
4145 "ldr%?\t%0, %1\t@ unaligned"
4146 [(set_attr "arch" "t2,any")
4147 (set_attr "length" "2,4")
4148 (set_attr "predicable" "yes")
d952d547 4149 (set_attr "predicable_short_it" "yes,no")
eb04cafb 4150 (set_attr "type" "load1")])
4151
4152(define_insn "unaligned_loadhis"
4153 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
4154 (sign_extend:SI
e3f4ccee 4155 (unspec:HI [(match_operand:HI 1 "memory_operand" "Uw,Uh")]
eb04cafb 4156 UNSPEC_UNALIGNED_LOAD)))]
4157 "unaligned_access && TARGET_32BIT"
4158 "ldr%(sh%)\t%0, %1\t@ unaligned"
4159 [(set_attr "arch" "t2,any")
4160 (set_attr "length" "2,4")
4161 (set_attr "predicable" "yes")
d952d547 4162 (set_attr "predicable_short_it" "yes,no")
eb04cafb 4163 (set_attr "type" "load_byte")])
4164
4165(define_insn "unaligned_loadhiu"
4166 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
4167 (zero_extend:SI
4168 (unspec:HI [(match_operand:HI 1 "memory_operand" "Uw,m")]
4169 UNSPEC_UNALIGNED_LOAD)))]
4170 "unaligned_access && TARGET_32BIT"
4171 "ldr%(h%)\t%0, %1\t@ unaligned"
4172 [(set_attr "arch" "t2,any")
4173 (set_attr "length" "2,4")
4174 (set_attr "predicable" "yes")
d952d547 4175 (set_attr "predicable_short_it" "yes,no")
eb04cafb 4176 (set_attr "type" "load_byte")])
4177
4178(define_insn "unaligned_storesi"
4179 [(set (match_operand:SI 0 "memory_operand" "=Uw,m")
4180 (unspec:SI [(match_operand:SI 1 "s_register_operand" "l,r")]
4181 UNSPEC_UNALIGNED_STORE))]
4182 "unaligned_access && TARGET_32BIT"
4183 "str%?\t%1, %0\t@ unaligned"
4184 [(set_attr "arch" "t2,any")
4185 (set_attr "length" "2,4")
4186 (set_attr "predicable" "yes")
d952d547 4187 (set_attr "predicable_short_it" "yes,no")
eb04cafb 4188 (set_attr "type" "store1")])
4189
4190(define_insn "unaligned_storehi"
4191 [(set (match_operand:HI 0 "memory_operand" "=Uw,m")
4192 (unspec:HI [(match_operand:HI 1 "s_register_operand" "l,r")]
4193 UNSPEC_UNALIGNED_STORE))]
4194 "unaligned_access && TARGET_32BIT"
4195 "str%(h%)\t%1, %0\t@ unaligned"
4196 [(set_attr "arch" "t2,any")
4197 (set_attr "length" "2,4")
4198 (set_attr "predicable" "yes")
d952d547 4199 (set_attr "predicable_short_it" "yes,no")
eb04cafb 4200 (set_attr "type" "store1")])
4201
ae51a965 4202;; Unaligned double-word load and store.
4203;; Split after reload into two unaligned single-word accesses.
4204;; It prevents lower_subreg from splitting some other aligned
4205;; double-word accesses too early. Used for internal memcpy.
4206
4207(define_insn_and_split "unaligned_loaddi"
4208 [(set (match_operand:DI 0 "s_register_operand" "=l,r")
4209 (unspec:DI [(match_operand:DI 1 "memory_operand" "o,o")]
4210 UNSPEC_UNALIGNED_LOAD))]
4211 "unaligned_access && TARGET_32BIT"
4212 "#"
4213 "&& reload_completed"
4214 [(set (match_dup 0) (unspec:SI [(match_dup 1)] UNSPEC_UNALIGNED_LOAD))
4215 (set (match_dup 2) (unspec:SI [(match_dup 3)] UNSPEC_UNALIGNED_LOAD))]
4216 {
4217 operands[2] = gen_highpart (SImode, operands[0]);
4218 operands[0] = gen_lowpart (SImode, operands[0]);
4219 operands[3] = gen_highpart (SImode, operands[1]);
4220 operands[1] = gen_lowpart (SImode, operands[1]);
4221
4222 /* If the first destination register overlaps with the base address,
4223 swap the order in which the loads are emitted. */
4224 if (reg_overlap_mentioned_p (operands[0], operands[1]))
4225 {
4226 rtx tmp = operands[1];
4227 operands[1] = operands[3];
4228 operands[3] = tmp;
4229 tmp = operands[0];
4230 operands[0] = operands[2];
4231 operands[2] = tmp;
4232 }
4233 }
4234 [(set_attr "arch" "t2,any")
4235 (set_attr "length" "4,8")
4236 (set_attr "predicable" "yes")
4237 (set_attr "type" "load2")])
4238
4239(define_insn_and_split "unaligned_storedi"
4240 [(set (match_operand:DI 0 "memory_operand" "=o,o")
4241 (unspec:DI [(match_operand:DI 1 "s_register_operand" "l,r")]
4242 UNSPEC_UNALIGNED_STORE))]
4243 "unaligned_access && TARGET_32BIT"
4244 "#"
4245 "&& reload_completed"
4246 [(set (match_dup 0) (unspec:SI [(match_dup 1)] UNSPEC_UNALIGNED_STORE))
4247 (set (match_dup 2) (unspec:SI [(match_dup 3)] UNSPEC_UNALIGNED_STORE))]
4248 {
4249 operands[2] = gen_highpart (SImode, operands[0]);
4250 operands[0] = gen_lowpart (SImode, operands[0]);
4251 operands[3] = gen_highpart (SImode, operands[1]);
4252 operands[1] = gen_lowpart (SImode, operands[1]);
4253 }
4254 [(set_attr "arch" "t2,any")
4255 (set_attr "length" "4,8")
4256 (set_attr "predicable" "yes")
4257 (set_attr "type" "store2")])
4258
4259
eb04cafb 4260(define_insn "*extv_reg"
8b054d5a 4261 [(set (match_operand:SI 0 "s_register_operand" "=r")
4262 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
809003b3 4263 (match_operand:SI 2 "const_int_M_operand" "M")
4264 (match_operand:SI 3 "const_int_M_operand" "M")))]
8b054d5a 4265 "arm_arch_thumb2"
4266 "sbfx%?\t%0, %1, %3, %2"
4267 [(set_attr "length" "4")
d952d547 4268 (set_attr "predicable" "yes")
d82e788e 4269 (set_attr "predicable_short_it" "no")
4270 (set_attr "type" "bfm")]
8b054d5a 4271)
4272
4273(define_insn "extzv_t2"
4274 [(set (match_operand:SI 0 "s_register_operand" "=r")
4275 (zero_extract:SI (match_operand:SI 1 "s_register_operand" "r")
809003b3 4276 (match_operand:SI 2 "const_int_M_operand" "M")
4277 (match_operand:SI 3 "const_int_M_operand" "M")))]
8b054d5a 4278 "arm_arch_thumb2"
4279 "ubfx%?\t%0, %1, %3, %2"
4280 [(set_attr "length" "4")
d952d547 4281 (set_attr "predicable" "yes")
d82e788e 4282 (set_attr "predicable_short_it" "no")
4283 (set_attr "type" "bfm")]
8b054d5a 4284)
4285
7d3cda8c 4286
4287;; Division instructions
4288(define_insn "divsi3"
4289 [(set (match_operand:SI 0 "s_register_operand" "=r")
4290 (div:SI (match_operand:SI 1 "s_register_operand" "r")
4291 (match_operand:SI 2 "s_register_operand" "r")))]
4292 "TARGET_IDIV"
4293 "sdiv%?\t%0, %1, %2"
4294 [(set_attr "predicable" "yes")
d952d547 4295 (set_attr "predicable_short_it" "no")
9da0ec36 4296 (set_attr "type" "sdiv")]
7d3cda8c 4297)
4298
4299(define_insn "udivsi3"
4300 [(set (match_operand:SI 0 "s_register_operand" "=r")
4301 (udiv:SI (match_operand:SI 1 "s_register_operand" "r")
4302 (match_operand:SI 2 "s_register_operand" "r")))]
4303 "TARGET_IDIV"
4304 "udiv%?\t%0, %1, %2"
4305 [(set_attr "predicable" "yes")
d952d547 4306 (set_attr "predicable_short_it" "no")
9da0ec36 4307 (set_attr "type" "udiv")]
7d3cda8c 4308)
4309
b11cae9e 4310\f
4311;; Unary arithmetic insns
4312
cffb2a26 4313(define_expand "negdi2"
4314 [(parallel
8135a42b 4315 [(set (match_operand:DI 0 "s_register_operand" "")
4316 (neg:DI (match_operand:DI 1 "s_register_operand" "")))
bd5b4116 4317 (clobber (reg:CC CC_REGNUM))])]
cffb2a26 4318 "TARGET_EITHER"
774d2fbb 4319 {
4320 if (TARGET_NEON)
4321 {
4322 emit_insn (gen_negdi2_neon (operands[0], operands[1]));
4323 DONE;
4324 }
4325 }
cffb2a26 4326)
4327
4328;; The constraints here are to prevent a *partial* overlap (where %Q0 == %R1).
e5fea38e 4329;; The first alternative allows the common case of a *full* overlap.
ba6a3b2f 4330(define_insn_and_split "*arm_negdi2"
458a8706 4331 [(set (match_operand:DI 0 "s_register_operand" "=r,&r")
e5fea38e 4332 (neg:DI (match_operand:DI 1 "s_register_operand" "0,r")))
bd5b4116 4333 (clobber (reg:CC CC_REGNUM))]
cffb2a26 4334 "TARGET_ARM"
ba6a3b2f 4335 "#" ; "rsbs\\t%Q0, %Q1, #0\;rsc\\t%R0, %R1, #0"
4336 "&& reload_completed"
4337 [(parallel [(set (reg:CC CC_REGNUM)
4338 (compare:CC (const_int 0) (match_dup 1)))
4339 (set (match_dup 0) (minus:SI (const_int 0) (match_dup 1)))])
4340 (set (match_dup 2) (minus:SI (minus:SI (const_int 0) (match_dup 3))
4341 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
4342 {
4343 operands[2] = gen_highpart (SImode, operands[0]);
4344 operands[0] = gen_lowpart (SImode, operands[0]);
4345 operands[3] = gen_highpart (SImode, operands[1]);
4346 operands[1] = gen_lowpart (SImode, operands[1]);
4347 }
cffb2a26 4348 [(set_attr "conds" "clob")
1b7da4ac 4349 (set_attr "length" "8")
4350 (set_attr "type" "multiple")]
cffb2a26 4351)
b11cae9e 4352
cffb2a26 4353(define_expand "negsi2"
4354 [(set (match_operand:SI 0 "s_register_operand" "")
4355 (neg:SI (match_operand:SI 1 "s_register_operand" "")))]
4356 "TARGET_EITHER"
b11cae9e 4357 ""
cffb2a26 4358)
4359
4360(define_insn "*arm_negsi2"
d952d547 4361 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
4362 (neg:SI (match_operand:SI 1 "s_register_operand" "l,r")))]
25f905c2 4363 "TARGET_32BIT"
cffb2a26 4364 "rsb%?\\t%0, %1, #0"
d952d547 4365 [(set_attr "predicable" "yes")
4366 (set_attr "predicable_short_it" "yes,no")
4367 (set_attr "arch" "t2,*")
1b7da4ac 4368 (set_attr "length" "4")
112eda6f 4369 (set_attr "type" "alu_sreg")]
cffb2a26 4370)
4371
604f3a0a 4372(define_expand "negsf2"
4373 [(set (match_operand:SF 0 "s_register_operand" "")
4374 (neg:SF (match_operand:SF 1 "s_register_operand" "")))]
994606f8 4375 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
604f3a0a 4376 ""
4377)
4378
4379(define_expand "negdf2"
4380 [(set (match_operand:DF 0 "s_register_operand" "")
4381 (neg:DF (match_operand:DF 1 "s_register_operand" "")))]
994606f8 4382 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
604f3a0a 4383 "")
4384
7eaf2be0 4385(define_insn_and_split "*zextendsidi_negsi"
4386 [(set (match_operand:DI 0 "s_register_operand" "=r")
4387 (zero_extend:DI (neg:SI (match_operand:SI 1 "s_register_operand" "r"))))]
4388 "TARGET_32BIT"
4389 "#"
4390 ""
4391 [(set (match_dup 2)
4392 (neg:SI (match_dup 1)))
4393 (set (match_dup 3)
4394 (const_int 0))]
4395 {
4396 operands[2] = gen_lowpart (SImode, operands[0]);
4397 operands[3] = gen_highpart (SImode, operands[0]);
4398 }
4399 [(set_attr "length" "8")
4400 (set_attr "type" "multiple")]
4401)
4402
83e2b922 4403;; Negate an extended 32-bit value.
4404(define_insn_and_split "*negdi_extendsidi"
61fa8ff2 4405 [(set (match_operand:DI 0 "s_register_operand" "=l,r")
4406 (neg:DI (sign_extend:DI
4407 (match_operand:SI 1 "s_register_operand" "l,r"))))
83e2b922 4408 (clobber (reg:CC CC_REGNUM))]
4409 "TARGET_32BIT"
61fa8ff2 4410 "#"
83e2b922 4411 "&& reload_completed"
4412 [(const_int 0)]
4413 {
61fa8ff2 4414 rtx low = gen_lowpart (SImode, operands[0]);
4415 rtx high = gen_highpart (SImode, operands[0]);
4416
4417 if (reg_overlap_mentioned_p (low, operands[1]))
4418 {
4419 /* Input overlaps the low word of the output. Use:
4420 asr Rhi, Rin, #31
4421 rsbs Rlo, Rin, #0
4422 rsc Rhi, Rhi, #0 (thumb2: sbc Rhi, Rhi, Rhi, lsl #1). */
4423 rtx cc_reg = gen_rtx_REG (CC_Cmode, CC_REGNUM);
4424
4425 emit_insn (gen_rtx_SET (VOIDmode, high,
4426 gen_rtx_ASHIFTRT (SImode, operands[1],
4427 GEN_INT (31))));
4428
4429 emit_insn (gen_subsi3_compare (low, const0_rtx, operands[1]));
4430 if (TARGET_ARM)
4431 emit_insn (gen_rtx_SET (VOIDmode, high,
4432 gen_rtx_MINUS (SImode,
4433 gen_rtx_MINUS (SImode,
4434 const0_rtx,
4435 high),
4436 gen_rtx_LTU (SImode,
4437 cc_reg,
4438 const0_rtx))));
4439 else
4440 {
4441 rtx two_x = gen_rtx_ASHIFT (SImode, high, GEN_INT (1));
4442 emit_insn (gen_rtx_SET (VOIDmode, high,
4443 gen_rtx_MINUS (SImode,
4444 gen_rtx_MINUS (SImode,
4445 high,
4446 two_x),
4447 gen_rtx_LTU (SImode,
4448 cc_reg,
4449 const0_rtx))));
4450 }
4451 }
4452 else
4453 {
4454 /* No overlap, or overlap on high word. Use:
4455 rsb Rlo, Rin, #0
4456 bic Rhi, Rlo, Rin
4457 asr Rhi, Rhi, #31
4458 Flags not needed for this sequence. */
4459 emit_insn (gen_rtx_SET (VOIDmode, low,
4460 gen_rtx_NEG (SImode, operands[1])));
4461 emit_insn (gen_rtx_SET (VOIDmode, high,
4462 gen_rtx_AND (SImode,
4463 gen_rtx_NOT (SImode, operands[1]),
4464 low)));
4465 emit_insn (gen_rtx_SET (VOIDmode, high,
4466 gen_rtx_ASHIFTRT (SImode, high,
4467 GEN_INT (31))));
4468 }
4469 DONE;
83e2b922 4470 }
61fa8ff2 4471 [(set_attr "length" "12")
4472 (set_attr "arch" "t2,*")
1b7da4ac 4473 (set_attr "type" "multiple")]
83e2b922 4474)
4475
4476(define_insn_and_split "*negdi_zero_extendsidi"
4477 [(set (match_operand:DI 0 "s_register_operand" "=r,&r")
4478 (neg:DI (zero_extend:DI (match_operand:SI 1 "s_register_operand" "0,r"))))
4479 (clobber (reg:CC CC_REGNUM))]
4480 "TARGET_32BIT"
4481 "#" ; "rsbs\\t%Q0, %1, #0\;sbc\\t%R0,%R0,%R0"
4482 ;; Don't care what register is input to sbc,
4483 ;; since we just just need to propagate the carry.
4484 "&& reload_completed"
4485 [(parallel [(set (reg:CC CC_REGNUM)
4486 (compare:CC (const_int 0) (match_dup 1)))
4487 (set (match_dup 0) (minus:SI (const_int 0) (match_dup 1)))])
4488 (set (match_dup 2) (minus:SI (minus:SI (match_dup 2) (match_dup 2))
4489 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
4490 {
4491 operands[2] = gen_highpart (SImode, operands[0]);
4492 operands[0] = gen_lowpart (SImode, operands[0]);
4493 }
4494 [(set_attr "conds" "clob")
1b7da4ac 4495 (set_attr "length" "8")
4496 (set_attr "type" "multiple")] ;; length in thumb is 4
83e2b922 4497)
4498
9c08d1fa 4499;; abssi2 doesn't really clobber the condition codes if a different register
4500;; is being set. To keep things simple, assume during rtl manipulations that
4501;; it does, but tell the final scan operator the truth. Similarly for
4502;; (neg (abs...))
4503
604f3a0a 4504(define_expand "abssi2"
4505 [(parallel
4506 [(set (match_operand:SI 0 "s_register_operand" "")
4507 (abs:SI (match_operand:SI 1 "s_register_operand" "")))
ba156559 4508 (clobber (match_dup 2))])]
4509 "TARGET_EITHER"
4510 "
25f905c2 4511 if (TARGET_THUMB1)
ba156559 4512 operands[2] = gen_rtx_SCRATCH (SImode);
4513 else
4514 operands[2] = gen_rtx_REG (CCmode, CC_REGNUM);
4515")
604f3a0a 4516
ba6a3b2f 4517(define_insn_and_split "*arm_abssi2"
ba156559 4518 [(set (match_operand:SI 0 "s_register_operand" "=r,&r")
9c08d1fa 4519 (abs:SI (match_operand:SI 1 "s_register_operand" "0,r")))
bd5b4116 4520 (clobber (reg:CC CC_REGNUM))]
cffb2a26 4521 "TARGET_ARM"
ba6a3b2f 4522 "#"
4523 "&& reload_completed"
4524 [(const_int 0)]
4525 {
4526 /* if (which_alternative == 0) */
4527 if (REGNO(operands[0]) == REGNO(operands[1]))
4528 {
4529 /* Emit the pattern:
4530 cmp\\t%0, #0\;rsblt\\t%0, %0, #0
4531 [(set (reg:CC CC_REGNUM)
4532 (compare:CC (match_dup 0) (const_int 0)))
4533 (cond_exec (lt:CC (reg:CC CC_REGNUM) (const_int 0))
4534 (set (match_dup 0) (minus:SI (const_int 0) (match_dup 1))))]
4535 */
4536 emit_insn (gen_rtx_SET (VOIDmode,
4537 gen_rtx_REG (CCmode, CC_REGNUM),
4538 gen_rtx_COMPARE (CCmode, operands[0], const0_rtx)));
4539 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
4540 (gen_rtx_LT (SImode,
4541 gen_rtx_REG (CCmode, CC_REGNUM),
4542 const0_rtx)),
4543 (gen_rtx_SET (VOIDmode,
4544 operands[0],
4545 (gen_rtx_MINUS (SImode,
4546 const0_rtx,
4547 operands[1]))))));
4548 DONE;
4549 }
4550 else
4551 {
4552 /* Emit the pattern:
4553 alt1: eor%?\\t%0, %1, %1, asr #31\;sub%?\\t%0, %0, %1, asr #31
4554 [(set (match_dup 0)
4555 (xor:SI (match_dup 1)
4556 (ashiftrt:SI (match_dup 1) (const_int 31))))
4557 (set (match_dup 0)
4558 (minus:SI (match_dup 0)
4559 (ashiftrt:SI (match_dup 1) (const_int 31))))]
4560 */
4561 emit_insn (gen_rtx_SET (VOIDmode,
4562 operands[0],
4563 gen_rtx_XOR (SImode,
4564 gen_rtx_ASHIFTRT (SImode,
4565 operands[1],
4566 GEN_INT (31)),
4567 operands[1])));
4568 emit_insn (gen_rtx_SET (VOIDmode,
4569 operands[0],
4570 gen_rtx_MINUS (SImode,
4571 operands[0],
4572 gen_rtx_ASHIFTRT (SImode,
4573 operands[1],
4574 GEN_INT (31)))));
4575 DONE;
4576 }
4577 }
cffb2a26 4578 [(set_attr "conds" "clob,*")
331beb1a 4579 (set_attr "shift" "1")
2ad08b65 4580 (set_attr "predicable" "no, yes")
1b7da4ac 4581 (set_attr "length" "8")
4582 (set_attr "type" "multiple")]
cffb2a26 4583)
9c08d1fa 4584
ba6a3b2f 4585(define_insn_and_split "*arm_neg_abssi2"
9c08d1fa 4586 [(set (match_operand:SI 0 "s_register_operand" "=r,&r")
4587 (neg:SI (abs:SI (match_operand:SI 1 "s_register_operand" "0,r"))))
bd5b4116 4588 (clobber (reg:CC CC_REGNUM))]
cffb2a26 4589 "TARGET_ARM"
ba6a3b2f 4590 "#"
4591 "&& reload_completed"
4592 [(const_int 0)]
4593 {
4594 /* if (which_alternative == 0) */
4595 if (REGNO (operands[0]) == REGNO (operands[1]))
4596 {
4597 /* Emit the pattern:
4598 cmp\\t%0, #0\;rsbgt\\t%0, %0, #0
4599 */
4600 emit_insn (gen_rtx_SET (VOIDmode,
4601 gen_rtx_REG (CCmode, CC_REGNUM),
4602 gen_rtx_COMPARE (CCmode, operands[0], const0_rtx)));
4603 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
4604 gen_rtx_GT (SImode,
4605 gen_rtx_REG (CCmode, CC_REGNUM),
4606 const0_rtx),
4607 gen_rtx_SET (VOIDmode,
4608 operands[0],
4609 (gen_rtx_MINUS (SImode,
4610 const0_rtx,
4611 operands[1])))));
4612 }
4613 else
4614 {
4615 /* Emit the pattern:
4616 eor%?\\t%0, %1, %1, asr #31\;rsb%?\\t%0, %0, %1, asr #31
4617 */
4618 emit_insn (gen_rtx_SET (VOIDmode,
4619 operands[0],
4620 gen_rtx_XOR (SImode,
4621 gen_rtx_ASHIFTRT (SImode,
4622 operands[1],
4623 GEN_INT (31)),
4624 operands[1])));
4625 emit_insn (gen_rtx_SET (VOIDmode,
4626 operands[0],
4627 gen_rtx_MINUS (SImode,
4628 gen_rtx_ASHIFTRT (SImode,
4629 operands[1],
4630 GEN_INT (31)),
4631 operands[0])));
4632 }
4633 DONE;
4634 }
cffb2a26 4635 [(set_attr "conds" "clob,*")
331beb1a 4636 (set_attr "shift" "1")
2ad08b65 4637 (set_attr "predicable" "no, yes")
1b7da4ac 4638 (set_attr "length" "8")
4639 (set_attr "type" "multiple")]
cffb2a26 4640)
b11cae9e 4641
604f3a0a 4642(define_expand "abssf2"
4643 [(set (match_operand:SF 0 "s_register_operand" "")
4644 (abs:SF (match_operand:SF 1 "s_register_operand" "")))]
25f905c2 4645 "TARGET_32BIT && TARGET_HARD_FLOAT"
604f3a0a 4646 "")
4647
604f3a0a 4648(define_expand "absdf2"
4649 [(set (match_operand:DF 0 "s_register_operand" "")
4650 (abs:DF (match_operand:DF 1 "s_register_operand" "")))]
a50d7267 4651 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
604f3a0a 4652 "")
4653
7db9af5d 4654(define_expand "sqrtsf2"
4655 [(set (match_operand:SF 0 "s_register_operand" "")
4656 (sqrt:SF (match_operand:SF 1 "s_register_operand" "")))]
994606f8 4657 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
7db9af5d 4658 "")
9c08d1fa 4659
7db9af5d 4660(define_expand "sqrtdf2"
4661 [(set (match_operand:DF 0 "s_register_operand" "")
4662 (sqrt:DF (match_operand:DF 1 "s_register_operand" "")))]
994606f8 4663 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
7db9af5d 4664 "")
9c08d1fa 4665
a0f94409 4666(define_insn_and_split "one_cmpldi2"
10efb95f 4667 [(set (match_operand:DI 0 "s_register_operand" "=w,&r,&r,?w")
4668 (not:DI (match_operand:DI 1 "s_register_operand" " w, 0, r, w")))]
25f905c2 4669 "TARGET_32BIT"
10efb95f 4670 "@
4671 vmvn\t%P0, %P1
4672 #
4673 #
4674 vmvn\t%P0, %P1"
4675 "TARGET_32BIT && reload_completed
4676 && arm_general_register_operand (operands[0], DImode)"
a0f94409 4677 [(set (match_dup 0) (not:SI (match_dup 1)))
4678 (set (match_dup 2) (not:SI (match_dup 3)))]
4679 "
4680 {
4681 operands[2] = gen_highpart (SImode, operands[0]);
4682 operands[0] = gen_lowpart (SImode, operands[0]);
4683 operands[3] = gen_highpart (SImode, operands[1]);
4684 operands[1] = gen_lowpart (SImode, operands[1]);
4685 }"
10efb95f 4686 [(set_attr "length" "*,8,8,*")
4687 (set_attr "predicable" "no,yes,yes,no")
32093010 4688 (set_attr "type" "neon_move,multiple,multiple,neon_move")
b6779ddc 4689 (set_attr "arch" "neon_for_64bits,*,*,avoid_neon_for_64bits")]
cffb2a26 4690)
b11cae9e 4691
cffb2a26 4692(define_expand "one_cmplsi2"
4693 [(set (match_operand:SI 0 "s_register_operand" "")
4694 (not:SI (match_operand:SI 1 "s_register_operand" "")))]
4695 "TARGET_EITHER"
b11cae9e 4696 ""
cffb2a26 4697)
4698
4699(define_insn "*arm_one_cmplsi2"
d952d547 4700 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
4701 (not:SI (match_operand:SI 1 "s_register_operand" "l,r")))]
25f905c2 4702 "TARGET_32BIT"
cffb2a26 4703 "mvn%?\\t%0, %1"
d2a518d1 4704 [(set_attr "predicable" "yes")
d952d547 4705 (set_attr "predicable_short_it" "yes,no")
4706 (set_attr "arch" "t2,*")
4707 (set_attr "length" "4")
1aed5204 4708 (set_attr "type" "mvn_reg")]
cffb2a26 4709)
4710
f7fbdd4a 4711(define_insn "*notsi_compare0"
bd5b4116 4712 [(set (reg:CC_NOOV CC_REGNUM)
9c08d1fa 4713 (compare:CC_NOOV (not:SI (match_operand:SI 1 "s_register_operand" "r"))
4714 (const_int 0)))
4715 (set (match_operand:SI 0 "s_register_operand" "=r")
4716 (not:SI (match_dup 1)))]
25f905c2 4717 "TARGET_32BIT"
4718 "mvn%.\\t%0, %1"
d2a518d1 4719 [(set_attr "conds" "set")
1aed5204 4720 (set_attr "type" "mvn_reg")]
cffb2a26 4721)
9c08d1fa 4722
f7fbdd4a 4723(define_insn "*notsi_compare0_scratch"
bd5b4116 4724 [(set (reg:CC_NOOV CC_REGNUM)
9c08d1fa 4725 (compare:CC_NOOV (not:SI (match_operand:SI 1 "s_register_operand" "r"))
4726 (const_int 0)))
4727 (clobber (match_scratch:SI 0 "=r"))]
25f905c2 4728 "TARGET_32BIT"
4729 "mvn%.\\t%0, %1"
d2a518d1 4730 [(set_attr "conds" "set")
1aed5204 4731 (set_attr "type" "mvn_reg")]
cffb2a26 4732)
b11cae9e 4733\f
4734;; Fixed <--> Floating conversion insns
4735
9b8516be 4736(define_expand "floatsihf2"
4737 [(set (match_operand:HF 0 "general_operand" "")
4738 (float:HF (match_operand:SI 1 "general_operand" "")))]
4739 "TARGET_EITHER"
4740 "
4741 {
4742 rtx op1 = gen_reg_rtx (SFmode);
4743 expand_float (op1, operands[1], 0);
4744 op1 = convert_to_mode (HFmode, op1, 0);
4745 emit_move_insn (operands[0], op1);
4746 DONE;
4747 }"
4748)
4749
4750(define_expand "floatdihf2"
4751 [(set (match_operand:HF 0 "general_operand" "")
4752 (float:HF (match_operand:DI 1 "general_operand" "")))]
4753 "TARGET_EITHER"
4754 "
4755 {
4756 rtx op1 = gen_reg_rtx (SFmode);
4757 expand_float (op1, operands[1], 0);
4758 op1 = convert_to_mode (HFmode, op1, 0);
4759 emit_move_insn (operands[0], op1);
4760 DONE;
4761 }"
4762)
4763
604f3a0a 4764(define_expand "floatsisf2"
4765 [(set (match_operand:SF 0 "s_register_operand" "")
4766 (float:SF (match_operand:SI 1 "s_register_operand" "")))]
25f905c2 4767 "TARGET_32BIT && TARGET_HARD_FLOAT"
604f3a0a 4768 "
604f3a0a 4769")
4770
604f3a0a 4771(define_expand "floatsidf2"
4772 [(set (match_operand:DF 0 "s_register_operand" "")
4773 (float:DF (match_operand:SI 1 "s_register_operand" "")))]
a50d7267 4774 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
604f3a0a 4775 "
604f3a0a 4776")
4777
9b8516be 4778(define_expand "fix_trunchfsi2"
4779 [(set (match_operand:SI 0 "general_operand" "")
4780 (fix:SI (fix:HF (match_operand:HF 1 "general_operand" ""))))]
4781 "TARGET_EITHER"
4782 "
4783 {
4784 rtx op1 = convert_to_mode (SFmode, operands[1], 0);
4785 expand_fix (operands[0], op1, 0);
4786 DONE;
4787 }"
4788)
4789
4790(define_expand "fix_trunchfdi2"
4791 [(set (match_operand:DI 0 "general_operand" "")
4792 (fix:DI (fix:HF (match_operand:HF 1 "general_operand" ""))))]
4793 "TARGET_EITHER"
4794 "
4795 {
4796 rtx op1 = convert_to_mode (SFmode, operands[1], 0);
4797 expand_fix (operands[0], op1, 0);
4798 DONE;
4799 }"
4800)
4801
604f3a0a 4802(define_expand "fix_truncsfsi2"
4803 [(set (match_operand:SI 0 "s_register_operand" "")
a33d5c9c 4804 (fix:SI (fix:SF (match_operand:SF 1 "s_register_operand" ""))))]
25f905c2 4805 "TARGET_32BIT && TARGET_HARD_FLOAT"
604f3a0a 4806 "
604f3a0a 4807")
4808
604f3a0a 4809(define_expand "fix_truncdfsi2"
4810 [(set (match_operand:SI 0 "s_register_operand" "")
a33d5c9c 4811 (fix:SI (fix:DF (match_operand:DF 1 "s_register_operand" ""))))]
a50d7267 4812 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
604f3a0a 4813 "
604f3a0a 4814")
4815
f544c6d2 4816;; Truncation insns
b11cae9e 4817
604f3a0a 4818(define_expand "truncdfsf2"
4819 [(set (match_operand:SF 0 "s_register_operand" "")
4820 (float_truncate:SF
4821 (match_operand:DF 1 "s_register_operand" "")))]
a50d7267 4822 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
604f3a0a 4823 ""
4824)
9b8516be 4825
4826/* DFmode -> HFmode conversions have to go through SFmode. */
4827(define_expand "truncdfhf2"
4828 [(set (match_operand:HF 0 "general_operand" "")
4829 (float_truncate:HF
4830 (match_operand:DF 1 "general_operand" "")))]
4831 "TARGET_EITHER"
4832 "
4833 {
4834 rtx op1;
4835 op1 = convert_to_mode (SFmode, operands[1], 0);
4836 op1 = convert_to_mode (HFmode, op1, 0);
4837 emit_move_insn (operands[0], op1);
4838 DONE;
4839 }"
4840)
b11cae9e 4841\f
9c08d1fa 4842;; Zero and sign extension instructions.
b11cae9e 4843
848e66ac 4844(define_insn "zero_extend<mode>di2"
6aa689e8 4845 [(set (match_operand:DI 0 "s_register_operand" "=w,r,?r,w")
6d97728e 4846 (zero_extend:DI (match_operand:QHSI 1 "<qhs_zextenddi_op>"
4847 "<qhs_zextenddi_cstr>")))]
848e66ac 4848 "TARGET_32BIT <qhs_zextenddi_cond>"
4849 "#"
6aa689e8 4850 [(set_attr "length" "8,4,8,8")
b6779ddc 4851 (set_attr "arch" "neon_for_64bits,*,*,avoid_neon_for_64bits")
848e66ac 4852 (set_attr "ce_count" "2")
efbb5e19 4853 (set_attr "predicable" "yes")
4854 (set_attr "type" "multiple,mov_reg,multiple,multiple")]
25f905c2 4855)
4856
848e66ac 4857(define_insn "extend<mode>di2"
6aa689e8 4858 [(set (match_operand:DI 0 "s_register_operand" "=w,r,?r,?r,w")
63d204a8 4859 (sign_extend:DI (match_operand:QHSI 1 "<qhs_extenddi_op>"
4860 "<qhs_extenddi_cstr>")))]
848e66ac 4861 "TARGET_32BIT <qhs_sextenddi_cond>"
4862 "#"
6aa689e8 4863 [(set_attr "length" "8,4,8,8,8")
848e66ac 4864 (set_attr "ce_count" "2")
4865 (set_attr "shift" "1")
8012d2c2 4866 (set_attr "predicable" "yes")
1b7da4ac 4867 (set_attr "arch" "neon_for_64bits,*,a,t,avoid_neon_for_64bits")
4868 (set_attr "type" "multiple,mov_reg,multiple,multiple,multiple")]
0d66636f 4869)
9c08d1fa 4870
848e66ac 4871;; Splits for all extensions to DImode
4872(define_split
4873 [(set (match_operand:DI 0 "s_register_operand" "")
4874 (zero_extend:DI (match_operand 1 "nonimmediate_operand" "")))]
6aa689e8 4875 "TARGET_32BIT && reload_completed && !IS_VFP_REGNUM (REGNO (operands[0]))"
848e66ac 4876 [(set (match_dup 0) (match_dup 1))]
4877{
848e66ac 4878 rtx lo_part = gen_lowpart (SImode, operands[0]);
4879 enum machine_mode src_mode = GET_MODE (operands[1]);
4880
4881 if (REG_P (operands[0])
4882 && !reg_overlap_mentioned_p (operands[0], operands[1]))
4883 emit_clobber (operands[0]);
4884 if (!REG_P (lo_part) || src_mode != SImode
4885 || !rtx_equal_p (lo_part, operands[1]))
4886 {
4887 if (src_mode == SImode)
4888 emit_move_insn (lo_part, operands[1]);
4889 else
4890 emit_insn (gen_rtx_SET (VOIDmode, lo_part,
4891 gen_rtx_ZERO_EXTEND (SImode, operands[1])));
4892 operands[1] = lo_part;
4893 }
4894 operands[0] = gen_highpart (SImode, operands[0]);
4895 operands[1] = const0_rtx;
4896})
9c08d1fa 4897
848e66ac 4898(define_split
25f905c2 4899 [(set (match_operand:DI 0 "s_register_operand" "")
848e66ac 4900 (sign_extend:DI (match_operand 1 "nonimmediate_operand" "")))]
6aa689e8 4901 "TARGET_32BIT && reload_completed && !IS_VFP_REGNUM (REGNO (operands[0]))"
848e66ac 4902 [(set (match_dup 0) (ashiftrt:SI (match_dup 1) (const_int 31)))]
4903{
4904 rtx lo_part = gen_lowpart (SImode, operands[0]);
4905 enum machine_mode src_mode = GET_MODE (operands[1]);
25f905c2 4906
848e66ac 4907 if (REG_P (operands[0])
4908 && !reg_overlap_mentioned_p (operands[0], operands[1]))
4909 emit_clobber (operands[0]);
4910
4911 if (!REG_P (lo_part) || src_mode != SImode
4912 || !rtx_equal_p (lo_part, operands[1]))
4913 {
4914 if (src_mode == SImode)
4915 emit_move_insn (lo_part, operands[1]);
4916 else
4917 emit_insn (gen_rtx_SET (VOIDmode, lo_part,
4918 gen_rtx_SIGN_EXTEND (SImode, operands[1])));
4919 operands[1] = lo_part;
4920 }
4921 operands[0] = gen_highpart (SImode, operands[0]);
4922})
9c08d1fa 4923
4924(define_expand "zero_extendhisi2"
ef51b8e1 4925 [(set (match_operand:SI 0 "s_register_operand" "")
4926 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
cffb2a26 4927 "TARGET_EITHER"
ef51b8e1 4928{
4929 if (TARGET_ARM && !arm_arch4 && MEM_P (operands[1]))
f7fbdd4a 4930 {
ef51b8e1 4931 emit_insn (gen_movhi_bytes (operands[0], operands[1]));
4932 DONE;
25f7a26e 4933 }
ef51b8e1 4934 if (!arm_arch6 && !MEM_P (operands[1]))
4935 {
4936 rtx t = gen_lowpart (SImode, operands[1]);
4937 rtx tmp = gen_reg_rtx (SImode);
4938 emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (16)));
4939 emit_insn (gen_lshrsi3 (operands[0], tmp, GEN_INT (16)));
4940 DONE;
4941 }
4942})
9c08d1fa 4943
ef51b8e1 4944(define_split
b146458f 4945 [(set (match_operand:SI 0 "s_register_operand" "")
4946 (zero_extend:SI (match_operand:HI 1 "s_register_operand" "")))]
ef51b8e1 4947 "!TARGET_THUMB2 && !arm_arch6"
4948 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
4949 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 16)))]
4950{
4951 operands[2] = gen_lowpart (SImode, operands[1]);
4952})
4953
cffb2a26 4954(define_insn "*arm_zero_extendhisi2"
ef51b8e1 4955 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4956 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
a2cd141b 4957 "TARGET_ARM && arm_arch4 && !arm_arch6"
ef51b8e1 4958 "@
4959 #
4960 ldr%(h%)\\t%0, %1"
d82e788e 4961 [(set_attr "type" "alu_shift_reg,load_byte")
848e66ac 4962 (set_attr "predicable" "yes")]
cffb2a26 4963)
f7fbdd4a 4964
a2cd141b 4965(define_insn "*arm_zero_extendhisi2_v6"
4966 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
e3f4ccee 4967 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,Uh")))]
a2cd141b 4968 "TARGET_ARM && arm_arch6"
4969 "@
4970 uxth%?\\t%0, %1
25f905c2 4971 ldr%(h%)\\t%0, %1"
65f68e55 4972 [(set_attr "predicable" "yes")
6b6abc9c 4973 (set_attr "type" "extend,load_byte")]
a2cd141b 4974)
4975
4976(define_insn "*arm_zero_extendhisi2addsi"
4977 [(set (match_operand:SI 0 "s_register_operand" "=r")
4978 (plus:SI (zero_extend:SI (match_operand:HI 1 "s_register_operand" "r"))
4979 (match_operand:SI 2 "s_register_operand" "r")))]
25f905c2 4980 "TARGET_INT_SIMD"
a2cd141b 4981 "uxtah%?\\t%0, %2, %1"
d82e788e 4982 [(set_attr "type" "alu_shift_reg")
d952d547 4983 (set_attr "predicable" "yes")
4984 (set_attr "predicable_short_it" "no")]
a2cd141b 4985)
4986
87b22bf7 4987(define_expand "zero_extendqisi2"
cffb2a26 4988 [(set (match_operand:SI 0 "s_register_operand" "")
4989 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))]
4990 "TARGET_EITHER"
ef51b8e1 4991{
0438d37f 4992 if (TARGET_ARM && !arm_arch6 && !MEM_P (operands[1]))
87b22bf7 4993 {
ef51b8e1 4994 emit_insn (gen_andsi3 (operands[0],
4995 gen_lowpart (SImode, operands[1]),
4996 GEN_INT (255)));
4997 DONE;
4998 }
4999 if (!arm_arch6 && !MEM_P (operands[1]))
5000 {
5001 rtx t = gen_lowpart (SImode, operands[1]);
5002 rtx tmp = gen_reg_rtx (SImode);
5003 emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (24)));
5004 emit_insn (gen_lshrsi3 (operands[0], tmp, GEN_INT (24)));
5005 DONE;
5006 }
5007})
cffb2a26 5008
ef51b8e1 5009(define_split
b146458f 5010 [(set (match_operand:SI 0 "s_register_operand" "")
5011 (zero_extend:SI (match_operand:QI 1 "s_register_operand" "")))]
ef51b8e1 5012 "!arm_arch6"
5013 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 24)))
5014 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 24)))]
5015{
5016 operands[2] = simplify_gen_subreg (SImode, operands[1], QImode, 0);
5017 if (TARGET_ARM)
5018 {
5019 emit_insn (gen_andsi3 (operands[0], operands[2], GEN_INT (255)));
87b22bf7 5020 DONE;
5021 }
ef51b8e1 5022})
9c08d1fa 5023
cffb2a26 5024(define_insn "*arm_zero_extendqisi2"
ef51b8e1 5025 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5026 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
a2cd141b 5027 "TARGET_ARM && !arm_arch6"
ef51b8e1 5028 "@
5029 #
5030 ldr%(b%)\\t%0, %1\\t%@ zero_extendqisi2"
5031 [(set_attr "length" "8,4")
d82e788e 5032 (set_attr "type" "alu_shift_reg,load_byte")
848e66ac 5033 (set_attr "predicable" "yes")]
cffb2a26 5034)
87b22bf7 5035
a2cd141b 5036(define_insn "*arm_zero_extendqisi2_v6"
5037 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
e3f4ccee 5038 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "r,Uh")))]
a2cd141b 5039 "TARGET_ARM && arm_arch6"
5040 "@
25f905c2 5041 uxtb%(%)\\t%0, %1
5042 ldr%(b%)\\t%0, %1\\t%@ zero_extendqisi2"
6b6abc9c 5043 [(set_attr "type" "extend,load_byte")
848e66ac 5044 (set_attr "predicable" "yes")]
a2cd141b 5045)
5046
5047(define_insn "*arm_zero_extendqisi2addsi"
5048 [(set (match_operand:SI 0 "s_register_operand" "=r")
5049 (plus:SI (zero_extend:SI (match_operand:QI 1 "s_register_operand" "r"))
5050 (match_operand:SI 2 "s_register_operand" "r")))]
25f905c2 5051 "TARGET_INT_SIMD"
a2cd141b 5052 "uxtab%?\\t%0, %2, %1"
5053 [(set_attr "predicable" "yes")
d952d547 5054 (set_attr "predicable_short_it" "no")
d82e788e 5055 (set_attr "type" "alu_shift_reg")]
a2cd141b 5056)
5057
87b22bf7 5058(define_split
5059 [(set (match_operand:SI 0 "s_register_operand" "")
5060 (zero_extend:SI (subreg:QI (match_operand:SI 1 "" "") 0)))
5061 (clobber (match_operand:SI 2 "s_register_operand" ""))]
0438d37f 5062 "TARGET_32BIT && (!MEM_P (operands[1])) && ! BYTES_BIG_ENDIAN"
87b22bf7 5063 [(set (match_dup 2) (match_dup 1))
5064 (set (match_dup 0) (and:SI (match_dup 2) (const_int 255)))]
cffb2a26 5065 ""
5066)
9c08d1fa 5067
8a4d25d6 5068(define_split
5069 [(set (match_operand:SI 0 "s_register_operand" "")
5070 (zero_extend:SI (subreg:QI (match_operand:SI 1 "" "") 3)))
5071 (clobber (match_operand:SI 2 "s_register_operand" ""))]
0438d37f 5072 "TARGET_32BIT && (!MEM_P (operands[1])) && BYTES_BIG_ENDIAN"
8a4d25d6 5073 [(set (match_dup 2) (match_dup 1))
5074 (set (match_dup 0) (and:SI (match_dup 2) (const_int 255)))]
5075 ""
5076)
5077
1c274529 5078
5079(define_split
5080 [(set (match_operand:SI 0 "s_register_operand" "")
5081 (ior_xor:SI (and:SI (ashift:SI
5082 (match_operand:SI 1 "s_register_operand" "")
5083 (match_operand:SI 2 "const_int_operand" ""))
5084 (match_operand:SI 3 "const_int_operand" ""))
5085 (zero_extend:SI
5086 (match_operator 5 "subreg_lowpart_operator"
5087 [(match_operand:SI 4 "s_register_operand" "")]))))]
5088 "TARGET_32BIT
63787642 5089 && ((unsigned HOST_WIDE_INT) INTVAL (operands[3])
1c274529 5090 == (GET_MODE_MASK (GET_MODE (operands[5]))
5091 & (GET_MODE_MASK (GET_MODE (operands[5]))
5092 << (INTVAL (operands[2])))))"
5093 [(set (match_dup 0) (ior_xor:SI (ashift:SI (match_dup 1) (match_dup 2))
5094 (match_dup 4)))
5095 (set (match_dup 0) (zero_extend:SI (match_dup 5)))]
5096 "operands[5] = gen_lowpart (GET_MODE (operands[5]), operands[0]);"
5097)
5098
f7fbdd4a 5099(define_insn "*compareqi_eq0"
bd5b4116 5100 [(set (reg:CC_Z CC_REGNUM)
206ee9a2 5101 (compare:CC_Z (match_operand:QI 0 "s_register_operand" "r")
87b22bf7 5102 (const_int 0)))]
25f905c2 5103 "TARGET_32BIT"
596e5e8f 5104 "tst%?\\t%0, #255"
5105 [(set_attr "conds" "set")
d952d547 5106 (set_attr "predicable" "yes")
1b7da4ac 5107 (set_attr "predicable_short_it" "no")
5108 (set_attr "type" "logic_imm")]
cffb2a26 5109)
b11cae9e 5110
b11cae9e 5111(define_expand "extendhisi2"
ef51b8e1 5112 [(set (match_operand:SI 0 "s_register_operand" "")
5113 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
cffb2a26 5114 "TARGET_EITHER"
ef51b8e1 5115{
5116 if (TARGET_THUMB1)
5117 {
5118 emit_insn (gen_thumb1_extendhisi2 (operands[0], operands[1]));
5119 DONE;
5120 }
5121 if (MEM_P (operands[1]) && TARGET_ARM && !arm_arch4)
5122 {
5123 emit_insn (gen_extendhisi2_mem (operands[0], operands[1]));
5124 DONE;
5125 }
ed29c566 5126
ef51b8e1 5127 if (!arm_arch6 && !MEM_P (operands[1]))
5128 {
5129 rtx t = gen_lowpart (SImode, operands[1]);
5130 rtx tmp = gen_reg_rtx (SImode);
5131 emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (16)));
5132 emit_insn (gen_ashrsi3 (operands[0], tmp, GEN_INT (16)));
5133 DONE;
5134 }
5135})
cffb2a26 5136
ef51b8e1 5137(define_split
5138 [(parallel
5139 [(set (match_operand:SI 0 "register_operand" "")
5140 (sign_extend:SI (match_operand:HI 1 "register_operand" "")))
5141 (clobber (match_scratch:SI 2 ""))])]
5142 "!arm_arch6"
5143 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
5144 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 16)))]
5145{
5146 operands[2] = simplify_gen_subreg (SImode, operands[1], HImode, 0);
5147})
25f7a26e 5148
25f905c2 5149;; This pattern will only be used when ldsh is not available
25f7a26e 5150(define_expand "extendhisi2_mem"
eab14235 5151 [(set (match_dup 2) (zero_extend:SI (match_operand:HI 1 "" "")))
25f7a26e 5152 (set (match_dup 3)
eab14235 5153 (zero_extend:SI (match_dup 7)))
25f7a26e 5154 (set (match_dup 6) (ashift:SI (match_dup 4) (const_int 24)))
5155 (set (match_operand:SI 0 "" "")
5156 (ior:SI (ashiftrt:SI (match_dup 6) (const_int 16)) (match_dup 5)))]
cffb2a26 5157 "TARGET_ARM"
25f7a26e 5158 "
215b30b3 5159 {
5160 rtx mem1, mem2;
5161 rtx addr = copy_to_mode_reg (SImode, XEXP (operands[1], 0));
5162
788fcce0 5163 mem1 = change_address (operands[1], QImode, addr);
29c05e22 5164 mem2 = change_address (operands[1], QImode,
5165 plus_constant (Pmode, addr, 1));
215b30b3 5166 operands[0] = gen_lowpart (SImode, operands[0]);
5167 operands[1] = mem1;
5168 operands[2] = gen_reg_rtx (SImode);
5169 operands[3] = gen_reg_rtx (SImode);
5170 operands[6] = gen_reg_rtx (SImode);
5171 operands[7] = mem2;
25f7a26e 5172
215b30b3 5173 if (BYTES_BIG_ENDIAN)
5174 {
5175 operands[4] = operands[2];
5176 operands[5] = operands[3];
5177 }
5178 else
5179 {
5180 operands[4] = operands[3];
5181 operands[5] = operands[2];
5182 }
5183 }"
5184)
b11cae9e 5185
ef51b8e1 5186(define_split
5187 [(set (match_operand:SI 0 "register_operand" "")
5188 (sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
5189 "!arm_arch6"
5190 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
5191 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 16)))]
5192{
5193 operands[2] = simplify_gen_subreg (SImode, operands[1], HImode, 0);
5194})
5195
a2cd141b 5196(define_insn "*arm_extendhisi2"
ef51b8e1 5197 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
e3f4ccee 5198 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,Uh")))]
a2cd141b 5199 "TARGET_ARM && arm_arch4 && !arm_arch6"
ef51b8e1 5200 "@
5201 #
5202 ldr%(sh%)\\t%0, %1"
5203 [(set_attr "length" "8,4")
d82e788e 5204 (set_attr "type" "alu_shift_reg,load_byte")
e3f4ccee 5205 (set_attr "predicable" "yes")]
cffb2a26 5206)
f7fbdd4a 5207
25f905c2 5208;; ??? Check Thumb-2 pool range
a2cd141b 5209(define_insn "*arm_extendhisi2_v6"
5210 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
e3f4ccee 5211 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,Uh")))]
25f905c2 5212 "TARGET_32BIT && arm_arch6"
a2cd141b 5213 "@
5214 sxth%?\\t%0, %1
25f905c2 5215 ldr%(sh%)\\t%0, %1"
6b6abc9c 5216 [(set_attr "type" "extend,load_byte")
a2cd141b 5217 (set_attr "predicable" "yes")
e3f4ccee 5218 (set_attr "predicable_short_it" "no")]
a2cd141b 5219)
5220
5221(define_insn "*arm_extendhisi2addsi"
5222 [(set (match_operand:SI 0 "s_register_operand" "=r")
5223 (plus:SI (sign_extend:SI (match_operand:HI 1 "s_register_operand" "r"))
5224 (match_operand:SI 2 "s_register_operand" "r")))]
25f905c2 5225 "TARGET_INT_SIMD"
a2cd141b 5226 "sxtah%?\\t%0, %2, %1"
1b7da4ac 5227 [(set_attr "type" "alu_shift_reg")]
a2cd141b 5228)
5229
c8f69309 5230(define_expand "extendqihi2"
5231 [(set (match_dup 2)
bed7d9a5 5232 (ashift:SI (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "")
c8f69309 5233 (const_int 24)))
9c08d1fa 5234 (set (match_operand:HI 0 "s_register_operand" "")
c8f69309 5235 (ashiftrt:SI (match_dup 2)
5236 (const_int 24)))]
cffb2a26 5237 "TARGET_ARM"
c8f69309 5238 "
215b30b3 5239 {
0438d37f 5240 if (arm_arch4 && MEM_P (operands[1]))
215b30b3 5241 {
5242 emit_insn (gen_rtx_SET (VOIDmode,
5243 operands[0],
5244 gen_rtx_SIGN_EXTEND (HImode, operands[1])));
5245 DONE;
5246 }
5247 if (!s_register_operand (operands[1], QImode))
5248 operands[1] = copy_to_mode_reg (QImode, operands[1]);
5249 operands[0] = gen_lowpart (SImode, operands[0]);
5250 operands[1] = gen_lowpart (SImode, operands[1]);
5251 operands[2] = gen_reg_rtx (SImode);
5252 }"
5253)
f7fbdd4a 5254
25f905c2 5255(define_insn "*arm_extendqihi_insn"
b4e8a300 5256 [(set (match_operand:HI 0 "s_register_operand" "=r")
bed7d9a5 5257 (sign_extend:HI (match_operand:QI 1 "arm_extendqisi_mem_op" "Uq")))]
cffb2a26 5258 "TARGET_ARM && arm_arch4"
25f905c2 5259 "ldr%(sb%)\\t%0, %1"
a2cd141b 5260 [(set_attr "type" "load_byte")
e3f4ccee 5261 (set_attr "predicable" "yes")]
cffb2a26 5262)
3fc2009e 5263
b11cae9e 5264(define_expand "extendqisi2"
ef51b8e1 5265 [(set (match_operand:SI 0 "s_register_operand" "")
5266 (sign_extend:SI (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "")))]
cffb2a26 5267 "TARGET_EITHER"
ef51b8e1 5268{
5269 if (!arm_arch4 && MEM_P (operands[1]))
5270 operands[1] = copy_to_mode_reg (QImode, operands[1]);
a2cd141b 5271
ef51b8e1 5272 if (!arm_arch6 && !MEM_P (operands[1]))
5273 {
5274 rtx t = gen_lowpart (SImode, operands[1]);
5275 rtx tmp = gen_reg_rtx (SImode);
5276 emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (24)));
5277 emit_insn (gen_ashrsi3 (operands[0], tmp, GEN_INT (24)));
5278 DONE;
5279 }
5280})
a2cd141b 5281
ef51b8e1 5282(define_split
5283 [(set (match_operand:SI 0 "register_operand" "")
5284 (sign_extend:SI (match_operand:QI 1 "register_operand" "")))]
5285 "!arm_arch6"
5286 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 24)))
5287 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 24)))]
5288{
5289 operands[2] = simplify_gen_subreg (SImode, operands[1], QImode, 0);
5290})
f7fbdd4a 5291
a2cd141b 5292(define_insn "*arm_extendqisi"
ef51b8e1 5293 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5294 (sign_extend:SI (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "r,Uq")))]
a2cd141b 5295 "TARGET_ARM && arm_arch4 && !arm_arch6"
ef51b8e1 5296 "@
5297 #
5298 ldr%(sb%)\\t%0, %1"
5299 [(set_attr "length" "8,4")
d82e788e 5300 (set_attr "type" "alu_shift_reg,load_byte")
e3f4ccee 5301 (set_attr "predicable" "yes")]
cffb2a26 5302)
3fc2009e 5303
a2cd141b 5304(define_insn "*arm_extendqisi_v6"
5305 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
bed7d9a5 5306 (sign_extend:SI
5307 (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "r,Uq")))]
a2cd141b 5308 "TARGET_ARM && arm_arch6"
b4e8a300 5309 "@
5310 sxtb%?\\t%0, %1
25f905c2 5311 ldr%(sb%)\\t%0, %1"
6b6abc9c 5312 [(set_attr "type" "extend,load_byte")
e3f4ccee 5313 (set_attr "predicable" "yes")]
a2cd141b 5314)
5315
5316(define_insn "*arm_extendqisi2addsi"
5317 [(set (match_operand:SI 0 "s_register_operand" "=r")
5318 (plus:SI (sign_extend:SI (match_operand:QI 1 "s_register_operand" "r"))
5319 (match_operand:SI 2 "s_register_operand" "r")))]
25f905c2 5320 "TARGET_INT_SIMD"
a2cd141b 5321 "sxtab%?\\t%0, %2, %1"
d82e788e 5322 [(set_attr "type" "alu_shift_reg")
d952d547 5323 (set_attr "predicable" "yes")
5324 (set_attr "predicable_short_it" "no")]
a2cd141b 5325)
5326
caedf871 5327(define_expand "extendsfdf2"
5328 [(set (match_operand:DF 0 "s_register_operand" "")
5329 (float_extend:DF (match_operand:SF 1 "s_register_operand" "")))]
a50d7267 5330 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
caedf871 5331 ""
5332)
9b8516be 5333
5334/* HFmode -> DFmode conversions have to go through SFmode. */
5335(define_expand "extendhfdf2"
5336 [(set (match_operand:DF 0 "general_operand" "")
5337 (float_extend:DF (match_operand:HF 1 "general_operand" "")))]
5338 "TARGET_EITHER"
5339 "
5340 {
5341 rtx op1;
5342 op1 = convert_to_mode (SFmode, operands[1], 0);
5343 op1 = convert_to_mode (DFmode, op1, 0);
5344 emit_insn (gen_movdf (operands[0], op1));
5345 DONE;
5346 }"
5347)
b11cae9e 5348\f
5349;; Move insns (including loads and stores)
5350
5351;; XXX Just some ideas about movti.
9c08d1fa 5352;; I don't think these are a good idea on the arm, there just aren't enough
5353;; registers
b11cae9e 5354;;(define_expand "loadti"
9c08d1fa 5355;; [(set (match_operand:TI 0 "s_register_operand" "")
b11cae9e 5356;; (mem:TI (match_operand:SI 1 "address_operand" "")))]
5357;; "" "")
5358
5359;;(define_expand "storeti"
5360;; [(set (mem:TI (match_operand:TI 0 "address_operand" ""))
9c08d1fa 5361;; (match_operand:TI 1 "s_register_operand" ""))]
b11cae9e 5362;; "" "")
5363
5364;;(define_expand "movti"
5365;; [(set (match_operand:TI 0 "general_operand" "")
5366;; (match_operand:TI 1 "general_operand" ""))]
5367;; ""
5368;; "
5369;;{
5370;; rtx insn;
5371;;
0438d37f 5372;; if (MEM_P (operands[0]) && MEM_P (operands[1]))
b11cae9e 5373;; operands[1] = copy_to_reg (operands[1]);
0438d37f 5374;; if (MEM_P (operands[0]))
b11cae9e 5375;; insn = gen_storeti (XEXP (operands[0], 0), operands[1]);
0438d37f 5376;; else if (MEM_P (operands[1]))
b11cae9e 5377;; insn = gen_loadti (operands[0], XEXP (operands[1], 0));
5378;; else
5379;; FAIL;
5380;;
5381;; emit_insn (insn);
5382;; DONE;
5383;;}")
5384
a2f10574 5385;; Recognize garbage generated above.
b11cae9e 5386
5387;;(define_insn ""
5388;; [(set (match_operand:TI 0 "general_operand" "=r,r,r,<,>,m")
5389;; (match_operand:TI 1 "general_operand" "<,>,m,r,r,r"))]
5390;; ""
5391;; "*
5392;; {
5393;; register mem = (which_alternative < 3);
0d66636f 5394;; register const char *template;
b11cae9e 5395;;
5396;; operands[mem] = XEXP (operands[mem], 0);
5397;; switch (which_alternative)
5398;; {
5399;; case 0: template = \"ldmdb\\t%1!, %M0\"; break;
5400;; case 1: template = \"ldmia\\t%1!, %M0\"; break;
5401;; case 2: template = \"ldmia\\t%1, %M0\"; break;
5402;; case 3: template = \"stmdb\\t%0!, %M1\"; break;
5403;; case 4: template = \"stmia\\t%0!, %M1\"; break;
5404;; case 5: template = \"stmia\\t%0, %M1\"; break;
5405;; }
e2348bcb 5406;; output_asm_insn (template, operands);
5407;; return \"\";
b11cae9e 5408;; }")
5409
cffb2a26 5410(define_expand "movdi"
5411 [(set (match_operand:DI 0 "general_operand" "")
5412 (match_operand:DI 1 "general_operand" ""))]
5413 "TARGET_EITHER"
5414 "
e1ba4a27 5415 if (can_create_pseudo_p ())
cffb2a26 5416 {
0438d37f 5417 if (!REG_P (operands[0]))
b2778788 5418 operands[1] = force_reg (DImode, operands[1]);
cffb2a26 5419 }
5420 "
5421)
b11cae9e 5422
cffb2a26 5423(define_insn "*arm_movdi"
353cf59a 5424 [(set (match_operand:DI 0 "nonimmediate_di_operand" "=r, r, r, q, m")
5425 (match_operand:DI 1 "di_operand" "rDa,Db,Dc,mi,q"))]
cde1623a 5426 "TARGET_32BIT
b805622c 5427 && !(TARGET_HARD_FLOAT && TARGET_VFP)
b2778788 5428 && !TARGET_IWMMXT
5429 && ( register_operand (operands[0], DImode)
5430 || register_operand (operands[1], DImode))"
b11cae9e 5431 "*
d51f92df 5432 switch (which_alternative)
5433 {
5434 case 0:
5435 case 1:
5436 case 2:
5437 return \"#\";
5438 default:
26ff80c0 5439 return output_move_double (operands, true, NULL);
d51f92df 5440 }
cffb2a26 5441 "
359a6e9f 5442 [(set_attr "length" "8,12,16,8,8")
1b7da4ac 5443 (set_attr "type" "multiple,multiple,multiple,load2,store2")
cde1623a 5444 (set_attr "arm_pool_range" "*,*,*,1020,*")
8848d797 5445 (set_attr "arm_neg_pool_range" "*,*,*,1004,*")
42e1de19 5446 (set_attr "thumb2_pool_range" "*,*,*,4094,*")
cde1623a 5447 (set_attr "thumb2_neg_pool_range" "*,*,*,0,*")]
cffb2a26 5448)
5449
d51f92df 5450(define_split
5451 [(set (match_operand:ANY64 0 "arm_general_register_operand" "")
e6dd3afa 5452 (match_operand:ANY64 1 "immediate_operand" ""))]
25f905c2 5453 "TARGET_32BIT
d51f92df 5454 && reload_completed
5455 && (arm_const_double_inline_cost (operands[1])
861033d5 5456 <= arm_max_const_double_inline_cost ())"
d51f92df 5457 [(const_int 0)]
5458 "
5459 arm_split_constant (SET, SImode, curr_insn,
5460 INTVAL (gen_lowpart (SImode, operands[1])),
5461 gen_lowpart (SImode, operands[0]), NULL_RTX, 0);
5462 arm_split_constant (SET, SImode, curr_insn,
5463 INTVAL (gen_highpart_mode (SImode,
5464 GET_MODE (operands[0]),
5465 operands[1])),
5466 gen_highpart (SImode, operands[0]), NULL_RTX, 0);
5467 DONE;
5468 "
5469)
5470
e5ba9289 5471; If optimizing for size, or if we have load delay slots, then
5472; we want to split the constant into two separate operations.
5473; In both cases this may split a trivial part into a single data op
5474; leaving a single complex constant to load. We can also get longer
5475; offsets in a LDR which means we get better chances of sharing the pool
5476; entries. Finally, we can normally do a better job of scheduling
5477; LDR instructions than we can with LDM.
5478; This pattern will only match if the one above did not.
5479(define_split
5480 [(set (match_operand:ANY64 0 "arm_general_register_operand" "")
5481 (match_operand:ANY64 1 "const_double_operand" ""))]
5482 "TARGET_ARM && reload_completed
5483 && arm_const_double_by_parts (operands[1])"
5484 [(set (match_dup 0) (match_dup 1))
5485 (set (match_dup 2) (match_dup 3))]
5486 "
5487 operands[2] = gen_highpart (SImode, operands[0]);
5488 operands[3] = gen_highpart_mode (SImode, GET_MODE (operands[0]),
5489 operands[1]);
5490 operands[0] = gen_lowpart (SImode, operands[0]);
5491 operands[1] = gen_lowpart (SImode, operands[1]);
5492 "
5493)
5494
d51f92df 5495(define_split
5496 [(set (match_operand:ANY64 0 "arm_general_register_operand" "")
5497 (match_operand:ANY64 1 "arm_general_register_operand" ""))]
5498 "TARGET_EITHER && reload_completed"
5499 [(set (match_dup 0) (match_dup 1))
5500 (set (match_dup 2) (match_dup 3))]
5501 "
5502 operands[2] = gen_highpart (SImode, operands[0]);
5503 operands[3] = gen_highpart (SImode, operands[1]);
5504 operands[0] = gen_lowpart (SImode, operands[0]);
5505 operands[1] = gen_lowpart (SImode, operands[1]);
5506
5507 /* Handle a partial overlap. */
5508 if (rtx_equal_p (operands[0], operands[3]))
5509 {
5510 rtx tmp0 = operands[0];
5511 rtx tmp1 = operands[1];
5512
5513 operands[0] = operands[2];
5514 operands[1] = operands[3];
5515 operands[2] = tmp0;
5516 operands[3] = tmp1;
5517 }
5518 "
5519)
5520
a8a3b539 5521;; We can't actually do base+index doubleword loads if the index and
5522;; destination overlap. Split here so that we at least have chance to
5523;; schedule.
5524(define_split
5525 [(set (match_operand:DI 0 "s_register_operand" "")
5526 (mem:DI (plus:SI (match_operand:SI 1 "s_register_operand" "")
5527 (match_operand:SI 2 "s_register_operand" ""))))]
5528 "TARGET_LDRD
5529 && reg_overlap_mentioned_p (operands[0], operands[1])
5530 && reg_overlap_mentioned_p (operands[0], operands[2])"
5531 [(set (match_dup 4)
5532 (plus:SI (match_dup 1)
5533 (match_dup 2)))
5534 (set (match_dup 0)
5535 (mem:DI (match_dup 4)))]
5536 "
5537 operands[4] = gen_rtx_REG (SImode, REGNO(operands[0]));
5538 "
5539)
5540
9c08d1fa 5541(define_expand "movsi"
5542 [(set (match_operand:SI 0 "general_operand" "")
5543 (match_operand:SI 1 "general_operand" ""))]
cffb2a26 5544 "TARGET_EITHER"
9c08d1fa 5545 "
befb0bac 5546 {
e348ff3e 5547 rtx base, offset, tmp;
5548
25f905c2 5549 if (TARGET_32BIT)
9c08d1fa 5550 {
674a8f0b 5551 /* Everything except mem = const or mem = mem can be done easily. */
0438d37f 5552 if (MEM_P (operands[0]))
cffb2a26 5553 operands[1] = force_reg (SImode, operands[1]);
a2cd141b 5554 if (arm_general_register_operand (operands[0], SImode)
0438d37f 5555 && CONST_INT_P (operands[1])
cffb2a26 5556 && !(const_ok_for_arm (INTVAL (operands[1]))
5557 || const_ok_for_arm (~INTVAL (operands[1]))))
5558 {
96f57e36 5559 arm_split_constant (SET, SImode, NULL_RTX,
5560 INTVAL (operands[1]), operands[0], NULL_RTX,
e1ba4a27 5561 optimize && can_create_pseudo_p ());
cffb2a26 5562 DONE;
5563 }
5564 }
25f905c2 5565 else /* TARGET_THUMB1... */
cffb2a26 5566 {
e1ba4a27 5567 if (can_create_pseudo_p ())
cffb2a26 5568 {
0438d37f 5569 if (!REG_P (operands[0]))
cffb2a26 5570 operands[1] = force_reg (SImode, operands[1]);
5571 }
9c08d1fa 5572 }
f655717d 5573
e348ff3e 5574 if (ARM_OFFSETS_MUST_BE_WITHIN_SECTIONS_P)
5575 {
5576 split_const (operands[1], &base, &offset);
5577 if (GET_CODE (base) == SYMBOL_REF
5578 && !offset_within_block_p (base, INTVAL (offset)))
5579 {
b308ddcf 5580 tmp = can_create_pseudo_p () ? gen_reg_rtx (SImode) : operands[0];
e348ff3e 5581 emit_move_insn (tmp, base);
5582 emit_insn (gen_addsi3 (operands[0], tmp, offset));
5583 DONE;
5584 }
5585 }
5586
f655717d 5587 /* Recognize the case where operand[1] is a reference to thread-local
5588 data and load its address to a register. */
5589 if (arm_tls_referenced_p (operands[1]))
5590 {
5591 rtx tmp = operands[1];
5592 rtx addend = NULL;
5593
5594 if (GET_CODE (tmp) == CONST && GET_CODE (XEXP (tmp, 0)) == PLUS)
5595 {
5596 addend = XEXP (XEXP (tmp, 0), 1);
5597 tmp = XEXP (XEXP (tmp, 0), 0);
5598 }
5599
5600 gcc_assert (GET_CODE (tmp) == SYMBOL_REF);
5601 gcc_assert (SYMBOL_REF_TLS_MODEL (tmp) != 0);
5602
e1ba4a27 5603 tmp = legitimize_tls_address (tmp,
5604 !can_create_pseudo_p () ? operands[0] : 0);
f655717d 5605 if (addend)
5606 {
5607 tmp = gen_rtx_PLUS (SImode, tmp, addend);
5608 tmp = force_operand (tmp, operands[0]);
5609 }
5610 operands[1] = tmp;
5611 }
5612 else if (flag_pic
5613 && (CONSTANT_P (operands[1])
5614 || symbol_mentioned_p (operands[1])
5615 || label_mentioned_p (operands[1])))
5616 operands[1] = legitimize_pic_address (operands[1], SImode,
e1ba4a27 5617 (!can_create_pseudo_p ()
5618 ? operands[0]
5619 : 0));
befb0bac 5620 }
215b30b3 5621 "
5622)
9c08d1fa 5623
d0e6a121 5624;; The ARM LO_SUM and HIGH are backwards - HIGH sets the low bits, and
5625;; LO_SUM adds in the high bits. Fortunately these are opaque operations
5626;; so this does not matter.
5627(define_insn "*arm_movt"
5628 [(set (match_operand:SI 0 "nonimmediate_operand" "=r")
5629 (lo_sum:SI (match_operand:SI 1 "nonimmediate_operand" "0")
5630 (match_operand:SI 2 "general_operand" "i")))]
c9b2ce40 5631 "arm_arch_thumb2"
d0e6a121 5632 "movt%?\t%0, #:upper16:%c2"
5633 [(set_attr "predicable" "yes")
d952d547 5634 (set_attr "predicable_short_it" "no")
1b7da4ac 5635 (set_attr "length" "4")
5636 (set_attr "type" "mov_imm")]
d0e6a121 5637)
5638
cffb2a26 5639(define_insn "*arm_movsi_insn"
aaa37ad6 5640 [(set (match_operand:SI 0 "nonimmediate_operand" "=rk,r,r,r,rk,m")
110eae03 5641 (match_operand:SI 1 "general_operand" "rk, I,K,j,mi,rk"))]
755eb2b4 5642 "TARGET_ARM && ! TARGET_IWMMXT
a2cd141b 5643 && !(TARGET_HARD_FLOAT && TARGET_VFP)
cffb2a26 5644 && ( register_operand (operands[0], SImode)
5645 || register_operand (operands[1], SImode))"
f7fbdd4a 5646 "@
aaa37ad6 5647 mov%?\\t%0, %1
f7fbdd4a 5648 mov%?\\t%0, %1
5649 mvn%?\\t%0, #%B1
25f905c2 5650 movw%?\\t%0, %1
f7fbdd4a 5651 ldr%?\\t%0, %1
5652 str%?\\t%1, %0"
1aed5204 5653 [(set_attr "type" "mov_reg,mov_imm,mvn_imm,mov_imm,load1,store1")
0d66636f 5654 (set_attr "predicable" "yes")
aaa37ad6 5655 (set_attr "pool_range" "*,*,*,*,4096,*")
5656 (set_attr "neg_pool_range" "*,*,*,*,4084,*")]
cffb2a26 5657)
87b22bf7 5658
5659(define_split
a2cd141b 5660 [(set (match_operand:SI 0 "arm_general_register_operand" "")
87b22bf7 5661 (match_operand:SI 1 "const_int_operand" ""))]
25f905c2 5662 "TARGET_32BIT
215b30b3 5663 && (!(const_ok_for_arm (INTVAL (operands[1]))
5664 || const_ok_for_arm (~INTVAL (operands[1]))))"
87b22bf7 5665 [(clobber (const_int 0))]
5666 "
96f57e36 5667 arm_split_constant (SET, SImode, NULL_RTX,
5668 INTVAL (operands[1]), operands[0], NULL_RTX, 0);
87b22bf7 5669 DONE;
215b30b3 5670 "
5671)
9c08d1fa 5672
861033d5 5673;; A normal way to do (symbol + offset) requires three instructions at least
5674;; (depends on how big the offset is) as below:
5675;; movw r0, #:lower16:g
5676;; movw r0, #:upper16:g
5677;; adds r0, #4
5678;;
5679;; A better way would be:
5680;; movw r0, #:lower16:g+4
5681;; movw r0, #:upper16:g+4
5682;;
5683;; The limitation of this way is that the length of offset should be a 16-bit
5684;; signed value, because current assembler only supports REL type relocation for
5685;; such case. If the more powerful RELA type is supported in future, we should
5686;; update this pattern to go with better way.
5687(define_split
5688 [(set (match_operand:SI 0 "arm_general_register_operand" "")
5689 (const:SI (plus:SI (match_operand:SI 1 "general_operand" "")
5690 (match_operand:SI 2 "const_int_operand" ""))))]
5691 "TARGET_THUMB2
5692 && arm_disable_literal_pool
5693 && reload_completed
5694 && GET_CODE (operands[1]) == SYMBOL_REF"
5695 [(clobber (const_int 0))]
5696 "
5697 int offset = INTVAL (operands[2]);
5698
5699 if (offset < -0x8000 || offset > 0x7fff)
5700 {
5701 arm_emit_movpair (operands[0], operands[1]);
5702 emit_insn (gen_rtx_SET (SImode, operands[0],
5703 gen_rtx_PLUS (SImode, operands[0], operands[2])));
5704 }
5705 else
5706 {
5707 rtx op = gen_rtx_CONST (SImode,
5708 gen_rtx_PLUS (SImode, operands[1], operands[2]));
5709 arm_emit_movpair (operands[0], op);
5710 }
5711 "
5712)
5713
b8d5d078 5714;; Split symbol_refs at the later stage (after cprop), instead of generating
5715;; movt/movw pair directly at expand. Otherwise corresponding high_sum
5716;; and lo_sum would be merged back into memory load at cprop. However,
5717;; if the default is to prefer movt/movw rather than a load from the constant
5718;; pool, the performance is better.
5719(define_split
5720 [(set (match_operand:SI 0 "arm_general_register_operand" "")
5721 (match_operand:SI 1 "general_operand" ""))]
5722 "TARGET_32BIT
5723 && TARGET_USE_MOVT && GET_CODE (operands[1]) == SYMBOL_REF
5724 && !flag_pic && !target_word_relocations
5725 && !arm_tls_referenced_p (operands[1])"
5726 [(clobber (const_int 0))]
5727{
5728 arm_emit_movpair (operands[0], operands[1]);
5729 DONE;
5730})
5731
bc360af8 5732;; When generating pic, we need to load the symbol offset into a register.
5733;; So that the optimizer does not confuse this with a normal symbol load
5734;; we use an unspec. The offset will be loaded from a constant pool entry,
5735;; since that is the only type of relocation we can use.
cffb2a26 5736
bc360af8 5737;; Wrap calculation of the whole PIC address in a single pattern for the
5738;; benefit of optimizers, particularly, PRE and HOIST. Calculation of
5739;; a PIC address involves two loads from memory, so we want to CSE it
5740;; as often as possible.
5741;; This pattern will be split into one of the pic_load_addr_* patterns
5742;; and a move after GCSE optimizations.
5743;;
5744;; Note: Update arm.c: legitimize_pic_address() when changing this pattern.
5745(define_expand "calculate_pic_address"
94f8caca 5746 [(set (match_operand:SI 0 "register_operand" "")
5747 (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "")
5748 (unspec:SI [(match_operand:SI 2 "" "")]
5749 UNSPEC_PIC_SYM))))]
5750 "flag_pic"
5751)
5752
5753;; Split calculate_pic_address into pic_load_addr_* and a move.
5754(define_split
5755 [(set (match_operand:SI 0 "register_operand" "")
5756 (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "")
5757 (unspec:SI [(match_operand:SI 2 "" "")]
5758 UNSPEC_PIC_SYM))))]
5759 "flag_pic"
5760 [(set (match_dup 3) (unspec:SI [(match_dup 2)] UNSPEC_PIC_SYM))
5761 (set (match_dup 0) (mem:SI (plus:SI (match_dup 1) (match_dup 3))))]
5762 "operands[3] = can_create_pseudo_p () ? gen_reg_rtx (SImode) : operands[0];"
5763)
5764
350ccca5 5765;; operand1 is the memory address to go into
5766;; pic_load_addr_32bit.
5767;; operand2 is the PIC label to be emitted
5768;; from pic_add_dot_plus_eight.
5769;; We do this to allow hoisting of the entire insn.
5770(define_insn_and_split "pic_load_addr_unified"
5771 [(set (match_operand:SI 0 "s_register_operand" "=r,r,l")
5772 (unspec:SI [(match_operand:SI 1 "" "mX,mX,mX")
5773 (match_operand:SI 2 "" "")]
5774 UNSPEC_PIC_UNIFIED))]
5775 "flag_pic"
5776 "#"
5777 "&& reload_completed"
5778 [(set (match_dup 0) (unspec:SI [(match_dup 1)] UNSPEC_PIC_SYM))
5779 (set (match_dup 0) (unspec:SI [(match_dup 0) (match_dup 3)
5780 (match_dup 2)] UNSPEC_PIC_BASE))]
5781 "operands[3] = TARGET_THUMB ? GEN_INT (4) : GEN_INT (8);"
5782 [(set_attr "type" "load1,load1,load1")
42e1de19 5783 (set_attr "pool_range" "4096,4094,1022")
350ccca5 5784 (set_attr "neg_pool_range" "4084,0,0")
5785 (set_attr "arch" "a,t2,t1")
5786 (set_attr "length" "8,6,4")]
5787)
5788
67336bcf 5789;; The rather odd constraints on the following are to force reload to leave
5790;; the insn alone, and to force the minipool generation pass to then move
5791;; the GOT symbol to memory.
849170fd 5792
b3cd5f55 5793(define_insn "pic_load_addr_32bit"
849170fd 5794 [(set (match_operand:SI 0 "s_register_operand" "=r")
e1159bbe 5795 (unspec:SI [(match_operand:SI 1 "" "mX")] UNSPEC_PIC_SYM))]
b3cd5f55 5796 "TARGET_32BIT && flag_pic"
67336bcf 5797 "ldr%?\\t%0, %1"
a2cd141b 5798 [(set_attr "type" "load1")
42e1de19 5799 (set (attr "pool_range")
5800 (if_then_else (eq_attr "is_thumb" "no")
5801 (const_int 4096)
5802 (const_int 4094)))
b3cd5f55 5803 (set (attr "neg_pool_range")
5804 (if_then_else (eq_attr "is_thumb" "no")
5805 (const_int 4084)
5806 (const_int 0)))]
8c4d8060 5807)
5808
25f905c2 5809(define_insn "pic_load_addr_thumb1"
8c4d8060 5810 [(set (match_operand:SI 0 "s_register_operand" "=l")
e1159bbe 5811 (unspec:SI [(match_operand:SI 1 "" "mX")] UNSPEC_PIC_SYM))]
25f905c2 5812 "TARGET_THUMB1 && flag_pic"
8c4d8060 5813 "ldr\\t%0, %1"
a2cd141b 5814 [(set_attr "type" "load1")
42e1de19 5815 (set (attr "pool_range") (const_int 1018))]
cffb2a26 5816)
849170fd 5817
cffb2a26 5818(define_insn "pic_add_dot_plus_four"
15d5d060 5819 [(set (match_operand:SI 0 "register_operand" "=r")
c0c1fba5 5820 (unspec:SI [(match_operand:SI 1 "register_operand" "0")
5821 (const_int 4)
beef0fb5 5822 (match_operand 2 "" "")]
5823 UNSPEC_PIC_BASE))]
b3cd5f55 5824 "TARGET_THUMB"
cffb2a26 5825 "*
6cdcb15c 5826 (*targetm.asm_out.internal_label) (asm_out_file, \"LPIC\",
5827 INTVAL (operands[2]));
cffb2a26 5828 return \"add\\t%0, %|pc\";
5829 "
1b7da4ac 5830 [(set_attr "length" "2")
112eda6f 5831 (set_attr "type" "alu_sreg")]
cffb2a26 5832)
849170fd 5833
5834(define_insn "pic_add_dot_plus_eight"
15d5d060 5835 [(set (match_operand:SI 0 "register_operand" "=r")
c0c1fba5 5836 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
5837 (const_int 8)
beef0fb5 5838 (match_operand 2 "" "")]
5839 UNSPEC_PIC_BASE))]
f655717d 5840 "TARGET_ARM"
c4034607 5841 "*
6cdcb15c 5842 (*targetm.asm_out.internal_label) (asm_out_file, \"LPIC\",
5843 INTVAL (operands[2]));
15d5d060 5844 return \"add%?\\t%0, %|pc, %1\";
cffb2a26 5845 "
1b7da4ac 5846 [(set_attr "predicable" "yes")
112eda6f 5847 (set_attr "type" "alu_sreg")]
cffb2a26 5848)
849170fd 5849
f655717d 5850(define_insn "tls_load_dot_plus_eight"
cc071db6 5851 [(set (match_operand:SI 0 "register_operand" "=r")
c0c1fba5 5852 (mem:SI (unspec:SI [(match_operand:SI 1 "register_operand" "r")
5853 (const_int 8)
beef0fb5 5854 (match_operand 2 "" "")]
5855 UNSPEC_PIC_BASE)))]
f655717d 5856 "TARGET_ARM"
5857 "*
6cdcb15c 5858 (*targetm.asm_out.internal_label) (asm_out_file, \"LPIC\",
5859 INTVAL (operands[2]));
f655717d 5860 return \"ldr%?\\t%0, [%|pc, %1]\t\t@ tls_load_dot_plus_eight\";
5861 "
1b7da4ac 5862 [(set_attr "predicable" "yes")
5863 (set_attr "type" "load1")]
f655717d 5864)
5865
5866;; PIC references to local variables can generate pic_add_dot_plus_eight
5867;; followed by a load. These sequences can be crunched down to
5868;; tls_load_dot_plus_eight by a peephole.
5869
5870(define_peephole2
c0c1fba5 5871 [(set (match_operand:SI 0 "register_operand" "")
5872 (unspec:SI [(match_operand:SI 3 "register_operand" "")
5873 (const_int 8)
5874 (match_operand 1 "" "")]
5875 UNSPEC_PIC_BASE))
2d05dfad 5876 (set (match_operand:SI 2 "arm_general_register_operand" "")
5877 (mem:SI (match_dup 0)))]
f655717d 5878 "TARGET_ARM && peep2_reg_dead_p (2, operands[0])"
c0c1fba5 5879 [(set (match_dup 2)
5880 (mem:SI (unspec:SI [(match_dup 3)
5881 (const_int 8)
5882 (match_dup 1)]
5883 UNSPEC_PIC_BASE)))]
f655717d 5884 ""
5885)
5886
bac7fc85 5887(define_insn "pic_offset_arm"
5888 [(set (match_operand:SI 0 "register_operand" "=r")
5889 (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
5890 (unspec:SI [(match_operand:SI 2 "" "X")]
5891 UNSPEC_PIC_OFFSET))))]
5892 "TARGET_VXWORKS_RTP && TARGET_ARM && flag_pic"
5893 "ldr%?\\t%0, [%1,%2]"
5894 [(set_attr "type" "load1")]
5895)
5896
95373f08 5897(define_expand "builtin_setjmp_receiver"
5898 [(label_ref (match_operand 0 "" ""))]
5899 "flag_pic"
5900 "
5901{
b935b306 5902 /* r3 is clobbered by set/longjmp, so we can use it as a scratch
5903 register. */
2cb7d577 5904 if (arm_pic_register != INVALID_REGNUM)
5905 arm_load_pic_register (1UL << 3);
95373f08 5906 DONE;
5907}")
5908
9c08d1fa 5909;; If copying one reg to another we can set the condition codes according to
5910;; its value. Such a move is common after a return from subroutine and the
5911;; result is being tested against zero.
5912
f7fbdd4a 5913(define_insn "*movsi_compare0"
bd5b4116 5914 [(set (reg:CC CC_REGNUM)
cffb2a26 5915 (compare:CC (match_operand:SI 1 "s_register_operand" "0,r")
5916 (const_int 0)))
5917 (set (match_operand:SI 0 "s_register_operand" "=r,r")
5918 (match_dup 1))]
25f905c2 5919 "TARGET_32BIT"
e2348bcb 5920 "@
40dbec34 5921 cmp%?\\t%0, #0
25f905c2 5922 sub%.\\t%0, %1, #0"
65f68e55 5923 [(set_attr "conds" "set")
d82e788e 5924 (set_attr "type" "alus_imm,alus_imm")]
cffb2a26 5925)
b11cae9e 5926
b11cae9e 5927;; Subroutine to store a half word from a register into memory.
5928;; Operand 0 is the source register (HImode)
c8f69309 5929;; Operand 1 is the destination address in a register (SImode)
b11cae9e 5930
9c08d1fa 5931;; In both this routine and the next, we must be careful not to spill
01cc3b75 5932;; a memory address of reg+large_const into a separate PLUS insn, since this
9c08d1fa 5933;; can generate unrecognizable rtl.
5934
b11cae9e 5935(define_expand "storehi"
c8f69309 5936 [;; store the low byte
f082f1c4 5937 (set (match_operand 1 "" "") (match_dup 3))
b11cae9e 5938 ;; extract the high byte
c8f69309 5939 (set (match_dup 2)
5940 (ashiftrt:SI (match_operand 0 "" "") (const_int 8)))
b11cae9e 5941 ;; store the high byte
787f8210 5942 (set (match_dup 4) (match_dup 5))]
cffb2a26 5943 "TARGET_ARM"
b11cae9e 5944 "
215b30b3 5945 {
537ffcfc 5946 rtx op1 = operands[1];
5947 rtx addr = XEXP (op1, 0);
215b30b3 5948 enum rtx_code code = GET_CODE (addr);
5949
0438d37f 5950 if ((code == PLUS && !CONST_INT_P (XEXP (addr, 1)))
215b30b3 5951 || code == MINUS)
537ffcfc 5952 op1 = replace_equiv_address (operands[1], force_reg (SImode, addr));
215b30b3 5953
537ffcfc 5954 operands[4] = adjust_address (op1, QImode, 1);
e513d163 5955 operands[1] = adjust_address (operands[1], QImode, 0);
215b30b3 5956 operands[3] = gen_lowpart (QImode, operands[0]);
5957 operands[0] = gen_lowpart (SImode, operands[0]);
787f8210 5958 operands[2] = gen_reg_rtx (SImode);
5959 operands[5] = gen_lowpart (QImode, operands[2]);
215b30b3 5960 }"
5961)
b11cae9e 5962
c7597b5d 5963(define_expand "storehi_bigend"
f082f1c4 5964 [(set (match_dup 4) (match_dup 3))
c7597b5d 5965 (set (match_dup 2)
5966 (ashiftrt:SI (match_operand 0 "" "") (const_int 8)))
787f8210 5967 (set (match_operand 1 "" "") (match_dup 5))]
cffb2a26 5968 "TARGET_ARM"
b11cae9e 5969 "
215b30b3 5970 {
537ffcfc 5971 rtx op1 = operands[1];
5972 rtx addr = XEXP (op1, 0);
215b30b3 5973 enum rtx_code code = GET_CODE (addr);
5974
0438d37f 5975 if ((code == PLUS && !CONST_INT_P (XEXP (addr, 1)))
215b30b3 5976 || code == MINUS)
537ffcfc 5977 op1 = replace_equiv_address (op1, force_reg (SImode, addr));
215b30b3 5978
537ffcfc 5979 operands[4] = adjust_address (op1, QImode, 1);
e513d163 5980 operands[1] = adjust_address (operands[1], QImode, 0);
215b30b3 5981 operands[3] = gen_lowpart (QImode, operands[0]);
5982 operands[0] = gen_lowpart (SImode, operands[0]);
5983 operands[2] = gen_reg_rtx (SImode);
787f8210 5984 operands[5] = gen_lowpart (QImode, operands[2]);
215b30b3 5985 }"
5986)
c7597b5d 5987
5988;; Subroutine to store a half word integer constant into memory.
5989(define_expand "storeinthi"
f082f1c4 5990 [(set (match_operand 0 "" "")
787f8210 5991 (match_operand 1 "" ""))
9e8503e6 5992 (set (match_dup 3) (match_dup 2))]
cffb2a26 5993 "TARGET_ARM"
c7597b5d 5994 "
215b30b3 5995 {
5996 HOST_WIDE_INT value = INTVAL (operands[1]);
5997 rtx addr = XEXP (operands[0], 0);
537ffcfc 5998 rtx op0 = operands[0];
215b30b3 5999 enum rtx_code code = GET_CODE (addr);
c7597b5d 6000
0438d37f 6001 if ((code == PLUS && !CONST_INT_P (XEXP (addr, 1)))
215b30b3 6002 || code == MINUS)
537ffcfc 6003 op0 = replace_equiv_address (op0, force_reg (SImode, addr));
c7597b5d 6004
215b30b3 6005 operands[1] = gen_reg_rtx (SImode);
6006 if (BYTES_BIG_ENDIAN)
6007 {
6008 emit_insn (gen_movsi (operands[1], GEN_INT ((value >> 8) & 255)));
6009 if ((value & 255) == ((value >> 8) & 255))
6010 operands[2] = operands[1];
6011 else
6012 {
6013 operands[2] = gen_reg_rtx (SImode);
6014 emit_insn (gen_movsi (operands[2], GEN_INT (value & 255)));
6015 }
6016 }
6017 else
6018 {
6019 emit_insn (gen_movsi (operands[1], GEN_INT (value & 255)));
6020 if ((value & 255) == ((value >> 8) & 255))
6021 operands[2] = operands[1];
6022 else
6023 {
6024 operands[2] = gen_reg_rtx (SImode);
6025 emit_insn (gen_movsi (operands[2], GEN_INT ((value >> 8) & 255)));
6026 }
6027 }
c7597b5d 6028
537ffcfc 6029 operands[3] = adjust_address (op0, QImode, 1);
e513d163 6030 operands[0] = adjust_address (operands[0], QImode, 0);
9e8503e6 6031 operands[2] = gen_lowpart (QImode, operands[2]);
787f8210 6032 operands[1] = gen_lowpart (QImode, operands[1]);
215b30b3 6033 }"
6034)
b11cae9e 6035
f7fbdd4a 6036(define_expand "storehi_single_op"
6037 [(set (match_operand:HI 0 "memory_operand" "")
6038 (match_operand:HI 1 "general_operand" ""))]
25f905c2 6039 "TARGET_32BIT && arm_arch4"
f7fbdd4a 6040 "
215b30b3 6041 if (!s_register_operand (operands[1], HImode))
f7fbdd4a 6042 operands[1] = copy_to_mode_reg (HImode, operands[1]);
215b30b3 6043 "
6044)
f7fbdd4a 6045
b11cae9e 6046(define_expand "movhi"
6047 [(set (match_operand:HI 0 "general_operand" "")
c8f69309 6048 (match_operand:HI 1 "general_operand" ""))]
cffb2a26 6049 "TARGET_EITHER"
b11cae9e 6050 "
cffb2a26 6051 if (TARGET_ARM)
b11cae9e 6052 {
e1ba4a27 6053 if (can_create_pseudo_p ())
cffb2a26 6054 {
0438d37f 6055 if (MEM_P (operands[0]))
b11cae9e 6056 {
cffb2a26 6057 if (arm_arch4)
6058 {
6059 emit_insn (gen_storehi_single_op (operands[0], operands[1]));
6060 DONE;
6061 }
0438d37f 6062 if (CONST_INT_P (operands[1]))
cffb2a26 6063 emit_insn (gen_storeinthi (operands[0], operands[1]));
c7597b5d 6064 else
cffb2a26 6065 {
0438d37f 6066 if (MEM_P (operands[1]))
cffb2a26 6067 operands[1] = force_reg (HImode, operands[1]);
6068 if (BYTES_BIG_ENDIAN)
6069 emit_insn (gen_storehi_bigend (operands[1], operands[0]));
6070 else
6071 emit_insn (gen_storehi (operands[1], operands[0]));
6072 }
6073 DONE;
b11cae9e 6074 }
cffb2a26 6075 /* Sign extend a constant, and keep it in an SImode reg. */
0438d37f 6076 else if (CONST_INT_P (operands[1]))
9c08d1fa 6077 {
cffb2a26 6078 rtx reg = gen_reg_rtx (SImode);
6079 HOST_WIDE_INT val = INTVAL (operands[1]) & 0xffff;
6080
6081 /* If the constant is already valid, leave it alone. */
215b30b3 6082 if (!const_ok_for_arm (val))
cffb2a26 6083 {
6084 /* If setting all the top bits will make the constant
6085 loadable in a single instruction, then set them.
6086 Otherwise, sign extend the number. */
6087
215b30b3 6088 if (const_ok_for_arm (~(val | ~0xffff)))
cffb2a26 6089 val |= ~0xffff;
6090 else if (val & 0x8000)
6091 val |= ~0xffff;
6092 }
6093
6094 emit_insn (gen_movsi (reg, GEN_INT (val)));
9e8503e6 6095 operands[1] = gen_lowpart (HImode, reg);
9c08d1fa 6096 }
e1ba4a27 6097 else if (arm_arch4 && optimize && can_create_pseudo_p ()
0438d37f 6098 && MEM_P (operands[1]))
0045890a 6099 {
6100 rtx reg = gen_reg_rtx (SImode);
6101
6102 emit_insn (gen_zero_extendhisi2 (reg, operands[1]));
6103 operands[1] = gen_lowpart (HImode, reg);
6104 }
215b30b3 6105 else if (!arm_arch4)
f7fbdd4a 6106 {
0438d37f 6107 if (MEM_P (operands[1]))
cffb2a26 6108 {
c1a66faf 6109 rtx base;
6110 rtx offset = const0_rtx;
6111 rtx reg = gen_reg_rtx (SImode);
6112
0438d37f 6113 if ((REG_P (base = XEXP (operands[1], 0))
c1a66faf 6114 || (GET_CODE (base) == PLUS
0438d37f 6115 && (CONST_INT_P (offset = XEXP (base, 1)))
c1a66faf 6116 && ((INTVAL(offset) & 1) != 1)
0438d37f 6117 && REG_P (base = XEXP (base, 0))))
c1a66faf 6118 && REGNO_POINTER_ALIGN (REGNO (base)) >= 32)
206ee9a2 6119 {
8deb3959 6120 rtx new_rtx;
c1a66faf 6121
8deb3959 6122 new_rtx = widen_memory_access (operands[1], SImode,
6123 ((INTVAL (offset) & ~3)
6124 - INTVAL (offset)));
6125 emit_insn (gen_movsi (reg, new_rtx));
c1a66faf 6126 if (((INTVAL (offset) & 2) != 0)
6127 ^ (BYTES_BIG_ENDIAN ? 1 : 0))
6128 {
6129 rtx reg2 = gen_reg_rtx (SImode);
6130
6131 emit_insn (gen_lshrsi3 (reg2, reg, GEN_INT (16)));
6132 reg = reg2;
6133 }
206ee9a2 6134 }
c1a66faf 6135 else
6136 emit_insn (gen_movhi_bytes (reg, operands[1]));
6137
6138 operands[1] = gen_lowpart (HImode, reg);
cffb2a26 6139 }
6140 }
6141 }
674a8f0b 6142 /* Handle loading a large integer during reload. */
0438d37f 6143 else if (CONST_INT_P (operands[1])
215b30b3 6144 && !const_ok_for_arm (INTVAL (operands[1]))
6145 && !const_ok_for_arm (~INTVAL (operands[1])))
cffb2a26 6146 {
6147 /* Writing a constant to memory needs a scratch, which should
6148 be handled with SECONDARY_RELOADs. */
0438d37f 6149 gcc_assert (REG_P (operands[0]));
cffb2a26 6150
6151 operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
6152 emit_insn (gen_movsi (operands[0], operands[1]));
6153 DONE;
6154 }
6155 }
25f905c2 6156 else if (TARGET_THUMB2)
6157 {
6158 /* Thumb-2 can do everything except mem=mem and mem=const easily. */
e1ba4a27 6159 if (can_create_pseudo_p ())
25f905c2 6160 {
0438d37f 6161 if (!REG_P (operands[0]))
25f905c2 6162 operands[1] = force_reg (HImode, operands[1]);
6163 /* Zero extend a constant, and keep it in an SImode reg. */
0438d37f 6164 else if (CONST_INT_P (operands[1]))
25f905c2 6165 {
6166 rtx reg = gen_reg_rtx (SImode);
6167 HOST_WIDE_INT val = INTVAL (operands[1]) & 0xffff;
6168
6169 emit_insn (gen_movsi (reg, GEN_INT (val)));
6170 operands[1] = gen_lowpart (HImode, reg);
6171 }
6172 }
6173 }
6174 else /* TARGET_THUMB1 */
cffb2a26 6175 {
e1ba4a27 6176 if (can_create_pseudo_p ())
cffb2a26 6177 {
0438d37f 6178 if (CONST_INT_P (operands[1]))
6cffc037 6179 {
6180 rtx reg = gen_reg_rtx (SImode);
6181
6182 emit_insn (gen_movsi (reg, operands[1]));
6183 operands[1] = gen_lowpart (HImode, reg);
6184 }
cffb2a26 6185
6186 /* ??? We shouldn't really get invalid addresses here, but this can
215b30b3 6187 happen if we are passed a SP (never OK for HImode/QImode) or
bc409cb4 6188 virtual register (also rejected as illegitimate for HImode/QImode)
6189 relative address. */
cffb2a26 6190 /* ??? This should perhaps be fixed elsewhere, for instance, in
6191 fixup_stack_1, by checking for other kinds of invalid addresses,
6192 e.g. a bare reference to a virtual register. This may confuse the
6193 alpha though, which must handle this case differently. */
0438d37f 6194 if (MEM_P (operands[0])
215b30b3 6195 && !memory_address_p (GET_MODE (operands[0]),
6196 XEXP (operands[0], 0)))
537ffcfc 6197 operands[0]
6198 = replace_equiv_address (operands[0],
6199 copy_to_reg (XEXP (operands[0], 0)));
cffb2a26 6200
0438d37f 6201 if (MEM_P (operands[1])
215b30b3 6202 && !memory_address_p (GET_MODE (operands[1]),
6203 XEXP (operands[1], 0)))
537ffcfc 6204 operands[1]
6205 = replace_equiv_address (operands[1],
6206 copy_to_reg (XEXP (operands[1], 0)));
6cffc037 6207
0438d37f 6208 if (MEM_P (operands[1]) && optimize > 0)
6cffc037 6209 {
6210 rtx reg = gen_reg_rtx (SImode);
6211
6212 emit_insn (gen_zero_extendhisi2 (reg, operands[1]));
6213 operands[1] = gen_lowpart (HImode, reg);
6214 }
6215
0438d37f 6216 if (MEM_P (operands[0]))
6cffc037 6217 operands[1] = force_reg (HImode, operands[1]);
cffb2a26 6218 }
0438d37f 6219 else if (CONST_INT_P (operands[1])
234f6557 6220 && !satisfies_constraint_I (operands[1]))
cffb2a26 6221 {
6cffc037 6222 /* Handle loading a large integer during reload. */
6223
cffb2a26 6224 /* Writing a constant to memory needs a scratch, which should
6225 be handled with SECONDARY_RELOADs. */
0438d37f 6226 gcc_assert (REG_P (operands[0]));
cffb2a26 6227
1a83b3ff 6228 operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
cffb2a26 6229 emit_insn (gen_movsi (operands[0], operands[1]));
6230 DONE;
6231 }
b11cae9e 6232 }
cffb2a26 6233 "
6234)
6235
25f7a26e 6236(define_expand "movhi_bytes"
eab14235 6237 [(set (match_dup 2) (zero_extend:SI (match_operand:HI 1 "" "")))
25f7a26e 6238 (set (match_dup 3)
eab14235 6239 (zero_extend:SI (match_dup 6)))
25f7a26e 6240 (set (match_operand:SI 0 "" "")
6241 (ior:SI (ashift:SI (match_dup 4) (const_int 8)) (match_dup 5)))]
cffb2a26 6242 "TARGET_ARM"
25f7a26e 6243 "
215b30b3 6244 {
6245 rtx mem1, mem2;
6246 rtx addr = copy_to_mode_reg (SImode, XEXP (operands[1], 0));
6247
788fcce0 6248 mem1 = change_address (operands[1], QImode, addr);
29c05e22 6249 mem2 = change_address (operands[1], QImode,
6250 plus_constant (Pmode, addr, 1));
215b30b3 6251 operands[0] = gen_lowpart (SImode, operands[0]);
6252 operands[1] = mem1;
6253 operands[2] = gen_reg_rtx (SImode);
6254 operands[3] = gen_reg_rtx (SImode);
6255 operands[6] = mem2;
25f7a26e 6256
215b30b3 6257 if (BYTES_BIG_ENDIAN)
6258 {
6259 operands[4] = operands[2];
6260 operands[5] = operands[3];
6261 }
6262 else
6263 {
6264 operands[4] = operands[3];
6265 operands[5] = operands[2];
6266 }
6267 }"
6268)
25f7a26e 6269
c7597b5d 6270(define_expand "movhi_bigend"
6271 [(set (match_dup 2)
6272 (rotate:SI (subreg:SI (match_operand:HI 1 "memory_operand" "") 0)
6273 (const_int 16)))
6274 (set (match_dup 3)
6275 (ashiftrt:SI (match_dup 2) (const_int 16)))
6276 (set (match_operand:HI 0 "s_register_operand" "")
787f8210 6277 (match_dup 4))]
cffb2a26 6278 "TARGET_ARM"
c7597b5d 6279 "
6280 operands[2] = gen_reg_rtx (SImode);
6281 operands[3] = gen_reg_rtx (SImode);
787f8210 6282 operands[4] = gen_lowpart (HImode, operands[3]);
215b30b3 6283 "
6284)
b11cae9e 6285
a2f10574 6286;; Pattern to recognize insn generated default case above
f7fbdd4a 6287(define_insn "*movhi_insn_arch4"
cde1623a 6288 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,m,r")
5fd254ed 6289 (match_operand:HI 1 "general_operand" "rIk,K,r,mi"))]
cffb2a26 6290 "TARGET_ARM
6291 && arm_arch4
85e02ccb 6292 && (register_operand (operands[0], HImode)
6293 || register_operand (operands[1], HImode))"
f7fbdd4a 6294 "@
6295 mov%?\\t%0, %1\\t%@ movhi
6296 mvn%?\\t%0, #%B1\\t%@ movhi
25f905c2 6297 str%(h%)\\t%1, %0\\t%@ movhi
6298 ldr%(h%)\\t%0, %1\\t%@ movhi"
65f68e55 6299 [(set_attr "predicable" "yes")
cffb2a26 6300 (set_attr "pool_range" "*,*,*,256")
65f68e55 6301 (set_attr "neg_pool_range" "*,*,*,244")
6302 (set_attr_alternative "type"
6303 [(if_then_else (match_operand 1 "const_int_operand" "")
1aed5204 6304 (const_string "mov_imm" )
6305 (const_string "mov_reg"))
6306 (const_string "mvn_imm")
65f68e55 6307 (const_string "store1")
6308 (const_string "load1")])]
cffb2a26 6309)
f7fbdd4a 6310
f7fbdd4a 6311(define_insn "*movhi_bytes"
65f68e55 6312 [(set (match_operand:HI 0 "s_register_operand" "=r,r,r")
5fd254ed 6313 (match_operand:HI 1 "arm_rhs_operand" "I,rk,K"))]
c1a66faf 6314 "TARGET_ARM"
25f7a26e 6315 "@
65f68e55 6316 mov%?\\t%0, %1\\t%@ movhi
25f7a26e 6317 mov%?\\t%0, %1\\t%@ movhi
0d66636f 6318 mvn%?\\t%0, #%B1\\t%@ movhi"
d2a518d1 6319 [(set_attr "predicable" "yes")
1aed5204 6320 (set_attr "type" "mov_imm,mov_reg,mvn_imm")]
0d66636f 6321)
cffb2a26 6322
bc5c7e08 6323;; We use a DImode scratch because we may occasionally need an additional
6324;; temporary if the address isn't offsettable -- push_reload doesn't seem
6325;; to take any notice of the "o" constraints on reload_memory_operand operand.
d3373b54 6326(define_expand "reload_outhi"
cffb2a26 6327 [(parallel [(match_operand:HI 0 "arm_reload_memory_operand" "=o")
215b30b3 6328 (match_operand:HI 1 "s_register_operand" "r")
6329 (match_operand:DI 2 "s_register_operand" "=&l")])]
cffb2a26 6330 "TARGET_EITHER"
6331 "if (TARGET_ARM)
6332 arm_reload_out_hi (operands);
6333 else
6334 thumb_reload_out_hi (operands);
d3373b54 6335 DONE;
cffb2a26 6336 "
6337)
d3373b54 6338
25f7a26e 6339(define_expand "reload_inhi"
6340 [(parallel [(match_operand:HI 0 "s_register_operand" "=r")
cffb2a26 6341 (match_operand:HI 1 "arm_reload_memory_operand" "o")
bc5c7e08 6342 (match_operand:DI 2 "s_register_operand" "=&r")])]
c1a66faf 6343 "TARGET_EITHER"
25f7a26e 6344 "
cffb2a26 6345 if (TARGET_ARM)
6346 arm_reload_in_hi (operands);
6347 else
6348 thumb_reload_out_hi (operands);
25f7a26e 6349 DONE;
6350")
6351
9c08d1fa 6352(define_expand "movqi"
6353 [(set (match_operand:QI 0 "general_operand" "")
6354 (match_operand:QI 1 "general_operand" ""))]
cffb2a26 6355 "TARGET_EITHER"
9c08d1fa 6356 "
6cffc037 6357 /* Everything except mem = const or mem = mem can be done easily */
0045890a 6358
e1ba4a27 6359 if (can_create_pseudo_p ())
cffb2a26 6360 {
0438d37f 6361 if (CONST_INT_P (operands[1]))
6cffc037 6362 {
6363 rtx reg = gen_reg_rtx (SImode);
6364
03770691 6365 /* For thumb we want an unsigned immediate, then we are more likely
6366 to be able to use a movs insn. */
6367 if (TARGET_THUMB)
6368 operands[1] = GEN_INT (INTVAL (operands[1]) & 255);
6369
6cffc037 6370 emit_insn (gen_movsi (reg, operands[1]));
6371 operands[1] = gen_lowpart (QImode, reg);
6372 }
cffb2a26 6373
6cffc037 6374 if (TARGET_THUMB)
6375 {
cffb2a26 6376 /* ??? We shouldn't really get invalid addresses here, but this can
215b30b3 6377 happen if we are passed a SP (never OK for HImode/QImode) or
bc409cb4 6378 virtual register (also rejected as illegitimate for HImode/QImode)
6379 relative address. */
cffb2a26 6380 /* ??? This should perhaps be fixed elsewhere, for instance, in
6381 fixup_stack_1, by checking for other kinds of invalid addresses,
6382 e.g. a bare reference to a virtual register. This may confuse the
6383 alpha though, which must handle this case differently. */
0438d37f 6384 if (MEM_P (operands[0])
215b30b3 6385 && !memory_address_p (GET_MODE (operands[0]),
cffb2a26 6386 XEXP (operands[0], 0)))
537ffcfc 6387 operands[0]
6388 = replace_equiv_address (operands[0],
6389 copy_to_reg (XEXP (operands[0], 0)));
0438d37f 6390 if (MEM_P (operands[1])
215b30b3 6391 && !memory_address_p (GET_MODE (operands[1]),
cffb2a26 6392 XEXP (operands[1], 0)))
537ffcfc 6393 operands[1]
6394 = replace_equiv_address (operands[1],
6395 copy_to_reg (XEXP (operands[1], 0)));
6cffc037 6396 }
6397
0438d37f 6398 if (MEM_P (operands[1]) && optimize > 0)
6cffc037 6399 {
6400 rtx reg = gen_reg_rtx (SImode);
6401
6402 emit_insn (gen_zero_extendqisi2 (reg, operands[1]));
6403 operands[1] = gen_lowpart (QImode, reg);
6404 }
6405
0438d37f 6406 if (MEM_P (operands[0]))
6cffc037 6407 operands[1] = force_reg (QImode, operands[1]);
6408 }
6409 else if (TARGET_THUMB
0438d37f 6410 && CONST_INT_P (operands[1])
234f6557 6411 && !satisfies_constraint_I (operands[1]))
6cffc037 6412 {
674a8f0b 6413 /* Handle loading a large integer during reload. */
cffb2a26 6414
6cffc037 6415 /* Writing a constant to memory needs a scratch, which should
6416 be handled with SECONDARY_RELOADs. */
0438d37f 6417 gcc_assert (REG_P (operands[0]));
6cffc037 6418
6419 operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
6420 emit_insn (gen_movsi (operands[0], operands[1]));
6421 DONE;
cffb2a26 6422 }
6423 "
6424)
b11cae9e 6425
cffb2a26 6426(define_insn "*arm_movqi_insn"
fd711051 6427 [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,r,l,r,l,Uu,r,m")
490f62ca 6428 (match_operand:QI 1 "general_operand" "rk,rk,I,Py,K,Uu,l,Uh,r"))]
25f905c2 6429 "TARGET_32BIT
cffb2a26 6430 && ( register_operand (operands[0], QImode)
6431 || register_operand (operands[1], QImode))"
5565501b 6432 "@
fd711051 6433 mov%?\\t%0, %1
6434 mov%?\\t%0, %1
65f68e55 6435 mov%?\\t%0, %1
5565501b 6436 mov%?\\t%0, %1
6437 mvn%?\\t%0, #%B1
25f905c2 6438 ldr%(b%)\\t%0, %1
a54e3e7b 6439 str%(b%)\\t%1, %0
6440 ldr%(b%)\\t%0, %1
25f905c2 6441 str%(b%)\\t%1, %0"
1aed5204 6442 [(set_attr "type" "mov_reg,mov_reg,mov_imm,mov_imm,mvn_imm,load1,store1,load1,store1")
a54e3e7b 6443 (set_attr "predicable" "yes")
fd711051 6444 (set_attr "predicable_short_it" "yes,yes,yes,no,no,no,no,no,no")
6445 (set_attr "arch" "t2,any,any,t2,any,t2,t2,any,any")
6446 (set_attr "length" "2,4,4,2,4,2,2,4,4")]
cffb2a26 6447)
6448
9b8516be 6449;; HFmode moves
6450(define_expand "movhf"
6451 [(set (match_operand:HF 0 "general_operand" "")
6452 (match_operand:HF 1 "general_operand" ""))]
6453 "TARGET_EITHER"
6454 "
6455 if (TARGET_32BIT)
6456 {
0438d37f 6457 if (MEM_P (operands[0]))
9b8516be 6458 operands[1] = force_reg (HFmode, operands[1]);
6459 }
6460 else /* TARGET_THUMB1 */
6461 {
6462 if (can_create_pseudo_p ())
6463 {
0438d37f 6464 if (!REG_P (operands[0]))
9b8516be 6465 operands[1] = force_reg (HFmode, operands[1]);
6466 }
6467 }
6468 "
6469)
6470
6471(define_insn "*arm32_movhf"
6472 [(set (match_operand:HF 0 "nonimmediate_operand" "=r,m,r,r")
6473 (match_operand:HF 1 "general_operand" " m,r,r,F"))]
7c36fe71 6474 "TARGET_32BIT && !(TARGET_HARD_FLOAT && TARGET_FP16) && !arm_restrict_it
9b8516be 6475 && ( s_register_operand (operands[0], HFmode)
6476 || s_register_operand (operands[1], HFmode))"
6477 "*
6478 switch (which_alternative)
6479 {
6480 case 0: /* ARM register from memory */
6481 return \"ldr%(h%)\\t%0, %1\\t%@ __fp16\";
6482 case 1: /* memory from ARM register */
6483 return \"str%(h%)\\t%1, %0\\t%@ __fp16\";
6484 case 2: /* ARM register from ARM register */
6485 return \"mov%?\\t%0, %1\\t%@ __fp16\";
6486 case 3: /* ARM register from constant */
6487 {
6488 REAL_VALUE_TYPE r;
6489 long bits;
6490 rtx ops[4];
6491
6492 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
6493 bits = real_to_target (NULL, &r, HFmode);
6494 ops[0] = operands[0];
6495 ops[1] = GEN_INT (bits);
6496 ops[2] = GEN_INT (bits & 0xff00);
6497 ops[3] = GEN_INT (bits & 0x00ff);
6498
6499 if (arm_arch_thumb2)
6500 output_asm_insn (\"movw%?\\t%0, %1\", ops);
6501 else
6502 output_asm_insn (\"mov%?\\t%0, %2\;orr%?\\t%0, %0, %3\", ops);
6503 return \"\";
6504 }
6505 default:
6506 gcc_unreachable ();
6507 }
6508 "
6509 [(set_attr "conds" "unconditional")
ad4fc3c0 6510 (set_attr "type" "load1,store1,mov_reg,multiple")
9b8516be 6511 (set_attr "length" "4,4,4,8")
d2a518d1 6512 (set_attr "predicable" "yes")]
9b8516be 6513)
6514
87b22bf7 6515(define_expand "movsf"
6516 [(set (match_operand:SF 0 "general_operand" "")
6517 (match_operand:SF 1 "general_operand" ""))]
cffb2a26 6518 "TARGET_EITHER"
87b22bf7 6519 "
25f905c2 6520 if (TARGET_32BIT)
cffb2a26 6521 {
0438d37f 6522 if (MEM_P (operands[0]))
cffb2a26 6523 operands[1] = force_reg (SFmode, operands[1]);
6524 }
25f905c2 6525 else /* TARGET_THUMB1 */
cffb2a26 6526 {
e1ba4a27 6527 if (can_create_pseudo_p ())
cffb2a26 6528 {
0438d37f 6529 if (!REG_P (operands[0]))
cffb2a26 6530 operands[1] = force_reg (SFmode, operands[1]);
6531 }
6532 }
6533 "
6534)
6535
03d440a6 6536;; Transform a floating-point move of a constant into a core register into
6537;; an SImode operation.
cffb2a26 6538(define_split
03d440a6 6539 [(set (match_operand:SF 0 "arm_general_register_operand" "")
cffb2a26 6540 (match_operand:SF 1 "immediate_operand" ""))]
339034d0 6541 "TARGET_EITHER
cffb2a26 6542 && reload_completed
0438d37f 6543 && CONST_DOUBLE_P (operands[1])"
cffb2a26 6544 [(set (match_dup 2) (match_dup 3))]
6545 "
6546 operands[2] = gen_lowpart (SImode, operands[0]);
6547 operands[3] = gen_lowpart (SImode, operands[1]);
6548 if (operands[2] == 0 || operands[3] == 0)
6549 FAIL;
215b30b3 6550 "
6551)
87b22bf7 6552
cffb2a26 6553(define_insn "*arm_movsf_soft_insn"
6554 [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,m")
6555 (match_operand:SF 1 "general_operand" "r,mE,r"))]
cde1623a 6556 "TARGET_32BIT
cffb2a26 6557 && TARGET_SOFT_FLOAT
0438d37f 6558 && (!MEM_P (operands[0])
215b30b3 6559 || register_operand (operands[1], SFmode))"
9a1112d7 6560 "@
6561 mov%?\\t%0, %1
6562 ldr%?\\t%0, %1\\t%@ float
6563 str%?\\t%1, %0\\t%@ float"
cde1623a 6564 [(set_attr "predicable" "yes")
7c36fe71 6565 (set_attr "predicable_short_it" "no")
1aed5204 6566 (set_attr "type" "mov_reg,load1,store1")
42e1de19 6567 (set_attr "arm_pool_range" "*,4096,*")
6568 (set_attr "thumb2_pool_range" "*,4094,*")
cde1623a 6569 (set_attr "arm_neg_pool_range" "*,4084,*")
6570 (set_attr "thumb2_neg_pool_range" "*,0,*")]
cffb2a26 6571)
6572
9c08d1fa 6573(define_expand "movdf"
87b22bf7 6574 [(set (match_operand:DF 0 "general_operand" "")
6575 (match_operand:DF 1 "general_operand" ""))]
cffb2a26 6576 "TARGET_EITHER"
9c08d1fa 6577 "
25f905c2 6578 if (TARGET_32BIT)
cffb2a26 6579 {
0438d37f 6580 if (MEM_P (operands[0]))
cffb2a26 6581 operands[1] = force_reg (DFmode, operands[1]);
6582 }
6583 else /* TARGET_THUMB */
6584 {
e1ba4a27 6585 if (can_create_pseudo_p ())
cffb2a26 6586 {
0438d37f 6587 if (!REG_P (operands[0]))
cffb2a26 6588 operands[1] = force_reg (DFmode, operands[1]);
6589 }
6590 }
6591 "
6592)
b11cae9e 6593
9c08d1fa 6594;; Reloading a df mode value stored in integer regs to memory can require a
6595;; scratch reg.
6596(define_expand "reload_outdf"
cffb2a26 6597 [(match_operand:DF 0 "arm_reload_memory_operand" "=o")
87b22bf7 6598 (match_operand:DF 1 "s_register_operand" "r")
6599 (match_operand:SI 2 "s_register_operand" "=&r")]
06adefdc 6600 "TARGET_THUMB2"
87b22bf7 6601 "
215b30b3 6602 {
6603 enum rtx_code code = GET_CODE (XEXP (operands[0], 0));
f7fbdd4a 6604
215b30b3 6605 if (code == REG)
6606 operands[2] = XEXP (operands[0], 0);
6607 else if (code == POST_INC || code == PRE_DEC)
6608 {
6609 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
6610 operands[1] = gen_rtx_SUBREG (DImode, operands[1], 0);
6611 emit_insn (gen_movdi (operands[0], operands[1]));
6612 DONE;
6613 }
6614 else if (code == PRE_INC)
6615 {
6616 rtx reg = XEXP (XEXP (operands[0], 0), 0);
f7fbdd4a 6617
215b30b3 6618 emit_insn (gen_addsi3 (reg, reg, GEN_INT (8)));
6619 operands[2] = reg;
6620 }
6621 else if (code == POST_DEC)
6622 operands[2] = XEXP (XEXP (operands[0], 0), 0);
6623 else
6624 emit_insn (gen_addsi3 (operands[2], XEXP (XEXP (operands[0], 0), 0),
6625 XEXP (XEXP (operands[0], 0), 1)));
f7fbdd4a 6626
788fcce0 6627 emit_insn (gen_rtx_SET (VOIDmode,
6628 replace_equiv_address (operands[0], operands[2]),
215b30b3 6629 operands[1]));
f7fbdd4a 6630
215b30b3 6631 if (code == POST_DEC)
6632 emit_insn (gen_addsi3 (operands[2], operands[2], GEN_INT (-8)));
6633
6634 DONE;
6635 }"
6636)
9c08d1fa 6637
9a1112d7 6638(define_insn "*movdf_soft_insn"
353cf59a 6639 [(set (match_operand:DF 0 "nonimmediate_soft_df_operand" "=r,r,r,q,m")
6640 (match_operand:DF 1 "soft_df_operand" "rDa,Db,Dc,mF,q"))]
cde1623a 6641 "TARGET_32BIT && TARGET_SOFT_FLOAT
b2778788 6642 && ( register_operand (operands[0], DFmode)
6643 || register_operand (operands[1], DFmode))"
d51f92df 6644 "*
6645 switch (which_alternative)
6646 {
6647 case 0:
6648 case 1:
6649 case 2:
6650 return \"#\";
6651 default:
26ff80c0 6652 return output_move_double (operands, true, NULL);
d51f92df 6653 }
6654 "
359a6e9f 6655 [(set_attr "length" "8,12,16,8,8")
1b7da4ac 6656 (set_attr "type" "multiple,multiple,multiple,load2,store2")
42e1de19 6657 (set_attr "arm_pool_range" "*,*,*,1020,*")
6658 (set_attr "thumb2_pool_range" "*,*,*,1018,*")
8848d797 6659 (set_attr "arm_neg_pool_range" "*,*,*,1004,*")
cde1623a 6660 (set_attr "thumb2_neg_pool_range" "*,*,*,0,*")]
cffb2a26 6661)
b11cae9e 6662\f
b11cae9e 6663
9c08d1fa 6664;; load- and store-multiple insns
6665;; The arm can load/store any set of registers, provided that they are in
320ea44d 6666;; ascending order, but these expanders assume a contiguous set.
b11cae9e 6667
9c08d1fa 6668(define_expand "load_multiple"
6669 [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
6670 (match_operand:SI 1 "" ""))
6671 (use (match_operand:SI 2 "" ""))])]
25f905c2 6672 "TARGET_32BIT"
9580c25f 6673{
6674 HOST_WIDE_INT offset = 0;
6675
bd5b4116 6676 /* Support only fixed point registers. */
0438d37f 6677 if (!CONST_INT_P (operands[2])
9c08d1fa 6678 || INTVAL (operands[2]) > 14
6679 || INTVAL (operands[2]) < 2
0438d37f 6680 || !MEM_P (operands[1])
6681 || !REG_P (operands[0])
bd5b4116 6682 || REGNO (operands[0]) > (LAST_ARM_REGNUM - 1)
6683 || REGNO (operands[0]) + INTVAL (operands[2]) > LAST_ARM_REGNUM)
9c08d1fa 6684 FAIL;
6685
6686 operands[3]
320ea44d 6687 = arm_gen_load_multiple (arm_regs_in_sequence + REGNO (operands[0]),
6688 INTVAL (operands[2]),
f082f1c4 6689 force_reg (SImode, XEXP (operands[1], 0)),
320ea44d 6690 FALSE, operands[1], &offset);
9580c25f 6691})
b11cae9e 6692
9c08d1fa 6693(define_expand "store_multiple"
6694 [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
6695 (match_operand:SI 1 "" ""))
6696 (use (match_operand:SI 2 "" ""))])]
25f905c2 6697 "TARGET_32BIT"
9580c25f 6698{
6699 HOST_WIDE_INT offset = 0;
6700
674a8f0b 6701 /* Support only fixed point registers. */
0438d37f 6702 if (!CONST_INT_P (operands[2])
9c08d1fa 6703 || INTVAL (operands[2]) > 14
6704 || INTVAL (operands[2]) < 2
0438d37f 6705 || !REG_P (operands[1])
6706 || !MEM_P (operands[0])
bd5b4116 6707 || REGNO (operands[1]) > (LAST_ARM_REGNUM - 1)
6708 || REGNO (operands[1]) + INTVAL (operands[2]) > LAST_ARM_REGNUM)
9c08d1fa 6709 FAIL;
6710
6711 operands[3]
320ea44d 6712 = arm_gen_store_multiple (arm_regs_in_sequence + REGNO (operands[1]),
6713 INTVAL (operands[2]),
f082f1c4 6714 force_reg (SImode, XEXP (operands[0], 0)),
320ea44d 6715 FALSE, operands[0], &offset);
9580c25f 6716})
b11cae9e 6717
9c08d1fa 6718
e34ebfca 6719(define_expand "setmemsi"
6720 [(match_operand:BLK 0 "general_operand" "")
6721 (match_operand:SI 1 "const_int_operand" "")
6722 (match_operand:SI 2 "const_int_operand" "")
6723 (match_operand:SI 3 "const_int_operand" "")]
6724 "TARGET_32BIT"
6725{
6726 if (arm_gen_setmem (operands))
6727 DONE;
6728
6729 FAIL;
6730})
6731
6732
9c08d1fa 6733;; Move a block of memory if it is word aligned and MORE than 2 words long.
6734;; We could let this apply for blocks of less than this, but it clobbers so
6735;; many registers that there is then probably a better way.
6736
008c057d 6737(define_expand "movmemqi"
34191dd1 6738 [(match_operand:BLK 0 "general_operand" "")
6739 (match_operand:BLK 1 "general_operand" "")
6740 (match_operand:SI 2 "const_int_operand" "")
6741 (match_operand:SI 3 "const_int_operand" "")]
ae51a965 6742 ""
9c08d1fa 6743 "
25f905c2 6744 if (TARGET_32BIT)
cffb2a26 6745 {
ae51a965 6746 if (TARGET_LDRD && current_tune->prefer_ldrd_strd
6747 && !optimize_function_for_size_p (cfun))
6748 {
6749 if (gen_movmem_ldrd_strd (operands))
6750 DONE;
6751 FAIL;
6752 }
6753
008c057d 6754 if (arm_gen_movmemqi (operands))
cffb2a26 6755 DONE;
6756 FAIL;
6757 }
25f905c2 6758 else /* TARGET_THUMB1 */
cffb2a26 6759 {
6760 if ( INTVAL (operands[3]) != 4
6761 || INTVAL (operands[2]) > 48)
6762 FAIL;
6763
008c057d 6764 thumb_expand_movmemqi (operands);
cffb2a26 6765 DONE;
6766 }
6767 "
6768)
9c08d1fa 6769\f
b11cae9e 6770
341940e8 6771;; Compare & branch insns
8d232dc7 6772;; The range calculations are based as follows:
341940e8 6773;; For forward branches, the address calculation returns the address of
6774;; the next instruction. This is 2 beyond the branch instruction.
6775;; For backward branches, the address calculation returns the address of
6776;; the first instruction in this pattern (cmp). This is 2 before the branch
6777;; instruction for the shortest sequence, and 4 before the branch instruction
6778;; if we have to jump around an unconditional branch.
6779;; To the basic branch range the PC offset must be added (this is +4).
6780;; So for forward branches we have
6781;; (pos_range - pos_base_offs + pc_offs) = (pos_range - 2 + 4).
6782;; And for backward branches we have
6783;; (neg_range - neg_base_offs + pc_offs) = (neg_range - (-2 or -4) + 4).
6784;;
6785;; For a 'b' pos_range = 2046, neg_range = -2048 giving (-2040->2048).
6786;; For a 'b<cond>' pos_range = 254, neg_range = -256 giving (-250 ->256).
cffb2a26 6787
aeac46d4 6788(define_expand "cbranchsi4"
6789 [(set (pc) (if_then_else
aa06947a 6790 (match_operator 0 "expandable_comparison_operator"
aeac46d4 6791 [(match_operand:SI 1 "s_register_operand" "")
6792 (match_operand:SI 2 "nonmemory_operand" "")])
6793 (label_ref (match_operand 3 "" ""))
6794 (pc)))]
f9aa4160 6795 "TARGET_EITHER"
aeac46d4 6796 "
74f4459c 6797 if (!TARGET_THUMB1)
6798 {
f9aa4160 6799 if (!arm_validize_comparison (&operands[0], &operands[1], &operands[2]))
6800 FAIL;
74f4459c 6801 emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
6802 operands[3]));
6803 DONE;
6804 }
25f905c2 6805 if (thumb1_cmpneg_operand (operands[2], SImode))
aeac46d4 6806 {
6807 emit_jump_insn (gen_cbranchsi4_scratch (NULL, operands[1], operands[2],
6808 operands[3], operands[0]));
6809 DONE;
6810 }
25f905c2 6811 if (!thumb1_cmp_operand (operands[2], SImode))
aeac46d4 6812 operands[2] = force_reg (SImode, operands[2]);
6813 ")
6814
74f4459c 6815(define_expand "cbranchsf4"
6816 [(set (pc) (if_then_else
aa06947a 6817 (match_operator 0 "expandable_comparison_operator"
74f4459c 6818 [(match_operand:SF 1 "s_register_operand" "")
6819 (match_operand:SF 2 "arm_float_compare_operand" "")])
6820 (label_ref (match_operand 3 "" ""))
6821 (pc)))]
6822 "TARGET_32BIT && TARGET_HARD_FLOAT"
6823 "emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
6824 operands[3])); DONE;"
6825)
6826
6827(define_expand "cbranchdf4"
6828 [(set (pc) (if_then_else
aa06947a 6829 (match_operator 0 "expandable_comparison_operator"
74f4459c 6830 [(match_operand:DF 1 "s_register_operand" "")
6831 (match_operand:DF 2 "arm_float_compare_operand" "")])
6832 (label_ref (match_operand 3 "" ""))
6833 (pc)))]
a50d7267 6834 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
74f4459c 6835 "emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
6836 operands[3])); DONE;"
6837)
6838
74f4459c 6839(define_expand "cbranchdi4"
6840 [(set (pc) (if_then_else
aa06947a 6841 (match_operator 0 "expandable_comparison_operator"
b8eae306 6842 [(match_operand:DI 1 "s_register_operand" "")
a8045a4f 6843 (match_operand:DI 2 "cmpdi_operand" "")])
74f4459c 6844 (label_ref (match_operand 3 "" ""))
6845 (pc)))]
a8045a4f 6846 "TARGET_32BIT"
6847 "{
0438d37f 6848 if (!arm_validize_comparison (&operands[0], &operands[1], &operands[2]))
f9aa4160 6849 FAIL;
6850 emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
a8045a4f 6851 operands[3]));
6852 DONE;
6853 }"
74f4459c 6854)
6855
9c08d1fa 6856;; Comparison and test insns
6857
cffb2a26 6858(define_insn "*arm_cmpsi_insn"
bd5b4116 6859 [(set (reg:CC CC_REGNUM)
f9f234ec 6860 (compare:CC (match_operand:SI 0 "s_register_operand" "l,r,r,r,r")
6861 (match_operand:SI 1 "arm_add_operand" "Py,r,r,I,L")))]
25f905c2 6862 "TARGET_32BIT"
5565501b 6863 "@
a6864a24 6864 cmp%?\\t%0, %1
6865 cmp%?\\t%0, %1
aea4c774 6866 cmp%?\\t%0, %1
f9f234ec 6867 cmp%?\\t%0, %1
aea4c774 6868 cmn%?\\t%0, #%n1"
a6864a24 6869 [(set_attr "conds" "set")
f9f234ec 6870 (set_attr "arch" "t2,t2,any,any,any")
6871 (set_attr "length" "2,2,4,4,4")
65f68e55 6872 (set_attr "predicable" "yes")
f9f234ec 6873 (set_attr "predicable_short_it" "yes,yes,yes,no,no")
112eda6f 6874 (set_attr "type" "alus_imm,alus_sreg,alus_sreg,alus_imm,alus_imm")]
cffb2a26 6875)
b11cae9e 6876
d5d4dc8d 6877(define_insn "*cmpsi_shiftsi"
bd5b4116 6878 [(set (reg:CC CC_REGNUM)
d82e788e 6879 (compare:CC (match_operand:SI 0 "s_register_operand" "r,r,r")
cffb2a26 6880 (match_operator:SI 3 "shift_operator"
d82e788e 6881 [(match_operand:SI 1 "s_register_operand" "r,r,r")
6882 (match_operand:SI 2 "shift_amount_operand" "M,r,M")])))]
d5d4dc8d 6883 "TARGET_32BIT"
f9f234ec 6884 "cmp\\t%0, %1%S3"
344495ea 6885 [(set_attr "conds" "set")
331beb1a 6886 (set_attr "shift" "1")
d82e788e 6887 (set_attr "arch" "32,a,a")
6888 (set_attr "type" "alus_shift_imm,alu_shift_reg,alus_shift_imm")])
b11cae9e 6889
d5d4dc8d 6890(define_insn "*cmpsi_shiftsi_swp"
bd5b4116 6891 [(set (reg:CC_SWP CC_REGNUM)
aea4c774 6892 (compare:CC_SWP (match_operator:SI 3 "shift_operator"
d82e788e 6893 [(match_operand:SI 1 "s_register_operand" "r,r,r")
6894 (match_operand:SI 2 "shift_amount_operand" "M,r,M")])
6895 (match_operand:SI 0 "s_register_operand" "r,r,r")))]
d5d4dc8d 6896 "TARGET_32BIT"
aea4c774 6897 "cmp%?\\t%0, %1%S3"
344495ea 6898 [(set_attr "conds" "set")
331beb1a 6899 (set_attr "shift" "1")
d82e788e 6900 (set_attr "arch" "32,a,a")
6901 (set_attr "type" "alus_shift_imm,alu_shift_reg,alus_shift_imm")])
b11cae9e 6902
25f905c2 6903(define_insn "*arm_cmpsi_negshiftsi_si"
aed179ae 6904 [(set (reg:CC_Z CC_REGNUM)
6905 (compare:CC_Z
6906 (neg:SI (match_operator:SI 1 "shift_operator"
6907 [(match_operand:SI 2 "s_register_operand" "r")
6908 (match_operand:SI 3 "reg_or_int_operand" "rM")]))
6909 (match_operand:SI 0 "s_register_operand" "r")))]
cffb2a26 6910 "TARGET_ARM"
aed179ae 6911 "cmn%?\\t%0, %2%S1"
344495ea 6912 [(set_attr "conds" "set")
aed179ae 6913 (set (attr "type") (if_then_else (match_operand 3 "const_int_operand" "")
d82e788e 6914 (const_string "alus_shift_imm")
6915 (const_string "alus_shift_reg")))
596e5e8f 6916 (set_attr "predicable" "yes")]
0d66636f 6917)
b11cae9e 6918
a8045a4f 6919;; DImode comparisons. The generic code generates branches that
6920;; if-conversion can not reduce to a conditional compare, so we do
6921;; that directly.
6922
ba6a3b2f 6923(define_insn_and_split "*arm_cmpdi_insn"
a8045a4f 6924 [(set (reg:CC_NCV CC_REGNUM)
6925 (compare:CC_NCV (match_operand:DI 0 "s_register_operand" "r")
6926 (match_operand:DI 1 "arm_di_operand" "rDi")))
6927 (clobber (match_scratch:SI 2 "=r"))]
b805622c 6928 "TARGET_32BIT"
ba6a3b2f 6929 "#" ; "cmp\\t%Q0, %Q1\;sbcs\\t%2, %R0, %R1"
6930 "&& reload_completed"
6931 [(set (reg:CC CC_REGNUM)
6932 (compare:CC (match_dup 0) (match_dup 1)))
6933 (parallel [(set (reg:CC CC_REGNUM)
6934 (compare:CC (match_dup 3) (match_dup 4)))
6935 (set (match_dup 2)
6936 (minus:SI (match_dup 5)
6937 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))])]
6938 {
6939 operands[3] = gen_highpart (SImode, operands[0]);
6940 operands[0] = gen_lowpart (SImode, operands[0]);
6941 if (CONST_INT_P (operands[1]))
6942 {
6943 operands[4] = GEN_INT (~INTVAL (gen_highpart_mode (SImode,
6944 DImode,
6945 operands[1])));
6946 operands[5] = gen_rtx_PLUS (SImode, operands[3], operands[4]);
6947 }
6948 else
6949 {
6950 operands[4] = gen_highpart (SImode, operands[1]);
6951 operands[5] = gen_rtx_MINUS (SImode, operands[3], operands[4]);
6952 }
6953 operands[1] = gen_lowpart (SImode, operands[1]);
6954 operands[2] = gen_lowpart (SImode, operands[2]);
6955 }
a8045a4f 6956 [(set_attr "conds" "set")
1b7da4ac 6957 (set_attr "length" "8")
6958 (set_attr "type" "multiple")]
a8045a4f 6959)
6960
ba6a3b2f 6961(define_insn_and_split "*arm_cmpdi_unsigned"
a8045a4f 6962 [(set (reg:CC_CZ CC_REGNUM)
1a86364b 6963 (compare:CC_CZ (match_operand:DI 0 "s_register_operand" "l,r,r,r")
6964 (match_operand:DI 1 "arm_di_operand" "Py,r,Di,rDi")))]
7c36fe71 6965
48a98053 6966 "TARGET_32BIT"
ba6a3b2f 6967 "#" ; "cmp\\t%R0, %R1\;it eq\;cmpeq\\t%Q0, %Q1"
6968 "&& reload_completed"
6969 [(set (reg:CC CC_REGNUM)
6970 (compare:CC (match_dup 2) (match_dup 3)))
6971 (cond_exec (eq:SI (reg:CC CC_REGNUM) (const_int 0))
6972 (set (reg:CC CC_REGNUM)
6973 (compare:CC (match_dup 0) (match_dup 1))))]
6974 {
6975 operands[2] = gen_highpart (SImode, operands[0]);
6976 operands[0] = gen_lowpart (SImode, operands[0]);
6977 if (CONST_INT_P (operands[1]))
6978 operands[3] = gen_highpart_mode (SImode, DImode, operands[1]);
6979 else
6980 operands[3] = gen_highpart (SImode, operands[1]);
6981 operands[1] = gen_lowpart (SImode, operands[1]);
6982 }
a8045a4f 6983 [(set_attr "conds" "set")
1a86364b 6984 (set_attr "enabled_for_depr_it" "yes,yes,no,*")
6985 (set_attr "arch" "t2,t2,t2,a")
6986 (set_attr "length" "6,6,10,8")
1b7da4ac 6987 (set_attr "type" "multiple")]
a8045a4f 6988)
6989
6990(define_insn "*arm_cmpdi_zero"
6991 [(set (reg:CC_Z CC_REGNUM)
6992 (compare:CC_Z (match_operand:DI 0 "s_register_operand" "r")
6993 (const_int 0)))
6994 (clobber (match_scratch:SI 1 "=r"))]
6995 "TARGET_32BIT"
6996 "orr%.\\t%1, %Q0, %R0"
1b7da4ac 6997 [(set_attr "conds" "set")
6998 (set_attr "type" "logics_reg")]
a8045a4f 6999)
7000
9c08d1fa 7001; This insn allows redundant compares to be removed by cse, nothing should
7002; ever appear in the output file since (set (reg x) (reg x)) is a no-op that
7003; is deleted later on. The match_dup will match the mode here, so that
7004; mode changes of the condition codes aren't lost by this even though we don't
7005; specify what they are.
7006
8a18b90c 7007(define_insn "*deleted_compare"
9c08d1fa 7008 [(set (match_operand 0 "cc_register" "") (match_dup 0))]
25f905c2 7009 "TARGET_32BIT"
40dbec34 7010 "\\t%@ deleted compare"
cffb2a26 7011 [(set_attr "conds" "set")
1b7da4ac 7012 (set_attr "length" "0")
7013 (set_attr "type" "no_insn")]
cffb2a26 7014)
9c08d1fa 7015
7016\f
7017;; Conditional branch insns
7018
74f4459c 7019(define_expand "cbranch_cc"
9c08d1fa 7020 [(set (pc)
74f4459c 7021 (if_then_else (match_operator 0 "" [(match_operand 1 "" "")
7022 (match_operand 2 "" "")])
7023 (label_ref (match_operand 3 "" ""))
9c08d1fa 7024 (pc)))]
25f905c2 7025 "TARGET_32BIT"
74f4459c 7026 "operands[1] = arm_gen_compare_reg (GET_CODE (operands[0]),
e1b93706 7027 operands[1], operands[2], NULL_RTX);
74f4459c 7028 operands[2] = const0_rtx;"
8fa3ba89 7029)
7030
7031;;
7032;; Patterns to match conditional branch insns.
7033;;
7034
ffcc986d 7035(define_insn "arm_cond_branch"
9c08d1fa 7036 [(set (pc)
8fa3ba89 7037 (if_then_else (match_operator 1 "arm_comparison_operator"
8a18b90c 7038 [(match_operand 2 "cc_register" "") (const_int 0)])
9c08d1fa 7039 (label_ref (match_operand 0 "" ""))
7040 (pc)))]
25f905c2 7041 "TARGET_32BIT"
d75350ce 7042 "*
9c08d1fa 7043 if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
cffb2a26 7044 {
7045 arm_ccfsm_state += 2;
7046 return \"\";
7047 }
e2348bcb 7048 return \"b%d1\\t%l0\";
cffb2a26 7049 "
a2cd141b 7050 [(set_attr "conds" "use")
a6864a24 7051 (set_attr "type" "branch")
7052 (set (attr "length")
7053 (if_then_else
0bf497f5 7054 (and (match_test "TARGET_THUMB2")
a6864a24 7055 (and (ge (minus (match_dup 0) (pc)) (const_int -250))
7056 (le (minus (match_dup 0) (pc)) (const_int 256))))
7057 (const_int 2)
7058 (const_int 4)))]
cffb2a26 7059)
d75350ce 7060
cffb2a26 7061(define_insn "*arm_cond_branch_reversed"
9c08d1fa 7062 [(set (pc)
8fa3ba89 7063 (if_then_else (match_operator 1 "arm_comparison_operator"
8a18b90c 7064 [(match_operand 2 "cc_register" "") (const_int 0)])
9c08d1fa 7065 (pc)
7066 (label_ref (match_operand 0 "" ""))))]
25f905c2 7067 "TARGET_32BIT"
d75350ce 7068 "*
9c08d1fa 7069 if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
cffb2a26 7070 {
7071 arm_ccfsm_state += 2;
7072 return \"\";
7073 }
e2348bcb 7074 return \"b%D1\\t%l0\";
cffb2a26 7075 "
a2cd141b 7076 [(set_attr "conds" "use")
a6864a24 7077 (set_attr "type" "branch")
7078 (set (attr "length")
7079 (if_then_else
0bf497f5 7080 (and (match_test "TARGET_THUMB2")
a6864a24 7081 (and (ge (minus (match_dup 0) (pc)) (const_int -250))
7082 (le (minus (match_dup 0) (pc)) (const_int 256))))
7083 (const_int 2)
7084 (const_int 4)))]
cffb2a26 7085)
7086
b11cae9e 7087\f
9c08d1fa 7088
7089; scc insns
7090
74f4459c 7091(define_expand "cstore_cc"
7db9af5d 7092 [(set (match_operand:SI 0 "s_register_operand" "")
74f4459c 7093 (match_operator:SI 1 "" [(match_operand 2 "" "")
7094 (match_operand 3 "" "")]))]
25f905c2 7095 "TARGET_32BIT"
74f4459c 7096 "operands[2] = arm_gen_compare_reg (GET_CODE (operands[1]),
e1b93706 7097 operands[2], operands[3], NULL_RTX);
74f4459c 7098 operands[3] = const0_rtx;"
8fa3ba89 7099)
7100
a3b84066 7101(define_insn_and_split "*mov_scc"
9c08d1fa 7102 [(set (match_operand:SI 0 "s_register_operand" "=r")
8fa3ba89 7103 (match_operator:SI 1 "arm_comparison_operator"
8a18b90c 7104 [(match_operand 2 "cc_register" "") (const_int 0)]))]
cffb2a26 7105 "TARGET_ARM"
a3b84066 7106 "#" ; "mov%D1\\t%0, #0\;mov%d1\\t%0, #1"
7107 "TARGET_ARM"
7108 [(set (match_dup 0)
7109 (if_then_else:SI (match_dup 1)
7110 (const_int 1)
7111 (const_int 0)))]
7112 ""
cffb2a26 7113 [(set_attr "conds" "use")
1b7da4ac 7114 (set_attr "length" "8")
7115 (set_attr "type" "multiple")]
cffb2a26 7116)
9c08d1fa 7117
a3b84066 7118(define_insn_and_split "*mov_negscc"
9c08d1fa 7119 [(set (match_operand:SI 0 "s_register_operand" "=r")
8fa3ba89 7120 (neg:SI (match_operator:SI 1 "arm_comparison_operator"
8a18b90c 7121 [(match_operand 2 "cc_register" "") (const_int 0)])))]
cffb2a26 7122 "TARGET_ARM"
a3b84066 7123 "#" ; "mov%D1\\t%0, #0\;mvn%d1\\t%0, #0"
7124 "TARGET_ARM"
7125 [(set (match_dup 0)
7126 (if_then_else:SI (match_dup 1)
7127 (match_dup 3)
7128 (const_int 0)))]
7129 {
7130 operands[3] = GEN_INT (~0);
7131 }
cffb2a26 7132 [(set_attr "conds" "use")
1b7da4ac 7133 (set_attr "length" "8")
7134 (set_attr "type" "multiple")]
cffb2a26 7135)
9c08d1fa 7136
a3b84066 7137(define_insn_and_split "*mov_notscc"
9c08d1fa 7138 [(set (match_operand:SI 0 "s_register_operand" "=r")
8fa3ba89 7139 (not:SI (match_operator:SI 1 "arm_comparison_operator"
8a18b90c 7140 [(match_operand 2 "cc_register" "") (const_int 0)])))]
cffb2a26 7141 "TARGET_ARM"
a3b84066 7142 "#" ; "mvn%D1\\t%0, #0\;mvn%d1\\t%0, #1"
7143 "TARGET_ARM"
7144 [(set (match_dup 0)
7145 (if_then_else:SI (match_dup 1)
7146 (match_dup 3)
7147 (match_dup 4)))]
7148 {
7149 operands[3] = GEN_INT (~1);
7150 operands[4] = GEN_INT (~0);
7151 }
cffb2a26 7152 [(set_attr "conds" "use")
1b7da4ac 7153 (set_attr "length" "8")
7154 (set_attr "type" "multiple")]
cffb2a26 7155)
9c08d1fa 7156
595d88b5 7157(define_expand "cstoresi4"
7158 [(set (match_operand:SI 0 "s_register_operand" "")
aa06947a 7159 (match_operator:SI 1 "expandable_comparison_operator"
595d88b5 7160 [(match_operand:SI 2 "s_register_operand" "")
7161 (match_operand:SI 3 "reg_or_int_operand" "")]))]
74f4459c 7162 "TARGET_32BIT || TARGET_THUMB1"
595d88b5 7163 "{
7164 rtx op3, scratch, scratch2;
7165
74f4459c 7166 if (!TARGET_THUMB1)
7167 {
7168 if (!arm_add_operand (operands[3], SImode))
7169 operands[3] = force_reg (SImode, operands[3]);
7170 emit_insn (gen_cstore_cc (operands[0], operands[1],
7171 operands[2], operands[3]));
7172 DONE;
7173 }
7174
595d88b5 7175 if (operands[3] == const0_rtx)
7176 {
7177 switch (GET_CODE (operands[1]))
7178 {
7179 case EQ:
25f905c2 7180 emit_insn (gen_cstoresi_eq0_thumb1 (operands[0], operands[2]));
595d88b5 7181 break;
7182
7183 case NE:
25f905c2 7184 emit_insn (gen_cstoresi_ne0_thumb1 (operands[0], operands[2]));
595d88b5 7185 break;
7186
7187 case LE:
7188 scratch = expand_binop (SImode, add_optab, operands[2], constm1_rtx,
7189 NULL_RTX, 0, OPTAB_WIDEN);
7190 scratch = expand_binop (SImode, ior_optab, operands[2], scratch,
7191 NULL_RTX, 0, OPTAB_WIDEN);
7192 expand_binop (SImode, lshr_optab, scratch, GEN_INT (31),
7193 operands[0], 1, OPTAB_WIDEN);
7194 break;
7195
7196 case GE:
7197 scratch = expand_unop (SImode, one_cmpl_optab, operands[2],
7198 NULL_RTX, 1);
7199 expand_binop (SImode, lshr_optab, scratch, GEN_INT (31),
7200 NULL_RTX, 1, OPTAB_WIDEN);
7201 break;
7202
7203 case GT:
7204 scratch = expand_binop (SImode, ashr_optab, operands[2],
7205 GEN_INT (31), NULL_RTX, 0, OPTAB_WIDEN);
7206 scratch = expand_binop (SImode, sub_optab, scratch, operands[2],
7207 NULL_RTX, 0, OPTAB_WIDEN);
7208 expand_binop (SImode, lshr_optab, scratch, GEN_INT (31), operands[0],
7209 0, OPTAB_WIDEN);
7210 break;
7211
7212 /* LT is handled by generic code. No need for unsigned with 0. */
7213 default:
7214 FAIL;
7215 }
7216 DONE;
7217 }
7218
7219 switch (GET_CODE (operands[1]))
7220 {
7221 case EQ:
7222 scratch = expand_binop (SImode, sub_optab, operands[2], operands[3],
7223 NULL_RTX, 0, OPTAB_WIDEN);
25f905c2 7224 emit_insn (gen_cstoresi_eq0_thumb1 (operands[0], scratch));
595d88b5 7225 break;
7226
7227 case NE:
7228 scratch = expand_binop (SImode, sub_optab, operands[2], operands[3],
7229 NULL_RTX, 0, OPTAB_WIDEN);
25f905c2 7230 emit_insn (gen_cstoresi_ne0_thumb1 (operands[0], scratch));
595d88b5 7231 break;
7232
7233 case LE:
7234 op3 = force_reg (SImode, operands[3]);
7235
7236 scratch = expand_binop (SImode, lshr_optab, operands[2], GEN_INT (31),
7237 NULL_RTX, 1, OPTAB_WIDEN);
7238 scratch2 = expand_binop (SImode, ashr_optab, op3, GEN_INT (31),
7239 NULL_RTX, 0, OPTAB_WIDEN);
25f905c2 7240 emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch2,
595d88b5 7241 op3, operands[2]));
7242 break;
7243
7244 case GE:
7245 op3 = operands[3];
25f905c2 7246 if (!thumb1_cmp_operand (op3, SImode))
595d88b5 7247 op3 = force_reg (SImode, op3);
7248 scratch = expand_binop (SImode, ashr_optab, operands[2], GEN_INT (31),
7249 NULL_RTX, 0, OPTAB_WIDEN);
7250 scratch2 = expand_binop (SImode, lshr_optab, op3, GEN_INT (31),
7251 NULL_RTX, 1, OPTAB_WIDEN);
25f905c2 7252 emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch2,
595d88b5 7253 operands[2], op3));
7254 break;
7255
7256 case LEU:
7257 op3 = force_reg (SImode, operands[3]);
7258 scratch = force_reg (SImode, const0_rtx);
25f905c2 7259 emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch,
595d88b5 7260 op3, operands[2]));
7261 break;
7262
7263 case GEU:
7264 op3 = operands[3];
25f905c2 7265 if (!thumb1_cmp_operand (op3, SImode))
595d88b5 7266 op3 = force_reg (SImode, op3);
7267 scratch = force_reg (SImode, const0_rtx);
25f905c2 7268 emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch,
595d88b5 7269 operands[2], op3));
7270 break;
7271
7272 case LTU:
7273 op3 = operands[3];
25f905c2 7274 if (!thumb1_cmp_operand (op3, SImode))
595d88b5 7275 op3 = force_reg (SImode, op3);
7276 scratch = gen_reg_rtx (SImode);
408b7ae5 7277 emit_insn (gen_cstoresi_ltu_thumb1 (operands[0], operands[2], op3));
595d88b5 7278 break;
7279
7280 case GTU:
7281 op3 = force_reg (SImode, operands[3]);
7282 scratch = gen_reg_rtx (SImode);
408b7ae5 7283 emit_insn (gen_cstoresi_ltu_thumb1 (operands[0], op3, operands[2]));
595d88b5 7284 break;
7285
7286 /* No good sequences for GT, LT. */
7287 default:
7288 FAIL;
7289 }
7290 DONE;
7291}")
7292
74f4459c 7293(define_expand "cstoresf4"
7294 [(set (match_operand:SI 0 "s_register_operand" "")
aa06947a 7295 (match_operator:SI 1 "expandable_comparison_operator"
74f4459c 7296 [(match_operand:SF 2 "s_register_operand" "")
7297 (match_operand:SF 3 "arm_float_compare_operand" "")]))]
7298 "TARGET_32BIT && TARGET_HARD_FLOAT"
7299 "emit_insn (gen_cstore_cc (operands[0], operands[1],
7300 operands[2], operands[3])); DONE;"
7301)
7302
7303(define_expand "cstoredf4"
7304 [(set (match_operand:SI 0 "s_register_operand" "")
aa06947a 7305 (match_operator:SI 1 "expandable_comparison_operator"
74f4459c 7306 [(match_operand:DF 2 "s_register_operand" "")
7307 (match_operand:DF 3 "arm_float_compare_operand" "")]))]
d63ed457 7308 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
74f4459c 7309 "emit_insn (gen_cstore_cc (operands[0], operands[1],
7310 operands[2], operands[3])); DONE;"
7311)
7312
74f4459c 7313(define_expand "cstoredi4"
7314 [(set (match_operand:SI 0 "s_register_operand" "")
aa06947a 7315 (match_operator:SI 1 "expandable_comparison_operator"
b8eae306 7316 [(match_operand:DI 2 "s_register_operand" "")
a8045a4f 7317 (match_operand:DI 3 "cmpdi_operand" "")]))]
7318 "TARGET_32BIT"
7319 "{
f9aa4160 7320 if (!arm_validize_comparison (&operands[1],
7321 &operands[2],
7322 &operands[3]))
7323 FAIL;
7324 emit_insn (gen_cstore_cc (operands[0], operands[1], operands[2],
a8045a4f 7325 operands[3]));
7326 DONE;
7327 }"
74f4459c 7328)
7329
9c08d1fa 7330\f
39b5e676 7331;; Conditional move insns
7332
7333(define_expand "movsicc"
8a18b90c 7334 [(set (match_operand:SI 0 "s_register_operand" "")
aa06947a 7335 (if_then_else:SI (match_operand 1 "expandable_comparison_operator" "")
aea4c774 7336 (match_operand:SI 2 "arm_not_operand" "")
8a18b90c 7337 (match_operand:SI 3 "arm_not_operand" "")))]
25f905c2 7338 "TARGET_32BIT"
39b5e676 7339 "
215b30b3 7340 {
f9aa4160 7341 enum rtx_code code;
278b301d 7342 rtx ccreg;
7343
f9aa4160 7344 if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0),
7345 &XEXP (operands[1], 1)))
278b301d 7346 FAIL;
f9aa4160 7347
7348 code = GET_CODE (operands[1]);
74f4459c 7349 ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
e1b93706 7350 XEXP (operands[1], 1), NULL_RTX);
29bb088d 7351 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
215b30b3 7352 }"
7353)
39b5e676 7354
7355(define_expand "movsfcc"
8a18b90c 7356 [(set (match_operand:SF 0 "s_register_operand" "")
4df97ffc 7357 (if_then_else:SF (match_operand 1 "arm_cond_move_operator" "")
8a18b90c 7358 (match_operand:SF 2 "s_register_operand" "")
d86c91f6 7359 (match_operand:SF 3 "s_register_operand" "")))]
19f6bf8d 7360 "TARGET_32BIT && TARGET_HARD_FLOAT"
39b5e676 7361 "
215b30b3 7362 {
7363 enum rtx_code code = GET_CODE (operands[1]);
7364 rtx ccreg;
f082f1c4 7365
f9aa4160 7366 if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0),
7367 &XEXP (operands[1], 1)))
7368 FAIL;
39b5e676 7369
f9aa4160 7370 code = GET_CODE (operands[1]);
74f4459c 7371 ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
e1b93706 7372 XEXP (operands[1], 1), NULL_RTX);
29bb088d 7373 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
215b30b3 7374 }"
7375)
39b5e676 7376
7377(define_expand "movdfcc"
8a18b90c 7378 [(set (match_operand:DF 0 "s_register_operand" "")
4df97ffc 7379 (if_then_else:DF (match_operand 1 "arm_cond_move_operator" "")
8a18b90c 7380 (match_operand:DF 2 "s_register_operand" "")
d86c91f6 7381 (match_operand:DF 3 "s_register_operand" "")))]
994606f8 7382 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
39b5e676 7383 "
215b30b3 7384 {
7385 enum rtx_code code = GET_CODE (operands[1]);
278b301d 7386 rtx ccreg;
39b5e676 7387
f9aa4160 7388 if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0),
7389 &XEXP (operands[1], 1)))
7390 FAIL;
7391 code = GET_CODE (operands[1]);
74f4459c 7392 ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
e1b93706 7393 XEXP (operands[1], 1), NULL_RTX);
29bb088d 7394 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
215b30b3 7395 }"
7396)
39b5e676 7397
91cb50d2 7398(define_insn "*cmov<mode>"
7399 [(set (match_operand:SDF 0 "s_register_operand" "=<F_constraint>")
7400 (if_then_else:SDF (match_operator 1 "arm_vsel_comparison_operator"
7401 [(match_operand 2 "cc_register" "") (const_int 0)])
7402 (match_operand:SDF 3 "s_register_operand"
7403 "<F_constraint>")
7404 (match_operand:SDF 4 "s_register_operand"
7405 "<F_constraint>")))]
7406 "TARGET_HARD_FLOAT && TARGET_FPU_ARMV8 <vfp_double_cond>"
7407 "*
7408 {
7409 enum arm_cond_code code = maybe_get_arm_condition_code (operands[1]);
7410 switch (code)
7411 {
7412 case ARM_GE:
7413 case ARM_GT:
7414 case ARM_EQ:
7415 case ARM_VS:
7416 return \"vsel%d1.<V_if_elem>\\t%<V_reg>0, %<V_reg>3, %<V_reg>4\";
7417 case ARM_LT:
7418 case ARM_LE:
7419 case ARM_NE:
7420 case ARM_VC:
7421 return \"vsel%D1.<V_if_elem>\\t%<V_reg>0, %<V_reg>4, %<V_reg>3\";
7422 default:
7423 gcc_unreachable ();
7424 }
7425 return \"\";
7426 }"
7427 [(set_attr "conds" "use")
6664d308 7428 (set_attr "type" "fcsel")]
91cb50d2 7429)
7430
190efb17 7431(define_insn_and_split "*movsicc_insn"
f082f1c4 7432 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r,r,r,r,r")
8a18b90c 7433 (if_then_else:SI
8fa3ba89 7434 (match_operator 3 "arm_comparison_operator"
8a18b90c 7435 [(match_operand 4 "cc_register" "") (const_int 0)])
f082f1c4 7436 (match_operand:SI 1 "arm_not_operand" "0,0,rI,K,rI,rI,K,K")
7437 (match_operand:SI 2 "arm_not_operand" "rI,K,0,0,rI,K,rI,K")))]
cffb2a26 7438 "TARGET_ARM"
39b5e676 7439 "@
8a18b90c 7440 mov%D3\\t%0, %2
7441 mvn%D3\\t%0, #%B2
f082f1c4 7442 mov%d3\\t%0, %1
7443 mvn%d3\\t%0, #%B1
190efb17 7444 #
7445 #
7446 #
7447 #"
7448 ; alt4: mov%d3\\t%0, %1\;mov%D3\\t%0, %2
7449 ; alt5: mov%d3\\t%0, %1\;mvn%D3\\t%0, #%B2
7450 ; alt6: mvn%d3\\t%0, #%B1\;mov%D3\\t%0, %2
7451 ; alt7: mvn%d3\\t%0, #%B1\;mvn%D3\\t%0, #%B2"
7452 "&& reload_completed"
7453 [(const_int 0)]
7454 {
7455 enum rtx_code rev_code;
7456 enum machine_mode mode;
7457 rtx rev_cond;
7458
7459 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
7460 operands[3],
7461 gen_rtx_SET (VOIDmode,
7462 operands[0],
7463 operands[1])));
7464
7465 rev_code = GET_CODE (operands[3]);
7466 mode = GET_MODE (operands[4]);
7467 if (mode == CCFPmode || mode == CCFPEmode)
7468 rev_code = reverse_condition_maybe_unordered (rev_code);
7469 else
7470 rev_code = reverse_condition (rev_code);
7471
7472 rev_cond = gen_rtx_fmt_ee (rev_code,
7473 VOIDmode,
7474 operands[4],
7475 const0_rtx);
7476 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
7477 rev_cond,
7478 gen_rtx_SET (VOIDmode,
7479 operands[0],
7480 operands[2])));
7481 DONE;
7482 }
f082f1c4 7483 [(set_attr "length" "4,4,4,4,8,8,8,8")
d2a518d1 7484 (set_attr "conds" "use")
65f68e55 7485 (set_attr_alternative "type"
7486 [(if_then_else (match_operand 2 "const_int_operand" "")
1aed5204 7487 (const_string "mov_imm")
7488 (const_string "mov_reg"))
7489 (const_string "mvn_imm")
65f68e55 7490 (if_then_else (match_operand 1 "const_int_operand" "")
1aed5204 7491 (const_string "mov_imm")
7492 (const_string "mov_reg"))
7493 (const_string "mvn_imm")
7494 (const_string "mov_reg")
7495 (const_string "mov_reg")
7496 (const_string "mov_reg")
7497 (const_string "mov_reg")])]
215b30b3 7498)
39b5e676 7499
39b5e676 7500(define_insn "*movsfcc_soft_insn"
f082f1c4 7501 [(set (match_operand:SF 0 "s_register_operand" "=r,r")
8fa3ba89 7502 (if_then_else:SF (match_operator 3 "arm_comparison_operator"
8a18b90c 7503 [(match_operand 4 "cc_register" "") (const_int 0)])
f082f1c4 7504 (match_operand:SF 1 "s_register_operand" "0,r")
7505 (match_operand:SF 2 "s_register_operand" "r,0")))]
cffb2a26 7506 "TARGET_ARM && TARGET_SOFT_FLOAT"
f082f1c4 7507 "@
7508 mov%D3\\t%0, %2
7509 mov%d3\\t%0, %1"
d2a518d1 7510 [(set_attr "conds" "use")
1aed5204 7511 (set_attr "type" "mov_reg")]
8fa3ba89 7512)
39b5e676 7513
39b5e676 7514\f
9c08d1fa 7515;; Jump and linkage insns
7516
cffb2a26 7517(define_expand "jump"
9c08d1fa 7518 [(set (pc)
7519 (label_ref (match_operand 0 "" "")))]
cffb2a26 7520 "TARGET_EITHER"
9c08d1fa 7521 ""
cffb2a26 7522)
7523
7524(define_insn "*arm_jump"
7525 [(set (pc)
7526 (label_ref (match_operand 0 "" "")))]
25f905c2 7527 "TARGET_32BIT"
9c08d1fa 7528 "*
0d66636f 7529 {
7530 if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
7531 {
7532 arm_ccfsm_state += 2;
7533 return \"\";
7534 }
7535 return \"b%?\\t%l0\";
7536 }
7537 "
a6864a24 7538 [(set_attr "predicable" "yes")
7539 (set (attr "length")
7540 (if_then_else
0bf497f5 7541 (and (match_test "TARGET_THUMB2")
a6864a24 7542 (and (ge (minus (match_dup 0) (pc)) (const_int -2044))
7543 (le (minus (match_dup 0) (pc)) (const_int 2048))))
7544 (const_int 2)
1b7da4ac 7545 (const_int 4)))
7546 (set_attr "type" "branch")]
0d66636f 7547)
9c08d1fa 7548
d3373b54 7549(define_expand "call"
7550 [(parallel [(call (match_operand 0 "memory_operand" "")
7551 (match_operand 1 "general_operand" ""))
cffb2a26 7552 (use (match_operand 2 "" ""))
bd5b4116 7553 (clobber (reg:SI LR_REGNUM))])]
cffb2a26 7554 "TARGET_EITHER"
6c4c2133 7555 "
7556 {
bac7fc85 7557 rtx callee, pat;
bbe777ea 7558
bbe777ea 7559 /* In an untyped call, we can get NULL for operand 2. */
7560 if (operands[2] == NULL_RTX)
7561 operands[2] = const0_rtx;
7562
de55252a 7563 /* Decide if we should generate indirect calls by loading the
85c36fd1 7564 32-bit address of the callee into a register before performing the
de55252a 7565 branch and link. */
7566 callee = XEXP (operands[0], 0);
7567 if (GET_CODE (callee) == SYMBOL_REF
7568 ? arm_is_long_call_p (SYMBOL_REF_DECL (callee))
7569 : !REG_P (callee))
bbe777ea 7570 XEXP (operands[0], 0) = force_reg (Pmode, callee);
bac7fc85 7571
7572 pat = gen_call_internal (operands[0], operands[1], operands[2]);
ca373797 7573 arm_emit_call_insn (pat, XEXP (operands[0], 0), false);
bac7fc85 7574 DONE;
6c4c2133 7575 }"
7576)
d3373b54 7577
bac7fc85 7578(define_expand "call_internal"
7579 [(parallel [(call (match_operand 0 "memory_operand" "")
7580 (match_operand 1 "general_operand" ""))
7581 (use (match_operand 2 "" ""))
7582 (clobber (reg:SI LR_REGNUM))])])
7583
f1039640 7584(define_insn "*call_reg_armv5"
d3373b54 7585 [(call (mem:SI (match_operand:SI 0 "s_register_operand" "r"))
cffb2a26 7586 (match_operand 1 "" ""))
7587 (use (match_operand 2 "" ""))
bd5b4116 7588 (clobber (reg:SI LR_REGNUM))]
33ae7c4b 7589 "TARGET_ARM && arm_arch5 && !SIBLING_CALL_P (insn)"
f1039640 7590 "blx%?\\t%0"
7591 [(set_attr "type" "call")]
7592)
7593
7594(define_insn "*call_reg_arm"
7595 [(call (mem:SI (match_operand:SI 0 "s_register_operand" "r"))
7596 (match_operand 1 "" ""))
7597 (use (match_operand 2 "" ""))
7598 (clobber (reg:SI LR_REGNUM))]
33ae7c4b 7599 "TARGET_ARM && !arm_arch5 && !SIBLING_CALL_P (insn)"
9c08d1fa 7600 "*
5565501b 7601 return output_call (operands);
cffb2a26 7602 "
7603 ;; length is worst case, normally it is only two
7604 [(set_attr "length" "12")
7605 (set_attr "type" "call")]
7606)
9c08d1fa 7607
89504fc1 7608
7609;; Note: not used for armv5+ because the sequence used (ldr pc, ...) is not
7610;; considered a function call by the branch predictor of some cores (PR40887).
7611;; Falls back to blx rN (*call_reg_armv5).
7612
f7fbdd4a 7613(define_insn "*call_mem"
a3c63a9d 7614 [(call (mem:SI (match_operand:SI 0 "call_memory_operand" "m"))
cffb2a26 7615 (match_operand 1 "" ""))
7616 (use (match_operand 2 "" ""))
bd5b4116 7617 (clobber (reg:SI LR_REGNUM))]
33ae7c4b 7618 "TARGET_ARM && !arm_arch5 && !SIBLING_CALL_P (insn)"
9c08d1fa 7619 "*
5565501b 7620 return output_call_mem (operands);
cffb2a26 7621 "
7622 [(set_attr "length" "12")
7623 (set_attr "type" "call")]
7624)
7625
d3373b54 7626(define_expand "call_value"
e0698af7 7627 [(parallel [(set (match_operand 0 "" "")
7628 (call (match_operand 1 "memory_operand" "")
7629 (match_operand 2 "general_operand" "")))
cffb2a26 7630 (use (match_operand 3 "" ""))
bd5b4116 7631 (clobber (reg:SI LR_REGNUM))])]
cffb2a26 7632 "TARGET_EITHER"
6c4c2133 7633 "
7634 {
bac7fc85 7635 rtx pat, callee;
bbe777ea 7636
7637 /* In an untyped call, we can get NULL for operand 2. */
7638 if (operands[3] == 0)
7639 operands[3] = const0_rtx;
7640
de55252a 7641 /* Decide if we should generate indirect calls by loading the
7642 32-bit address of the callee into a register before performing the
7643 branch and link. */
7644 callee = XEXP (operands[1], 0);
7645 if (GET_CODE (callee) == SYMBOL_REF
7646 ? arm_is_long_call_p (SYMBOL_REF_DECL (callee))
7647 : !REG_P (callee))
78fe751b 7648 XEXP (operands[1], 0) = force_reg (Pmode, callee);
bac7fc85 7649
7650 pat = gen_call_value_internal (operands[0], operands[1],
7651 operands[2], operands[3]);
ca373797 7652 arm_emit_call_insn (pat, XEXP (operands[1], 0), false);
bac7fc85 7653 DONE;
6c4c2133 7654 }"
7655)
d3373b54 7656
bac7fc85 7657(define_expand "call_value_internal"
7658 [(parallel [(set (match_operand 0 "" "")
7659 (call (match_operand 1 "memory_operand" "")
7660 (match_operand 2 "general_operand" "")))
7661 (use (match_operand 3 "" ""))
7662 (clobber (reg:SI LR_REGNUM))])])
7663
f1039640 7664(define_insn "*call_value_reg_armv5"
27ed6835 7665 [(set (match_operand 0 "" "")
755eb2b4 7666 (call (mem:SI (match_operand:SI 1 "s_register_operand" "r"))
cffb2a26 7667 (match_operand 2 "" "")))
bbe777ea 7668 (use (match_operand 3 "" ""))
bd5b4116 7669 (clobber (reg:SI LR_REGNUM))]
33ae7c4b 7670 "TARGET_ARM && arm_arch5 && !SIBLING_CALL_P (insn)"
f1039640 7671 "blx%?\\t%1"
7672 [(set_attr "type" "call")]
7673)
7674
7675(define_insn "*call_value_reg_arm"
7676 [(set (match_operand 0 "" "")
7677 (call (mem:SI (match_operand:SI 1 "s_register_operand" "r"))
7678 (match_operand 2 "" "")))
7679 (use (match_operand 3 "" ""))
7680 (clobber (reg:SI LR_REGNUM))]
33ae7c4b 7681 "TARGET_ARM && !arm_arch5 && !SIBLING_CALL_P (insn)"
9c08d1fa 7682 "*
215b30b3 7683 return output_call (&operands[1]);
cffb2a26 7684 "
7685 [(set_attr "length" "12")
7686 (set_attr "type" "call")]
7687)
9c08d1fa 7688
89504fc1 7689;; Note: see *call_mem
7690
f7fbdd4a 7691(define_insn "*call_value_mem"
27ed6835 7692 [(set (match_operand 0 "" "")
a3c63a9d 7693 (call (mem:SI (match_operand:SI 1 "call_memory_operand" "m"))
cffb2a26 7694 (match_operand 2 "" "")))
bbe777ea 7695 (use (match_operand 3 "" ""))
bd5b4116 7696 (clobber (reg:SI LR_REGNUM))]
33ae7c4b 7697 "TARGET_ARM && !arm_arch5 && (!CONSTANT_ADDRESS_P (XEXP (operands[1], 0)))
7698 && !SIBLING_CALL_P (insn)"
9c08d1fa 7699 "*
215b30b3 7700 return output_call_mem (&operands[1]);
cffb2a26 7701 "
7702 [(set_attr "length" "12")
7703 (set_attr "type" "call")]
7704)
9c08d1fa 7705
7706;; Allow calls to SYMBOL_REFs specially as they are not valid general addresses
7707;; The 'a' causes the operand to be treated as an address, i.e. no '#' output.
7708
f7fbdd4a 7709(define_insn "*call_symbol"
27ed6835 7710 [(call (mem:SI (match_operand:SI 0 "" ""))
cffb2a26 7711 (match_operand 1 "" ""))
bbe777ea 7712 (use (match_operand 2 "" ""))
bd5b4116 7713 (clobber (reg:SI LR_REGNUM))]
d68c2c10 7714 "TARGET_32BIT
33ae7c4b 7715 && !SIBLING_CALL_P (insn)
cffb2a26 7716 && (GET_CODE (operands[0]) == SYMBOL_REF)
de55252a 7717 && !arm_is_long_call_p (SYMBOL_REF_DECL (operands[0]))"
6ebaa29d 7718 "*
7719 {
55c1e470 7720 return NEED_PLT_RELOC ? \"bl%?\\t%a0(PLT)\" : \"bl%?\\t%a0\";
6ebaa29d 7721 }"
cffb2a26 7722 [(set_attr "type" "call")]
7723)
9c08d1fa 7724
f7fbdd4a 7725(define_insn "*call_value_symbol"
ccd90aaa 7726 [(set (match_operand 0 "" "")
27ed6835 7727 (call (mem:SI (match_operand:SI 1 "" ""))
dd6d7504 7728 (match_operand:SI 2 "" "")))
bbe777ea 7729 (use (match_operand 3 "" ""))
bd5b4116 7730 (clobber (reg:SI LR_REGNUM))]
d68c2c10 7731 "TARGET_32BIT
33ae7c4b 7732 && !SIBLING_CALL_P (insn)
cffb2a26 7733 && (GET_CODE (operands[1]) == SYMBOL_REF)
de55252a 7734 && !arm_is_long_call_p (SYMBOL_REF_DECL (operands[1]))"
6ebaa29d 7735 "*
7736 {
55c1e470 7737 return NEED_PLT_RELOC ? \"bl%?\\t%a1(PLT)\" : \"bl%?\\t%a1\";
6ebaa29d 7738 }"
cffb2a26 7739 [(set_attr "type" "call")]
7740)
7741
ca373797 7742(define_expand "sibcall_internal"
7743 [(parallel [(call (match_operand 0 "memory_operand" "")
7744 (match_operand 1 "general_operand" ""))
7745 (return)
7746 (use (match_operand 2 "" ""))])])
7747
1c494086 7748;; We may also be able to do sibcalls for Thumb, but it's much harder...
7749(define_expand "sibcall"
7750 [(parallel [(call (match_operand 0 "memory_operand" "")
7751 (match_operand 1 "general_operand" ""))
2ba80634 7752 (return)
7753 (use (match_operand 2 "" ""))])]
d68c2c10 7754 "TARGET_32BIT"
1c494086 7755 "
7756 {
ca373797 7757 rtx pat;
7758
3112c3f7 7759 if ((!REG_P (XEXP (operands[0], 0))
7760 && GET_CODE (XEXP (operands[0], 0)) != SYMBOL_REF)
7761 || (GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
7762 && arm_is_long_call_p (SYMBOL_REF_DECL (XEXP (operands[0], 0)))))
33ae7c4b 7763 XEXP (operands[0], 0) = force_reg (SImode, XEXP (operands[0], 0));
7764
1c494086 7765 if (operands[2] == NULL_RTX)
7766 operands[2] = const0_rtx;
ca373797 7767
7768 pat = gen_sibcall_internal (operands[0], operands[1], operands[2]);
7769 arm_emit_call_insn (pat, operands[0], true);
7770 DONE;
1c494086 7771 }"
7772)
7773
ca373797 7774(define_expand "sibcall_value_internal"
7775 [(parallel [(set (match_operand 0 "" "")
7776 (call (match_operand 1 "memory_operand" "")
7777 (match_operand 2 "general_operand" "")))
7778 (return)
7779 (use (match_operand 3 "" ""))])])
7780
1c494086 7781(define_expand "sibcall_value"
ccd90aaa 7782 [(parallel [(set (match_operand 0 "" "")
1c494086 7783 (call (match_operand 1 "memory_operand" "")
7784 (match_operand 2 "general_operand" "")))
2ba80634 7785 (return)
7786 (use (match_operand 3 "" ""))])]
d68c2c10 7787 "TARGET_32BIT"
1c494086 7788 "
7789 {
ca373797 7790 rtx pat;
7791
3112c3f7 7792 if ((!REG_P (XEXP (operands[1], 0))
7793 && GET_CODE (XEXP (operands[1], 0)) != SYMBOL_REF)
7794 || (GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
7795 && arm_is_long_call_p (SYMBOL_REF_DECL (XEXP (operands[1], 0)))))
33ae7c4b 7796 XEXP (operands[1], 0) = force_reg (SImode, XEXP (operands[1], 0));
7797
1c494086 7798 if (operands[3] == NULL_RTX)
7799 operands[3] = const0_rtx;
ca373797 7800
7801 pat = gen_sibcall_value_internal (operands[0], operands[1],
7802 operands[2], operands[3]);
7803 arm_emit_call_insn (pat, operands[1], true);
7804 DONE;
1c494086 7805 }"
7806)
7807
7808(define_insn "*sibcall_insn"
84ce8e5c 7809 [(call (mem:SI (match_operand:SI 0 "call_insn_operand" "Cs, US"))
1c494086 7810 (match_operand 1 "" ""))
2ba80634 7811 (return)
7812 (use (match_operand 2 "" ""))]
33ae7c4b 7813 "TARGET_32BIT && SIBLING_CALL_P (insn)"
1c494086 7814 "*
33ae7c4b 7815 if (which_alternative == 1)
7816 return NEED_PLT_RELOC ? \"b%?\\t%a0(PLT)\" : \"b%?\\t%a0\";
7817 else
7818 {
7819 if (arm_arch5 || arm_arch4t)
947d113e 7820 return \"bx%?\\t%0\\t%@ indirect register sibling call\";
33ae7c4b 7821 else
7822 return \"mov%?\\t%|pc, %0\\t%@ indirect register sibling call\";
7823 }
1c494086 7824 "
7825 [(set_attr "type" "call")]
7826)
7827
7828(define_insn "*sibcall_value_insn"
84ce8e5c 7829 [(set (match_operand 0 "" "")
7830 (call (mem:SI (match_operand:SI 1 "call_insn_operand" "Cs,US"))
1c494086 7831 (match_operand 2 "" "")))
2ba80634 7832 (return)
7833 (use (match_operand 3 "" ""))]
33ae7c4b 7834 "TARGET_32BIT && SIBLING_CALL_P (insn)"
1c494086 7835 "*
33ae7c4b 7836 if (which_alternative == 1)
7837 return NEED_PLT_RELOC ? \"b%?\\t%a1(PLT)\" : \"b%?\\t%a1\";
7838 else
7839 {
7840 if (arm_arch5 || arm_arch4t)
84ce8e5c 7841 return \"bx%?\\t%1\";
33ae7c4b 7842 else
7843 return \"mov%?\\t%|pc, %1\\t@ indirect sibling call \";
7844 }
1c494086 7845 "
7846 [(set_attr "type" "call")]
7847)
7848
0686440e 7849(define_expand "<return_str>return"
7850 [(returns)]
8cba51a5 7851 "(TARGET_ARM || (TARGET_THUMB2
7852 && ARM_FUNC_TYPE (arm_current_func_type ()) == ARM_FT_NORMAL
7853 && !IS_STACKALIGN (arm_current_func_type ())))
0686440e 7854 <return_cond_false>"
8cba51a5 7855 "
7856 {
7857 if (TARGET_THUMB2)
7858 {
0686440e 7859 thumb2_expand_return (<return_simple_p>);
8cba51a5 7860 DONE;
7861 }
7862 }
7863 "
7864)
d68c2c10 7865
9c08d1fa 7866;; Often the return insn will be the same as loading from memory, so set attr
d68c2c10 7867(define_insn "*arm_return"
9c08d1fa 7868 [(return)]
cffb2a26 7869 "TARGET_ARM && USE_RETURN_INSN (FALSE)"
9c08d1fa 7870 "*
9c08d1fa 7871 {
cffb2a26 7872 if (arm_ccfsm_state == 2)
7873 {
7874 arm_ccfsm_state += 2;
7875 return \"\";
7876 }
e2549f81 7877 return output_return_instruction (const_true_rtx, true, false, false);
cffb2a26 7878 }"
a2cd141b 7879 [(set_attr "type" "load1")
755eb2b4 7880 (set_attr "length" "12")
0d66636f 7881 (set_attr "predicable" "yes")]
cffb2a26 7882)
9c08d1fa 7883
0686440e 7884(define_insn "*cond_<return_str>return"
9c08d1fa 7885 [(set (pc)
8fa3ba89 7886 (if_then_else (match_operator 0 "arm_comparison_operator"
8a18b90c 7887 [(match_operand 1 "cc_register" "") (const_int 0)])
0686440e 7888 (returns)
9c08d1fa 7889 (pc)))]
0686440e 7890 "TARGET_ARM <return_cond_true>"
9c08d1fa 7891 "*
8fa3ba89 7892 {
7893 if (arm_ccfsm_state == 2)
7894 {
7895 arm_ccfsm_state += 2;
7896 return \"\";
7897 }
0686440e 7898 return output_return_instruction (operands[0], true, false,
7899 <return_simple_p>);
8fa3ba89 7900 }"
7901 [(set_attr "conds" "use")
755eb2b4 7902 (set_attr "length" "12")
a2cd141b 7903 (set_attr "type" "load1")]
8fa3ba89 7904)
9c08d1fa 7905
0686440e 7906(define_insn "*cond_<return_str>return_inverted"
9c08d1fa 7907 [(set (pc)
8fa3ba89 7908 (if_then_else (match_operator 0 "arm_comparison_operator"
8a18b90c 7909 [(match_operand 1 "cc_register" "") (const_int 0)])
9c08d1fa 7910 (pc)
0686440e 7911 (returns)))]
7912 "TARGET_ARM <return_cond_true>"
9c08d1fa 7913 "*
8fa3ba89 7914 {
7915 if (arm_ccfsm_state == 2)
7916 {
7917 arm_ccfsm_state += 2;
7918 return \"\";
7919 }
0686440e 7920 return output_return_instruction (operands[0], true, true,
7921 <return_simple_p>);
8fa3ba89 7922 }"
7923 [(set_attr "conds" "use")
37a1317b 7924 (set_attr "length" "12")
a2cd141b 7925 (set_attr "type" "load1")]
8fa3ba89 7926)
9c08d1fa 7927
e2549f81 7928(define_insn "*arm_simple_return"
7929 [(simple_return)]
7930 "TARGET_ARM"
7931 "*
7932 {
7933 if (arm_ccfsm_state == 2)
7934 {
7935 arm_ccfsm_state += 2;
7936 return \"\";
7937 }
7938 return output_return_instruction (const_true_rtx, true, false, true);
7939 }"
7940 [(set_attr "type" "branch")
7941 (set_attr "length" "4")
7942 (set_attr "predicable" "yes")]
7943)
7944
68121397 7945;; Generate a sequence of instructions to determine if the processor is
7946;; in 26-bit or 32-bit mode, and return the appropriate return address
7947;; mask.
7948
7949(define_expand "return_addr_mask"
7950 [(set (match_dup 1)
7951 (compare:CC_NOOV (unspec [(const_int 0)] UNSPEC_CHECK_ARCH)
7952 (const_int 0)))
7953 (set (match_operand:SI 0 "s_register_operand" "")
7954 (if_then_else:SI (eq (match_dup 1) (const_int 0))
7955 (const_int -1)
7956 (const_int 67108860)))] ; 0x03fffffc
7957 "TARGET_ARM"
7958 "
62eddbd4 7959 operands[1] = gen_rtx_REG (CC_NOOVmode, CC_REGNUM);
68121397 7960 ")
7961
7962(define_insn "*check_arch2"
7963 [(set (match_operand:CC_NOOV 0 "cc_register" "")
7964 (compare:CC_NOOV (unspec [(const_int 0)] UNSPEC_CHECK_ARCH)
7965 (const_int 0)))]
7966 "TARGET_ARM"
7967 "teq\\t%|r0, %|r0\;teq\\t%|pc, %|pc"
7968 [(set_attr "length" "8")
1b7da4ac 7969 (set_attr "conds" "set")
7970 (set_attr "type" "multiple")]
68121397 7971)
7972
9c08d1fa 7973;; Call subroutine returning any type.
7974
7975(define_expand "untyped_call"
7976 [(parallel [(call (match_operand 0 "" "")
7977 (const_int 0))
7978 (match_operand 1 "" "")
7979 (match_operand 2 "" "")])]
ccd90aaa 7980 "TARGET_EITHER"
9c08d1fa 7981 "
215b30b3 7982 {
7983 int i;
ccd90aaa 7984 rtx par = gen_rtx_PARALLEL (VOIDmode,
7985 rtvec_alloc (XVECLEN (operands[2], 0)));
7986 rtx addr = gen_reg_rtx (Pmode);
7987 rtx mem;
7988 int size = 0;
9c08d1fa 7989
ccd90aaa 7990 emit_move_insn (addr, XEXP (operands[1], 0));
7991 mem = change_address (operands[1], BLKmode, addr);
9c08d1fa 7992
215b30b3 7993 for (i = 0; i < XVECLEN (operands[2], 0); i++)
7994 {
ccd90aaa 7995 rtx src = SET_SRC (XVECEXP (operands[2], 0, i));
9c08d1fa 7996
ccd90aaa 7997 /* Default code only uses r0 as a return value, but we could
7998 be using anything up to 4 registers. */
7999 if (REGNO (src) == R0_REGNUM)
8000 src = gen_rtx_REG (TImode, R0_REGNUM);
8001
8002 XVECEXP (par, 0, i) = gen_rtx_EXPR_LIST (VOIDmode, src,
8003 GEN_INT (size));
8004 size += GET_MODE_SIZE (GET_MODE (src));
8005 }
8006
8007 emit_call_insn (GEN_CALL_VALUE (par, operands[0], const0_rtx, NULL,
8008 const0_rtx));
8009
8010 size = 0;
8011
8012 for (i = 0; i < XVECLEN (par, 0); i++)
8013 {
8014 HOST_WIDE_INT offset = 0;
8015 rtx reg = XEXP (XVECEXP (par, 0, i), 0);
8016
8017 if (size != 0)
29c05e22 8018 emit_move_insn (addr, plus_constant (Pmode, addr, size));
ccd90aaa 8019
8020 mem = change_address (mem, GET_MODE (reg), NULL);
8021 if (REGNO (reg) == R0_REGNUM)
8022 {
8023 /* On thumb we have to use a write-back instruction. */
320ea44d 8024 emit_insn (arm_gen_store_multiple (arm_regs_in_sequence, 4, addr,
8025 TARGET_THUMB ? TRUE : FALSE, mem, &offset));
ccd90aaa 8026 size = TARGET_ARM ? 16 : 0;
8027 }
8028 else
8029 {
8030 emit_move_insn (mem, reg);
8031 size = GET_MODE_SIZE (GET_MODE (reg));
8032 }
215b30b3 8033 }
9c08d1fa 8034
215b30b3 8035 /* The optimizer does not know that the call sets the function value
8036 registers we stored in the result block. We avoid problems by
8037 claiming that all hard registers are used and clobbered at this
8038 point. */
8039 emit_insn (gen_blockage ());
8040
8041 DONE;
8042 }"
8043)
9c08d1fa 8044
ccd90aaa 8045(define_expand "untyped_return"
8046 [(match_operand:BLK 0 "memory_operand" "")
8047 (match_operand 1 "" "")]
8048 "TARGET_EITHER"
8049 "
8050 {
8051 int i;
8052 rtx addr = gen_reg_rtx (Pmode);
8053 rtx mem;
8054 int size = 0;
8055
8056 emit_move_insn (addr, XEXP (operands[0], 0));
8057 mem = change_address (operands[0], BLKmode, addr);
8058
8059 for (i = 0; i < XVECLEN (operands[1], 0); i++)
8060 {
8061 HOST_WIDE_INT offset = 0;
8062 rtx reg = SET_DEST (XVECEXP (operands[1], 0, i));
8063
8064 if (size != 0)
29c05e22 8065 emit_move_insn (addr, plus_constant (Pmode, addr, size));
ccd90aaa 8066
8067 mem = change_address (mem, GET_MODE (reg), NULL);
8068 if (REGNO (reg) == R0_REGNUM)
8069 {
8070 /* On thumb we have to use a write-back instruction. */
320ea44d 8071 emit_insn (arm_gen_load_multiple (arm_regs_in_sequence, 4, addr,
8072 TARGET_THUMB ? TRUE : FALSE, mem, &offset));
ccd90aaa 8073 size = TARGET_ARM ? 16 : 0;
8074 }
8075 else
8076 {
8077 emit_move_insn (reg, mem);
8078 size = GET_MODE_SIZE (GET_MODE (reg));
8079 }
8080 }
8081
8082 /* Emit USE insns before the return. */
8083 for (i = 0; i < XVECLEN (operands[1], 0); i++)
18b42941 8084 emit_use (SET_DEST (XVECEXP (operands[1], 0, i)));
ccd90aaa 8085
8086 /* Construct the return. */
8087 expand_naked_return ();
8088
8089 DONE;
8090 }"
8091)
8092
9c08d1fa 8093;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
8094;; all of memory. This blocks insns from being moved across this point.
8095
8096(define_insn "blockage"
e1159bbe 8097 [(unspec_volatile [(const_int 0)] VUNSPEC_BLOCKAGE)]
cffb2a26 8098 "TARGET_EITHER"
9c08d1fa 8099 ""
cffb2a26 8100 [(set_attr "length" "0")
8101 (set_attr "type" "block")]
8102)
9c08d1fa 8103
f7fbdd4a 8104(define_expand "casesi"
8105 [(match_operand:SI 0 "s_register_operand" "") ; index to jump on
aea4c774 8106 (match_operand:SI 1 "const_int_operand" "") ; lower bound
8107 (match_operand:SI 2 "const_int_operand" "") ; total range
f7fbdd4a 8108 (match_operand:SI 3 "" "") ; table label
8109 (match_operand:SI 4 "" "")] ; Out of range label
e6ac8414 8110 "TARGET_32BIT || optimize_size || flag_pic"
f7fbdd4a 8111 "
215b30b3 8112 {
e6ac8414 8113 enum insn_code code;
215b30b3 8114 if (operands[1] != const0_rtx)
8115 {
e6ac8414 8116 rtx reg = gen_reg_rtx (SImode);
f7fbdd4a 8117
215b30b3 8118 emit_insn (gen_addsi3 (reg, operands[0],
d022fa24 8119 gen_int_mode (-INTVAL (operands[1]),
8120 SImode)));
215b30b3 8121 operands[0] = reg;
8122 }
9c08d1fa 8123
25f905c2 8124 if (TARGET_ARM)
e6ac8414 8125 code = CODE_FOR_arm_casesi_internal;
3db2019b 8126 else if (TARGET_THUMB1)
e6ac8414 8127 code = CODE_FOR_thumb1_casesi_internal_pic;
25f905c2 8128 else if (flag_pic)
e6ac8414 8129 code = CODE_FOR_thumb2_casesi_internal_pic;
25f905c2 8130 else
e6ac8414 8131 code = CODE_FOR_thumb2_casesi_internal;
8132
8133 if (!insn_data[(int) code].operand[1].predicate(operands[2], SImode))
8134 operands[2] = force_reg (SImode, operands[2]);
8135
8136 emit_jump_insn (GEN_FCN ((int) code) (operands[0], operands[2],
8137 operands[3], operands[4]));
215b30b3 8138 DONE;
8139 }"
8140)
f7fbdd4a 8141
f082f1c4 8142;; The USE in this pattern is needed to tell flow analysis that this is
8143;; a CASESI insn. It has no other purpose.
25f905c2 8144(define_insn "arm_casesi_internal"
f082f1c4 8145 [(parallel [(set (pc)
8146 (if_then_else
8147 (leu (match_operand:SI 0 "s_register_operand" "r")
8148 (match_operand:SI 1 "arm_rhs_operand" "rI"))
8149 (mem:SI (plus:SI (mult:SI (match_dup 0) (const_int 4))
8150 (label_ref (match_operand 2 "" ""))))
8151 (label_ref (match_operand 3 "" ""))))
bd5b4116 8152 (clobber (reg:CC CC_REGNUM))
f082f1c4 8153 (use (label_ref (match_dup 2)))])]
cffb2a26 8154 "TARGET_ARM"
f7fbdd4a 8155 "*
0d66636f 8156 if (flag_pic)
8157 return \"cmp\\t%0, %1\;addls\\t%|pc, %|pc, %0, asl #2\;b\\t%l3\";
8158 return \"cmp\\t%0, %1\;ldrls\\t%|pc, [%|pc, %0, asl #2]\;b\\t%l3\";
8159 "
8160 [(set_attr "conds" "clob")
1b7da4ac 8161 (set_attr "length" "12")
8162 (set_attr "type" "multiple")]
0d66636f 8163)
9c08d1fa 8164
cffb2a26 8165(define_expand "indirect_jump"
9c08d1fa 8166 [(set (pc)
cffb2a26 8167 (match_operand:SI 0 "s_register_operand" ""))]
8168 "TARGET_EITHER"
25f905c2 8169 "
8170 /* Thumb-2 doesn't have mov pc, reg. Explicitly set the low bit of the
8171 address and use bx. */
8172 if (TARGET_THUMB2)
8173 {
8174 rtx tmp;
8175 tmp = gen_reg_rtx (SImode);
8176 emit_insn (gen_iorsi3 (tmp, operands[0], GEN_INT(1)));
8177 operands[0] = tmp;
8178 }
8179 "
cffb2a26 8180)
8181
f1039640 8182;; NB Never uses BX.
cffb2a26 8183(define_insn "*arm_indirect_jump"
8184 [(set (pc)
8185 (match_operand:SI 0 "s_register_operand" "r"))]
8186 "TARGET_ARM"
8187 "mov%?\\t%|pc, %0\\t%@ indirect register jump"
1b7da4ac 8188 [(set_attr "predicable" "yes")
8189 (set_attr "type" "branch")]
cffb2a26 8190)
9c08d1fa 8191
f7fbdd4a 8192(define_insn "*load_indirect_jump"
9c08d1fa 8193 [(set (pc)
8194 (match_operand:SI 0 "memory_operand" "m"))]
cffb2a26 8195 "TARGET_ARM"
8196 "ldr%?\\t%|pc, %0\\t%@ indirect memory jump"
a2cd141b 8197 [(set_attr "type" "load1")
61a2d04c 8198 (set_attr "pool_range" "4096")
8199 (set_attr "neg_pool_range" "4084")
0d66636f 8200 (set_attr "predicable" "yes")]
cffb2a26 8201)
8202
9c08d1fa 8203\f
8204;; Misc insns
8205
8206(define_insn "nop"
8207 [(const_int 0)]
cffb2a26 8208 "TARGET_EITHER"
8209 "*
25f905c2 8210 if (TARGET_UNIFIED_ASM)
8211 return \"nop\";
cffb2a26 8212 if (TARGET_ARM)
8213 return \"mov%?\\t%|r0, %|r0\\t%@ nop\";
8214 return \"mov\\tr8, r8\";
8215 "
8216 [(set (attr "length")
8217 (if_then_else (eq_attr "is_thumb" "yes")
8218 (const_int 2)
1b7da4ac 8219 (const_int 4)))
8220 (set_attr "type" "mov_reg")]
cffb2a26 8221)
8222
ad9d4399 8223(define_insn "trap"
8224 [(trap_if (const_int 1) (const_int 0))]
8225 ""
8226 "*
8227 if (TARGET_ARM)
8228 return \".inst\\t0xe7f000f0\";
8229 else
8230 return \".inst\\t0xdeff\";
8231 "
8232 [(set (attr "length")
8233 (if_then_else (eq_attr "is_thumb" "yes")
8234 (const_int 2)
8235 (const_int 4)))
8236 (set_attr "type" "trap")
8237 (set_attr "conds" "unconditional")]
8238)
8239
9c08d1fa 8240\f
8241;; Patterns to allow combination of arithmetic, cond code and shifts
8242
0abea32c 8243(define_insn "*<arith_shift_insn>_multsi"
8244 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8245 (shiftable_ops:SI
8246 (mult:SI (match_operand:SI 2 "s_register_operand" "r,r")
8247 (match_operand:SI 3 "power_of_two_operand" ""))
8248 (match_operand:SI 1 "s_register_operand" "rk,<t2_binop0>")))]
d5d4dc8d 8249 "TARGET_32BIT"
0abea32c 8250 "<arith_shift_insn>%?\\t%0, %1, %2, lsl %b3"
8251 [(set_attr "predicable" "yes")
8252 (set_attr "predicable_short_it" "no")
8253 (set_attr "shift" "4")
8254 (set_attr "arch" "a,t2")
8255 (set_attr "type" "alu_shift_imm")])
8256
8257(define_insn "*<arith_shift_insn>_shiftsi"
8258 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
8259 (shiftable_ops:SI
8260 (match_operator:SI 2 "shift_nomul_operator"
8261 [(match_operand:SI 3 "s_register_operand" "r,r,r")
8262 (match_operand:SI 4 "shift_amount_operand" "M,M,r")])
8263 (match_operand:SI 1 "s_register_operand" "rk,<t2_binop0>,rk")))]
8264 "TARGET_32BIT && GET_CODE (operands[3]) != MULT"
8265 "<arith_shift_insn>%?\\t%0, %1, %3%S2"
344495ea 8266 [(set_attr "predicable" "yes")
74ef923b 8267 (set_attr "predicable_short_it" "no")
331beb1a 8268 (set_attr "shift" "4")
0abea32c 8269 (set_attr "arch" "a,t2,a")
8270 (set_attr "type" "alu_shift_imm,alu_shift_imm,alu_shift_reg")])
9c08d1fa 8271
d7863cfe 8272(define_split
8273 [(set (match_operand:SI 0 "s_register_operand" "")
8274 (match_operator:SI 1 "shiftable_operator"
8275 [(match_operator:SI 2 "shiftable_operator"
8276 [(match_operator:SI 3 "shift_operator"
8277 [(match_operand:SI 4 "s_register_operand" "")
8278 (match_operand:SI 5 "reg_or_int_operand" "")])
8279 (match_operand:SI 6 "s_register_operand" "")])
8280 (match_operand:SI 7 "arm_rhs_operand" "")]))
8281 (clobber (match_operand:SI 8 "s_register_operand" ""))]
d5d4dc8d 8282 "TARGET_32BIT"
d7863cfe 8283 [(set (match_dup 8)
8284 (match_op_dup 2 [(match_op_dup 3 [(match_dup 4) (match_dup 5)])
8285 (match_dup 6)]))
8286 (set (match_dup 0)
8287 (match_op_dup 1 [(match_dup 8) (match_dup 7)]))]
8288 "")
8289
f7fbdd4a 8290(define_insn "*arith_shiftsi_compare0"
bd5b4116 8291 [(set (reg:CC_NOOV CC_REGNUM)
d5d4dc8d 8292 (compare:CC_NOOV
8293 (match_operator:SI 1 "shiftable_operator"
8294 [(match_operator:SI 3 "shift_operator"
8295 [(match_operand:SI 4 "s_register_operand" "r,r")
8296 (match_operand:SI 5 "shift_amount_operand" "M,r")])
8297 (match_operand:SI 2 "s_register_operand" "r,r")])
8298 (const_int 0)))
8299 (set (match_operand:SI 0 "s_register_operand" "=r,r")
9c08d1fa 8300 (match_op_dup 1 [(match_op_dup 3 [(match_dup 4) (match_dup 5)])
8301 (match_dup 2)]))]
d5d4dc8d 8302 "TARGET_32BIT"
25f905c2 8303 "%i1%.\\t%0, %2, %4%S3"
344495ea 8304 [(set_attr "conds" "set")
331beb1a 8305 (set_attr "shift" "4")
d5d4dc8d 8306 (set_attr "arch" "32,a")
d82e788e 8307 (set_attr "type" "alus_shift_imm,alus_shift_reg")])
9c08d1fa 8308
f7fbdd4a 8309(define_insn "*arith_shiftsi_compare0_scratch"
bd5b4116 8310 [(set (reg:CC_NOOV CC_REGNUM)
d5d4dc8d 8311 (compare:CC_NOOV
8312 (match_operator:SI 1 "shiftable_operator"
8313 [(match_operator:SI 3 "shift_operator"
8314 [(match_operand:SI 4 "s_register_operand" "r,r")
8315 (match_operand:SI 5 "shift_amount_operand" "M,r")])
8316 (match_operand:SI 2 "s_register_operand" "r,r")])
8317 (const_int 0)))
8318 (clobber (match_scratch:SI 0 "=r,r"))]
8319 "TARGET_32BIT"
25f905c2 8320 "%i1%.\\t%0, %2, %4%S3"
344495ea 8321 [(set_attr "conds" "set")
331beb1a 8322 (set_attr "shift" "4")
d5d4dc8d 8323 (set_attr "arch" "32,a")
d82e788e 8324 (set_attr "type" "alus_shift_imm,alus_shift_reg")])
9c08d1fa 8325
f7fbdd4a 8326(define_insn "*sub_shiftsi"
d5d4dc8d 8327 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8328 (minus:SI (match_operand:SI 1 "s_register_operand" "r,r")
9c08d1fa 8329 (match_operator:SI 2 "shift_operator"
d5d4dc8d 8330 [(match_operand:SI 3 "s_register_operand" "r,r")
8331 (match_operand:SI 4 "shift_amount_operand" "M,r")])))]
8332 "TARGET_32BIT"
6c4c2133 8333 "sub%?\\t%0, %1, %3%S2"
344495ea 8334 [(set_attr "predicable" "yes")
331beb1a 8335 (set_attr "shift" "3")
d5d4dc8d 8336 (set_attr "arch" "32,a")
d82e788e 8337 (set_attr "type" "alus_shift_imm,alus_shift_reg")])
9c08d1fa 8338
f7fbdd4a 8339(define_insn "*sub_shiftsi_compare0"
bd5b4116 8340 [(set (reg:CC_NOOV CC_REGNUM)
40dbec34 8341 (compare:CC_NOOV
d82e788e 8342 (minus:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
40dbec34 8343 (match_operator:SI 2 "shift_operator"
d82e788e 8344 [(match_operand:SI 3 "s_register_operand" "r,r,r")
8345 (match_operand:SI 4 "shift_amount_operand" "M,r,M")]))
40dbec34 8346 (const_int 0)))
d82e788e 8347 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
d5d4dc8d 8348 (minus:SI (match_dup 1)
8349 (match_op_dup 2 [(match_dup 3) (match_dup 4)])))]
8350 "TARGET_32BIT"
25f905c2 8351 "sub%.\\t%0, %1, %3%S2"
344495ea 8352 [(set_attr "conds" "set")
a2cd141b 8353 (set_attr "shift" "3")
d82e788e 8354 (set_attr "arch" "32,a,a")
8355 (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")])
9c08d1fa 8356
f7fbdd4a 8357(define_insn "*sub_shiftsi_compare0_scratch"
bd5b4116 8358 [(set (reg:CC_NOOV CC_REGNUM)
40dbec34 8359 (compare:CC_NOOV
d82e788e 8360 (minus:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
40dbec34 8361 (match_operator:SI 2 "shift_operator"
d82e788e 8362 [(match_operand:SI 3 "s_register_operand" "r,r,r")
8363 (match_operand:SI 4 "shift_amount_operand" "M,r,M")]))
40dbec34 8364 (const_int 0)))
d82e788e 8365 (clobber (match_scratch:SI 0 "=r,r,r"))]
d5d4dc8d 8366 "TARGET_32BIT"
25f905c2 8367 "sub%.\\t%0, %1, %3%S2"
344495ea 8368 [(set_attr "conds" "set")
a2cd141b 8369 (set_attr "shift" "3")
d82e788e 8370 (set_attr "arch" "32,a,a")
8371 (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")])
9c08d1fa 8372\f
8373
190efb17 8374(define_insn_and_split "*and_scc"
9c08d1fa 8375 [(set (match_operand:SI 0 "s_register_operand" "=r")
8fa3ba89 8376 (and:SI (match_operator:SI 1 "arm_comparison_operator"
190efb17 8377 [(match_operand 2 "cc_register" "") (const_int 0)])
8378 (match_operand:SI 3 "s_register_operand" "r")))]
cffb2a26 8379 "TARGET_ARM"
190efb17 8380 "#" ; "mov%D1\\t%0, #0\;and%d1\\t%0, %3, #1"
8381 "&& reload_completed"
8382 [(cond_exec (match_dup 5) (set (match_dup 0) (const_int 0)))
8383 (cond_exec (match_dup 4) (set (match_dup 0)
8384 (and:SI (match_dup 3) (const_int 1))))]
8385 {
8386 enum machine_mode mode = GET_MODE (operands[2]);
8387 enum rtx_code rc = GET_CODE (operands[1]);
8388
8389 /* Note that operands[4] is the same as operands[1],
8390 but with VOIDmode as the result. */
8391 operands[4] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
8392 if (mode == CCFPmode || mode == CCFPEmode)
8393 rc = reverse_condition_maybe_unordered (rc);
8394 else
8395 rc = reverse_condition (rc);
8396 operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
8397 }
8fa3ba89 8398 [(set_attr "conds" "use")
1b7da4ac 8399 (set_attr "type" "multiple")
8fa3ba89 8400 (set_attr "length" "8")]
8401)
9c08d1fa 8402
190efb17 8403(define_insn_and_split "*ior_scc"
9c08d1fa 8404 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
190efb17 8405 (ior:SI (match_operator:SI 1 "arm_comparison_operator"
8406 [(match_operand 2 "cc_register" "") (const_int 0)])
8407 (match_operand:SI 3 "s_register_operand" "0,?r")))]
cffb2a26 8408 "TARGET_ARM"
e2348bcb 8409 "@
190efb17 8410 orr%d1\\t%0, %3, #1
8411 #"
8412 "&& reload_completed
8413 && REGNO (operands [0]) != REGNO (operands[3])"
8414 ;; && which_alternative == 1
8415 ; mov%D1\\t%0, %3\;orr%d1\\t%0, %3, #1
8416 [(cond_exec (match_dup 5) (set (match_dup 0) (match_dup 3)))
8417 (cond_exec (match_dup 4) (set (match_dup 0)
8418 (ior:SI (match_dup 3) (const_int 1))))]
8419 {
8420 enum machine_mode mode = GET_MODE (operands[2]);
8421 enum rtx_code rc = GET_CODE (operands[1]);
8422
8423 /* Note that operands[4] is the same as operands[1],
8424 but with VOIDmode as the result. */
8425 operands[4] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
8426 if (mode == CCFPmode || mode == CCFPEmode)
8427 rc = reverse_condition_maybe_unordered (rc);
8428 else
8429 rc = reverse_condition (rc);
8430 operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
8431 }
8fa3ba89 8432 [(set_attr "conds" "use")
1b7da4ac 8433 (set_attr "length" "4,8")
8434 (set_attr "type" "logic_imm,multiple")]
8fa3ba89 8435)
9c08d1fa 8436
2df9477b 8437; A series of splitters for the compare_scc pattern below. Note that
8438; order is important.
8439(define_split
8440 [(set (match_operand:SI 0 "s_register_operand" "")
8441 (lt:SI (match_operand:SI 1 "s_register_operand" "")
8442 (const_int 0)))
8443 (clobber (reg:CC CC_REGNUM))]
8444 "TARGET_32BIT && reload_completed"
8445 [(set (match_dup 0) (lshiftrt:SI (match_dup 1) (const_int 31)))])
8446
8447(define_split
8448 [(set (match_operand:SI 0 "s_register_operand" "")
8449 (ge:SI (match_operand:SI 1 "s_register_operand" "")
8450 (const_int 0)))
8451 (clobber (reg:CC CC_REGNUM))]
8452 "TARGET_32BIT && reload_completed"
8453 [(set (match_dup 0) (not:SI (match_dup 1)))
8454 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 31)))])
8455
98562479 8456(define_split
8457 [(set (match_operand:SI 0 "s_register_operand" "")
8458 (eq:SI (match_operand:SI 1 "s_register_operand" "")
8459 (const_int 0)))
8460 (clobber (reg:CC CC_REGNUM))]
8461 "arm_arch5 && TARGET_32BIT"
8462 [(set (match_dup 0) (clz:SI (match_dup 1)))
8463 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 5)))]
8464)
8465
2df9477b 8466(define_split
8467 [(set (match_operand:SI 0 "s_register_operand" "")
8468 (eq:SI (match_operand:SI 1 "s_register_operand" "")
8469 (const_int 0)))
8470 (clobber (reg:CC CC_REGNUM))]
8471 "TARGET_32BIT && reload_completed"
8472 [(parallel
080c0b9a 8473 [(set (reg:CC CC_REGNUM)
8474 (compare:CC (const_int 1) (match_dup 1)))
2df9477b 8475 (set (match_dup 0)
8476 (minus:SI (const_int 1) (match_dup 1)))])
080c0b9a 8477 (cond_exec (ltu:CC (reg:CC CC_REGNUM) (const_int 0))
2df9477b 8478 (set (match_dup 0) (const_int 0)))])
8479
8480(define_split
8481 [(set (match_operand:SI 0 "s_register_operand" "")
8482 (ne:SI (match_operand:SI 1 "s_register_operand" "")
8483 (match_operand:SI 2 "const_int_operand" "")))
8484 (clobber (reg:CC CC_REGNUM))]
8485 "TARGET_32BIT && reload_completed"
8486 [(parallel
8487 [(set (reg:CC CC_REGNUM)
8488 (compare:CC (match_dup 1) (match_dup 2)))
8489 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 3)))])
8490 (cond_exec (ne:CC (reg:CC CC_REGNUM) (const_int 0))
8491 (set (match_dup 0) (const_int 1)))]
8492{
8493 operands[3] = GEN_INT (-INTVAL (operands[2]));
8494})
8495
8496(define_split
8497 [(set (match_operand:SI 0 "s_register_operand" "")
8498 (ne:SI (match_operand:SI 1 "s_register_operand" "")
8499 (match_operand:SI 2 "arm_add_operand" "")))
8500 (clobber (reg:CC CC_REGNUM))]
8501 "TARGET_32BIT && reload_completed"
8502 [(parallel
8503 [(set (reg:CC_NOOV CC_REGNUM)
8504 (compare:CC_NOOV (minus:SI (match_dup 1) (match_dup 2))
8505 (const_int 0)))
8506 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
8507 (cond_exec (ne:CC_NOOV (reg:CC_NOOV CC_REGNUM) (const_int 0))
8508 (set (match_dup 0) (const_int 1)))])
8509
8510(define_insn_and_split "*compare_scc"
fd711051 8511 [(set (match_operand:SI 0 "s_register_operand" "=Ts,Ts")
8fa3ba89 8512 (match_operator:SI 1 "arm_comparison_operator"
5565501b 8513 [(match_operand:SI 2 "s_register_operand" "r,r")
8514 (match_operand:SI 3 "arm_add_operand" "rI,L")]))
bd5b4116 8515 (clobber (reg:CC CC_REGNUM))]
2df9477b 8516 "TARGET_32BIT"
8517 "#"
8518 "&& reload_completed"
8519 [(set (reg:CC CC_REGNUM) (compare:CC (match_dup 2) (match_dup 3)))
8520 (cond_exec (match_dup 4) (set (match_dup 0) (const_int 0)))
8521 (cond_exec (match_dup 5) (set (match_dup 0) (const_int 1)))]
8522{
8523 rtx tmp1;
8524 enum machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
8525 operands[2], operands[3]);
8526 enum rtx_code rc = GET_CODE (operands[1]);
e2348bcb 8527
2df9477b 8528 tmp1 = gen_rtx_REG (mode, CC_REGNUM);
080c0b9a 8529
2df9477b 8530 operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, tmp1, const0_rtx);
8531 if (mode == CCFPmode || mode == CCFPEmode)
8532 rc = reverse_condition_maybe_unordered (rc);
8533 else
8534 rc = reverse_condition (rc);
8535 operands[4] = gen_rtx_fmt_ee (rc, VOIDmode, tmp1, const0_rtx);
1b7da4ac 8536}
8537 [(set_attr "type" "multiple")]
8538)
9c08d1fa 8539
080c0b9a 8540;; Attempt to improve the sequence generated by the compare_scc splitters
8541;; not to use conditional execution.
98562479 8542
8543;; Rd = (eq (reg1) (const_int0)) // ARMv5
8544;; clz Rd, reg1
8545;; lsr Rd, Rd, #5
080c0b9a 8546(define_peephole2
8547 [(set (reg:CC CC_REGNUM)
8548 (compare:CC (match_operand:SI 1 "register_operand" "")
98562479 8549 (const_int 0)))
8550 (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
8551 (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
8552 (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
8553 (set (match_dup 0) (const_int 1)))]
8554 "arm_arch5 && TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)"
8555 [(set (match_dup 0) (clz:SI (match_dup 1)))
8556 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 5)))]
8557)
8558
8559;; Rd = (eq (reg1) (const_int0)) // !ARMv5
8560;; negs Rd, reg1
8561;; adc Rd, Rd, reg1
8562(define_peephole2
8563 [(set (reg:CC CC_REGNUM)
8564 (compare:CC (match_operand:SI 1 "register_operand" "")
8565 (const_int 0)))
080c0b9a 8566 (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
8567 (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
8568 (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
8569 (set (match_dup 0) (const_int 1)))
98562479 8570 (match_scratch:SI 2 "r")]
8571 "TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)"
922b6913 8572 [(parallel
8573 [(set (reg:CC CC_REGNUM)
98562479 8574 (compare:CC (const_int 0) (match_dup 1)))
8575 (set (match_dup 2) (minus:SI (const_int 0) (match_dup 1)))])
8576 (set (match_dup 0)
8577 (plus:SI (plus:SI (match_dup 1) (match_dup 2))
8578 (geu:SI (reg:CC CC_REGNUM) (const_int 0))))]
8579)
8580
31991287 8581;; Rd = (eq (reg1) (reg2/imm)) // ARMv5 and optimising for speed.
98562479 8582;; sub Rd, Reg1, reg2
8583;; clz Rd, Rd
8584;; lsr Rd, Rd, #5
8585(define_peephole2
8586 [(set (reg:CC CC_REGNUM)
8587 (compare:CC (match_operand:SI 1 "register_operand" "")
8588 (match_operand:SI 2 "arm_rhs_operand" "")))
8589 (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
8590 (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
8591 (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
8592 (set (match_dup 0) (const_int 1)))]
31991287 8593 "arm_arch5 && TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)
8594 && !(TARGET_THUMB2 && optimize_insn_for_size_p ())"
98562479 8595 [(set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))
8596 (set (match_dup 0) (clz:SI (match_dup 0)))
8597 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 5)))]
8598)
8599
8600
31991287 8601;; Rd = (eq (reg1) (reg2)) // ! ARMv5 or optimising for size.
98562479 8602;; sub T1, Reg1, reg2
8603;; negs Rd, T1
8604;; adc Rd, Rd, T1
8605(define_peephole2
8606 [(set (reg:CC CC_REGNUM)
8607 (compare:CC (match_operand:SI 1 "register_operand" "")
8608 (match_operand:SI 2 "arm_rhs_operand" "")))
8609 (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
8610 (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
8611 (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
8612 (set (match_dup 0) (const_int 1)))
8613 (match_scratch:SI 3 "r")]
8614 "TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)"
31991287 8615 [(set (match_dup 3) (match_dup 4))
080c0b9a 8616 (parallel
8617 [(set (reg:CC CC_REGNUM)
8618 (compare:CC (const_int 0) (match_dup 3)))
8619 (set (match_dup 0) (minus:SI (const_int 0) (match_dup 3)))])
98562479 8620 (set (match_dup 0)
8621 (plus:SI (plus:SI (match_dup 0) (match_dup 3))
8622 (geu:SI (reg:CC CC_REGNUM) (const_int 0))))]
31991287 8623 "
8624 if (CONST_INT_P (operands[2]))
8625 operands[4] = plus_constant (SImode, operands[1], -INTVAL (operands[2]));
8626 else
8627 operands[4] = gen_rtx_MINUS (SImode, operands[1], operands[2]);
8628 ")
080c0b9a 8629
f7fbdd4a 8630(define_insn "*cond_move"
9c08d1fa 8631 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
aea4c774 8632 (if_then_else:SI (match_operator 3 "equality_operator"
8fa3ba89 8633 [(match_operator 4 "arm_comparison_operator"
8a18b90c 8634 [(match_operand 5 "cc_register" "") (const_int 0)])
aea4c774 8635 (const_int 0)])
8636 (match_operand:SI 1 "arm_rhs_operand" "0,rI,?rI")
8637 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))]
cffb2a26 8638 "TARGET_ARM"
9c08d1fa 8639 "*
8fa3ba89 8640 if (GET_CODE (operands[3]) == NE)
8641 {
8642 if (which_alternative != 1)
8643 output_asm_insn (\"mov%D4\\t%0, %2\", operands);
8644 if (which_alternative != 0)
8645 output_asm_insn (\"mov%d4\\t%0, %1\", operands);
8646 return \"\";
8647 }
8648 if (which_alternative != 0)
8649 output_asm_insn (\"mov%D4\\t%0, %1\", operands);
8650 if (which_alternative != 1)
8651 output_asm_insn (\"mov%d4\\t%0, %2\", operands);
8652 return \"\";
8653 "
8654 [(set_attr "conds" "use")
1b7da4ac 8655 (set_attr "type" "mov_reg,mov_reg,multiple")
8fa3ba89 8656 (set_attr "length" "4,4,8")]
8657)
9c08d1fa 8658
f7fbdd4a 8659(define_insn "*cond_arith"
9c08d1fa 8660 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8661 (match_operator:SI 5 "shiftable_operator"
8fa3ba89 8662 [(match_operator:SI 4 "arm_comparison_operator"
9c08d1fa 8663 [(match_operand:SI 2 "s_register_operand" "r,r")
8664 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
8665 (match_operand:SI 1 "s_register_operand" "0,?r")]))
bd5b4116 8666 (clobber (reg:CC CC_REGNUM))]
cffb2a26 8667 "TARGET_ARM"
9c08d1fa 8668 "*
8fa3ba89 8669 if (GET_CODE (operands[4]) == LT && operands[3] == const0_rtx)
8670 return \"%i5\\t%0, %1, %2, lsr #31\";
40dbec34 8671
8fa3ba89 8672 output_asm_insn (\"cmp\\t%2, %3\", operands);
8673 if (GET_CODE (operands[5]) == AND)
8674 output_asm_insn (\"mov%D4\\t%0, #0\", operands);
8675 else if (GET_CODE (operands[5]) == MINUS)
8676 output_asm_insn (\"rsb%D4\\t%0, %1, #0\", operands);
8677 else if (which_alternative != 0)
8678 output_asm_insn (\"mov%D4\\t%0, %1\", operands);
8679 return \"%i5%d4\\t%0, %1, #1\";
8680 "
8681 [(set_attr "conds" "clob")
1b7da4ac 8682 (set_attr "length" "12")
8683 (set_attr "type" "multiple")]
8fa3ba89 8684)
9c08d1fa 8685
f7fbdd4a 8686(define_insn "*cond_sub"
9c08d1fa 8687 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8688 (minus:SI (match_operand:SI 1 "s_register_operand" "0,?r")
8fa3ba89 8689 (match_operator:SI 4 "arm_comparison_operator"
9c08d1fa 8690 [(match_operand:SI 2 "s_register_operand" "r,r")
8691 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))
bd5b4116 8692 (clobber (reg:CC CC_REGNUM))]
cffb2a26 8693 "TARGET_ARM"
9c08d1fa 8694 "*
8fa3ba89 8695 output_asm_insn (\"cmp\\t%2, %3\", operands);
8696 if (which_alternative != 0)
8697 output_asm_insn (\"mov%D4\\t%0, %1\", operands);
8698 return \"sub%d4\\t%0, %1, #1\";
8699 "
8700 [(set_attr "conds" "clob")
1b7da4ac 8701 (set_attr "length" "8,12")
8702 (set_attr "type" "multiple")]
8fa3ba89 8703)
9c08d1fa 8704
aea4c774 8705(define_insn "*cmp_ite0"
cffb2a26 8706 [(set (match_operand 6 "dominant_cc_register" "")
aea4c774 8707 (compare
8708 (if_then_else:SI
8fa3ba89 8709 (match_operator 4 "arm_comparison_operator"
2ff91fec 8710 [(match_operand:SI 0 "s_register_operand"
8711 "l,l,l,r,r,r,r,r,r")
8712 (match_operand:SI 1 "arm_add_operand"
8713 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
8fa3ba89 8714 (match_operator:SI 5 "arm_comparison_operator"
2ff91fec 8715 [(match_operand:SI 2 "s_register_operand"
8716 "l,r,r,l,l,r,r,r,r")
8717 (match_operand:SI 3 "arm_add_operand"
8718 "lPy,rI,L,lPy,lPy,rI,rI,L,L")])
aea4c774 8719 (const_int 0))
8720 (const_int 0)))]
2ff91fec 8721 "TARGET_32BIT"
9c08d1fa 8722 "*
aea4c774 8723 {
2ff91fec 8724 static const char * const cmp1[NUM_OF_COND_CMP][2] =
8725 {
8726 {\"cmp%d5\\t%0, %1\",
8727 \"cmp%d4\\t%2, %3\"},
8728 {\"cmn%d5\\t%0, #%n1\",
8729 \"cmp%d4\\t%2, %3\"},
8730 {\"cmp%d5\\t%0, %1\",
8731 \"cmn%d4\\t%2, #%n3\"},
8732 {\"cmn%d5\\t%0, #%n1\",
8733 \"cmn%d4\\t%2, #%n3\"}
8734 };
8735 static const char * const cmp2[NUM_OF_COND_CMP][2] =
8736 {
8737 {\"cmp\\t%2, %3\",
8738 \"cmp\\t%0, %1\"},
8739 {\"cmp\\t%2, %3\",
8740 \"cmn\\t%0, #%n1\"},
8741 {\"cmn\\t%2, #%n3\",
8742 \"cmp\\t%0, %1\"},
8743 {\"cmn\\t%2, #%n3\",
8744 \"cmn\\t%0, #%n1\"}
8745 };
8746 static const char * const ite[2] =
8fa3ba89 8747 {
2ff91fec 8748 \"it\\t%d5\",
8749 \"it\\t%d4\"
8fa3ba89 8750 };
2ff91fec 8751 static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
8752 CMP_CMP, CMN_CMP, CMP_CMP,
8753 CMN_CMP, CMP_CMN, CMN_CMN};
8fa3ba89 8754 int swap =
8755 comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4]));
8756
2ff91fec 8757 output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
8758 if (TARGET_THUMB2) {
8759 output_asm_insn (ite[swap], operands);
8760 }
8761 output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
8762 return \"\";
8fa3ba89 8763 }"
8764 [(set_attr "conds" "set")
2ff91fec 8765 (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
1b7da4ac 8766 (set_attr "type" "multiple")
2ff91fec 8767 (set_attr_alternative "length"
8768 [(const_int 6)
8769 (const_int 8)
8770 (const_int 8)
8771 (const_int 8)
8772 (const_int 8)
8773 (if_then_else (eq_attr "is_thumb" "no")
8774 (const_int 8)
8775 (const_int 10))
8776 (if_then_else (eq_attr "is_thumb" "no")
8777 (const_int 8)
8778 (const_int 10))
8779 (if_then_else (eq_attr "is_thumb" "no")
8780 (const_int 8)
8781 (const_int 10))
8782 (if_then_else (eq_attr "is_thumb" "no")
8783 (const_int 8)
8784 (const_int 10))])]
8fa3ba89 8785)
9c08d1fa 8786
aea4c774 8787(define_insn "*cmp_ite1"
cffb2a26 8788 [(set (match_operand 6 "dominant_cc_register" "")
aea4c774 8789 (compare
8790 (if_then_else:SI
8fa3ba89 8791 (match_operator 4 "arm_comparison_operator"
2ff91fec 8792 [(match_operand:SI 0 "s_register_operand"
8793 "l,l,l,r,r,r,r,r,r")
8794 (match_operand:SI 1 "arm_add_operand"
8795 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
8fa3ba89 8796 (match_operator:SI 5 "arm_comparison_operator"
2ff91fec 8797 [(match_operand:SI 2 "s_register_operand"
8798 "l,r,r,l,l,r,r,r,r")
8799 (match_operand:SI 3 "arm_add_operand"
8800 "lPy,rI,L,lPy,lPy,rI,rI,L,L")])
aea4c774 8801 (const_int 1))
8802 (const_int 0)))]
2ff91fec 8803 "TARGET_32BIT"
9c08d1fa 8804 "*
9c08d1fa 8805 {
2ff91fec 8806 static const char * const cmp1[NUM_OF_COND_CMP][2] =
8807 {
8808 {\"cmp\\t%0, %1\",
8809 \"cmp\\t%2, %3\"},
8810 {\"cmn\\t%0, #%n1\",
8811 \"cmp\\t%2, %3\"},
8812 {\"cmp\\t%0, %1\",
8813 \"cmn\\t%2, #%n3\"},
8814 {\"cmn\\t%0, #%n1\",
8815 \"cmn\\t%2, #%n3\"}
8816 };
8817 static const char * const cmp2[NUM_OF_COND_CMP][2] =
215b30b3 8818 {
2ff91fec 8819 {\"cmp%d4\\t%2, %3\",
8820 \"cmp%D5\\t%0, %1\"},
8821 {\"cmp%d4\\t%2, %3\",
8822 \"cmn%D5\\t%0, #%n1\"},
8823 {\"cmn%d4\\t%2, #%n3\",
8824 \"cmp%D5\\t%0, %1\"},
8825 {\"cmn%d4\\t%2, #%n3\",
8826 \"cmn%D5\\t%0, #%n1\"}
215b30b3 8827 };
2ff91fec 8828 static const char * const ite[2] =
8829 {
8830 \"it\\t%d4\",
8831 \"it\\t%D5\"
8832 };
8833 static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
8834 CMP_CMP, CMN_CMP, CMP_CMP,
8835 CMN_CMP, CMP_CMN, CMN_CMN};
215b30b3 8836 int swap =
8837 comparison_dominates_p (GET_CODE (operands[5]),
8838 reverse_condition (GET_CODE (operands[4])));
8839
2ff91fec 8840 output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
8841 if (TARGET_THUMB2) {
8842 output_asm_insn (ite[swap], operands);
8843 }
8844 output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
8845 return \"\";
215b30b3 8846 }"
8fa3ba89 8847 [(set_attr "conds" "set")
2ff91fec 8848 (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
8849 (set_attr_alternative "length"
8850 [(const_int 6)
8851 (const_int 8)
8852 (const_int 8)
8853 (const_int 8)
8854 (const_int 8)
8855 (if_then_else (eq_attr "is_thumb" "no")
8856 (const_int 8)
8857 (const_int 10))
8858 (if_then_else (eq_attr "is_thumb" "no")
8859 (const_int 8)
8860 (const_int 10))
8861 (if_then_else (eq_attr "is_thumb" "no")
8862 (const_int 8)
8863 (const_int 10))
8864 (if_then_else (eq_attr "is_thumb" "no")
8865 (const_int 8)
1b7da4ac 8866 (const_int 10))])
8867 (set_attr "type" "multiple")]
8fa3ba89 8868)
9c08d1fa 8869
f6c53574 8870(define_insn "*cmp_and"
8871 [(set (match_operand 6 "dominant_cc_register" "")
8872 (compare
8873 (and:SI
8874 (match_operator 4 "arm_comparison_operator"
2ff91fec 8875 [(match_operand:SI 0 "s_register_operand"
8876 "l,l,l,r,r,r,r,r,r")
8877 (match_operand:SI 1 "arm_add_operand"
8878 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
f6c53574 8879 (match_operator:SI 5 "arm_comparison_operator"
2ff91fec 8880 [(match_operand:SI 2 "s_register_operand"
8881 "l,r,r,l,l,r,r,r,r")
8882 (match_operand:SI 3 "arm_add_operand"
8883 "lPy,rI,L,lPy,lPy,rI,rI,L,L")]))
f6c53574 8884 (const_int 0)))]
2ff91fec 8885 "TARGET_32BIT"
f6c53574 8886 "*
8887 {
2ff91fec 8888 static const char *const cmp1[NUM_OF_COND_CMP][2] =
f6c53574 8889 {
2ff91fec 8890 {\"cmp%d5\\t%0, %1\",
8891 \"cmp%d4\\t%2, %3\"},
8892 {\"cmn%d5\\t%0, #%n1\",
8893 \"cmp%d4\\t%2, %3\"},
8894 {\"cmp%d5\\t%0, %1\",
8895 \"cmn%d4\\t%2, #%n3\"},
8896 {\"cmn%d5\\t%0, #%n1\",
8897 \"cmn%d4\\t%2, #%n3\"}
f6c53574 8898 };
2ff91fec 8899 static const char *const cmp2[NUM_OF_COND_CMP][2] =
8900 {
8901 {\"cmp\\t%2, %3\",
8902 \"cmp\\t%0, %1\"},
8903 {\"cmp\\t%2, %3\",
8904 \"cmn\\t%0, #%n1\"},
8905 {\"cmn\\t%2, #%n3\",
8906 \"cmp\\t%0, %1\"},
8907 {\"cmn\\t%2, #%n3\",
8908 \"cmn\\t%0, #%n1\"}
8909 };
8910 static const char *const ite[2] =
8911 {
8912 \"it\\t%d5\",
8913 \"it\\t%d4\"
8914 };
8915 static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
8916 CMP_CMP, CMN_CMP, CMP_CMP,
8917 CMN_CMP, CMP_CMN, CMN_CMN};
f6c53574 8918 int swap =
8919 comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4]));
8920
2ff91fec 8921 output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
8922 if (TARGET_THUMB2) {
8923 output_asm_insn (ite[swap], operands);
8924 }
8925 output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
8926 return \"\";
f6c53574 8927 }"
8928 [(set_attr "conds" "set")
8929 (set_attr "predicable" "no")
2ff91fec 8930 (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
8931 (set_attr_alternative "length"
8932 [(const_int 6)
8933 (const_int 8)
8934 (const_int 8)
8935 (const_int 8)
8936 (const_int 8)
8937 (if_then_else (eq_attr "is_thumb" "no")
8938 (const_int 8)
8939 (const_int 10))
8940 (if_then_else (eq_attr "is_thumb" "no")
8941 (const_int 8)
8942 (const_int 10))
8943 (if_then_else (eq_attr "is_thumb" "no")
8944 (const_int 8)
8945 (const_int 10))
8946 (if_then_else (eq_attr "is_thumb" "no")
8947 (const_int 8)
1b7da4ac 8948 (const_int 10))])
8949 (set_attr "type" "multiple")]
f6c53574 8950)
8951
8952(define_insn "*cmp_ior"
8953 [(set (match_operand 6 "dominant_cc_register" "")
8954 (compare
8955 (ior:SI
8956 (match_operator 4 "arm_comparison_operator"
2ff91fec 8957 [(match_operand:SI 0 "s_register_operand"
8958 "l,l,l,r,r,r,r,r,r")
8959 (match_operand:SI 1 "arm_add_operand"
8960 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
f6c53574 8961 (match_operator:SI 5 "arm_comparison_operator"
2ff91fec 8962 [(match_operand:SI 2 "s_register_operand"
8963 "l,r,r,l,l,r,r,r,r")
8964 (match_operand:SI 3 "arm_add_operand"
8965 "lPy,rI,L,lPy,lPy,rI,rI,L,L")]))
f6c53574 8966 (const_int 0)))]
2ff91fec 8967 "TARGET_32BIT"
f6c53574 8968 "*
f6c53574 8969 {
2ff91fec 8970 static const char *const cmp1[NUM_OF_COND_CMP][2] =
8971 {
8972 {\"cmp\\t%0, %1\",
8973 \"cmp\\t%2, %3\"},
8974 {\"cmn\\t%0, #%n1\",
8975 \"cmp\\t%2, %3\"},
8976 {\"cmp\\t%0, %1\",
8977 \"cmn\\t%2, #%n3\"},
8978 {\"cmn\\t%0, #%n1\",
8979 \"cmn\\t%2, #%n3\"}
8980 };
8981 static const char *const cmp2[NUM_OF_COND_CMP][2] =
8982 {
8983 {\"cmp%D4\\t%2, %3\",
8984 \"cmp%D5\\t%0, %1\"},
8985 {\"cmp%D4\\t%2, %3\",
8986 \"cmn%D5\\t%0, #%n1\"},
8987 {\"cmn%D4\\t%2, #%n3\",
8988 \"cmp%D5\\t%0, %1\"},
8989 {\"cmn%D4\\t%2, #%n3\",
8990 \"cmn%D5\\t%0, #%n1\"}
8991 };
8992 static const char *const ite[2] =
8993 {
8994 \"it\\t%D4\",
8995 \"it\\t%D5\"
8996 };
8997 static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
8998 CMP_CMP, CMN_CMP, CMP_CMP,
8999 CMN_CMP, CMP_CMN, CMN_CMN};
9000 int swap =
9001 comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4]));
9002
9003 output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
9004 if (TARGET_THUMB2) {
9005 output_asm_insn (ite[swap], operands);
9006 }
9007 output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
9008 return \"\";
9009 }
9010 "
f6c53574 9011 [(set_attr "conds" "set")
2ff91fec 9012 (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
9013 (set_attr_alternative "length"
9014 [(const_int 6)
9015 (const_int 8)
9016 (const_int 8)
9017 (const_int 8)
9018 (const_int 8)
9019 (if_then_else (eq_attr "is_thumb" "no")
9020 (const_int 8)
9021 (const_int 10))
9022 (if_then_else (eq_attr "is_thumb" "no")
9023 (const_int 8)
9024 (const_int 10))
9025 (if_then_else (eq_attr "is_thumb" "no")
9026 (const_int 8)
9027 (const_int 10))
9028 (if_then_else (eq_attr "is_thumb" "no")
9029 (const_int 8)
1b7da4ac 9030 (const_int 10))])
9031 (set_attr "type" "multiple")]
f6c53574 9032)
9033
3c5afce6 9034(define_insn_and_split "*ior_scc_scc"
fd711051 9035 [(set (match_operand:SI 0 "s_register_operand" "=Ts")
3c5afce6 9036 (ior:SI (match_operator:SI 3 "arm_comparison_operator"
9037 [(match_operand:SI 1 "s_register_operand" "r")
9038 (match_operand:SI 2 "arm_add_operand" "rIL")])
9039 (match_operator:SI 6 "arm_comparison_operator"
9040 [(match_operand:SI 4 "s_register_operand" "r")
9041 (match_operand:SI 5 "arm_add_operand" "rIL")])))
9042 (clobber (reg:CC CC_REGNUM))]
2ff91fec 9043 "TARGET_32BIT
3c5afce6 9044 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_OR_Y)
9045 != CCmode)"
9046 "#"
2ff91fec 9047 "TARGET_32BIT && reload_completed"
3c5afce6 9048 [(set (match_dup 7)
9049 (compare
9050 (ior:SI
9051 (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9052 (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9053 (const_int 0)))
9054 (set (match_dup 0) (ne:SI (match_dup 7) (const_int 0)))]
9055 "operands[7]
9056 = gen_rtx_REG (arm_select_dominance_cc_mode (operands[3], operands[6],
9057 DOM_CC_X_OR_Y),
601f584c 9058 CC_REGNUM);"
9059 [(set_attr "conds" "clob")
1b7da4ac 9060 (set_attr "length" "16")
9061 (set_attr "type" "multiple")]
9062)
601f584c 9063
9064; If the above pattern is followed by a CMP insn, then the compare is
9065; redundant, since we can rework the conditional instruction that follows.
9066(define_insn_and_split "*ior_scc_scc_cmp"
9067 [(set (match_operand 0 "dominant_cc_register" "")
9068 (compare (ior:SI (match_operator:SI 3 "arm_comparison_operator"
9069 [(match_operand:SI 1 "s_register_operand" "r")
9070 (match_operand:SI 2 "arm_add_operand" "rIL")])
9071 (match_operator:SI 6 "arm_comparison_operator"
9072 [(match_operand:SI 4 "s_register_operand" "r")
9073 (match_operand:SI 5 "arm_add_operand" "rIL")]))
9074 (const_int 0)))
fd711051 9075 (set (match_operand:SI 7 "s_register_operand" "=Ts")
601f584c 9076 (ior:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9077 (match_op_dup 6 [(match_dup 4) (match_dup 5)])))]
2ff91fec 9078 "TARGET_32BIT"
601f584c 9079 "#"
2ff91fec 9080 "TARGET_32BIT && reload_completed"
601f584c 9081 [(set (match_dup 0)
9082 (compare
9083 (ior:SI
9084 (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9085 (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9086 (const_int 0)))
9087 (set (match_dup 7) (ne:SI (match_dup 0) (const_int 0)))]
9088 ""
9089 [(set_attr "conds" "set")
1b7da4ac 9090 (set_attr "length" "16")
9091 (set_attr "type" "multiple")]
9092)
3c5afce6 9093
9094(define_insn_and_split "*and_scc_scc"
fd711051 9095 [(set (match_operand:SI 0 "s_register_operand" "=Ts")
3c5afce6 9096 (and:SI (match_operator:SI 3 "arm_comparison_operator"
9097 [(match_operand:SI 1 "s_register_operand" "r")
9098 (match_operand:SI 2 "arm_add_operand" "rIL")])
9099 (match_operator:SI 6 "arm_comparison_operator"
9100 [(match_operand:SI 4 "s_register_operand" "r")
9101 (match_operand:SI 5 "arm_add_operand" "rIL")])))
9102 (clobber (reg:CC CC_REGNUM))]
2ff91fec 9103 "TARGET_32BIT
3c5afce6 9104 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y)
9105 != CCmode)"
9106 "#"
2ff91fec 9107 "TARGET_32BIT && reload_completed
601f584c 9108 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y)
9109 != CCmode)"
3c5afce6 9110 [(set (match_dup 7)
9111 (compare
9112 (and:SI
9113 (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9114 (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9115 (const_int 0)))
9116 (set (match_dup 0) (ne:SI (match_dup 7) (const_int 0)))]
9117 "operands[7]
9118 = gen_rtx_REG (arm_select_dominance_cc_mode (operands[3], operands[6],
9119 DOM_CC_X_AND_Y),
601f584c 9120 CC_REGNUM);"
9121 [(set_attr "conds" "clob")
1b7da4ac 9122 (set_attr "length" "16")
9123 (set_attr "type" "multiple")]
9124)
601f584c 9125
9126; If the above pattern is followed by a CMP insn, then the compare is
9127; redundant, since we can rework the conditional instruction that follows.
9128(define_insn_and_split "*and_scc_scc_cmp"
9129 [(set (match_operand 0 "dominant_cc_register" "")
9130 (compare (and:SI (match_operator:SI 3 "arm_comparison_operator"
9131 [(match_operand:SI 1 "s_register_operand" "r")
9132 (match_operand:SI 2 "arm_add_operand" "rIL")])
9133 (match_operator:SI 6 "arm_comparison_operator"
9134 [(match_operand:SI 4 "s_register_operand" "r")
9135 (match_operand:SI 5 "arm_add_operand" "rIL")]))
9136 (const_int 0)))
fd711051 9137 (set (match_operand:SI 7 "s_register_operand" "=Ts")
601f584c 9138 (and:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9139 (match_op_dup 6 [(match_dup 4) (match_dup 5)])))]
2ff91fec 9140 "TARGET_32BIT"
601f584c 9141 "#"
2ff91fec 9142 "TARGET_32BIT && reload_completed"
601f584c 9143 [(set (match_dup 0)
9144 (compare
9145 (and:SI
9146 (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9147 (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9148 (const_int 0)))
9149 (set (match_dup 7) (ne:SI (match_dup 0) (const_int 0)))]
9150 ""
9151 [(set_attr "conds" "set")
1b7da4ac 9152 (set_attr "length" "16")
9153 (set_attr "type" "multiple")]
9154)
601f584c 9155
9156;; If there is no dominance in the comparison, then we can still save an
9157;; instruction in the AND case, since we can know that the second compare
9158;; need only zero the value if false (if true, then the value is already
9159;; correct).
9160(define_insn_and_split "*and_scc_scc_nodom"
fd711051 9161 [(set (match_operand:SI 0 "s_register_operand" "=&Ts,&Ts,&Ts")
601f584c 9162 (and:SI (match_operator:SI 3 "arm_comparison_operator"
9163 [(match_operand:SI 1 "s_register_operand" "r,r,0")
9164 (match_operand:SI 2 "arm_add_operand" "rIL,0,rIL")])
9165 (match_operator:SI 6 "arm_comparison_operator"
9166 [(match_operand:SI 4 "s_register_operand" "r,r,r")
9167 (match_operand:SI 5 "arm_add_operand" "rIL,rIL,rIL")])))
9168 (clobber (reg:CC CC_REGNUM))]
2ff91fec 9169 "TARGET_32BIT
601f584c 9170 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y)
9171 == CCmode)"
9172 "#"
2ff91fec 9173 "TARGET_32BIT && reload_completed"
601f584c 9174 [(parallel [(set (match_dup 0)
9175 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
9176 (clobber (reg:CC CC_REGNUM))])
9177 (set (match_dup 7) (match_op_dup 8 [(match_dup 4) (match_dup 5)]))
9178 (set (match_dup 0)
9179 (if_then_else:SI (match_op_dup 6 [(match_dup 7) (const_int 0)])
9180 (match_dup 0)
9181 (const_int 0)))]
9182 "operands[7] = gen_rtx_REG (SELECT_CC_MODE (GET_CODE (operands[6]),
9183 operands[4], operands[5]),
9184 CC_REGNUM);
9185 operands[8] = gen_rtx_COMPARE (GET_MODE (operands[7]), operands[4],
9186 operands[5]);"
9187 [(set_attr "conds" "clob")
1b7da4ac 9188 (set_attr "length" "20")
9189 (set_attr "type" "multiple")]
9190)
3c5afce6 9191
3a0bdee0 9192(define_split
9193 [(set (reg:CC_NOOV CC_REGNUM)
9194 (compare:CC_NOOV (ior:SI
9195 (and:SI (match_operand:SI 0 "s_register_operand" "")
9196 (const_int 1))
b0694be0 9197 (match_operator:SI 1 "arm_comparison_operator"
3a0bdee0 9198 [(match_operand:SI 2 "s_register_operand" "")
9199 (match_operand:SI 3 "arm_add_operand" "")]))
9200 (const_int 0)))
9201 (clobber (match_operand:SI 4 "s_register_operand" ""))]
9202 "TARGET_ARM"
9203 [(set (match_dup 4)
9204 (ior:SI (match_op_dup 1 [(match_dup 2) (match_dup 3)])
9205 (match_dup 0)))
9206 (set (reg:CC_NOOV CC_REGNUM)
9207 (compare:CC_NOOV (and:SI (match_dup 4) (const_int 1))
9208 (const_int 0)))]
9209 "")
9210
9211(define_split
9212 [(set (reg:CC_NOOV CC_REGNUM)
9213 (compare:CC_NOOV (ior:SI
b0694be0 9214 (match_operator:SI 1 "arm_comparison_operator"
3a0bdee0 9215 [(match_operand:SI 2 "s_register_operand" "")
9216 (match_operand:SI 3 "arm_add_operand" "")])
9217 (and:SI (match_operand:SI 0 "s_register_operand" "")
9218 (const_int 1)))
9219 (const_int 0)))
9220 (clobber (match_operand:SI 4 "s_register_operand" ""))]
9221 "TARGET_ARM"
9222 [(set (match_dup 4)
9223 (ior:SI (match_op_dup 1 [(match_dup 2) (match_dup 3)])
9224 (match_dup 0)))
9225 (set (reg:CC_NOOV CC_REGNUM)
9226 (compare:CC_NOOV (and:SI (match_dup 4) (const_int 1))
9227 (const_int 0)))]
9228 "")
25f905c2 9229;; ??? The conditional patterns above need checking for Thumb-2 usefulness
3a0bdee0 9230
190efb17 9231(define_insn_and_split "*negscc"
9c08d1fa 9232 [(set (match_operand:SI 0 "s_register_operand" "=r")
8fa3ba89 9233 (neg:SI (match_operator 3 "arm_comparison_operator"
9c08d1fa 9234 [(match_operand:SI 1 "s_register_operand" "r")
9235 (match_operand:SI 2 "arm_rhs_operand" "rI")])))
bd5b4116 9236 (clobber (reg:CC CC_REGNUM))]
cffb2a26 9237 "TARGET_ARM"
190efb17 9238 "#"
9239 "&& reload_completed"
9240 [(const_int 0)]
9241 {
9242 rtx cc_reg = gen_rtx_REG (CCmode, CC_REGNUM);
e2348bcb 9243
190efb17 9244 if (GET_CODE (operands[3]) == LT && operands[2] == const0_rtx)
9245 {
9246 /* Emit mov\\t%0, %1, asr #31 */
9247 emit_insn (gen_rtx_SET (VOIDmode,
9248 operands[0],
9249 gen_rtx_ASHIFTRT (SImode,
9250 operands[1],
9251 GEN_INT (31))));
9252 DONE;
9253 }
9254 else if (GET_CODE (operands[3]) == NE)
9255 {
9256 /* Emit subs\\t%0, %1, %2\;mvnne\\t%0, #0 */
9257 if (CONST_INT_P (operands[2]))
9258 emit_insn (gen_cmpsi2_addneg (operands[0], operands[1], operands[2],
9259 GEN_INT (- INTVAL (operands[2]))));
9260 else
9261 emit_insn (gen_subsi3_compare (operands[0], operands[1], operands[2]));
9262
9263 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
9264 gen_rtx_NE (SImode,
9265 cc_reg,
9266 const0_rtx),
9267 gen_rtx_SET (SImode,
9268 operands[0],
9269 GEN_INT (~0))));
9270 DONE;
9271 }
9272 else
9273 {
9274 /* Emit: cmp\\t%1, %2\;mov%D3\\t%0, #0\;mvn%d3\\t%0, #0 */
9275 emit_insn (gen_rtx_SET (VOIDmode,
9276 cc_reg,
9277 gen_rtx_COMPARE (CCmode, operands[1], operands[2])));
9278 enum rtx_code rc = GET_CODE (operands[3]);
9279
9280 rc = reverse_condition (rc);
9281 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
9282 gen_rtx_fmt_ee (rc,
9283 VOIDmode,
9284 cc_reg,
9285 const0_rtx),
9286 gen_rtx_SET (VOIDmode, operands[0], const0_rtx)));
9287 rc = GET_CODE (operands[3]);
9288 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
9289 gen_rtx_fmt_ee (rc,
9290 VOIDmode,
9291 cc_reg,
9292 const0_rtx),
9293 gen_rtx_SET (VOIDmode,
9294 operands[0],
9295 GEN_INT (~0))));
9296 DONE;
9297 }
9298 FAIL;
9299 }
8fa3ba89 9300 [(set_attr "conds" "clob")
1b7da4ac 9301 (set_attr "length" "12")
9302 (set_attr "type" "multiple")]
8fa3ba89 9303)
9c08d1fa 9304
90404b57 9305(define_insn_and_split "movcond_addsi"
9306 [(set (match_operand:SI 0 "s_register_operand" "=r,l,r")
9307 (if_then_else:SI
9308 (match_operator 5 "comparison_operator"
9309 [(plus:SI (match_operand:SI 3 "s_register_operand" "r,r,r")
9310 (match_operand:SI 4 "arm_add_operand" "rIL,rIL,rIL"))
9311 (const_int 0)])
9312 (match_operand:SI 1 "arm_rhs_operand" "rI,rPy,r")
9313 (match_operand:SI 2 "arm_rhs_operand" "rI,rPy,r")))
9314 (clobber (reg:CC CC_REGNUM))]
9315 "TARGET_32BIT"
9316 "#"
9317 "&& reload_completed"
9318 [(set (reg:CC_NOOV CC_REGNUM)
9319 (compare:CC_NOOV
9320 (plus:SI (match_dup 3)
9321 (match_dup 4))
9322 (const_int 0)))
9323 (set (match_dup 0) (match_dup 1))
9324 (cond_exec (match_dup 6)
9325 (set (match_dup 0) (match_dup 2)))]
9326 "
9327 {
9328 enum machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[5]),
9329 operands[3], operands[4]);
9330 enum rtx_code rc = GET_CODE (operands[5]);
90404b57 9331 operands[6] = gen_rtx_REG (mode, CC_REGNUM);
9332 gcc_assert (!(mode == CCFPmode || mode == CCFPEmode));
4d01ce2f 9333 if (REGNO (operands[2]) != REGNO (operands[0]))
9334 rc = reverse_condition (rc);
9335 else
9336 {
9337 rtx tmp = operands[1];
9338 operands[1] = operands[2];
9339 operands[2] = tmp;
9340 }
90404b57 9341
9342 operands[6] = gen_rtx_fmt_ee (rc, VOIDmode, operands[6], const0_rtx);
9343 }
9344 "
9345 [(set_attr "conds" "clob")
1b7da4ac 9346 (set_attr "enabled_for_depr_it" "no,yes,yes")
9347 (set_attr "type" "multiple")]
90404b57 9348)
9349
9c08d1fa 9350(define_insn "movcond"
9351 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
5565501b 9352 (if_then_else:SI
8fa3ba89 9353 (match_operator 5 "arm_comparison_operator"
5565501b 9354 [(match_operand:SI 3 "s_register_operand" "r,r,r")
9355 (match_operand:SI 4 "arm_add_operand" "rIL,rIL,rIL")])
9356 (match_operand:SI 1 "arm_rhs_operand" "0,rI,?rI")
9357 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
bd5b4116 9358 (clobber (reg:CC CC_REGNUM))]
cffb2a26 9359 "TARGET_ARM"
9c08d1fa 9360 "*
9361 if (GET_CODE (operands[5]) == LT
9362 && (operands[4] == const0_rtx))
9363 {
0438d37f 9364 if (which_alternative != 1 && REG_P (operands[1]))
9c08d1fa 9365 {
9c08d1fa 9366 if (operands[2] == const0_rtx)
e2348bcb 9367 return \"and\\t%0, %1, %3, asr #31\";
9368 return \"ands\\t%0, %1, %3, asr #32\;movcc\\t%0, %2\";
9c08d1fa 9369 }
0438d37f 9370 else if (which_alternative != 0 && REG_P (operands[2]))
9c08d1fa 9371 {
9c08d1fa 9372 if (operands[1] == const0_rtx)
e2348bcb 9373 return \"bic\\t%0, %2, %3, asr #31\";
9374 return \"bics\\t%0, %2, %3, asr #32\;movcs\\t%0, %1\";
9c08d1fa 9375 }
9376 /* The only case that falls through to here is when both ops 1 & 2
674a8f0b 9377 are constants. */
9c08d1fa 9378 }
e2348bcb 9379
9c08d1fa 9380 if (GET_CODE (operands[5]) == GE
9381 && (operands[4] == const0_rtx))
9382 {
0438d37f 9383 if (which_alternative != 1 && REG_P (operands[1]))
9c08d1fa 9384 {
9c08d1fa 9385 if (operands[2] == const0_rtx)
e2348bcb 9386 return \"bic\\t%0, %1, %3, asr #31\";
9387 return \"bics\\t%0, %1, %3, asr #32\;movcs\\t%0, %2\";
9c08d1fa 9388 }
0438d37f 9389 else if (which_alternative != 0 && REG_P (operands[2]))
9c08d1fa 9390 {
9c08d1fa 9391 if (operands[1] == const0_rtx)
e2348bcb 9392 return \"and\\t%0, %2, %3, asr #31\";
9393 return \"ands\\t%0, %2, %3, asr #32\;movcc\\t%0, %1\";
9c08d1fa 9394 }
9395 /* The only case that falls through to here is when both ops 1 & 2
674a8f0b 9396 are constants. */
9c08d1fa 9397 }
0438d37f 9398 if (CONST_INT_P (operands[4])
9c08d1fa 9399 && !const_ok_for_arm (INTVAL (operands[4])))
e2348bcb 9400 output_asm_insn (\"cmn\\t%3, #%n4\", operands);
9c08d1fa 9401 else
e2348bcb 9402 output_asm_insn (\"cmp\\t%3, %4\", operands);
9c08d1fa 9403 if (which_alternative != 0)
e2348bcb 9404 output_asm_insn (\"mov%d5\\t%0, %1\", operands);
9c08d1fa 9405 if (which_alternative != 1)
e2348bcb 9406 output_asm_insn (\"mov%D5\\t%0, %2\", operands);
9c08d1fa 9407 return \"\";
215b30b3 9408 "
8fa3ba89 9409 [(set_attr "conds" "clob")
1b7da4ac 9410 (set_attr "length" "8,8,12")
9411 (set_attr "type" "multiple")]
8fa3ba89 9412)
9c08d1fa 9413
25f905c2 9414;; ??? The patterns below need checking for Thumb-2 usefulness.
9415
8a18b90c 9416(define_insn "*ifcompare_plus_move"
9417 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8fa3ba89 9418 (if_then_else:SI (match_operator 6 "arm_comparison_operator"
8a18b90c 9419 [(match_operand:SI 4 "s_register_operand" "r,r")
9420 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
9421 (plus:SI
9422 (match_operand:SI 2 "s_register_operand" "r,r")
9423 (match_operand:SI 3 "arm_add_operand" "rIL,rIL"))
129a2fe4 9424 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))
bd5b4116 9425 (clobber (reg:CC CC_REGNUM))]
cffb2a26 9426 "TARGET_ARM"
8a18b90c 9427 "#"
8fa3ba89 9428 [(set_attr "conds" "clob")
1b7da4ac 9429 (set_attr "length" "8,12")
9430 (set_attr "type" "multiple")]
8fa3ba89 9431)
8a18b90c 9432
9433(define_insn "*if_plus_move"
129a2fe4 9434 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r")
8a18b90c 9435 (if_then_else:SI
8fa3ba89 9436 (match_operator 4 "arm_comparison_operator"
8a18b90c 9437 [(match_operand 5 "cc_register" "") (const_int 0)])
9438 (plus:SI
129a2fe4 9439 (match_operand:SI 2 "s_register_operand" "r,r,r,r")
9440 (match_operand:SI 3 "arm_add_operand" "rI,L,rI,L"))
9441 (match_operand:SI 1 "arm_rhs_operand" "0,0,?rI,?rI")))]
cffb2a26 9442 "TARGET_ARM"
8a18b90c 9443 "@
9444 add%d4\\t%0, %2, %3
9445 sub%d4\\t%0, %2, #%n3
9446 add%d4\\t%0, %2, %3\;mov%D4\\t%0, %1
129a2fe4 9447 sub%d4\\t%0, %2, #%n3\;mov%D4\\t%0, %1"
8fa3ba89 9448 [(set_attr "conds" "use")
9449 (set_attr "length" "4,4,8,8")
65f68e55 9450 (set_attr_alternative "type"
9451 [(if_then_else (match_operand 3 "const_int_operand" "")
d82e788e 9452 (const_string "alu_imm" )
112eda6f 9453 (const_string "alu_sreg"))
d82e788e 9454 (const_string "alu_imm")
112eda6f 9455 (const_string "alu_sreg")
9456 (const_string "alu_sreg")])]
8fa3ba89 9457)
8a18b90c 9458
9459(define_insn "*ifcompare_move_plus"
5565501b 9460 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8fa3ba89 9461 (if_then_else:SI (match_operator 6 "arm_comparison_operator"
8a18b90c 9462 [(match_operand:SI 4 "s_register_operand" "r,r")
9463 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
129a2fe4 9464 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
8a18b90c 9465 (plus:SI
9466 (match_operand:SI 2 "s_register_operand" "r,r")
9467 (match_operand:SI 3 "arm_add_operand" "rIL,rIL"))))
bd5b4116 9468 (clobber (reg:CC CC_REGNUM))]
cffb2a26 9469 "TARGET_ARM"
8a18b90c 9470 "#"
8fa3ba89 9471 [(set_attr "conds" "clob")
1b7da4ac 9472 (set_attr "length" "8,12")
9473 (set_attr "type" "multiple")]
8fa3ba89 9474)
8a18b90c 9475
9476(define_insn "*if_move_plus"
129a2fe4 9477 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r")
8a18b90c 9478 (if_then_else:SI
8fa3ba89 9479 (match_operator 4 "arm_comparison_operator"
8a18b90c 9480 [(match_operand 5 "cc_register" "") (const_int 0)])
129a2fe4 9481 (match_operand:SI 1 "arm_rhs_operand" "0,0,?rI,?rI")
8a18b90c 9482 (plus:SI
129a2fe4 9483 (match_operand:SI 2 "s_register_operand" "r,r,r,r")
9484 (match_operand:SI 3 "arm_add_operand" "rI,L,rI,L"))))]
cffb2a26 9485 "TARGET_ARM"
8a18b90c 9486 "@
9487 add%D4\\t%0, %2, %3
9488 sub%D4\\t%0, %2, #%n3
9489 add%D4\\t%0, %2, %3\;mov%d4\\t%0, %1
129a2fe4 9490 sub%D4\\t%0, %2, #%n3\;mov%d4\\t%0, %1"
8fa3ba89 9491 [(set_attr "conds" "use")
9492 (set_attr "length" "4,4,8,8")
112eda6f 9493 (set_attr "type" "alu_sreg,alu_imm,multiple,multiple")]
8fa3ba89 9494)
8a18b90c 9495
9496(define_insn "*ifcompare_arith_arith"
9497 [(set (match_operand:SI 0 "s_register_operand" "=r")
8fa3ba89 9498 (if_then_else:SI (match_operator 9 "arm_comparison_operator"
8a18b90c 9499 [(match_operand:SI 5 "s_register_operand" "r")
9500 (match_operand:SI 6 "arm_add_operand" "rIL")])
9c08d1fa 9501 (match_operator:SI 8 "shiftable_operator"
8a18b90c 9502 [(match_operand:SI 1 "s_register_operand" "r")
9503 (match_operand:SI 2 "arm_rhs_operand" "rI")])
9c08d1fa 9504 (match_operator:SI 7 "shiftable_operator"
8a18b90c 9505 [(match_operand:SI 3 "s_register_operand" "r")
9506 (match_operand:SI 4 "arm_rhs_operand" "rI")])))
bd5b4116 9507 (clobber (reg:CC CC_REGNUM))]
cffb2a26 9508 "TARGET_ARM"
8a18b90c 9509 "#"
8fa3ba89 9510 [(set_attr "conds" "clob")
1b7da4ac 9511 (set_attr "length" "12")
9512 (set_attr "type" "multiple")]
8fa3ba89 9513)
9c08d1fa 9514
8a18b90c 9515(define_insn "*if_arith_arith"
9516 [(set (match_operand:SI 0 "s_register_operand" "=r")
8fa3ba89 9517 (if_then_else:SI (match_operator 5 "arm_comparison_operator"
8a18b90c 9518 [(match_operand 8 "cc_register" "") (const_int 0)])
9519 (match_operator:SI 6 "shiftable_operator"
9520 [(match_operand:SI 1 "s_register_operand" "r")
9521 (match_operand:SI 2 "arm_rhs_operand" "rI")])
9522 (match_operator:SI 7 "shiftable_operator"
9523 [(match_operand:SI 3 "s_register_operand" "r")
9524 (match_operand:SI 4 "arm_rhs_operand" "rI")])))]
cffb2a26 9525 "TARGET_ARM"
8a18b90c 9526 "%I6%d5\\t%0, %1, %2\;%I7%D5\\t%0, %3, %4"
8fa3ba89 9527 [(set_attr "conds" "use")
1b7da4ac 9528 (set_attr "length" "8")
9529 (set_attr "type" "multiple")]
8fa3ba89 9530)
8a18b90c 9531
f7fbdd4a 9532(define_insn "*ifcompare_arith_move"
9c08d1fa 9533 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8fa3ba89 9534 (if_then_else:SI (match_operator 6 "arm_comparison_operator"
9c08d1fa 9535 [(match_operand:SI 2 "s_register_operand" "r,r")
5565501b 9536 (match_operand:SI 3 "arm_add_operand" "rIL,rIL")])
9c08d1fa 9537 (match_operator:SI 7 "shiftable_operator"
9538 [(match_operand:SI 4 "s_register_operand" "r,r")
9539 (match_operand:SI 5 "arm_rhs_operand" "rI,rI")])
129a2fe4 9540 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))
bd5b4116 9541 (clobber (reg:CC CC_REGNUM))]
cffb2a26 9542 "TARGET_ARM"
9c08d1fa 9543 "*
9c08d1fa 9544 /* If we have an operation where (op x 0) is the identity operation and
01cc3b75 9545 the conditional operator is LT or GE and we are comparing against zero and
674a8f0b 9546 everything is in registers then we can do this in two instructions. */
9c08d1fa 9547 if (operands[3] == const0_rtx
9548 && GET_CODE (operands[7]) != AND
0438d37f 9549 && REG_P (operands[5])
9550 && REG_P (operands[1])
9c08d1fa 9551 && REGNO (operands[1]) == REGNO (operands[4])
9552 && REGNO (operands[4]) != REGNO (operands[0]))
9553 {
9554 if (GET_CODE (operands[6]) == LT)
40dbec34 9555 return \"and\\t%0, %5, %2, asr #31\;%I7\\t%0, %4, %0\";
9c08d1fa 9556 else if (GET_CODE (operands[6]) == GE)
40dbec34 9557 return \"bic\\t%0, %5, %2, asr #31\;%I7\\t%0, %4, %0\";
9c08d1fa 9558 }
0438d37f 9559 if (CONST_INT_P (operands[3])
9c08d1fa 9560 && !const_ok_for_arm (INTVAL (operands[3])))
e2348bcb 9561 output_asm_insn (\"cmn\\t%2, #%n3\", operands);
9c08d1fa 9562 else
e2348bcb 9563 output_asm_insn (\"cmp\\t%2, %3\", operands);
40dbec34 9564 output_asm_insn (\"%I7%d6\\t%0, %4, %5\", operands);
9c08d1fa 9565 if (which_alternative != 0)
129a2fe4 9566 return \"mov%D6\\t%0, %1\";
9c08d1fa 9567 return \"\";
215b30b3 9568 "
8fa3ba89 9569 [(set_attr "conds" "clob")
1b7da4ac 9570 (set_attr "length" "8,12")
9571 (set_attr "type" "multiple")]
8fa3ba89 9572)
9c08d1fa 9573
8a18b90c 9574(define_insn "*if_arith_move"
129a2fe4 9575 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8fa3ba89 9576 (if_then_else:SI (match_operator 4 "arm_comparison_operator"
8a18b90c 9577 [(match_operand 6 "cc_register" "") (const_int 0)])
9578 (match_operator:SI 5 "shiftable_operator"
129a2fe4 9579 [(match_operand:SI 2 "s_register_operand" "r,r")
9580 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
9581 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))]
cffb2a26 9582 "TARGET_ARM"
8a18b90c 9583 "@
9584 %I5%d4\\t%0, %2, %3
129a2fe4 9585 %I5%d4\\t%0, %2, %3\;mov%D4\\t%0, %1"
8fa3ba89 9586 [(set_attr "conds" "use")
9587 (set_attr "length" "4,8")
1b7da4ac 9588 (set_attr "type" "alu_shift_reg,multiple")]
8fa3ba89 9589)
8a18b90c 9590
f7fbdd4a 9591(define_insn "*ifcompare_move_arith"
9c08d1fa 9592 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8fa3ba89 9593 (if_then_else:SI (match_operator 6 "arm_comparison_operator"
9c08d1fa 9594 [(match_operand:SI 4 "s_register_operand" "r,r")
5565501b 9595 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
129a2fe4 9596 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
9c08d1fa 9597 (match_operator:SI 7 "shiftable_operator"
9598 [(match_operand:SI 2 "s_register_operand" "r,r")
9599 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))
bd5b4116 9600 (clobber (reg:CC CC_REGNUM))]
cffb2a26 9601 "TARGET_ARM"
9c08d1fa 9602 "*
9c08d1fa 9603 /* If we have an operation where (op x 0) is the identity operation and
01cc3b75 9604 the conditional operator is LT or GE and we are comparing against zero and
9c08d1fa 9605 everything is in registers then we can do this in two instructions */
9606 if (operands[5] == const0_rtx
9607 && GET_CODE (operands[7]) != AND
0438d37f 9608 && REG_P (operands[3])
9609 && REG_P (operands[1])
9c08d1fa 9610 && REGNO (operands[1]) == REGNO (operands[2])
9611 && REGNO (operands[2]) != REGNO (operands[0]))
9612 {
9613 if (GET_CODE (operands[6]) == GE)
40dbec34 9614 return \"and\\t%0, %3, %4, asr #31\;%I7\\t%0, %2, %0\";
9c08d1fa 9615 else if (GET_CODE (operands[6]) == LT)
40dbec34 9616 return \"bic\\t%0, %3, %4, asr #31\;%I7\\t%0, %2, %0\";
9c08d1fa 9617 }
40dbec34 9618
0438d37f 9619 if (CONST_INT_P (operands[5])
9c08d1fa 9620 && !const_ok_for_arm (INTVAL (operands[5])))
e2348bcb 9621 output_asm_insn (\"cmn\\t%4, #%n5\", operands);
9c08d1fa 9622 else
e2348bcb 9623 output_asm_insn (\"cmp\\t%4, %5\", operands);
40dbec34 9624
9c08d1fa 9625 if (which_alternative != 0)
129a2fe4 9626 output_asm_insn (\"mov%d6\\t%0, %1\", operands);
40dbec34 9627 return \"%I7%D6\\t%0, %2, %3\";
215b30b3 9628 "
8fa3ba89 9629 [(set_attr "conds" "clob")
1b7da4ac 9630 (set_attr "length" "8,12")
9631 (set_attr "type" "multiple")]
8fa3ba89 9632)
9c08d1fa 9633
8a18b90c 9634(define_insn "*if_move_arith"
129a2fe4 9635 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8a18b90c 9636 (if_then_else:SI
8fa3ba89 9637 (match_operator 4 "arm_comparison_operator"
8a18b90c 9638 [(match_operand 6 "cc_register" "") (const_int 0)])
129a2fe4 9639 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
8a18b90c 9640 (match_operator:SI 5 "shiftable_operator"
129a2fe4 9641 [(match_operand:SI 2 "s_register_operand" "r,r")
9642 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))]
cffb2a26 9643 "TARGET_ARM"
8a18b90c 9644 "@
9645 %I5%D4\\t%0, %2, %3
129a2fe4 9646 %I5%D4\\t%0, %2, %3\;mov%d4\\t%0, %1"
8fa3ba89 9647 [(set_attr "conds" "use")
9648 (set_attr "length" "4,8")
1b7da4ac 9649 (set_attr "type" "alu_shift_reg,multiple")]
8fa3ba89 9650)
8a18b90c 9651
9652(define_insn "*ifcompare_move_not"
9c08d1fa 9653 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8a18b90c 9654 (if_then_else:SI
8fa3ba89 9655 (match_operator 5 "arm_comparison_operator"
8a18b90c 9656 [(match_operand:SI 3 "s_register_operand" "r,r")
9657 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
9658 (match_operand:SI 1 "arm_not_operand" "0,?rIK")
9659 (not:SI
9660 (match_operand:SI 2 "s_register_operand" "r,r"))))
bd5b4116 9661 (clobber (reg:CC CC_REGNUM))]
cffb2a26 9662 "TARGET_ARM"
8a18b90c 9663 "#"
8fa3ba89 9664 [(set_attr "conds" "clob")
1b7da4ac 9665 (set_attr "length" "8,12")
9666 (set_attr "type" "multiple")]
8fa3ba89 9667)
9c08d1fa 9668
8a18b90c 9669(define_insn "*if_move_not"
9670 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9671 (if_then_else:SI
8fa3ba89 9672 (match_operator 4 "arm_comparison_operator"
8a18b90c 9673 [(match_operand 3 "cc_register" "") (const_int 0)])
9674 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")
9675 (not:SI (match_operand:SI 2 "s_register_operand" "r,r,r"))))]
cffb2a26 9676 "TARGET_ARM"
8a18b90c 9677 "@
9678 mvn%D4\\t%0, %2
9679 mov%d4\\t%0, %1\;mvn%D4\\t%0, %2
9680 mvn%d4\\t%0, #%B1\;mvn%D4\\t%0, %2"
8fa3ba89 9681 [(set_attr "conds" "use")
1aed5204 9682 (set_attr "type" "mvn_reg")
1b7da4ac 9683 (set_attr "length" "4,8,8")
9684 (set_attr "type" "mvn_reg,multiple,multiple")]
8fa3ba89 9685)
8a18b90c 9686
9687(define_insn "*ifcompare_not_move"
9c08d1fa 9688 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8a18b90c 9689 (if_then_else:SI
8fa3ba89 9690 (match_operator 5 "arm_comparison_operator"
8a18b90c 9691 [(match_operand:SI 3 "s_register_operand" "r,r")
9692 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
9693 (not:SI
9694 (match_operand:SI 2 "s_register_operand" "r,r"))
9695 (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
bd5b4116 9696 (clobber (reg:CC CC_REGNUM))]
cffb2a26 9697 "TARGET_ARM"
8a18b90c 9698 "#"
8fa3ba89 9699 [(set_attr "conds" "clob")
1b7da4ac 9700 (set_attr "length" "8,12")
9701 (set_attr "type" "multiple")]
8fa3ba89 9702)
9c08d1fa 9703
8a18b90c 9704(define_insn "*if_not_move"
9705 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9706 (if_then_else:SI
8fa3ba89 9707 (match_operator 4 "arm_comparison_operator"
8a18b90c 9708 [(match_operand 3 "cc_register" "") (const_int 0)])
9709 (not:SI (match_operand:SI 2 "s_register_operand" "r,r,r"))
9710 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")))]
cffb2a26 9711 "TARGET_ARM"
8a18b90c 9712 "@
9713 mvn%d4\\t%0, %2
9714 mov%D4\\t%0, %1\;mvn%d4\\t%0, %2
9715 mvn%D4\\t%0, #%B1\;mvn%d4\\t%0, %2"
8fa3ba89 9716 [(set_attr "conds" "use")
1b7da4ac 9717 (set_attr "type" "mvn_reg,multiple,multiple")
8fa3ba89 9718 (set_attr "length" "4,8,8")]
9719)
8a18b90c 9720
9721(define_insn "*ifcompare_shift_move"
9c08d1fa 9722 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8a18b90c 9723 (if_then_else:SI
8fa3ba89 9724 (match_operator 6 "arm_comparison_operator"
8a18b90c 9725 [(match_operand:SI 4 "s_register_operand" "r,r")
9726 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
9727 (match_operator:SI 7 "shift_operator"
9728 [(match_operand:SI 2 "s_register_operand" "r,r")
9729 (match_operand:SI 3 "arm_rhs_operand" "rM,rM")])
9730 (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
bd5b4116 9731 (clobber (reg:CC CC_REGNUM))]
cffb2a26 9732 "TARGET_ARM"
9c08d1fa 9733 "#"
8fa3ba89 9734 [(set_attr "conds" "clob")
1b7da4ac 9735 (set_attr "length" "8,12")
9736 (set_attr "type" "multiple")]
8fa3ba89 9737)
9c08d1fa 9738
8a18b90c 9739(define_insn "*if_shift_move"
9740 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9741 (if_then_else:SI
8fa3ba89 9742 (match_operator 5 "arm_comparison_operator"
8a18b90c 9743 [(match_operand 6 "cc_register" "") (const_int 0)])
9744 (match_operator:SI 4 "shift_operator"
9745 [(match_operand:SI 2 "s_register_operand" "r,r,r")
9746 (match_operand:SI 3 "arm_rhs_operand" "rM,rM,rM")])
9747 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")))]
cffb2a26 9748 "TARGET_ARM"
5565501b 9749 "@
8a18b90c 9750 mov%d5\\t%0, %2%S4
9751 mov%D5\\t%0, %1\;mov%d5\\t%0, %2%S4
9752 mvn%D5\\t%0, #%B1\;mov%d5\\t%0, %2%S4"
8fa3ba89 9753 [(set_attr "conds" "use")
331beb1a 9754 (set_attr "shift" "2")
a2cd141b 9755 (set_attr "length" "4,8,8")
1b7da4ac 9756 (set_attr "type" "mov_shift_reg,multiple,multiple")]
8fa3ba89 9757)
5565501b 9758
8a18b90c 9759(define_insn "*ifcompare_move_shift"
9760 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5565501b 9761 (if_then_else:SI
8fa3ba89 9762 (match_operator 6 "arm_comparison_operator"
8a18b90c 9763 [(match_operand:SI 4 "s_register_operand" "r,r")
9764 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
9765 (match_operand:SI 1 "arm_not_operand" "0,?rIK")
5565501b 9766 (match_operator:SI 7 "shift_operator"
8a18b90c 9767 [(match_operand:SI 2 "s_register_operand" "r,r")
9768 (match_operand:SI 3 "arm_rhs_operand" "rM,rM")])))
bd5b4116 9769 (clobber (reg:CC CC_REGNUM))]
cffb2a26 9770 "TARGET_ARM"
8a18b90c 9771 "#"
8fa3ba89 9772 [(set_attr "conds" "clob")
1b7da4ac 9773 (set_attr "length" "8,12")
9774 (set_attr "type" "multiple")]
8fa3ba89 9775)
5565501b 9776
8a18b90c 9777(define_insn "*if_move_shift"
9778 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
5565501b 9779 (if_then_else:SI
8fa3ba89 9780 (match_operator 5 "arm_comparison_operator"
8a18b90c 9781 [(match_operand 6 "cc_register" "") (const_int 0)])
9782 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")
9783 (match_operator:SI 4 "shift_operator"
9784 [(match_operand:SI 2 "s_register_operand" "r,r,r")
9785 (match_operand:SI 3 "arm_rhs_operand" "rM,rM,rM")])))]
cffb2a26 9786 "TARGET_ARM"
5565501b 9787 "@
8a18b90c 9788 mov%D5\\t%0, %2%S4
9789 mov%d5\\t%0, %1\;mov%D5\\t%0, %2%S4
9790 mvn%d5\\t%0, #%B1\;mov%D5\\t%0, %2%S4"
8fa3ba89 9791 [(set_attr "conds" "use")
331beb1a 9792 (set_attr "shift" "2")
a2cd141b 9793 (set_attr "length" "4,8,8")
1b7da4ac 9794 (set_attr "type" "mov_shift_reg,multiple,multiple")]
8fa3ba89 9795)
9c08d1fa 9796
f7fbdd4a 9797(define_insn "*ifcompare_shift_shift"
8a18b90c 9798 [(set (match_operand:SI 0 "s_register_operand" "=r")
5565501b 9799 (if_then_else:SI
8fa3ba89 9800 (match_operator 7 "arm_comparison_operator"
8a18b90c 9801 [(match_operand:SI 5 "s_register_operand" "r")
9802 (match_operand:SI 6 "arm_add_operand" "rIL")])
5565501b 9803 (match_operator:SI 8 "shift_operator"
8a18b90c 9804 [(match_operand:SI 1 "s_register_operand" "r")
9805 (match_operand:SI 2 "arm_rhs_operand" "rM")])
5565501b 9806 (match_operator:SI 9 "shift_operator"
8a18b90c 9807 [(match_operand:SI 3 "s_register_operand" "r")
9808 (match_operand:SI 4 "arm_rhs_operand" "rM")])))
bd5b4116 9809 (clobber (reg:CC CC_REGNUM))]
cffb2a26 9810 "TARGET_ARM"
8a18b90c 9811 "#"
8fa3ba89 9812 [(set_attr "conds" "clob")
1b7da4ac 9813 (set_attr "length" "12")
9814 (set_attr "type" "multiple")]
8fa3ba89 9815)
9c08d1fa 9816
8a18b90c 9817(define_insn "*if_shift_shift"
9818 [(set (match_operand:SI 0 "s_register_operand" "=r")
9819 (if_then_else:SI
8fa3ba89 9820 (match_operator 5 "arm_comparison_operator"
8a18b90c 9821 [(match_operand 8 "cc_register" "") (const_int 0)])
9822 (match_operator:SI 6 "shift_operator"
9823 [(match_operand:SI 1 "s_register_operand" "r")
9824 (match_operand:SI 2 "arm_rhs_operand" "rM")])
9825 (match_operator:SI 7 "shift_operator"
9826 [(match_operand:SI 3 "s_register_operand" "r")
9827 (match_operand:SI 4 "arm_rhs_operand" "rM")])))]
cffb2a26 9828 "TARGET_ARM"
8a18b90c 9829 "mov%d5\\t%0, %1%S6\;mov%D5\\t%0, %3%S7"
8fa3ba89 9830 [(set_attr "conds" "use")
331beb1a 9831 (set_attr "shift" "1")
a2cd141b 9832 (set_attr "length" "8")
9833 (set (attr "type") (if_then_else
9834 (and (match_operand 2 "const_int_operand" "")
9835 (match_operand 4 "const_int_operand" ""))
1aed5204 9836 (const_string "mov_shift")
9837 (const_string "mov_shift_reg")))]
8fa3ba89 9838)
8a18b90c 9839
f7fbdd4a 9840(define_insn "*ifcompare_not_arith"
8a18b90c 9841 [(set (match_operand:SI 0 "s_register_operand" "=r")
5565501b 9842 (if_then_else:SI
8fa3ba89 9843 (match_operator 6 "arm_comparison_operator"
8a18b90c 9844 [(match_operand:SI 4 "s_register_operand" "r")
9845 (match_operand:SI 5 "arm_add_operand" "rIL")])
9846 (not:SI (match_operand:SI 1 "s_register_operand" "r"))
5565501b 9847 (match_operator:SI 7 "shiftable_operator"
8a18b90c 9848 [(match_operand:SI 2 "s_register_operand" "r")
9849 (match_operand:SI 3 "arm_rhs_operand" "rI")])))
bd5b4116 9850 (clobber (reg:CC CC_REGNUM))]
cffb2a26 9851 "TARGET_ARM"
8a18b90c 9852 "#"
8fa3ba89 9853 [(set_attr "conds" "clob")
1b7da4ac 9854 (set_attr "length" "12")
9855 (set_attr "type" "multiple")]
8fa3ba89 9856)
9c08d1fa 9857
8a18b90c 9858(define_insn "*if_not_arith"
9859 [(set (match_operand:SI 0 "s_register_operand" "=r")
9860 (if_then_else:SI
8fa3ba89 9861 (match_operator 5 "arm_comparison_operator"
8a18b90c 9862 [(match_operand 4 "cc_register" "") (const_int 0)])
9863 (not:SI (match_operand:SI 1 "s_register_operand" "r"))
9864 (match_operator:SI 6 "shiftable_operator"
9865 [(match_operand:SI 2 "s_register_operand" "r")
9866 (match_operand:SI 3 "arm_rhs_operand" "rI")])))]
cffb2a26 9867 "TARGET_ARM"
8a18b90c 9868 "mvn%d5\\t%0, %1\;%I6%D5\\t%0, %2, %3"
8fa3ba89 9869 [(set_attr "conds" "use")
1aed5204 9870 (set_attr "type" "mvn_reg")
8fa3ba89 9871 (set_attr "length" "8")]
9872)
8a18b90c 9873
9874(define_insn "*ifcompare_arith_not"
9875 [(set (match_operand:SI 0 "s_register_operand" "=r")
5565501b 9876 (if_then_else:SI
8fa3ba89 9877 (match_operator 6 "arm_comparison_operator"
8a18b90c 9878 [(match_operand:SI 4 "s_register_operand" "r")
9879 (match_operand:SI 5 "arm_add_operand" "rIL")])
5565501b 9880 (match_operator:SI 7 "shiftable_operator"
8a18b90c 9881 [(match_operand:SI 2 "s_register_operand" "r")
9882 (match_operand:SI 3 "arm_rhs_operand" "rI")])
9883 (not:SI (match_operand:SI 1 "s_register_operand" "r"))))
bd5b4116 9884 (clobber (reg:CC CC_REGNUM))]
cffb2a26 9885 "TARGET_ARM"
8a18b90c 9886 "#"
8fa3ba89 9887 [(set_attr "conds" "clob")
1b7da4ac 9888 (set_attr "length" "12")
9889 (set_attr "type" "multiple")]
8fa3ba89 9890)
9c08d1fa 9891
8a18b90c 9892(define_insn "*if_arith_not"
9893 [(set (match_operand:SI 0 "s_register_operand" "=r")
9894 (if_then_else:SI
8fa3ba89 9895 (match_operator 5 "arm_comparison_operator"
8a18b90c 9896 [(match_operand 4 "cc_register" "") (const_int 0)])
9897 (match_operator:SI 6 "shiftable_operator"
9898 [(match_operand:SI 2 "s_register_operand" "r")
9899 (match_operand:SI 3 "arm_rhs_operand" "rI")])
9900 (not:SI (match_operand:SI 1 "s_register_operand" "r"))))]
cffb2a26 9901 "TARGET_ARM"
8a18b90c 9902 "mvn%D5\\t%0, %1\;%I6%d5\\t%0, %2, %3"
8fa3ba89 9903 [(set_attr "conds" "use")
1b7da4ac 9904 (set_attr "type" "multiple")
8fa3ba89 9905 (set_attr "length" "8")]
9906)
8a18b90c 9907
f7fbdd4a 9908(define_insn "*ifcompare_neg_move"
8a18b90c 9909 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5565501b 9910 (if_then_else:SI
8fa3ba89 9911 (match_operator 5 "arm_comparison_operator"
8a18b90c 9912 [(match_operand:SI 3 "s_register_operand" "r,r")
9913 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
9914 (neg:SI (match_operand:SI 2 "s_register_operand" "r,r"))
9915 (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
bd5b4116 9916 (clobber (reg:CC CC_REGNUM))]
cffb2a26 9917 "TARGET_ARM"
8a18b90c 9918 "#"
8fa3ba89 9919 [(set_attr "conds" "clob")
1b7da4ac 9920 (set_attr "length" "8,12")
9921 (set_attr "type" "multiple")]
8fa3ba89 9922)
8a18b90c 9923
9924(define_insn "*if_neg_move"
9925 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9926 (if_then_else:SI
8fa3ba89 9927 (match_operator 4 "arm_comparison_operator"
8a18b90c 9928 [(match_operand 3 "cc_register" "") (const_int 0)])
9929 (neg:SI (match_operand:SI 2 "s_register_operand" "r,r,r"))
9930 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")))]
cffb2a26 9931 "TARGET_ARM"
8a18b90c 9932 "@
9933 rsb%d4\\t%0, %2, #0
9934 mov%D4\\t%0, %1\;rsb%d4\\t%0, %2, #0
9935 mvn%D4\\t%0, #%B1\;rsb%d4\\t%0, %2, #0"
8fa3ba89 9936 [(set_attr "conds" "use")
1b7da4ac 9937 (set_attr "length" "4,8,8")
9938 (set_attr "type" "logic_shift_imm,multiple,multiple")]
8fa3ba89 9939)
9c08d1fa 9940
f7fbdd4a 9941(define_insn "*ifcompare_move_neg"
8a18b90c 9942 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5565501b 9943 (if_then_else:SI
8fa3ba89 9944 (match_operator 5 "arm_comparison_operator"
8a18b90c 9945 [(match_operand:SI 3 "s_register_operand" "r,r")
9946 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
9947 (match_operand:SI 1 "arm_not_operand" "0,?rIK")
9948 (neg:SI (match_operand:SI 2 "s_register_operand" "r,r"))))
bd5b4116 9949 (clobber (reg:CC CC_REGNUM))]
cffb2a26 9950 "TARGET_ARM"
8a18b90c 9951 "#"
8fa3ba89 9952 [(set_attr "conds" "clob")
1b7da4ac 9953 (set_attr "length" "8,12")
9954 (set_attr "type" "multiple")]
8fa3ba89 9955)
8a18b90c 9956
9957(define_insn "*if_move_neg"
9958 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9959 (if_then_else:SI
8fa3ba89 9960 (match_operator 4 "arm_comparison_operator"
8a18b90c 9961 [(match_operand 3 "cc_register" "") (const_int 0)])
9962 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")
9963 (neg:SI (match_operand:SI 2 "s_register_operand" "r,r,r"))))]
cffb2a26 9964 "TARGET_ARM"
8a18b90c 9965 "@
9966 rsb%D4\\t%0, %2, #0
9967 mov%d4\\t%0, %1\;rsb%D4\\t%0, %2, #0
9968 mvn%d4\\t%0, #%B1\;rsb%D4\\t%0, %2, #0"
0d66636f 9969 [(set_attr "conds" "use")
1b7da4ac 9970 (set_attr "length" "4,8,8")
9971 (set_attr "type" "logic_shift_imm,multiple,multiple")]
0d66636f 9972)
9c08d1fa 9973
f7fbdd4a 9974(define_insn "*arith_adjacentmem"
9c08d1fa 9975 [(set (match_operand:SI 0 "s_register_operand" "=r")
9976 (match_operator:SI 1 "shiftable_operator"
9977 [(match_operand:SI 2 "memory_operand" "m")
9978 (match_operand:SI 3 "memory_operand" "m")]))
9979 (clobber (match_scratch:SI 4 "=r"))]
cffb2a26 9980 "TARGET_ARM && adjacent_mem_locations (operands[2], operands[3])"
9c08d1fa 9981 "*
215b30b3 9982 {
9983 rtx ldm[3];
9984 rtx arith[4];
94dee231 9985 rtx base_reg;
9986 HOST_WIDE_INT val1 = 0, val2 = 0;
9c08d1fa 9987
215b30b3 9988 if (REGNO (operands[0]) > REGNO (operands[4]))
9989 {
9990 ldm[1] = operands[4];
9991 ldm[2] = operands[0];
9992 }
9993 else
9994 {
9995 ldm[1] = operands[0];
9996 ldm[2] = operands[4];
9997 }
94dee231 9998
9999 base_reg = XEXP (operands[2], 0);
10000
10001 if (!REG_P (base_reg))
10002 {
10003 val1 = INTVAL (XEXP (base_reg, 1));
10004 base_reg = XEXP (base_reg, 0);
10005 }
10006
10007 if (!REG_P (XEXP (operands[3], 0)))
215b30b3 10008 val2 = INTVAL (XEXP (XEXP (operands[3], 0), 1));
94dee231 10009
215b30b3 10010 arith[0] = operands[0];
10011 arith[3] = operands[1];
94dee231 10012
215b30b3 10013 if (val1 < val2)
10014 {
10015 arith[1] = ldm[1];
10016 arith[2] = ldm[2];
10017 }
10018 else
10019 {
10020 arith[1] = ldm[2];
10021 arith[2] = ldm[1];
10022 }
94dee231 10023
10024 ldm[0] = base_reg;
10025 if (val1 !=0 && val2 != 0)
215b30b3 10026 {
cdb1295a 10027 rtx ops[3];
10028
94dee231 10029 if (val1 == 4 || val2 == 4)
10030 /* Other val must be 8, since we know they are adjacent and neither
10031 is zero. */
25f905c2 10032 output_asm_insn (\"ldm%(ib%)\\t%0, {%1, %2}\", ldm);
cdb1295a 10033 else if (const_ok_for_arm (val1) || const_ok_for_arm (-val1))
94dee231 10034 {
94dee231 10035 ldm[0] = ops[0] = operands[4];
10036 ops[1] = base_reg;
10037 ops[2] = GEN_INT (val1);
10038 output_add_immediate (ops);
10039 if (val1 < val2)
25f905c2 10040 output_asm_insn (\"ldm%(ia%)\\t%0, {%1, %2}\", ldm);
94dee231 10041 else
25f905c2 10042 output_asm_insn (\"ldm%(da%)\\t%0, {%1, %2}\", ldm);
94dee231 10043 }
cdb1295a 10044 else
10045 {
10046 /* Offset is out of range for a single add, so use two ldr. */
10047 ops[0] = ldm[1];
10048 ops[1] = base_reg;
10049 ops[2] = GEN_INT (val1);
10050 output_asm_insn (\"ldr%?\\t%0, [%1, %2]\", ops);
10051 ops[0] = ldm[2];
10052 ops[2] = GEN_INT (val2);
10053 output_asm_insn (\"ldr%?\\t%0, [%1, %2]\", ops);
10054 }
215b30b3 10055 }
94dee231 10056 else if (val1 != 0)
215b30b3 10057 {
215b30b3 10058 if (val1 < val2)
25f905c2 10059 output_asm_insn (\"ldm%(da%)\\t%0, {%1, %2}\", ldm);
215b30b3 10060 else
25f905c2 10061 output_asm_insn (\"ldm%(ia%)\\t%0, {%1, %2}\", ldm);
215b30b3 10062 }
10063 else
10064 {
215b30b3 10065 if (val1 < val2)
25f905c2 10066 output_asm_insn (\"ldm%(ia%)\\t%0, {%1, %2}\", ldm);
215b30b3 10067 else
25f905c2 10068 output_asm_insn (\"ldm%(da%)\\t%0, {%1, %2}\", ldm);
215b30b3 10069 }
10070 output_asm_insn (\"%I3%?\\t%0, %1, %2\", arith);
10071 return \"\";
10072 }"
10073 [(set_attr "length" "12")
10074 (set_attr "predicable" "yes")
a2cd141b 10075 (set_attr "type" "load1")]
215b30b3 10076)
9c08d1fa 10077
9c08d1fa 10078; This pattern is never tried by combine, so do it as a peephole
10079
a0f94409 10080(define_peephole2
372575c7 10081 [(set (match_operand:SI 0 "arm_general_register_operand" "")
10082 (match_operand:SI 1 "arm_general_register_operand" ""))
bd5b4116 10083 (set (reg:CC CC_REGNUM)
aea4c774 10084 (compare:CC (match_dup 1) (const_int 0)))]
372575c7 10085 "TARGET_ARM"
a0f94409 10086 [(parallel [(set (reg:CC CC_REGNUM) (compare:CC (match_dup 1) (const_int 0)))
10087 (set (match_dup 0) (match_dup 1))])]
10088 ""
0d66636f 10089)
9c08d1fa 10090
9c08d1fa 10091(define_split
10092 [(set (match_operand:SI 0 "s_register_operand" "")
10093 (and:SI (ge:SI (match_operand:SI 1 "s_register_operand" "")
10094 (const_int 0))
8fa3ba89 10095 (neg:SI (match_operator:SI 2 "arm_comparison_operator"
9c08d1fa 10096 [(match_operand:SI 3 "s_register_operand" "")
10097 (match_operand:SI 4 "arm_rhs_operand" "")]))))
10098 (clobber (match_operand:SI 5 "s_register_operand" ""))]
cffb2a26 10099 "TARGET_ARM"
9c08d1fa 10100 [(set (match_dup 5) (not:SI (ashiftrt:SI (match_dup 1) (const_int 31))))
10101 (set (match_dup 0) (and:SI (match_op_dup 2 [(match_dup 3) (match_dup 4)])
10102 (match_dup 5)))]
215b30b3 10103 ""
10104)
9c08d1fa 10105
aea4c774 10106;; This split can be used because CC_Z mode implies that the following
10107;; branch will be an equality, or an unsigned inequality, so the sign
10108;; extension is not needed.
9c08d1fa 10109
aea4c774 10110(define_split
bd5b4116 10111 [(set (reg:CC_Z CC_REGNUM)
aea4c774 10112 (compare:CC_Z
10113 (ashift:SI (subreg:SI (match_operand:QI 0 "memory_operand" "") 0)
9c08d1fa 10114 (const_int 24))
aea4c774 10115 (match_operand 1 "const_int_operand" "")))
10116 (clobber (match_scratch:SI 2 ""))]
cffb2a26 10117 "TARGET_ARM
10118 && (((unsigned HOST_WIDE_INT) INTVAL (operands[1]))
10119 == (((unsigned HOST_WIDE_INT) INTVAL (operands[1])) >> 24) << 24)"
aea4c774 10120 [(set (match_dup 2) (zero_extend:SI (match_dup 0)))
bd5b4116 10121 (set (reg:CC CC_REGNUM) (compare:CC (match_dup 2) (match_dup 1)))]
aea4c774 10122 "
9c08d1fa 10123 operands[1] = GEN_INT (((unsigned long) INTVAL (operands[1])) >> 24);
215b30b3 10124 "
10125)
25f905c2 10126;; ??? Check the patterns above for Thumb-2 usefulness
9c08d1fa 10127
87b22bf7 10128(define_expand "prologue"
10129 [(clobber (const_int 0))]
cffb2a26 10130 "TARGET_EITHER"
25f905c2 10131 "if (TARGET_32BIT)
cffb2a26 10132 arm_expand_prologue ();
10133 else
25f905c2 10134 thumb1_expand_prologue ();
87b22bf7 10135 DONE;
cffb2a26 10136 "
10137)
87b22bf7 10138
56d27660 10139(define_expand "epilogue"
4c44712e 10140 [(clobber (const_int 0))]
cffb2a26 10141 "TARGET_EITHER"
56d27660 10142 "
18d50ae6 10143 if (crtl->calls_eh_return)
fb94f18b 10144 emit_insn (gen_force_register_use (gen_rtx_REG (Pmode, 2)));
25f905c2 10145 if (TARGET_THUMB1)
c3635784 10146 {
10147 thumb1_expand_epilogue ();
10148 emit_jump_insn (gen_rtx_UNSPEC_VOLATILE (VOIDmode,
10149 gen_rtvec (1, ret_rtx), VUNSPEC_EPILOGUE));
10150 }
10151 else if (HAVE_return)
10152 {
10153 /* HAVE_return is testing for USE_RETURN_INSN (FALSE). Hence,
10154 no need for explicit testing again. */
10155 emit_jump_insn (gen_return ());
10156 }
10157 else if (TARGET_32BIT)
10158 {
10159 arm_expand_epilogue (true);
10160 }
cffb2a26 10161 DONE;
10162 "
10163)
56d27660 10164
ef5651d0 10165;; Note - although unspec_volatile's USE all hard registers,
10166;; USEs are ignored after relaod has completed. Thus we need
10167;; to add an unspec of the link register to ensure that flow
10168;; does not think that it is unused by the sibcall branch that
10169;; will replace the standard function epilogue.
c3635784 10170(define_expand "sibcall_epilogue"
fb94f18b 10171 [(parallel [(unspec:SI [(reg:SI LR_REGNUM)] UNSPEC_REGISTER_USE)
c3635784 10172 (unspec_volatile [(return)] VUNSPEC_EPILOGUE)])]
10173 "TARGET_32BIT"
10174 "
10175 arm_expand_epilogue (false);
10176 DONE;
10177 "
1c494086 10178)
10179
cffb2a26 10180(define_expand "eh_epilogue"
7db9af5d 10181 [(use (match_operand:SI 0 "register_operand" ""))
10182 (use (match_operand:SI 1 "register_operand" ""))
10183 (use (match_operand:SI 2 "register_operand" ""))]
cffb2a26 10184 "TARGET_EITHER"
10185 "
215b30b3 10186 {
10187 cfun->machine->eh_epilogue_sp_ofs = operands[1];
0438d37f 10188 if (!REG_P (operands[2]) || REGNO (operands[2]) != 2)
215b30b3 10189 {
10190 rtx ra = gen_rtx_REG (Pmode, 2);
10191
10192 emit_move_insn (ra, operands[2]);
10193 operands[2] = ra;
10194 }
5cf3595a 10195 /* This is a hack -- we may have crystalized the function type too
10196 early. */
10197 cfun->machine->func_type = 0;
215b30b3 10198 }"
10199)
56d27660 10200
9c08d1fa 10201;; This split is only used during output to reduce the number of patterns
10202;; that need assembler instructions adding to them. We allowed the setting
10203;; of the conditions to be implicit during rtl generation so that
10204;; the conditional compare patterns would work. However this conflicts to
8a18b90c 10205;; some extent with the conditional data operations, so we have to split them
9c08d1fa 10206;; up again here.
10207
25f905c2 10208;; ??? Need to audit these splitters for Thumb-2. Why isn't normal
10209;; conditional execution sufficient?
10210
9c08d1fa 10211(define_split
10212 [(set (match_operand:SI 0 "s_register_operand" "")
8fa3ba89 10213 (if_then_else:SI (match_operator 1 "arm_comparison_operator"
10214 [(match_operand 2 "" "") (match_operand 3 "" "")])
10215 (match_dup 0)
10216 (match_operand 4 "" "")))
bd5b4116 10217 (clobber (reg:CC CC_REGNUM))]
ac8b093b 10218 "TARGET_ARM && reload_completed"
8fa3ba89 10219 [(set (match_dup 5) (match_dup 6))
10220 (cond_exec (match_dup 7)
10221 (set (match_dup 0) (match_dup 4)))]
10222 "
10223 {
10224 enum machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
10225 operands[2], operands[3]);
10226 enum rtx_code rc = GET_CODE (operands[1]);
10227
bd5b4116 10228 operands[5] = gen_rtx_REG (mode, CC_REGNUM);
8fa3ba89 10229 operands[6] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
10230 if (mode == CCFPmode || mode == CCFPEmode)
10231 rc = reverse_condition_maybe_unordered (rc);
10232 else
10233 rc = reverse_condition (rc);
10234
10235 operands[7] = gen_rtx_fmt_ee (rc, VOIDmode, operands[5], const0_rtx);
10236 }"
10237)
10238
10239(define_split
10240 [(set (match_operand:SI 0 "s_register_operand" "")
10241 (if_then_else:SI (match_operator 1 "arm_comparison_operator"
10242 [(match_operand 2 "" "") (match_operand 3 "" "")])
10243 (match_operand 4 "" "")
10244 (match_dup 0)))
bd5b4116 10245 (clobber (reg:CC CC_REGNUM))]
ac8b093b 10246 "TARGET_ARM && reload_completed"
8fa3ba89 10247 [(set (match_dup 5) (match_dup 6))
10248 (cond_exec (match_op_dup 1 [(match_dup 5) (const_int 0)])
10249 (set (match_dup 0) (match_dup 4)))]
10250 "
10251 {
10252 enum machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
10253 operands[2], operands[3]);
10254
bd5b4116 10255 operands[5] = gen_rtx_REG (mode, CC_REGNUM);
8fa3ba89 10256 operands[6] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
10257 }"
10258)
10259
10260(define_split
10261 [(set (match_operand:SI 0 "s_register_operand" "")
10262 (if_then_else:SI (match_operator 1 "arm_comparison_operator"
9c08d1fa 10263 [(match_operand 2 "" "") (match_operand 3 "" "")])
10264 (match_operand 4 "" "")
10265 (match_operand 5 "" "")))
bd5b4116 10266 (clobber (reg:CC CC_REGNUM))]
ac8b093b 10267 "TARGET_ARM && reload_completed"
8fa3ba89 10268 [(set (match_dup 6) (match_dup 7))
10269 (cond_exec (match_op_dup 1 [(match_dup 6) (const_int 0)])
10270 (set (match_dup 0) (match_dup 4)))
10271 (cond_exec (match_dup 8)
10272 (set (match_dup 0) (match_dup 5)))]
10273 "
10274 {
10275 enum machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
10276 operands[2], operands[3]);
10277 enum rtx_code rc = GET_CODE (operands[1]);
10278
bd5b4116 10279 operands[6] = gen_rtx_REG (mode, CC_REGNUM);
8fa3ba89 10280 operands[7] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
10281 if (mode == CCFPmode || mode == CCFPEmode)
10282 rc = reverse_condition_maybe_unordered (rc);
10283 else
10284 rc = reverse_condition (rc);
10285
10286 operands[8] = gen_rtx_fmt_ee (rc, VOIDmode, operands[6], const0_rtx);
10287 }"
10288)
10289
cffb2a26 10290(define_split
10291 [(set (match_operand:SI 0 "s_register_operand" "")
8fa3ba89 10292 (if_then_else:SI (match_operator 1 "arm_comparison_operator"
cffb2a26 10293 [(match_operand:SI 2 "s_register_operand" "")
10294 (match_operand:SI 3 "arm_add_operand" "")])
10295 (match_operand:SI 4 "arm_rhs_operand" "")
10296 (not:SI
10297 (match_operand:SI 5 "s_register_operand" ""))))
bd5b4116 10298 (clobber (reg:CC CC_REGNUM))]
ac8b093b 10299 "TARGET_ARM && reload_completed"
cffb2a26 10300 [(set (match_dup 6) (match_dup 7))
f6c53574 10301 (cond_exec (match_op_dup 1 [(match_dup 6) (const_int 0)])
10302 (set (match_dup 0) (match_dup 4)))
10303 (cond_exec (match_dup 8)
10304 (set (match_dup 0) (not:SI (match_dup 5))))]
cffb2a26 10305 "
215b30b3 10306 {
10307 enum machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
10308 operands[2], operands[3]);
f6c53574 10309 enum rtx_code rc = GET_CODE (operands[1]);
cffb2a26 10310
bd5b4116 10311 operands[6] = gen_rtx_REG (mode, CC_REGNUM);
1a83b3ff 10312 operands[7] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
f6c53574 10313 if (mode == CCFPmode || mode == CCFPEmode)
10314 rc = reverse_condition_maybe_unordered (rc);
10315 else
10316 rc = reverse_condition (rc);
10317
10318 operands[8] = gen_rtx_fmt_ee (rc, VOIDmode, operands[6], const0_rtx);
215b30b3 10319 }"
10320)
cffb2a26 10321
10322(define_insn "*cond_move_not"
10323 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8fa3ba89 10324 (if_then_else:SI (match_operator 4 "arm_comparison_operator"
cffb2a26 10325 [(match_operand 3 "cc_register" "") (const_int 0)])
10326 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
10327 (not:SI
10328 (match_operand:SI 2 "s_register_operand" "r,r"))))]
10329 "TARGET_ARM"
10330 "@
10331 mvn%D4\\t%0, %2
10332 mov%d4\\t%0, %1\;mvn%D4\\t%0, %2"
0d66636f 10333 [(set_attr "conds" "use")
1b7da4ac 10334 (set_attr "type" "mvn_reg,multiple")
0d66636f 10335 (set_attr "length" "4,8")]
10336)
cffb2a26 10337
9c08d1fa 10338;; The next two patterns occur when an AND operation is followed by a
10339;; scc insn sequence
10340
f7fbdd4a 10341(define_insn "*sign_extract_onebit"
9c08d1fa 10342 [(set (match_operand:SI 0 "s_register_operand" "=r")
10343 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
10344 (const_int 1)
ed750274 10345 (match_operand:SI 2 "const_int_operand" "n")))
10346 (clobber (reg:CC CC_REGNUM))]
cffb2a26 10347 "TARGET_ARM"
9c08d1fa 10348 "*
0d66636f 10349 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
10350 output_asm_insn (\"ands\\t%0, %1, %2\", operands);
10351 return \"mvnne\\t%0, #0\";
10352 "
10353 [(set_attr "conds" "clob")
1b7da4ac 10354 (set_attr "length" "8")
10355 (set_attr "type" "multiple")]
0d66636f 10356)
9c08d1fa 10357
f7fbdd4a 10358(define_insn "*not_signextract_onebit"
9c08d1fa 10359 [(set (match_operand:SI 0 "s_register_operand" "=r")
10360 (not:SI
10361 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
10362 (const_int 1)
ed750274 10363 (match_operand:SI 2 "const_int_operand" "n"))))
10364 (clobber (reg:CC CC_REGNUM))]
cffb2a26 10365 "TARGET_ARM"
9c08d1fa 10366 "*
0d66636f 10367 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
10368 output_asm_insn (\"tst\\t%1, %2\", operands);
10369 output_asm_insn (\"mvneq\\t%0, #0\", operands);
10370 return \"movne\\t%0, #0\";
10371 "
10372 [(set_attr "conds" "clob")
1b7da4ac 10373 (set_attr "length" "12")
10374 (set_attr "type" "multiple")]
0d66636f 10375)
25f905c2 10376;; ??? The above patterns need auditing for Thumb-2
87b22bf7 10377
0d66636f 10378;; Push multiple registers to the stack. Registers are in parallel (use ...)
10379;; expressions. For simplicity, the first register is also in the unspec
10380;; part.
08508cbf 10381;; To avoid the usage of GNU extension, the length attribute is computed
10382;; in a C function arm_attr_length_push_multi.
f7fbdd4a 10383(define_insn "*push_multi"
87b22bf7 10384 [(match_parallel 2 "multi_register_push"
7571d3f7 10385 [(set (match_operand:BLK 0 "push_mult_memory_operand" "")
3cc80a30 10386 (unspec:BLK [(match_operand:SI 1 "s_register_operand" "")]
e1159bbe 10387 UNSPEC_PUSH_MULT))])]
7571d3f7 10388 ""
87b22bf7 10389 "*
215b30b3 10390 {
10391 int num_saves = XVECLEN (operands[2], 0);
ed593f11 10392
215b30b3 10393 /* For the StrongARM at least it is faster to
25f905c2 10394 use STR to store only a single register.
542d5028 10395 In Thumb mode always use push, and the assembler will pick
10396 something appropriate. */
25f905c2 10397 if (num_saves == 1 && TARGET_ARM)
61309563 10398 output_asm_insn (\"str%?\\t%1, [%m0, #-4]!\", operands);
215b30b3 10399 else
10400 {
10401 int i;
10402 char pattern[100];
ed593f11 10403
25f905c2 10404 if (TARGET_ARM)
61309563 10405 strcpy (pattern, \"stm%(fd%)\\t%m0!, {%1\");
10406 else if (TARGET_THUMB2)
10407 strcpy (pattern, \"push%?\\t{%1\");
25f905c2 10408 else
10409 strcpy (pattern, \"push\\t{%1\");
215b30b3 10410
6079f055 10411 for (i = 1; i < num_saves; i++)
215b30b3 10412 {
10413 strcat (pattern, \", %|\");
10414 strcat (pattern,
10415 reg_names[REGNO (XEXP (XVECEXP (operands[2], 0, i), 0))]);
10416 }
10417
10418 strcat (pattern, \"}\");
10419 output_asm_insn (pattern, operands);
10420 }
10421
10422 return \"\";
10423 }"
a6864a24 10424 [(set_attr "type" "store4")
10425 (set (attr "length")
08508cbf 10426 (symbol_ref "arm_attr_length_push_multi (operands[2], operands[1])"))]
215b30b3 10427)
f7fbdd4a 10428
4c58c898 10429(define_insn "stack_tie"
10430 [(set (mem:BLK (scratch))
aaa37ad6 10431 (unspec:BLK [(match_operand:SI 0 "s_register_operand" "rk")
10432 (match_operand:SI 1 "s_register_operand" "rk")]
4c58c898 10433 UNSPEC_PRLG_STK))]
10434 ""
10435 ""
1b7da4ac 10436 [(set_attr "length" "0")
10437 (set_attr "type" "block")]
4c58c898 10438)
10439
426be8c5 10440;; Pop (as used in epilogue RTL)
10441;;
10442(define_insn "*load_multiple_with_writeback"
10443 [(match_parallel 0 "load_multiple_operation"
10444 [(set (match_operand:SI 1 "s_register_operand" "+rk")
10445 (plus:SI (match_dup 1)
809003b3 10446 (match_operand:SI 2 "const_int_I_operand" "I")))
426be8c5 10447 (set (match_operand:SI 3 "s_register_operand" "=rk")
10448 (mem:SI (match_dup 1)))
10449 ])]
10450 "TARGET_32BIT && (reload_in_progress || reload_completed)"
10451 "*
10452 {
10453 arm_output_multireg_pop (operands, /*return_pc=*/false,
10454 /*cond=*/const_true_rtx,
10455 /*reverse=*/false,
10456 /*update=*/true);
10457 return \"\";
10458 }
10459 "
10460 [(set_attr "type" "load4")
10461 (set_attr "predicable" "yes")]
10462)
10463
10464;; Pop with return (as used in epilogue RTL)
10465;;
10466;; This instruction is generated when the registers are popped at the end of
10467;; epilogue. Here, instead of popping the value into LR and then generating
10468;; jump to LR, value is popped into PC directly. Hence, the pattern is combined
10469;; with (return).
10470(define_insn "*pop_multiple_with_writeback_and_return"
10471 [(match_parallel 0 "pop_multiple_return"
10472 [(return)
10473 (set (match_operand:SI 1 "s_register_operand" "+rk")
10474 (plus:SI (match_dup 1)
809003b3 10475 (match_operand:SI 2 "const_int_I_operand" "I")))
426be8c5 10476 (set (match_operand:SI 3 "s_register_operand" "=rk")
10477 (mem:SI (match_dup 1)))
10478 ])]
10479 "TARGET_32BIT && (reload_in_progress || reload_completed)"
10480 "*
10481 {
10482 arm_output_multireg_pop (operands, /*return_pc=*/true,
10483 /*cond=*/const_true_rtx,
10484 /*reverse=*/false,
10485 /*update=*/true);
10486 return \"\";
10487 }
10488 "
10489 [(set_attr "type" "load4")
10490 (set_attr "predicable" "yes")]
10491)
10492
10493(define_insn "*pop_multiple_with_return"
10494 [(match_parallel 0 "pop_multiple_return"
10495 [(return)
10496 (set (match_operand:SI 2 "s_register_operand" "=rk")
10497 (mem:SI (match_operand:SI 1 "s_register_operand" "rk")))
10498 ])]
10499 "TARGET_32BIT && (reload_in_progress || reload_completed)"
10500 "*
10501 {
10502 arm_output_multireg_pop (operands, /*return_pc=*/true,
10503 /*cond=*/const_true_rtx,
10504 /*reverse=*/false,
10505 /*update=*/false);
10506 return \"\";
10507 }
10508 "
10509 [(set_attr "type" "load4")
10510 (set_attr "predicable" "yes")]
10511)
10512
10513;; Load into PC and return
10514(define_insn "*ldr_with_return"
10515 [(return)
10516 (set (reg:SI PC_REGNUM)
10517 (mem:SI (post_inc:SI (match_operand:SI 0 "s_register_operand" "+rk"))))]
10518 "TARGET_32BIT && (reload_in_progress || reload_completed)"
10519 "ldr%?\t%|pc, [%0], #4"
10520 [(set_attr "type" "load1")
10521 (set_attr "predicable" "yes")]
10522)
1a0b0f12 10523;; Pop for floating point registers (as used in epilogue RTL)
10524(define_insn "*vfp_pop_multiple_with_writeback"
10525 [(match_parallel 0 "pop_multiple_fp"
10526 [(set (match_operand:SI 1 "s_register_operand" "+rk")
10527 (plus:SI (match_dup 1)
809003b3 10528 (match_operand:SI 2 "const_int_I_operand" "I")))
2f2163a4 10529 (set (match_operand:DF 3 "vfp_hard_register_operand" "")
1a0b0f12 10530 (mem:DF (match_dup 1)))])]
10531 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
10532 "*
10533 {
10534 int num_regs = XVECLEN (operands[0], 0);
10535 char pattern[100];
10536 rtx op_list[2];
b34d8dac 10537 strcpy (pattern, \"vldm\\t\");
1a0b0f12 10538 strcat (pattern, reg_names[REGNO (SET_DEST (XVECEXP (operands[0], 0, 0)))]);
10539 strcat (pattern, \"!, {\");
10540 op_list[0] = XEXP (XVECEXP (operands[0], 0, 1), 0);
10541 strcat (pattern, \"%P0\");
10542 if ((num_regs - 1) > 1)
10543 {
10544 strcat (pattern, \"-%P1\");
10545 op_list [1] = XEXP (XVECEXP (operands[0], 0, num_regs - 1), 0);
10546 }
10547
10548 strcat (pattern, \"}\");
10549 output_asm_insn (pattern, op_list);
10550 return \"\";
10551 }
10552 "
10553 [(set_attr "type" "load4")
10554 (set_attr "conds" "unconditional")
10555 (set_attr "predicable" "no")]
10556)
10557
f7fbdd4a 10558;; Special patterns for dealing with the constant pool
10559
cffb2a26 10560(define_insn "align_4"
e1159bbe 10561 [(unspec_volatile [(const_int 0)] VUNSPEC_ALIGN)]
cffb2a26 10562 "TARGET_EITHER"
f7fbdd4a 10563 "*
cffb2a26 10564 assemble_align (32);
f7fbdd4a 10565 return \"\";
cffb2a26 10566 "
1b7da4ac 10567 [(set_attr "type" "no_insn")]
cffb2a26 10568)
f7fbdd4a 10569
755eb2b4 10570(define_insn "align_8"
10571 [(unspec_volatile [(const_int 0)] VUNSPEC_ALIGN8)]
f9273c43 10572 "TARGET_EITHER"
755eb2b4 10573 "*
10574 assemble_align (64);
10575 return \"\";
10576 "
1b7da4ac 10577 [(set_attr "type" "no_insn")]
755eb2b4 10578)
10579
cffb2a26 10580(define_insn "consttable_end"
e1159bbe 10581 [(unspec_volatile [(const_int 0)] VUNSPEC_POOL_END)]
cffb2a26 10582 "TARGET_EITHER"
f7fbdd4a 10583 "*
cffb2a26 10584 making_const_table = FALSE;
f7fbdd4a 10585 return \"\";
cffb2a26 10586 "
1b7da4ac 10587 [(set_attr "type" "no_insn")]
cffb2a26 10588)
f7fbdd4a 10589
cffb2a26 10590(define_insn "consttable_4"
e1159bbe 10591 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_4)]
cffb2a26 10592 "TARGET_EITHER"
10593 "*
10594 {
9b8516be 10595 rtx x = operands[0];
cffb2a26 10596 making_const_table = TRUE;
9b8516be 10597 switch (GET_MODE_CLASS (GET_MODE (x)))
cffb2a26 10598 {
10599 case MODE_FLOAT:
9b8516be 10600 if (GET_MODE (x) == HFmode)
10601 arm_emit_fp16_const (x);
10602 else
10603 {
10604 REAL_VALUE_TYPE r;
10605 REAL_VALUE_FROM_CONST_DOUBLE (r, x);
10606 assemble_real (r, GET_MODE (x), BITS_PER_WORD);
10607 }
10608 break;
cffb2a26 10609 default:
7b04c5d5 10610 /* XXX: Sometimes gcc does something really dumb and ends up with
10611 a HIGH in a constant pool entry, usually because it's trying to
10612 load into a VFP register. We know this will always be used in
10613 combination with a LO_SUM which ignores the high bits, so just
10614 strip off the HIGH. */
10615 if (GET_CODE (x) == HIGH)
10616 x = XEXP (x, 0);
9b8516be 10617 assemble_integer (x, 4, BITS_PER_WORD, 1);
10618 mark_symbol_refs_as_used (x);
cffb2a26 10619 break;
10620 }
10621 return \"\";
10622 }"
1b7da4ac 10623 [(set_attr "length" "4")
10624 (set_attr "type" "no_insn")]
cffb2a26 10625)
10626
10627(define_insn "consttable_8"
e1159bbe 10628 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_8)]
cffb2a26 10629 "TARGET_EITHER"
10630 "*
10631 {
10632 making_const_table = TRUE;
10633 switch (GET_MODE_CLASS (GET_MODE (operands[0])))
10634 {
10635 case MODE_FLOAT:
10636 {
badfe841 10637 REAL_VALUE_TYPE r;
10638 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[0]);
10639 assemble_real (r, GET_MODE (operands[0]), BITS_PER_WORD);
cffb2a26 10640 break;
10641 }
10642 default:
09d688ff 10643 assemble_integer (operands[0], 8, BITS_PER_WORD, 1);
cffb2a26 10644 break;
10645 }
10646 return \"\";
10647 }"
1b7da4ac 10648 [(set_attr "length" "8")
10649 (set_attr "type" "no_insn")]
cffb2a26 10650)
10651
d98a3884 10652(define_insn "consttable_16"
10653 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_16)]
10654 "TARGET_EITHER"
10655 "*
10656 {
10657 making_const_table = TRUE;
10658 switch (GET_MODE_CLASS (GET_MODE (operands[0])))
10659 {
10660 case MODE_FLOAT:
10661 {
10662 REAL_VALUE_TYPE r;
10663 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[0]);
10664 assemble_real (r, GET_MODE (operands[0]), BITS_PER_WORD);
10665 break;
10666 }
10667 default:
10668 assemble_integer (operands[0], 16, BITS_PER_WORD, 1);
10669 break;
10670 }
10671 return \"\";
10672 }"
1b7da4ac 10673 [(set_attr "length" "16")
10674 (set_attr "type" "no_insn")]
d98a3884 10675)
10676
331beb1a 10677;; V5 Instructions,
10678
8f4be2be 10679(define_insn "clzsi2"
10680 [(set (match_operand:SI 0 "s_register_operand" "=r")
10681 (clz:SI (match_operand:SI 1 "s_register_operand" "r")))]
25f905c2 10682 "TARGET_32BIT && arm_arch5"
ee7cbe0e 10683 "clz%?\\t%0, %1"
bcaec148 10684 [(set_attr "predicable" "yes")
4a510717 10685 (set_attr "predicable_short_it" "no")
bebe9bbb 10686 (set_attr "type" "clz")])
331beb1a 10687
099ad98b 10688(define_insn "rbitsi2"
10689 [(set (match_operand:SI 0 "s_register_operand" "=r")
10690 (unspec:SI [(match_operand:SI 1 "s_register_operand" "r")] UNSPEC_RBIT))]
10691 "TARGET_32BIT && arm_arch_thumb2"
10692 "rbit%?\\t%0, %1"
10693 [(set_attr "predicable" "yes")
4a510717 10694 (set_attr "predicable_short_it" "no")
bebe9bbb 10695 (set_attr "type" "clz")])
099ad98b 10696
10697(define_expand "ctzsi2"
10698 [(set (match_operand:SI 0 "s_register_operand" "")
10699 (ctz:SI (match_operand:SI 1 "s_register_operand" "")))]
10700 "TARGET_32BIT && arm_arch_thumb2"
10701 "
30191172 10702 {
10703 rtx tmp = gen_reg_rtx (SImode);
10704 emit_insn (gen_rbitsi2 (tmp, operands[1]));
10705 emit_insn (gen_clzsi2 (operands[0], tmp));
10706 }
099ad98b 10707 DONE;
10708 "
10709)
10710
e1159bbe 10711;; V5E instructions.
331beb1a 10712
10713(define_insn "prefetch"
f4e79814 10714 [(prefetch (match_operand:SI 0 "address_operand" "p")
10715 (match_operand:SI 1 "" "")
10716 (match_operand:SI 2 "" ""))]
25f905c2 10717 "TARGET_32BIT && arm_arch5e"
1b7da4ac 10718 "pld\\t%a0"
10719 [(set_attr "type" "load1")]
10720)
331beb1a 10721
0d66636f 10722;; General predication pattern
10723
10724(define_cond_exec
10725 [(match_operator 0 "arm_comparison_operator"
10726 [(match_operand 1 "cc_register" "")
10727 (const_int 0)])]
25f905c2 10728 "TARGET_32BIT"
0d66636f 10729 ""
c7a58118 10730[(set_attr "predicated" "yes")]
0d66636f 10731)
10732
fb94f18b 10733(define_insn "force_register_use"
10734 [(unspec:SI [(match_operand:SI 0 "register_operand" "")] UNSPEC_REGISTER_USE)]
063a05c7 10735 ""
fb94f18b 10736 "%@ %0 needed"
1b7da4ac 10737 [(set_attr "length" "0")
10738 (set_attr "type" "no_insn")]
063a05c7 10739)
7db9af5d 10740
4c44712e 10741
10742;; Patterns for exception handling
10743
10744(define_expand "eh_return"
10745 [(use (match_operand 0 "general_operand" ""))]
10746 "TARGET_EITHER"
10747 "
10748 {
25f905c2 10749 if (TARGET_32BIT)
4c44712e 10750 emit_insn (gen_arm_eh_return (operands[0]));
10751 else
10752 emit_insn (gen_thumb_eh_return (operands[0]));
10753 DONE;
10754 }"
10755)
10756
10757;; We can't expand this before we know where the link register is stored.
10758(define_insn_and_split "arm_eh_return"
10759 [(unspec_volatile [(match_operand:SI 0 "s_register_operand" "r")]
10760 VUNSPEC_EH_RETURN)
10761 (clobber (match_scratch:SI 1 "=&r"))]
10762 "TARGET_ARM"
10763 "#"
10764 "&& reload_completed"
10765 [(const_int 0)]
10766 "
10767 {
10768 arm_set_return_address (operands[0], operands[1]);
10769 DONE;
10770 }"
10771)
10772
f655717d 10773\f
10774;; TLS support
10775
10776(define_insn "load_tp_hard"
10777 [(set (match_operand:SI 0 "register_operand" "=r")
10778 (unspec:SI [(const_int 0)] UNSPEC_TLS))]
10779 "TARGET_HARD_TP"
10780 "mrc%?\\tp15, 0, %0, c13, c0, 3\\t@ load_tp_hard"
1b7da4ac 10781 [(set_attr "predicable" "yes")
4b5d7374 10782 (set_attr "type" "mrs")]
f655717d 10783)
10784
10785;; Doesn't clobber R1-R3. Must use r0 for the first operand.
10786(define_insn "load_tp_soft"
10787 [(set (reg:SI 0) (unspec:SI [(const_int 0)] UNSPEC_TLS))
10788 (clobber (reg:SI LR_REGNUM))
10789 (clobber (reg:SI IP_REGNUM))
10790 (clobber (reg:CC CC_REGNUM))]
10791 "TARGET_SOFT_TP"
10792 "bl\\t__aeabi_read_tp\\t@ load_tp_soft"
1b7da4ac 10793 [(set_attr "conds" "clob")
10794 (set_attr "type" "branch")]
f655717d 10795)
10796
f41e4452 10797;; tls descriptor call
10798(define_insn "tlscall"
10799 [(set (reg:SI R0_REGNUM)
10800 (unspec:SI [(reg:SI R0_REGNUM)
10801 (match_operand:SI 0 "" "X")
10802 (match_operand 1 "" "")] UNSPEC_TLS))
10803 (clobber (reg:SI R1_REGNUM))
10804 (clobber (reg:SI LR_REGNUM))
10805 (clobber (reg:SI CC_REGNUM))]
10806 "TARGET_GNU2_TLS"
10807 {
10808 targetm.asm_out.internal_label (asm_out_file, "LPIC",
10809 INTVAL (operands[1]));
10810 return "bl\\t%c0(tlscall)";
10811 }
10812 [(set_attr "conds" "clob")
1b7da4ac 10813 (set_attr "length" "4")
10814 (set_attr "type" "branch")]
f41e4452 10815)
10816
1fe0edab 10817;; For thread pointer builtin
10818(define_expand "get_thread_pointersi"
10819 [(match_operand:SI 0 "s_register_operand" "=r")]
10820 ""
10821 "
10822 {
10823 arm_load_tp (operands[0]);
10824 DONE;
10825 }")
10826
f41e4452 10827;;
10828
aabe09ac 10829;; We only care about the lower 16 bits of the constant
10830;; being inserted into the upper 16 bits of the register.
eca5c984 10831(define_insn "*arm_movtas_ze"
10832 [(set (zero_extract:SI (match_operand:SI 0 "s_register_operand" "+r")
10833 (const_int 16)
10834 (const_int 16))
10835 (match_operand:SI 1 "const_int_operand" ""))]
181ab277 10836 "arm_arch_thumb2"
aabe09ac 10837 "movt%?\t%0, %L1"
eca5c984 10838 [(set_attr "predicable" "yes")
7c36fe71 10839 (set_attr "predicable_short_it" "no")
1b7da4ac 10840 (set_attr "length" "4")
10841 (set_attr "type" "mov_imm")]
eca5c984 10842)
10843
c0fc3696 10844(define_insn "*arm_rev"
a486b499 10845 [(set (match_operand:SI 0 "s_register_operand" "=l,l,r")
10846 (bswap:SI (match_operand:SI 1 "s_register_operand" "l,l,r")))]
10847 "arm_arch6"
10848 "@
10849 rev\t%0, %1
10850 rev%?\t%0, %1
10851 rev%?\t%0, %1"
10852 [(set_attr "arch" "t1,t2,32")
1b7da4ac 10853 (set_attr "length" "2,2,4")
4a510717 10854 (set_attr "predicable" "no,yes,yes")
10855 (set_attr "predicable_short_it" "no")
1b7da4ac 10856 (set_attr "type" "rev")]
ff82f757 10857)
10858
10859(define_expand "arm_legacy_rev"
10860 [(set (match_operand:SI 2 "s_register_operand" "")
10861 (xor:SI (rotatert:SI (match_operand:SI 1 "s_register_operand" "")
10862 (const_int 16))
10863 (match_dup 1)))
10864 (set (match_dup 2)
10865 (lshiftrt:SI (match_dup 2)
10866 (const_int 8)))
10867 (set (match_operand:SI 3 "s_register_operand" "")
10868 (rotatert:SI (match_dup 1)
10869 (const_int 8)))
10870 (set (match_dup 2)
10871 (and:SI (match_dup 2)
10872 (const_int -65281)))
10873 (set (match_operand:SI 0 "s_register_operand" "")
10874 (xor:SI (match_dup 3)
10875 (match_dup 2)))]
10876 "TARGET_32BIT"
10877 ""
10878)
10879
10880;; Reuse temporaries to keep register pressure down.
10881(define_expand "thumb_legacy_rev"
10882 [(set (match_operand:SI 2 "s_register_operand" "")
10883 (ashift:SI (match_operand:SI 1 "s_register_operand" "")
10884 (const_int 24)))
10885 (set (match_operand:SI 3 "s_register_operand" "")
10886 (lshiftrt:SI (match_dup 1)
10887 (const_int 24)))
10888 (set (match_dup 3)
10889 (ior:SI (match_dup 3)
10890 (match_dup 2)))
10891 (set (match_operand:SI 4 "s_register_operand" "")
10892 (const_int 16))
10893 (set (match_operand:SI 5 "s_register_operand" "")
10894 (rotatert:SI (match_dup 1)
10895 (match_dup 4)))
10896 (set (match_dup 2)
10897 (ashift:SI (match_dup 5)
10898 (const_int 24)))
10899 (set (match_dup 5)
10900 (lshiftrt:SI (match_dup 5)
10901 (const_int 24)))
10902 (set (match_dup 5)
10903 (ior:SI (match_dup 5)
10904 (match_dup 2)))
10905 (set (match_dup 5)
10906 (rotatert:SI (match_dup 5)
10907 (match_dup 4)))
10908 (set (match_operand:SI 0 "s_register_operand" "")
10909 (ior:SI (match_dup 5)
10910 (match_dup 3)))]
10911 "TARGET_THUMB"
10912 ""
10913)
10914
10915(define_expand "bswapsi2"
10916 [(set (match_operand:SI 0 "s_register_operand" "=r")
10917 (bswap:SI (match_operand:SI 1 "s_register_operand" "r")))]
8d1af482 10918"TARGET_EITHER && (arm_arch6 || !optimize_size)"
ff82f757 10919"
8d1af482 10920 if (!arm_arch6)
10921 {
10922 rtx op2 = gen_reg_rtx (SImode);
10923 rtx op3 = gen_reg_rtx (SImode);
ff82f757 10924
8d1af482 10925 if (TARGET_THUMB)
10926 {
10927 rtx op4 = gen_reg_rtx (SImode);
10928 rtx op5 = gen_reg_rtx (SImode);
ff82f757 10929
8d1af482 10930 emit_insn (gen_thumb_legacy_rev (operands[0], operands[1],
10931 op2, op3, op4, op5));
10932 }
10933 else
10934 {
10935 emit_insn (gen_arm_legacy_rev (operands[0], operands[1],
10936 op2, op3));
10937 }
ff82f757 10938
8d1af482 10939 DONE;
10940 }
ff82f757 10941 "
10942)
10943
a486b499 10944;; bswap16 patterns: use revsh and rev16 instructions for the signed
10945;; and unsigned variants, respectively. For rev16, expose
10946;; byte-swapping in the lower 16 bits only.
10947(define_insn "*arm_revsh"
10948 [(set (match_operand:SI 0 "s_register_operand" "=l,l,r")
10949 (sign_extend:SI (bswap:HI (match_operand:HI 1 "s_register_operand" "l,l,r"))))]
10950 "arm_arch6"
10951 "@
10952 revsh\t%0, %1
10953 revsh%?\t%0, %1
10954 revsh%?\t%0, %1"
10955 [(set_attr "arch" "t1,t2,32")
1b7da4ac 10956 (set_attr "length" "2,2,4")
10957 (set_attr "type" "rev")]
a486b499 10958)
10959
10960(define_insn "*arm_rev16"
10961 [(set (match_operand:HI 0 "s_register_operand" "=l,l,r")
10962 (bswap:HI (match_operand:HI 1 "s_register_operand" "l,l,r")))]
10963 "arm_arch6"
10964 "@
10965 rev16\t%0, %1
10966 rev16%?\t%0, %1
10967 rev16%?\t%0, %1"
10968 [(set_attr "arch" "t1,t2,32")
1b7da4ac 10969 (set_attr "length" "2,2,4")
10970 (set_attr "type" "rev")]
09f69e55 10971)
10972
10973;; There are no canonicalisation rules for the position of the lshiftrt, ashift
10974;; operations within an IOR/AND RTX, therefore we have two patterns matching
10975;; each valid permutation.
10976
10977(define_insn "arm_rev16si2"
10978 [(set (match_operand:SI 0 "register_operand" "=l,l,r")
10979 (ior:SI (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "l,l,r")
10980 (const_int 8))
10981 (match_operand:SI 3 "const_int_operand" "n,n,n"))
10982 (and:SI (lshiftrt:SI (match_dup 1)
10983 (const_int 8))
10984 (match_operand:SI 2 "const_int_operand" "n,n,n"))))]
10985 "arm_arch6
10986 && aarch_rev16_shleft_mask_imm_p (operands[3], SImode)
10987 && aarch_rev16_shright_mask_imm_p (operands[2], SImode)"
10988 "rev16\\t%0, %1"
10989 [(set_attr "arch" "t1,t2,32")
10990 (set_attr "length" "2,2,4")
10991 (set_attr "type" "rev")]
10992)
10993
10994(define_insn "arm_rev16si2_alt"
10995 [(set (match_operand:SI 0 "register_operand" "=l,l,r")
10996 (ior:SI (and:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" "l,l,r")
10997 (const_int 8))
10998 (match_operand:SI 2 "const_int_operand" "n,n,n"))
10999 (and:SI (ashift:SI (match_dup 1)
11000 (const_int 8))
11001 (match_operand:SI 3 "const_int_operand" "n,n,n"))))]
11002 "arm_arch6
11003 && aarch_rev16_shleft_mask_imm_p (operands[3], SImode)
11004 && aarch_rev16_shright_mask_imm_p (operands[2], SImode)"
11005 "rev16\\t%0, %1"
11006 [(set_attr "arch" "t1,t2,32")
11007 (set_attr "length" "2,2,4")
11008 (set_attr "type" "rev")]
a486b499 11009)
11010
11011(define_expand "bswaphi2"
11012 [(set (match_operand:HI 0 "s_register_operand" "=r")
11013 (bswap:HI (match_operand:HI 1 "s_register_operand" "r")))]
11014"arm_arch6"
11015""
11016)
11017
1653cf17 11018;; Patterns for LDRD/STRD in Thumb2 mode
11019
11020(define_insn "*thumb2_ldrd"
11021 [(set (match_operand:SI 0 "s_register_operand" "=r")
11022 (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "rk")
11023 (match_operand:SI 2 "ldrd_strd_offset_operand" "Do"))))
11024 (set (match_operand:SI 3 "s_register_operand" "=r")
11025 (mem:SI (plus:SI (match_dup 1)
11026 (match_operand:SI 4 "const_int_operand" ""))))]
11027 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11028 && current_tune->prefer_ldrd_strd
11029 && ((INTVAL (operands[2]) + 4) == INTVAL (operands[4]))
11030 && (operands_ok_ldrd_strd (operands[0], operands[3],
11031 operands[1], INTVAL (operands[2]),
11032 false, true))"
11033 "ldrd%?\t%0, %3, [%1, %2]"
11034 [(set_attr "type" "load2")
d952d547 11035 (set_attr "predicable" "yes")
11036 (set_attr "predicable_short_it" "no")])
1653cf17 11037
11038(define_insn "*thumb2_ldrd_base"
11039 [(set (match_operand:SI 0 "s_register_operand" "=r")
11040 (mem:SI (match_operand:SI 1 "s_register_operand" "rk")))
11041 (set (match_operand:SI 2 "s_register_operand" "=r")
11042 (mem:SI (plus:SI (match_dup 1)
11043 (const_int 4))))]
11044 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11045 && current_tune->prefer_ldrd_strd
11046 && (operands_ok_ldrd_strd (operands[0], operands[2],
11047 operands[1], 0, false, true))"
11048 "ldrd%?\t%0, %2, [%1]"
11049 [(set_attr "type" "load2")
d952d547 11050 (set_attr "predicable" "yes")
11051 (set_attr "predicable_short_it" "no")])
1653cf17 11052
11053(define_insn "*thumb2_ldrd_base_neg"
11054 [(set (match_operand:SI 0 "s_register_operand" "=r")
11055 (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "rk")
11056 (const_int -4))))
11057 (set (match_operand:SI 2 "s_register_operand" "=r")
11058 (mem:SI (match_dup 1)))]
11059 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11060 && current_tune->prefer_ldrd_strd
11061 && (operands_ok_ldrd_strd (operands[0], operands[2],
11062 operands[1], -4, false, true))"
11063 "ldrd%?\t%0, %2, [%1, #-4]"
11064 [(set_attr "type" "load2")
d952d547 11065 (set_attr "predicable" "yes")
11066 (set_attr "predicable_short_it" "no")])
1653cf17 11067
11068(define_insn "*thumb2_strd"
11069 [(set (mem:SI (plus:SI (match_operand:SI 0 "s_register_operand" "rk")
11070 (match_operand:SI 1 "ldrd_strd_offset_operand" "Do")))
11071 (match_operand:SI 2 "s_register_operand" "r"))
11072 (set (mem:SI (plus:SI (match_dup 0)
11073 (match_operand:SI 3 "const_int_operand" "")))
11074 (match_operand:SI 4 "s_register_operand" "r"))]
11075 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11076 && current_tune->prefer_ldrd_strd
11077 && ((INTVAL (operands[1]) + 4) == INTVAL (operands[3]))
11078 && (operands_ok_ldrd_strd (operands[2], operands[4],
11079 operands[0], INTVAL (operands[1]),
11080 false, false))"
11081 "strd%?\t%2, %4, [%0, %1]"
11082 [(set_attr "type" "store2")
d952d547 11083 (set_attr "predicable" "yes")
11084 (set_attr "predicable_short_it" "no")])
1653cf17 11085
11086(define_insn "*thumb2_strd_base"
11087 [(set (mem:SI (match_operand:SI 0 "s_register_operand" "rk"))
11088 (match_operand:SI 1 "s_register_operand" "r"))
11089 (set (mem:SI (plus:SI (match_dup 0)
11090 (const_int 4)))
11091 (match_operand:SI 2 "s_register_operand" "r"))]
11092 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11093 && current_tune->prefer_ldrd_strd
11094 && (operands_ok_ldrd_strd (operands[1], operands[2],
11095 operands[0], 0, false, false))"
11096 "strd%?\t%1, %2, [%0]"
11097 [(set_attr "type" "store2")
d952d547 11098 (set_attr "predicable" "yes")
11099 (set_attr "predicable_short_it" "no")])
1653cf17 11100
11101(define_insn "*thumb2_strd_base_neg"
11102 [(set (mem:SI (plus:SI (match_operand:SI 0 "s_register_operand" "rk")
11103 (const_int -4)))
11104 (match_operand:SI 1 "s_register_operand" "r"))
11105 (set (mem:SI (match_dup 0))
11106 (match_operand:SI 2 "s_register_operand" "r"))]
11107 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11108 && current_tune->prefer_ldrd_strd
11109 && (operands_ok_ldrd_strd (operands[1], operands[2],
11110 operands[0], -4, false, false))"
11111 "strd%?\t%1, %2, [%0, #-4]"
11112 [(set_attr "type" "store2")
d952d547 11113 (set_attr "predicable" "yes")
11114 (set_attr "predicable_short_it" "no")])
1653cf17 11115
2a0c73f2 11116;; ARMv8 CRC32 instructions.
11117(define_insn "<crc_variant>"
11118 [(set (match_operand:SI 0 "s_register_operand" "=r")
11119 (unspec:SI [(match_operand:SI 1 "s_register_operand" "r")
11120 (match_operand:<crc_mode> 2 "s_register_operand" "r")]
11121 CRC))]
11122 "TARGET_CRC32"
11123 "<crc_variant>\\t%0, %1, %2"
11124 [(set_attr "type" "crc")
11125 (set_attr "conds" "unconditional")]
11126)
1653cf17 11127
353cf59a 11128;; Load the load/store double peephole optimizations.
11129(include "ldrdstrd.md")
11130
320ea44d 11131;; Load the load/store multiple patterns
11132(include "ldmstm.md")
426be8c5 11133
11134;; Patterns in ldmstm.md don't cover more than 4 registers. This pattern covers
11135;; large lists without explicit writeback generated for APCS_FRAME epilogue.
11136(define_insn "*load_multiple"
11137 [(match_parallel 0 "load_multiple_operation"
11138 [(set (match_operand:SI 2 "s_register_operand" "=rk")
11139 (mem:SI (match_operand:SI 1 "s_register_operand" "rk")))
11140 ])]
11141 "TARGET_32BIT"
11142 "*
11143 {
11144 arm_output_multireg_pop (operands, /*return_pc=*/false,
11145 /*cond=*/const_true_rtx,
11146 /*reverse=*/false,
11147 /*update=*/false);
11148 return \"\";
11149 }
11150 "
11151 [(set_attr "predicable" "yes")]
11152)
11153
d98a3884 11154;; Vector bits common to IWMMXT and Neon
11155(include "vec-common.md")
755eb2b4 11156;; Load the Intel Wireless Multimedia Extension patterns
11157(include "iwmmxt.md")
a2cd141b 11158;; Load the VFP co-processor patterns
11159(include "vfp.md")
bc360af8 11160;; Thumb-1 patterns
11161(include "thumb1.md")
25f905c2 11162;; Thumb-2 patterns
11163(include "thumb2.md")
d98a3884 11164;; Neon patterns
11165(include "neon.md")
e84fdf6e 11166;; Crypto patterns
11167(include "crypto.md")
06df6b17 11168;; Synchronization Primitives
11169(include "sync.md")
bbbe4599 11170;; Fixed-point patterns
11171(include "arm-fixed.md")