]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/config/arm/arm.md
Daily bump.
[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"
d82e788e 323 "adc_imm, adc_reg, adcs_imm, adcs_reg, adr, alu_ext, alu_imm, alu_reg,\
324 alu_shift_imm, alu_shift_reg, alus_ext, alus_imm, alus_reg,\
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")
605 (const_string "alu_reg")))
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")
1b7da4ac 623 (set_attr "type" "alus_imm,alus_imm,alus_reg")]
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")
1b7da4ac 639 (set_attr "type" "alus_imm,alus_imm,alus_reg")]
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")
654 (set_attr "type" "alus_reg")]
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")
672 (set_attr "type" "alus_reg")]
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")
d82e788e 730 (set_attr "type" "alus_imm,alus_imm,alus_reg")]
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")
d82e788e 747 (set_attr "type" "alus_imm,alus_imm,alus_reg")]
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")
d82e788e 768 (set_attr "type" "alus_imm,alus_reg,alus_imm,alus_imm,alus_reg")]
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")
d82e788e 789 (set_attr "type" "alus_imm,alus_reg,alus_imm,alus_imm,alus_reg")]
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")
1b7da4ac 1204 (set_attr "type" "alu_reg,alu_reg,alu_reg,alu_reg,alu_imm,alu_imm,alu_reg,alu_reg,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")
d82e788e 1234 (set_attr "type" "alus_imm,alus_reg,alus_reg")]
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")
d82e788e 1249 (set_attr "type" "alus_imm,alus_reg,alus_reg")]
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
4155 (unspec:HI [(match_operand:HI 1 "memory_operand" "Uw,m")]
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")
4369 (set_attr "type" "alu_reg")]
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")
4967 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
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")
5038 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
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")
5198 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
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")
0d66636f 5205 (set_attr "predicable" "yes")
ef51b8e1 5206 (set_attr "pool_range" "*,256")
5207 (set_attr "neg_pool_range" "*,244")]
cffb2a26 5208)
f7fbdd4a 5209
25f905c2 5210;; ??? Check Thumb-2 pool range
a2cd141b 5211(define_insn "*arm_extendhisi2_v6"
5212 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5213 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
25f905c2 5214 "TARGET_32BIT && arm_arch6"
a2cd141b 5215 "@
5216 sxth%?\\t%0, %1
25f905c2 5217 ldr%(sh%)\\t%0, %1"
6b6abc9c 5218 [(set_attr "type" "extend,load_byte")
a2cd141b 5219 (set_attr "predicable" "yes")
d952d547 5220 (set_attr "predicable_short_it" "no")
a2cd141b 5221 (set_attr "pool_range" "*,256")
5222 (set_attr "neg_pool_range" "*,244")]
5223)
5224
5225(define_insn "*arm_extendhisi2addsi"
5226 [(set (match_operand:SI 0 "s_register_operand" "=r")
5227 (plus:SI (sign_extend:SI (match_operand:HI 1 "s_register_operand" "r"))
5228 (match_operand:SI 2 "s_register_operand" "r")))]
25f905c2 5229 "TARGET_INT_SIMD"
a2cd141b 5230 "sxtah%?\\t%0, %2, %1"
1b7da4ac 5231 [(set_attr "type" "alu_shift_reg")]
a2cd141b 5232)
5233
c8f69309 5234(define_expand "extendqihi2"
5235 [(set (match_dup 2)
bed7d9a5 5236 (ashift:SI (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "")
c8f69309 5237 (const_int 24)))
9c08d1fa 5238 (set (match_operand:HI 0 "s_register_operand" "")
c8f69309 5239 (ashiftrt:SI (match_dup 2)
5240 (const_int 24)))]
cffb2a26 5241 "TARGET_ARM"
c8f69309 5242 "
215b30b3 5243 {
0438d37f 5244 if (arm_arch4 && MEM_P (operands[1]))
215b30b3 5245 {
5246 emit_insn (gen_rtx_SET (VOIDmode,
5247 operands[0],
5248 gen_rtx_SIGN_EXTEND (HImode, operands[1])));
5249 DONE;
5250 }
5251 if (!s_register_operand (operands[1], QImode))
5252 operands[1] = copy_to_mode_reg (QImode, operands[1]);
5253 operands[0] = gen_lowpart (SImode, operands[0]);
5254 operands[1] = gen_lowpart (SImode, operands[1]);
5255 operands[2] = gen_reg_rtx (SImode);
5256 }"
5257)
f7fbdd4a 5258
25f905c2 5259(define_insn "*arm_extendqihi_insn"
b4e8a300 5260 [(set (match_operand:HI 0 "s_register_operand" "=r")
bed7d9a5 5261 (sign_extend:HI (match_operand:QI 1 "arm_extendqisi_mem_op" "Uq")))]
cffb2a26 5262 "TARGET_ARM && arm_arch4"
25f905c2 5263 "ldr%(sb%)\\t%0, %1"
a2cd141b 5264 [(set_attr "type" "load_byte")
0d66636f 5265 (set_attr "predicable" "yes")
cffb2a26 5266 (set_attr "pool_range" "256")
5267 (set_attr "neg_pool_range" "244")]
5268)
3fc2009e 5269
b11cae9e 5270(define_expand "extendqisi2"
ef51b8e1 5271 [(set (match_operand:SI 0 "s_register_operand" "")
5272 (sign_extend:SI (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "")))]
cffb2a26 5273 "TARGET_EITHER"
ef51b8e1 5274{
5275 if (!arm_arch4 && MEM_P (operands[1]))
5276 operands[1] = copy_to_mode_reg (QImode, operands[1]);
a2cd141b 5277
ef51b8e1 5278 if (!arm_arch6 && !MEM_P (operands[1]))
5279 {
5280 rtx t = gen_lowpart (SImode, operands[1]);
5281 rtx tmp = gen_reg_rtx (SImode);
5282 emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (24)));
5283 emit_insn (gen_ashrsi3 (operands[0], tmp, GEN_INT (24)));
5284 DONE;
5285 }
5286})
a2cd141b 5287
ef51b8e1 5288(define_split
5289 [(set (match_operand:SI 0 "register_operand" "")
5290 (sign_extend:SI (match_operand:QI 1 "register_operand" "")))]
5291 "!arm_arch6"
5292 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 24)))
5293 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 24)))]
5294{
5295 operands[2] = simplify_gen_subreg (SImode, operands[1], QImode, 0);
5296})
f7fbdd4a 5297
a2cd141b 5298(define_insn "*arm_extendqisi"
ef51b8e1 5299 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5300 (sign_extend:SI (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "r,Uq")))]
a2cd141b 5301 "TARGET_ARM && arm_arch4 && !arm_arch6"
ef51b8e1 5302 "@
5303 #
5304 ldr%(sb%)\\t%0, %1"
5305 [(set_attr "length" "8,4")
d82e788e 5306 (set_attr "type" "alu_shift_reg,load_byte")
0d66636f 5307 (set_attr "predicable" "yes")
ef51b8e1 5308 (set_attr "pool_range" "*,256")
5309 (set_attr "neg_pool_range" "*,244")]
cffb2a26 5310)
3fc2009e 5311
a2cd141b 5312(define_insn "*arm_extendqisi_v6"
5313 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
bed7d9a5 5314 (sign_extend:SI
5315 (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "r,Uq")))]
a2cd141b 5316 "TARGET_ARM && arm_arch6"
b4e8a300 5317 "@
5318 sxtb%?\\t%0, %1
25f905c2 5319 ldr%(sb%)\\t%0, %1"
6b6abc9c 5320 [(set_attr "type" "extend,load_byte")
a2cd141b 5321 (set_attr "predicable" "yes")
a2cd141b 5322 (set_attr "pool_range" "*,256")
5323 (set_attr "neg_pool_range" "*,244")]
5324)
5325
5326(define_insn "*arm_extendqisi2addsi"
5327 [(set (match_operand:SI 0 "s_register_operand" "=r")
5328 (plus:SI (sign_extend:SI (match_operand:QI 1 "s_register_operand" "r"))
5329 (match_operand:SI 2 "s_register_operand" "r")))]
25f905c2 5330 "TARGET_INT_SIMD"
a2cd141b 5331 "sxtab%?\\t%0, %2, %1"
d82e788e 5332 [(set_attr "type" "alu_shift_reg")
d952d547 5333 (set_attr "predicable" "yes")
5334 (set_attr "predicable_short_it" "no")]
a2cd141b 5335)
5336
caedf871 5337(define_expand "extendsfdf2"
5338 [(set (match_operand:DF 0 "s_register_operand" "")
5339 (float_extend:DF (match_operand:SF 1 "s_register_operand" "")))]
a50d7267 5340 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
caedf871 5341 ""
5342)
9b8516be 5343
5344/* HFmode -> DFmode conversions have to go through SFmode. */
5345(define_expand "extendhfdf2"
5346 [(set (match_operand:DF 0 "general_operand" "")
5347 (float_extend:DF (match_operand:HF 1 "general_operand" "")))]
5348 "TARGET_EITHER"
5349 "
5350 {
5351 rtx op1;
5352 op1 = convert_to_mode (SFmode, operands[1], 0);
5353 op1 = convert_to_mode (DFmode, op1, 0);
5354 emit_insn (gen_movdf (operands[0], op1));
5355 DONE;
5356 }"
5357)
b11cae9e 5358\f
5359;; Move insns (including loads and stores)
5360
5361;; XXX Just some ideas about movti.
9c08d1fa 5362;; I don't think these are a good idea on the arm, there just aren't enough
5363;; registers
b11cae9e 5364;;(define_expand "loadti"
9c08d1fa 5365;; [(set (match_operand:TI 0 "s_register_operand" "")
b11cae9e 5366;; (mem:TI (match_operand:SI 1 "address_operand" "")))]
5367;; "" "")
5368
5369;;(define_expand "storeti"
5370;; [(set (mem:TI (match_operand:TI 0 "address_operand" ""))
9c08d1fa 5371;; (match_operand:TI 1 "s_register_operand" ""))]
b11cae9e 5372;; "" "")
5373
5374;;(define_expand "movti"
5375;; [(set (match_operand:TI 0 "general_operand" "")
5376;; (match_operand:TI 1 "general_operand" ""))]
5377;; ""
5378;; "
5379;;{
5380;; rtx insn;
5381;;
0438d37f 5382;; if (MEM_P (operands[0]) && MEM_P (operands[1]))
b11cae9e 5383;; operands[1] = copy_to_reg (operands[1]);
0438d37f 5384;; if (MEM_P (operands[0]))
b11cae9e 5385;; insn = gen_storeti (XEXP (operands[0], 0), operands[1]);
0438d37f 5386;; else if (MEM_P (operands[1]))
b11cae9e 5387;; insn = gen_loadti (operands[0], XEXP (operands[1], 0));
5388;; else
5389;; FAIL;
5390;;
5391;; emit_insn (insn);
5392;; DONE;
5393;;}")
5394
a2f10574 5395;; Recognize garbage generated above.
b11cae9e 5396
5397;;(define_insn ""
5398;; [(set (match_operand:TI 0 "general_operand" "=r,r,r,<,>,m")
5399;; (match_operand:TI 1 "general_operand" "<,>,m,r,r,r"))]
5400;; ""
5401;; "*
5402;; {
5403;; register mem = (which_alternative < 3);
0d66636f 5404;; register const char *template;
b11cae9e 5405;;
5406;; operands[mem] = XEXP (operands[mem], 0);
5407;; switch (which_alternative)
5408;; {
5409;; case 0: template = \"ldmdb\\t%1!, %M0\"; break;
5410;; case 1: template = \"ldmia\\t%1!, %M0\"; break;
5411;; case 2: template = \"ldmia\\t%1, %M0\"; break;
5412;; case 3: template = \"stmdb\\t%0!, %M1\"; break;
5413;; case 4: template = \"stmia\\t%0!, %M1\"; break;
5414;; case 5: template = \"stmia\\t%0, %M1\"; break;
5415;; }
e2348bcb 5416;; output_asm_insn (template, operands);
5417;; return \"\";
b11cae9e 5418;; }")
5419
cffb2a26 5420(define_expand "movdi"
5421 [(set (match_operand:DI 0 "general_operand" "")
5422 (match_operand:DI 1 "general_operand" ""))]
5423 "TARGET_EITHER"
5424 "
e1ba4a27 5425 if (can_create_pseudo_p ())
cffb2a26 5426 {
0438d37f 5427 if (!REG_P (operands[0]))
b2778788 5428 operands[1] = force_reg (DImode, operands[1]);
cffb2a26 5429 }
5430 "
5431)
b11cae9e 5432
cffb2a26 5433(define_insn "*arm_movdi"
353cf59a 5434 [(set (match_operand:DI 0 "nonimmediate_di_operand" "=r, r, r, q, m")
5435 (match_operand:DI 1 "di_operand" "rDa,Db,Dc,mi,q"))]
cde1623a 5436 "TARGET_32BIT
b805622c 5437 && !(TARGET_HARD_FLOAT && TARGET_VFP)
b2778788 5438 && !TARGET_IWMMXT
5439 && ( register_operand (operands[0], DImode)
5440 || register_operand (operands[1], DImode))"
b11cae9e 5441 "*
d51f92df 5442 switch (which_alternative)
5443 {
5444 case 0:
5445 case 1:
5446 case 2:
5447 return \"#\";
5448 default:
26ff80c0 5449 return output_move_double (operands, true, NULL);
d51f92df 5450 }
cffb2a26 5451 "
359a6e9f 5452 [(set_attr "length" "8,12,16,8,8")
1b7da4ac 5453 (set_attr "type" "multiple,multiple,multiple,load2,store2")
cde1623a 5454 (set_attr "arm_pool_range" "*,*,*,1020,*")
8848d797 5455 (set_attr "arm_neg_pool_range" "*,*,*,1004,*")
42e1de19 5456 (set_attr "thumb2_pool_range" "*,*,*,4094,*")
cde1623a 5457 (set_attr "thumb2_neg_pool_range" "*,*,*,0,*")]
cffb2a26 5458)
5459
d51f92df 5460(define_split
5461 [(set (match_operand:ANY64 0 "arm_general_register_operand" "")
e6dd3afa 5462 (match_operand:ANY64 1 "immediate_operand" ""))]
25f905c2 5463 "TARGET_32BIT
d51f92df 5464 && reload_completed
5465 && (arm_const_double_inline_cost (operands[1])
861033d5 5466 <= arm_max_const_double_inline_cost ())"
d51f92df 5467 [(const_int 0)]
5468 "
5469 arm_split_constant (SET, SImode, curr_insn,
5470 INTVAL (gen_lowpart (SImode, operands[1])),
5471 gen_lowpart (SImode, operands[0]), NULL_RTX, 0);
5472 arm_split_constant (SET, SImode, curr_insn,
5473 INTVAL (gen_highpart_mode (SImode,
5474 GET_MODE (operands[0]),
5475 operands[1])),
5476 gen_highpart (SImode, operands[0]), NULL_RTX, 0);
5477 DONE;
5478 "
5479)
5480
e5ba9289 5481; If optimizing for size, or if we have load delay slots, then
5482; we want to split the constant into two separate operations.
5483; In both cases this may split a trivial part into a single data op
5484; leaving a single complex constant to load. We can also get longer
5485; offsets in a LDR which means we get better chances of sharing the pool
5486; entries. Finally, we can normally do a better job of scheduling
5487; LDR instructions than we can with LDM.
5488; This pattern will only match if the one above did not.
5489(define_split
5490 [(set (match_operand:ANY64 0 "arm_general_register_operand" "")
5491 (match_operand:ANY64 1 "const_double_operand" ""))]
5492 "TARGET_ARM && reload_completed
5493 && arm_const_double_by_parts (operands[1])"
5494 [(set (match_dup 0) (match_dup 1))
5495 (set (match_dup 2) (match_dup 3))]
5496 "
5497 operands[2] = gen_highpart (SImode, operands[0]);
5498 operands[3] = gen_highpart_mode (SImode, GET_MODE (operands[0]),
5499 operands[1]);
5500 operands[0] = gen_lowpart (SImode, operands[0]);
5501 operands[1] = gen_lowpart (SImode, operands[1]);
5502 "
5503)
5504
d51f92df 5505(define_split
5506 [(set (match_operand:ANY64 0 "arm_general_register_operand" "")
5507 (match_operand:ANY64 1 "arm_general_register_operand" ""))]
5508 "TARGET_EITHER && reload_completed"
5509 [(set (match_dup 0) (match_dup 1))
5510 (set (match_dup 2) (match_dup 3))]
5511 "
5512 operands[2] = gen_highpart (SImode, operands[0]);
5513 operands[3] = gen_highpart (SImode, operands[1]);
5514 operands[0] = gen_lowpart (SImode, operands[0]);
5515 operands[1] = gen_lowpart (SImode, operands[1]);
5516
5517 /* Handle a partial overlap. */
5518 if (rtx_equal_p (operands[0], operands[3]))
5519 {
5520 rtx tmp0 = operands[0];
5521 rtx tmp1 = operands[1];
5522
5523 operands[0] = operands[2];
5524 operands[1] = operands[3];
5525 operands[2] = tmp0;
5526 operands[3] = tmp1;
5527 }
5528 "
5529)
5530
a8a3b539 5531;; We can't actually do base+index doubleword loads if the index and
5532;; destination overlap. Split here so that we at least have chance to
5533;; schedule.
5534(define_split
5535 [(set (match_operand:DI 0 "s_register_operand" "")
5536 (mem:DI (plus:SI (match_operand:SI 1 "s_register_operand" "")
5537 (match_operand:SI 2 "s_register_operand" ""))))]
5538 "TARGET_LDRD
5539 && reg_overlap_mentioned_p (operands[0], operands[1])
5540 && reg_overlap_mentioned_p (operands[0], operands[2])"
5541 [(set (match_dup 4)
5542 (plus:SI (match_dup 1)
5543 (match_dup 2)))
5544 (set (match_dup 0)
5545 (mem:DI (match_dup 4)))]
5546 "
5547 operands[4] = gen_rtx_REG (SImode, REGNO(operands[0]));
5548 "
5549)
5550
9c08d1fa 5551(define_expand "movsi"
5552 [(set (match_operand:SI 0 "general_operand" "")
5553 (match_operand:SI 1 "general_operand" ""))]
cffb2a26 5554 "TARGET_EITHER"
9c08d1fa 5555 "
befb0bac 5556 {
e348ff3e 5557 rtx base, offset, tmp;
5558
25f905c2 5559 if (TARGET_32BIT)
9c08d1fa 5560 {
674a8f0b 5561 /* Everything except mem = const or mem = mem can be done easily. */
0438d37f 5562 if (MEM_P (operands[0]))
cffb2a26 5563 operands[1] = force_reg (SImode, operands[1]);
a2cd141b 5564 if (arm_general_register_operand (operands[0], SImode)
0438d37f 5565 && CONST_INT_P (operands[1])
cffb2a26 5566 && !(const_ok_for_arm (INTVAL (operands[1]))
5567 || const_ok_for_arm (~INTVAL (operands[1]))))
5568 {
96f57e36 5569 arm_split_constant (SET, SImode, NULL_RTX,
5570 INTVAL (operands[1]), operands[0], NULL_RTX,
e1ba4a27 5571 optimize && can_create_pseudo_p ());
cffb2a26 5572 DONE;
5573 }
5574 }
25f905c2 5575 else /* TARGET_THUMB1... */
cffb2a26 5576 {
e1ba4a27 5577 if (can_create_pseudo_p ())
cffb2a26 5578 {
0438d37f 5579 if (!REG_P (operands[0]))
cffb2a26 5580 operands[1] = force_reg (SImode, operands[1]);
5581 }
9c08d1fa 5582 }
f655717d 5583
e348ff3e 5584 if (ARM_OFFSETS_MUST_BE_WITHIN_SECTIONS_P)
5585 {
5586 split_const (operands[1], &base, &offset);
5587 if (GET_CODE (base) == SYMBOL_REF
5588 && !offset_within_block_p (base, INTVAL (offset)))
5589 {
b308ddcf 5590 tmp = can_create_pseudo_p () ? gen_reg_rtx (SImode) : operands[0];
e348ff3e 5591 emit_move_insn (tmp, base);
5592 emit_insn (gen_addsi3 (operands[0], tmp, offset));
5593 DONE;
5594 }
5595 }
5596
f655717d 5597 /* Recognize the case where operand[1] is a reference to thread-local
5598 data and load its address to a register. */
5599 if (arm_tls_referenced_p (operands[1]))
5600 {
5601 rtx tmp = operands[1];
5602 rtx addend = NULL;
5603
5604 if (GET_CODE (tmp) == CONST && GET_CODE (XEXP (tmp, 0)) == PLUS)
5605 {
5606 addend = XEXP (XEXP (tmp, 0), 1);
5607 tmp = XEXP (XEXP (tmp, 0), 0);
5608 }
5609
5610 gcc_assert (GET_CODE (tmp) == SYMBOL_REF);
5611 gcc_assert (SYMBOL_REF_TLS_MODEL (tmp) != 0);
5612
e1ba4a27 5613 tmp = legitimize_tls_address (tmp,
5614 !can_create_pseudo_p () ? operands[0] : 0);
f655717d 5615 if (addend)
5616 {
5617 tmp = gen_rtx_PLUS (SImode, tmp, addend);
5618 tmp = force_operand (tmp, operands[0]);
5619 }
5620 operands[1] = tmp;
5621 }
5622 else if (flag_pic
5623 && (CONSTANT_P (operands[1])
5624 || symbol_mentioned_p (operands[1])
5625 || label_mentioned_p (operands[1])))
5626 operands[1] = legitimize_pic_address (operands[1], SImode,
e1ba4a27 5627 (!can_create_pseudo_p ()
5628 ? operands[0]
5629 : 0));
befb0bac 5630 }
215b30b3 5631 "
5632)
9c08d1fa 5633
d0e6a121 5634;; The ARM LO_SUM and HIGH are backwards - HIGH sets the low bits, and
5635;; LO_SUM adds in the high bits. Fortunately these are opaque operations
5636;; so this does not matter.
5637(define_insn "*arm_movt"
5638 [(set (match_operand:SI 0 "nonimmediate_operand" "=r")
5639 (lo_sum:SI (match_operand:SI 1 "nonimmediate_operand" "0")
5640 (match_operand:SI 2 "general_operand" "i")))]
c9b2ce40 5641 "arm_arch_thumb2"
d0e6a121 5642 "movt%?\t%0, #:upper16:%c2"
5643 [(set_attr "predicable" "yes")
d952d547 5644 (set_attr "predicable_short_it" "no")
1b7da4ac 5645 (set_attr "length" "4")
5646 (set_attr "type" "mov_imm")]
d0e6a121 5647)
5648
cffb2a26 5649(define_insn "*arm_movsi_insn"
aaa37ad6 5650 [(set (match_operand:SI 0 "nonimmediate_operand" "=rk,r,r,r,rk,m")
110eae03 5651 (match_operand:SI 1 "general_operand" "rk, I,K,j,mi,rk"))]
755eb2b4 5652 "TARGET_ARM && ! TARGET_IWMMXT
a2cd141b 5653 && !(TARGET_HARD_FLOAT && TARGET_VFP)
cffb2a26 5654 && ( register_operand (operands[0], SImode)
5655 || register_operand (operands[1], SImode))"
f7fbdd4a 5656 "@
aaa37ad6 5657 mov%?\\t%0, %1
f7fbdd4a 5658 mov%?\\t%0, %1
5659 mvn%?\\t%0, #%B1
25f905c2 5660 movw%?\\t%0, %1
f7fbdd4a 5661 ldr%?\\t%0, %1
5662 str%?\\t%1, %0"
1aed5204 5663 [(set_attr "type" "mov_reg,mov_imm,mvn_imm,mov_imm,load1,store1")
0d66636f 5664 (set_attr "predicable" "yes")
aaa37ad6 5665 (set_attr "pool_range" "*,*,*,*,4096,*")
5666 (set_attr "neg_pool_range" "*,*,*,*,4084,*")]
cffb2a26 5667)
87b22bf7 5668
5669(define_split
a2cd141b 5670 [(set (match_operand:SI 0 "arm_general_register_operand" "")
87b22bf7 5671 (match_operand:SI 1 "const_int_operand" ""))]
25f905c2 5672 "TARGET_32BIT
215b30b3 5673 && (!(const_ok_for_arm (INTVAL (operands[1]))
5674 || const_ok_for_arm (~INTVAL (operands[1]))))"
87b22bf7 5675 [(clobber (const_int 0))]
5676 "
96f57e36 5677 arm_split_constant (SET, SImode, NULL_RTX,
5678 INTVAL (operands[1]), operands[0], NULL_RTX, 0);
87b22bf7 5679 DONE;
215b30b3 5680 "
5681)
9c08d1fa 5682
861033d5 5683;; A normal way to do (symbol + offset) requires three instructions at least
5684;; (depends on how big the offset is) as below:
5685;; movw r0, #:lower16:g
5686;; movw r0, #:upper16:g
5687;; adds r0, #4
5688;;
5689;; A better way would be:
5690;; movw r0, #:lower16:g+4
5691;; movw r0, #:upper16:g+4
5692;;
5693;; The limitation of this way is that the length of offset should be a 16-bit
5694;; signed value, because current assembler only supports REL type relocation for
5695;; such case. If the more powerful RELA type is supported in future, we should
5696;; update this pattern to go with better way.
5697(define_split
5698 [(set (match_operand:SI 0 "arm_general_register_operand" "")
5699 (const:SI (plus:SI (match_operand:SI 1 "general_operand" "")
5700 (match_operand:SI 2 "const_int_operand" ""))))]
5701 "TARGET_THUMB2
5702 && arm_disable_literal_pool
5703 && reload_completed
5704 && GET_CODE (operands[1]) == SYMBOL_REF"
5705 [(clobber (const_int 0))]
5706 "
5707 int offset = INTVAL (operands[2]);
5708
5709 if (offset < -0x8000 || offset > 0x7fff)
5710 {
5711 arm_emit_movpair (operands[0], operands[1]);
5712 emit_insn (gen_rtx_SET (SImode, operands[0],
5713 gen_rtx_PLUS (SImode, operands[0], operands[2])));
5714 }
5715 else
5716 {
5717 rtx op = gen_rtx_CONST (SImode,
5718 gen_rtx_PLUS (SImode, operands[1], operands[2]));
5719 arm_emit_movpair (operands[0], op);
5720 }
5721 "
5722)
5723
b8d5d078 5724;; Split symbol_refs at the later stage (after cprop), instead of generating
5725;; movt/movw pair directly at expand. Otherwise corresponding high_sum
5726;; and lo_sum would be merged back into memory load at cprop. However,
5727;; if the default is to prefer movt/movw rather than a load from the constant
5728;; pool, the performance is better.
5729(define_split
5730 [(set (match_operand:SI 0 "arm_general_register_operand" "")
5731 (match_operand:SI 1 "general_operand" ""))]
5732 "TARGET_32BIT
5733 && TARGET_USE_MOVT && GET_CODE (operands[1]) == SYMBOL_REF
5734 && !flag_pic && !target_word_relocations
5735 && !arm_tls_referenced_p (operands[1])"
5736 [(clobber (const_int 0))]
5737{
5738 arm_emit_movpair (operands[0], operands[1]);
5739 DONE;
5740})
5741
bc360af8 5742;; When generating pic, we need to load the symbol offset into a register.
5743;; So that the optimizer does not confuse this with a normal symbol load
5744;; we use an unspec. The offset will be loaded from a constant pool entry,
5745;; since that is the only type of relocation we can use.
cffb2a26 5746
bc360af8 5747;; Wrap calculation of the whole PIC address in a single pattern for the
5748;; benefit of optimizers, particularly, PRE and HOIST. Calculation of
5749;; a PIC address involves two loads from memory, so we want to CSE it
5750;; as often as possible.
5751;; This pattern will be split into one of the pic_load_addr_* patterns
5752;; and a move after GCSE optimizations.
5753;;
5754;; Note: Update arm.c: legitimize_pic_address() when changing this pattern.
5755(define_expand "calculate_pic_address"
94f8caca 5756 [(set (match_operand:SI 0 "register_operand" "")
5757 (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "")
5758 (unspec:SI [(match_operand:SI 2 "" "")]
5759 UNSPEC_PIC_SYM))))]
5760 "flag_pic"
5761)
5762
5763;; Split calculate_pic_address into pic_load_addr_* and a move.
5764(define_split
5765 [(set (match_operand:SI 0 "register_operand" "")
5766 (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "")
5767 (unspec:SI [(match_operand:SI 2 "" "")]
5768 UNSPEC_PIC_SYM))))]
5769 "flag_pic"
5770 [(set (match_dup 3) (unspec:SI [(match_dup 2)] UNSPEC_PIC_SYM))
5771 (set (match_dup 0) (mem:SI (plus:SI (match_dup 1) (match_dup 3))))]
5772 "operands[3] = can_create_pseudo_p () ? gen_reg_rtx (SImode) : operands[0];"
5773)
5774
350ccca5 5775;; operand1 is the memory address to go into
5776;; pic_load_addr_32bit.
5777;; operand2 is the PIC label to be emitted
5778;; from pic_add_dot_plus_eight.
5779;; We do this to allow hoisting of the entire insn.
5780(define_insn_and_split "pic_load_addr_unified"
5781 [(set (match_operand:SI 0 "s_register_operand" "=r,r,l")
5782 (unspec:SI [(match_operand:SI 1 "" "mX,mX,mX")
5783 (match_operand:SI 2 "" "")]
5784 UNSPEC_PIC_UNIFIED))]
5785 "flag_pic"
5786 "#"
5787 "&& reload_completed"
5788 [(set (match_dup 0) (unspec:SI [(match_dup 1)] UNSPEC_PIC_SYM))
5789 (set (match_dup 0) (unspec:SI [(match_dup 0) (match_dup 3)
5790 (match_dup 2)] UNSPEC_PIC_BASE))]
5791 "operands[3] = TARGET_THUMB ? GEN_INT (4) : GEN_INT (8);"
5792 [(set_attr "type" "load1,load1,load1")
42e1de19 5793 (set_attr "pool_range" "4096,4094,1022")
350ccca5 5794 (set_attr "neg_pool_range" "4084,0,0")
5795 (set_attr "arch" "a,t2,t1")
5796 (set_attr "length" "8,6,4")]
5797)
5798
67336bcf 5799;; The rather odd constraints on the following are to force reload to leave
5800;; the insn alone, and to force the minipool generation pass to then move
5801;; the GOT symbol to memory.
849170fd 5802
b3cd5f55 5803(define_insn "pic_load_addr_32bit"
849170fd 5804 [(set (match_operand:SI 0 "s_register_operand" "=r")
e1159bbe 5805 (unspec:SI [(match_operand:SI 1 "" "mX")] UNSPEC_PIC_SYM))]
b3cd5f55 5806 "TARGET_32BIT && flag_pic"
67336bcf 5807 "ldr%?\\t%0, %1"
a2cd141b 5808 [(set_attr "type" "load1")
42e1de19 5809 (set (attr "pool_range")
5810 (if_then_else (eq_attr "is_thumb" "no")
5811 (const_int 4096)
5812 (const_int 4094)))
b3cd5f55 5813 (set (attr "neg_pool_range")
5814 (if_then_else (eq_attr "is_thumb" "no")
5815 (const_int 4084)
5816 (const_int 0)))]
8c4d8060 5817)
5818
25f905c2 5819(define_insn "pic_load_addr_thumb1"
8c4d8060 5820 [(set (match_operand:SI 0 "s_register_operand" "=l")
e1159bbe 5821 (unspec:SI [(match_operand:SI 1 "" "mX")] UNSPEC_PIC_SYM))]
25f905c2 5822 "TARGET_THUMB1 && flag_pic"
8c4d8060 5823 "ldr\\t%0, %1"
a2cd141b 5824 [(set_attr "type" "load1")
42e1de19 5825 (set (attr "pool_range") (const_int 1018))]
cffb2a26 5826)
849170fd 5827
cffb2a26 5828(define_insn "pic_add_dot_plus_four"
15d5d060 5829 [(set (match_operand:SI 0 "register_operand" "=r")
c0c1fba5 5830 (unspec:SI [(match_operand:SI 1 "register_operand" "0")
5831 (const_int 4)
beef0fb5 5832 (match_operand 2 "" "")]
5833 UNSPEC_PIC_BASE))]
b3cd5f55 5834 "TARGET_THUMB"
cffb2a26 5835 "*
6cdcb15c 5836 (*targetm.asm_out.internal_label) (asm_out_file, \"LPIC\",
5837 INTVAL (operands[2]));
cffb2a26 5838 return \"add\\t%0, %|pc\";
5839 "
1b7da4ac 5840 [(set_attr "length" "2")
5841 (set_attr "type" "alu_reg")]
cffb2a26 5842)
849170fd 5843
5844(define_insn "pic_add_dot_plus_eight"
15d5d060 5845 [(set (match_operand:SI 0 "register_operand" "=r")
c0c1fba5 5846 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
5847 (const_int 8)
beef0fb5 5848 (match_operand 2 "" "")]
5849 UNSPEC_PIC_BASE))]
f655717d 5850 "TARGET_ARM"
c4034607 5851 "*
6cdcb15c 5852 (*targetm.asm_out.internal_label) (asm_out_file, \"LPIC\",
5853 INTVAL (operands[2]));
15d5d060 5854 return \"add%?\\t%0, %|pc, %1\";
cffb2a26 5855 "
1b7da4ac 5856 [(set_attr "predicable" "yes")
5857 (set_attr "type" "alu_reg")]
cffb2a26 5858)
849170fd 5859
f655717d 5860(define_insn "tls_load_dot_plus_eight"
cc071db6 5861 [(set (match_operand:SI 0 "register_operand" "=r")
c0c1fba5 5862 (mem:SI (unspec:SI [(match_operand:SI 1 "register_operand" "r")
5863 (const_int 8)
beef0fb5 5864 (match_operand 2 "" "")]
5865 UNSPEC_PIC_BASE)))]
f655717d 5866 "TARGET_ARM"
5867 "*
6cdcb15c 5868 (*targetm.asm_out.internal_label) (asm_out_file, \"LPIC\",
5869 INTVAL (operands[2]));
f655717d 5870 return \"ldr%?\\t%0, [%|pc, %1]\t\t@ tls_load_dot_plus_eight\";
5871 "
1b7da4ac 5872 [(set_attr "predicable" "yes")
5873 (set_attr "type" "load1")]
f655717d 5874)
5875
5876;; PIC references to local variables can generate pic_add_dot_plus_eight
5877;; followed by a load. These sequences can be crunched down to
5878;; tls_load_dot_plus_eight by a peephole.
5879
5880(define_peephole2
c0c1fba5 5881 [(set (match_operand:SI 0 "register_operand" "")
5882 (unspec:SI [(match_operand:SI 3 "register_operand" "")
5883 (const_int 8)
5884 (match_operand 1 "" "")]
5885 UNSPEC_PIC_BASE))
2d05dfad 5886 (set (match_operand:SI 2 "arm_general_register_operand" "")
5887 (mem:SI (match_dup 0)))]
f655717d 5888 "TARGET_ARM && peep2_reg_dead_p (2, operands[0])"
c0c1fba5 5889 [(set (match_dup 2)
5890 (mem:SI (unspec:SI [(match_dup 3)
5891 (const_int 8)
5892 (match_dup 1)]
5893 UNSPEC_PIC_BASE)))]
f655717d 5894 ""
5895)
5896
bac7fc85 5897(define_insn "pic_offset_arm"
5898 [(set (match_operand:SI 0 "register_operand" "=r")
5899 (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
5900 (unspec:SI [(match_operand:SI 2 "" "X")]
5901 UNSPEC_PIC_OFFSET))))]
5902 "TARGET_VXWORKS_RTP && TARGET_ARM && flag_pic"
5903 "ldr%?\\t%0, [%1,%2]"
5904 [(set_attr "type" "load1")]
5905)
5906
95373f08 5907(define_expand "builtin_setjmp_receiver"
5908 [(label_ref (match_operand 0 "" ""))]
5909 "flag_pic"
5910 "
5911{
b935b306 5912 /* r3 is clobbered by set/longjmp, so we can use it as a scratch
5913 register. */
2cb7d577 5914 if (arm_pic_register != INVALID_REGNUM)
5915 arm_load_pic_register (1UL << 3);
95373f08 5916 DONE;
5917}")
5918
9c08d1fa 5919;; If copying one reg to another we can set the condition codes according to
5920;; its value. Such a move is common after a return from subroutine and the
5921;; result is being tested against zero.
5922
f7fbdd4a 5923(define_insn "*movsi_compare0"
bd5b4116 5924 [(set (reg:CC CC_REGNUM)
cffb2a26 5925 (compare:CC (match_operand:SI 1 "s_register_operand" "0,r")
5926 (const_int 0)))
5927 (set (match_operand:SI 0 "s_register_operand" "=r,r")
5928 (match_dup 1))]
25f905c2 5929 "TARGET_32BIT"
e2348bcb 5930 "@
40dbec34 5931 cmp%?\\t%0, #0
25f905c2 5932 sub%.\\t%0, %1, #0"
65f68e55 5933 [(set_attr "conds" "set")
d82e788e 5934 (set_attr "type" "alus_imm,alus_imm")]
cffb2a26 5935)
b11cae9e 5936
b11cae9e 5937;; Subroutine to store a half word from a register into memory.
5938;; Operand 0 is the source register (HImode)
c8f69309 5939;; Operand 1 is the destination address in a register (SImode)
b11cae9e 5940
9c08d1fa 5941;; In both this routine and the next, we must be careful not to spill
01cc3b75 5942;; a memory address of reg+large_const into a separate PLUS insn, since this
9c08d1fa 5943;; can generate unrecognizable rtl.
5944
b11cae9e 5945(define_expand "storehi"
c8f69309 5946 [;; store the low byte
f082f1c4 5947 (set (match_operand 1 "" "") (match_dup 3))
b11cae9e 5948 ;; extract the high byte
c8f69309 5949 (set (match_dup 2)
5950 (ashiftrt:SI (match_operand 0 "" "") (const_int 8)))
b11cae9e 5951 ;; store the high byte
787f8210 5952 (set (match_dup 4) (match_dup 5))]
cffb2a26 5953 "TARGET_ARM"
b11cae9e 5954 "
215b30b3 5955 {
537ffcfc 5956 rtx op1 = operands[1];
5957 rtx addr = XEXP (op1, 0);
215b30b3 5958 enum rtx_code code = GET_CODE (addr);
5959
0438d37f 5960 if ((code == PLUS && !CONST_INT_P (XEXP (addr, 1)))
215b30b3 5961 || code == MINUS)
537ffcfc 5962 op1 = replace_equiv_address (operands[1], force_reg (SImode, addr));
215b30b3 5963
537ffcfc 5964 operands[4] = adjust_address (op1, QImode, 1);
e513d163 5965 operands[1] = adjust_address (operands[1], QImode, 0);
215b30b3 5966 operands[3] = gen_lowpart (QImode, operands[0]);
5967 operands[0] = gen_lowpart (SImode, operands[0]);
787f8210 5968 operands[2] = gen_reg_rtx (SImode);
5969 operands[5] = gen_lowpart (QImode, operands[2]);
215b30b3 5970 }"
5971)
b11cae9e 5972
c7597b5d 5973(define_expand "storehi_bigend"
f082f1c4 5974 [(set (match_dup 4) (match_dup 3))
c7597b5d 5975 (set (match_dup 2)
5976 (ashiftrt:SI (match_operand 0 "" "") (const_int 8)))
787f8210 5977 (set (match_operand 1 "" "") (match_dup 5))]
cffb2a26 5978 "TARGET_ARM"
b11cae9e 5979 "
215b30b3 5980 {
537ffcfc 5981 rtx op1 = operands[1];
5982 rtx addr = XEXP (op1, 0);
215b30b3 5983 enum rtx_code code = GET_CODE (addr);
5984
0438d37f 5985 if ((code == PLUS && !CONST_INT_P (XEXP (addr, 1)))
215b30b3 5986 || code == MINUS)
537ffcfc 5987 op1 = replace_equiv_address (op1, force_reg (SImode, addr));
215b30b3 5988
537ffcfc 5989 operands[4] = adjust_address (op1, QImode, 1);
e513d163 5990 operands[1] = adjust_address (operands[1], QImode, 0);
215b30b3 5991 operands[3] = gen_lowpart (QImode, operands[0]);
5992 operands[0] = gen_lowpart (SImode, operands[0]);
5993 operands[2] = gen_reg_rtx (SImode);
787f8210 5994 operands[5] = gen_lowpart (QImode, operands[2]);
215b30b3 5995 }"
5996)
c7597b5d 5997
5998;; Subroutine to store a half word integer constant into memory.
5999(define_expand "storeinthi"
f082f1c4 6000 [(set (match_operand 0 "" "")
787f8210 6001 (match_operand 1 "" ""))
9e8503e6 6002 (set (match_dup 3) (match_dup 2))]
cffb2a26 6003 "TARGET_ARM"
c7597b5d 6004 "
215b30b3 6005 {
6006 HOST_WIDE_INT value = INTVAL (operands[1]);
6007 rtx addr = XEXP (operands[0], 0);
537ffcfc 6008 rtx op0 = operands[0];
215b30b3 6009 enum rtx_code code = GET_CODE (addr);
c7597b5d 6010
0438d37f 6011 if ((code == PLUS && !CONST_INT_P (XEXP (addr, 1)))
215b30b3 6012 || code == MINUS)
537ffcfc 6013 op0 = replace_equiv_address (op0, force_reg (SImode, addr));
c7597b5d 6014
215b30b3 6015 operands[1] = gen_reg_rtx (SImode);
6016 if (BYTES_BIG_ENDIAN)
6017 {
6018 emit_insn (gen_movsi (operands[1], GEN_INT ((value >> 8) & 255)));
6019 if ((value & 255) == ((value >> 8) & 255))
6020 operands[2] = operands[1];
6021 else
6022 {
6023 operands[2] = gen_reg_rtx (SImode);
6024 emit_insn (gen_movsi (operands[2], GEN_INT (value & 255)));
6025 }
6026 }
6027 else
6028 {
6029 emit_insn (gen_movsi (operands[1], GEN_INT (value & 255)));
6030 if ((value & 255) == ((value >> 8) & 255))
6031 operands[2] = operands[1];
6032 else
6033 {
6034 operands[2] = gen_reg_rtx (SImode);
6035 emit_insn (gen_movsi (operands[2], GEN_INT ((value >> 8) & 255)));
6036 }
6037 }
c7597b5d 6038
537ffcfc 6039 operands[3] = adjust_address (op0, QImode, 1);
e513d163 6040 operands[0] = adjust_address (operands[0], QImode, 0);
9e8503e6 6041 operands[2] = gen_lowpart (QImode, operands[2]);
787f8210 6042 operands[1] = gen_lowpart (QImode, operands[1]);
215b30b3 6043 }"
6044)
b11cae9e 6045
f7fbdd4a 6046(define_expand "storehi_single_op"
6047 [(set (match_operand:HI 0 "memory_operand" "")
6048 (match_operand:HI 1 "general_operand" ""))]
25f905c2 6049 "TARGET_32BIT && arm_arch4"
f7fbdd4a 6050 "
215b30b3 6051 if (!s_register_operand (operands[1], HImode))
f7fbdd4a 6052 operands[1] = copy_to_mode_reg (HImode, operands[1]);
215b30b3 6053 "
6054)
f7fbdd4a 6055
b11cae9e 6056(define_expand "movhi"
6057 [(set (match_operand:HI 0 "general_operand" "")
c8f69309 6058 (match_operand:HI 1 "general_operand" ""))]
cffb2a26 6059 "TARGET_EITHER"
b11cae9e 6060 "
cffb2a26 6061 if (TARGET_ARM)
b11cae9e 6062 {
e1ba4a27 6063 if (can_create_pseudo_p ())
cffb2a26 6064 {
0438d37f 6065 if (MEM_P (operands[0]))
b11cae9e 6066 {
cffb2a26 6067 if (arm_arch4)
6068 {
6069 emit_insn (gen_storehi_single_op (operands[0], operands[1]));
6070 DONE;
6071 }
0438d37f 6072 if (CONST_INT_P (operands[1]))
cffb2a26 6073 emit_insn (gen_storeinthi (operands[0], operands[1]));
c7597b5d 6074 else
cffb2a26 6075 {
0438d37f 6076 if (MEM_P (operands[1]))
cffb2a26 6077 operands[1] = force_reg (HImode, operands[1]);
6078 if (BYTES_BIG_ENDIAN)
6079 emit_insn (gen_storehi_bigend (operands[1], operands[0]));
6080 else
6081 emit_insn (gen_storehi (operands[1], operands[0]));
6082 }
6083 DONE;
b11cae9e 6084 }
cffb2a26 6085 /* Sign extend a constant, and keep it in an SImode reg. */
0438d37f 6086 else if (CONST_INT_P (operands[1]))
9c08d1fa 6087 {
cffb2a26 6088 rtx reg = gen_reg_rtx (SImode);
6089 HOST_WIDE_INT val = INTVAL (operands[1]) & 0xffff;
6090
6091 /* If the constant is already valid, leave it alone. */
215b30b3 6092 if (!const_ok_for_arm (val))
cffb2a26 6093 {
6094 /* If setting all the top bits will make the constant
6095 loadable in a single instruction, then set them.
6096 Otherwise, sign extend the number. */
6097
215b30b3 6098 if (const_ok_for_arm (~(val | ~0xffff)))
cffb2a26 6099 val |= ~0xffff;
6100 else if (val & 0x8000)
6101 val |= ~0xffff;
6102 }
6103
6104 emit_insn (gen_movsi (reg, GEN_INT (val)));
9e8503e6 6105 operands[1] = gen_lowpart (HImode, reg);
9c08d1fa 6106 }
e1ba4a27 6107 else if (arm_arch4 && optimize && can_create_pseudo_p ()
0438d37f 6108 && MEM_P (operands[1]))
0045890a 6109 {
6110 rtx reg = gen_reg_rtx (SImode);
6111
6112 emit_insn (gen_zero_extendhisi2 (reg, operands[1]));
6113 operands[1] = gen_lowpart (HImode, reg);
6114 }
215b30b3 6115 else if (!arm_arch4)
f7fbdd4a 6116 {
0438d37f 6117 if (MEM_P (operands[1]))
cffb2a26 6118 {
c1a66faf 6119 rtx base;
6120 rtx offset = const0_rtx;
6121 rtx reg = gen_reg_rtx (SImode);
6122
0438d37f 6123 if ((REG_P (base = XEXP (operands[1], 0))
c1a66faf 6124 || (GET_CODE (base) == PLUS
0438d37f 6125 && (CONST_INT_P (offset = XEXP (base, 1)))
c1a66faf 6126 && ((INTVAL(offset) & 1) != 1)
0438d37f 6127 && REG_P (base = XEXP (base, 0))))
c1a66faf 6128 && REGNO_POINTER_ALIGN (REGNO (base)) >= 32)
206ee9a2 6129 {
8deb3959 6130 rtx new_rtx;
c1a66faf 6131
8deb3959 6132 new_rtx = widen_memory_access (operands[1], SImode,
6133 ((INTVAL (offset) & ~3)
6134 - INTVAL (offset)));
6135 emit_insn (gen_movsi (reg, new_rtx));
c1a66faf 6136 if (((INTVAL (offset) & 2) != 0)
6137 ^ (BYTES_BIG_ENDIAN ? 1 : 0))
6138 {
6139 rtx reg2 = gen_reg_rtx (SImode);
6140
6141 emit_insn (gen_lshrsi3 (reg2, reg, GEN_INT (16)));
6142 reg = reg2;
6143 }
206ee9a2 6144 }
c1a66faf 6145 else
6146 emit_insn (gen_movhi_bytes (reg, operands[1]));
6147
6148 operands[1] = gen_lowpart (HImode, reg);
cffb2a26 6149 }
6150 }
6151 }
674a8f0b 6152 /* Handle loading a large integer during reload. */
0438d37f 6153 else if (CONST_INT_P (operands[1])
215b30b3 6154 && !const_ok_for_arm (INTVAL (operands[1]))
6155 && !const_ok_for_arm (~INTVAL (operands[1])))
cffb2a26 6156 {
6157 /* Writing a constant to memory needs a scratch, which should
6158 be handled with SECONDARY_RELOADs. */
0438d37f 6159 gcc_assert (REG_P (operands[0]));
cffb2a26 6160
6161 operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
6162 emit_insn (gen_movsi (operands[0], operands[1]));
6163 DONE;
6164 }
6165 }
25f905c2 6166 else if (TARGET_THUMB2)
6167 {
6168 /* Thumb-2 can do everything except mem=mem and mem=const easily. */
e1ba4a27 6169 if (can_create_pseudo_p ())
25f905c2 6170 {
0438d37f 6171 if (!REG_P (operands[0]))
25f905c2 6172 operands[1] = force_reg (HImode, operands[1]);
6173 /* Zero extend a constant, and keep it in an SImode reg. */
0438d37f 6174 else if (CONST_INT_P (operands[1]))
25f905c2 6175 {
6176 rtx reg = gen_reg_rtx (SImode);
6177 HOST_WIDE_INT val = INTVAL (operands[1]) & 0xffff;
6178
6179 emit_insn (gen_movsi (reg, GEN_INT (val)));
6180 operands[1] = gen_lowpart (HImode, reg);
6181 }
6182 }
6183 }
6184 else /* TARGET_THUMB1 */
cffb2a26 6185 {
e1ba4a27 6186 if (can_create_pseudo_p ())
cffb2a26 6187 {
0438d37f 6188 if (CONST_INT_P (operands[1]))
6cffc037 6189 {
6190 rtx reg = gen_reg_rtx (SImode);
6191
6192 emit_insn (gen_movsi (reg, operands[1]));
6193 operands[1] = gen_lowpart (HImode, reg);
6194 }
cffb2a26 6195
6196 /* ??? We shouldn't really get invalid addresses here, but this can
215b30b3 6197 happen if we are passed a SP (never OK for HImode/QImode) or
bc409cb4 6198 virtual register (also rejected as illegitimate for HImode/QImode)
6199 relative address. */
cffb2a26 6200 /* ??? This should perhaps be fixed elsewhere, for instance, in
6201 fixup_stack_1, by checking for other kinds of invalid addresses,
6202 e.g. a bare reference to a virtual register. This may confuse the
6203 alpha though, which must handle this case differently. */
0438d37f 6204 if (MEM_P (operands[0])
215b30b3 6205 && !memory_address_p (GET_MODE (operands[0]),
6206 XEXP (operands[0], 0)))
537ffcfc 6207 operands[0]
6208 = replace_equiv_address (operands[0],
6209 copy_to_reg (XEXP (operands[0], 0)));
cffb2a26 6210
0438d37f 6211 if (MEM_P (operands[1])
215b30b3 6212 && !memory_address_p (GET_MODE (operands[1]),
6213 XEXP (operands[1], 0)))
537ffcfc 6214 operands[1]
6215 = replace_equiv_address (operands[1],
6216 copy_to_reg (XEXP (operands[1], 0)));
6cffc037 6217
0438d37f 6218 if (MEM_P (operands[1]) && optimize > 0)
6cffc037 6219 {
6220 rtx reg = gen_reg_rtx (SImode);
6221
6222 emit_insn (gen_zero_extendhisi2 (reg, operands[1]));
6223 operands[1] = gen_lowpart (HImode, reg);
6224 }
6225
0438d37f 6226 if (MEM_P (operands[0]))
6cffc037 6227 operands[1] = force_reg (HImode, operands[1]);
cffb2a26 6228 }
0438d37f 6229 else if (CONST_INT_P (operands[1])
234f6557 6230 && !satisfies_constraint_I (operands[1]))
cffb2a26 6231 {
6cffc037 6232 /* Handle loading a large integer during reload. */
6233
cffb2a26 6234 /* Writing a constant to memory needs a scratch, which should
6235 be handled with SECONDARY_RELOADs. */
0438d37f 6236 gcc_assert (REG_P (operands[0]));
cffb2a26 6237
1a83b3ff 6238 operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
cffb2a26 6239 emit_insn (gen_movsi (operands[0], operands[1]));
6240 DONE;
6241 }
b11cae9e 6242 }
cffb2a26 6243 "
6244)
6245
25f7a26e 6246(define_expand "movhi_bytes"
eab14235 6247 [(set (match_dup 2) (zero_extend:SI (match_operand:HI 1 "" "")))
25f7a26e 6248 (set (match_dup 3)
eab14235 6249 (zero_extend:SI (match_dup 6)))
25f7a26e 6250 (set (match_operand:SI 0 "" "")
6251 (ior:SI (ashift:SI (match_dup 4) (const_int 8)) (match_dup 5)))]
cffb2a26 6252 "TARGET_ARM"
25f7a26e 6253 "
215b30b3 6254 {
6255 rtx mem1, mem2;
6256 rtx addr = copy_to_mode_reg (SImode, XEXP (operands[1], 0));
6257
788fcce0 6258 mem1 = change_address (operands[1], QImode, addr);
29c05e22 6259 mem2 = change_address (operands[1], QImode,
6260 plus_constant (Pmode, addr, 1));
215b30b3 6261 operands[0] = gen_lowpart (SImode, operands[0]);
6262 operands[1] = mem1;
6263 operands[2] = gen_reg_rtx (SImode);
6264 operands[3] = gen_reg_rtx (SImode);
6265 operands[6] = mem2;
25f7a26e 6266
215b30b3 6267 if (BYTES_BIG_ENDIAN)
6268 {
6269 operands[4] = operands[2];
6270 operands[5] = operands[3];
6271 }
6272 else
6273 {
6274 operands[4] = operands[3];
6275 operands[5] = operands[2];
6276 }
6277 }"
6278)
25f7a26e 6279
c7597b5d 6280(define_expand "movhi_bigend"
6281 [(set (match_dup 2)
6282 (rotate:SI (subreg:SI (match_operand:HI 1 "memory_operand" "") 0)
6283 (const_int 16)))
6284 (set (match_dup 3)
6285 (ashiftrt:SI (match_dup 2) (const_int 16)))
6286 (set (match_operand:HI 0 "s_register_operand" "")
787f8210 6287 (match_dup 4))]
cffb2a26 6288 "TARGET_ARM"
c7597b5d 6289 "
6290 operands[2] = gen_reg_rtx (SImode);
6291 operands[3] = gen_reg_rtx (SImode);
787f8210 6292 operands[4] = gen_lowpart (HImode, operands[3]);
215b30b3 6293 "
6294)
b11cae9e 6295
a2f10574 6296;; Pattern to recognize insn generated default case above
f7fbdd4a 6297(define_insn "*movhi_insn_arch4"
cde1623a 6298 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,m,r")
85e02ccb 6299 (match_operand:HI 1 "general_operand" "rI,K,r,mi"))]
cffb2a26 6300 "TARGET_ARM
6301 && arm_arch4
85e02ccb 6302 && (register_operand (operands[0], HImode)
6303 || register_operand (operands[1], HImode))"
f7fbdd4a 6304 "@
6305 mov%?\\t%0, %1\\t%@ movhi
6306 mvn%?\\t%0, #%B1\\t%@ movhi
25f905c2 6307 str%(h%)\\t%1, %0\\t%@ movhi
6308 ldr%(h%)\\t%0, %1\\t%@ movhi"
65f68e55 6309 [(set_attr "predicable" "yes")
cffb2a26 6310 (set_attr "pool_range" "*,*,*,256")
65f68e55 6311 (set_attr "neg_pool_range" "*,*,*,244")
6312 (set_attr_alternative "type"
6313 [(if_then_else (match_operand 1 "const_int_operand" "")
1aed5204 6314 (const_string "mov_imm" )
6315 (const_string "mov_reg"))
6316 (const_string "mvn_imm")
65f68e55 6317 (const_string "store1")
6318 (const_string "load1")])]
cffb2a26 6319)
f7fbdd4a 6320
f7fbdd4a 6321(define_insn "*movhi_bytes"
65f68e55 6322 [(set (match_operand:HI 0 "s_register_operand" "=r,r,r")
6323 (match_operand:HI 1 "arm_rhs_operand" "I,r,K"))]
c1a66faf 6324 "TARGET_ARM"
25f7a26e 6325 "@
65f68e55 6326 mov%?\\t%0, %1\\t%@ movhi
25f7a26e 6327 mov%?\\t%0, %1\\t%@ movhi
0d66636f 6328 mvn%?\\t%0, #%B1\\t%@ movhi"
d2a518d1 6329 [(set_attr "predicable" "yes")
1aed5204 6330 (set_attr "type" "mov_imm,mov_reg,mvn_imm")]
0d66636f 6331)
cffb2a26 6332
bc5c7e08 6333;; We use a DImode scratch because we may occasionally need an additional
6334;; temporary if the address isn't offsettable -- push_reload doesn't seem
6335;; to take any notice of the "o" constraints on reload_memory_operand operand.
d3373b54 6336(define_expand "reload_outhi"
cffb2a26 6337 [(parallel [(match_operand:HI 0 "arm_reload_memory_operand" "=o")
215b30b3 6338 (match_operand:HI 1 "s_register_operand" "r")
6339 (match_operand:DI 2 "s_register_operand" "=&l")])]
cffb2a26 6340 "TARGET_EITHER"
6341 "if (TARGET_ARM)
6342 arm_reload_out_hi (operands);
6343 else
6344 thumb_reload_out_hi (operands);
d3373b54 6345 DONE;
cffb2a26 6346 "
6347)
d3373b54 6348
25f7a26e 6349(define_expand "reload_inhi"
6350 [(parallel [(match_operand:HI 0 "s_register_operand" "=r")
cffb2a26 6351 (match_operand:HI 1 "arm_reload_memory_operand" "o")
bc5c7e08 6352 (match_operand:DI 2 "s_register_operand" "=&r")])]
c1a66faf 6353 "TARGET_EITHER"
25f7a26e 6354 "
cffb2a26 6355 if (TARGET_ARM)
6356 arm_reload_in_hi (operands);
6357 else
6358 thumb_reload_out_hi (operands);
25f7a26e 6359 DONE;
6360")
6361
9c08d1fa 6362(define_expand "movqi"
6363 [(set (match_operand:QI 0 "general_operand" "")
6364 (match_operand:QI 1 "general_operand" ""))]
cffb2a26 6365 "TARGET_EITHER"
9c08d1fa 6366 "
6cffc037 6367 /* Everything except mem = const or mem = mem can be done easily */
0045890a 6368
e1ba4a27 6369 if (can_create_pseudo_p ())
cffb2a26 6370 {
0438d37f 6371 if (CONST_INT_P (operands[1]))
6cffc037 6372 {
6373 rtx reg = gen_reg_rtx (SImode);
6374
03770691 6375 /* For thumb we want an unsigned immediate, then we are more likely
6376 to be able to use a movs insn. */
6377 if (TARGET_THUMB)
6378 operands[1] = GEN_INT (INTVAL (operands[1]) & 255);
6379
6cffc037 6380 emit_insn (gen_movsi (reg, operands[1]));
6381 operands[1] = gen_lowpart (QImode, reg);
6382 }
cffb2a26 6383
6cffc037 6384 if (TARGET_THUMB)
6385 {
cffb2a26 6386 /* ??? We shouldn't really get invalid addresses here, but this can
215b30b3 6387 happen if we are passed a SP (never OK for HImode/QImode) or
bc409cb4 6388 virtual register (also rejected as illegitimate for HImode/QImode)
6389 relative address. */
cffb2a26 6390 /* ??? This should perhaps be fixed elsewhere, for instance, in
6391 fixup_stack_1, by checking for other kinds of invalid addresses,
6392 e.g. a bare reference to a virtual register. This may confuse the
6393 alpha though, which must handle this case differently. */
0438d37f 6394 if (MEM_P (operands[0])
215b30b3 6395 && !memory_address_p (GET_MODE (operands[0]),
cffb2a26 6396 XEXP (operands[0], 0)))
537ffcfc 6397 operands[0]
6398 = replace_equiv_address (operands[0],
6399 copy_to_reg (XEXP (operands[0], 0)));
0438d37f 6400 if (MEM_P (operands[1])
215b30b3 6401 && !memory_address_p (GET_MODE (operands[1]),
cffb2a26 6402 XEXP (operands[1], 0)))
537ffcfc 6403 operands[1]
6404 = replace_equiv_address (operands[1],
6405 copy_to_reg (XEXP (operands[1], 0)));
6cffc037 6406 }
6407
0438d37f 6408 if (MEM_P (operands[1]) && optimize > 0)
6cffc037 6409 {
6410 rtx reg = gen_reg_rtx (SImode);
6411
6412 emit_insn (gen_zero_extendqisi2 (reg, operands[1]));
6413 operands[1] = gen_lowpart (QImode, reg);
6414 }
6415
0438d37f 6416 if (MEM_P (operands[0]))
6cffc037 6417 operands[1] = force_reg (QImode, operands[1]);
6418 }
6419 else if (TARGET_THUMB
0438d37f 6420 && CONST_INT_P (operands[1])
234f6557 6421 && !satisfies_constraint_I (operands[1]))
6cffc037 6422 {
674a8f0b 6423 /* Handle loading a large integer during reload. */
cffb2a26 6424
6cffc037 6425 /* Writing a constant to memory needs a scratch, which should
6426 be handled with SECONDARY_RELOADs. */
0438d37f 6427 gcc_assert (REG_P (operands[0]));
6cffc037 6428
6429 operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
6430 emit_insn (gen_movsi (operands[0], operands[1]));
6431 DONE;
cffb2a26 6432 }
6433 "
6434)
b11cae9e 6435
cffb2a26 6436(define_insn "*arm_movqi_insn"
fd711051 6437 [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,r,l,r,l,Uu,r,m")
6438 (match_operand:QI 1 "general_operand" "r,r,I,Py,K,Uu,l,m,r"))]
25f905c2 6439 "TARGET_32BIT
cffb2a26 6440 && ( register_operand (operands[0], QImode)
6441 || register_operand (operands[1], QImode))"
5565501b 6442 "@
fd711051 6443 mov%?\\t%0, %1
6444 mov%?\\t%0, %1
65f68e55 6445 mov%?\\t%0, %1
5565501b 6446 mov%?\\t%0, %1
6447 mvn%?\\t%0, #%B1
25f905c2 6448 ldr%(b%)\\t%0, %1
a54e3e7b 6449 str%(b%)\\t%1, %0
6450 ldr%(b%)\\t%0, %1
25f905c2 6451 str%(b%)\\t%1, %0"
1aed5204 6452 [(set_attr "type" "mov_reg,mov_reg,mov_imm,mov_imm,mvn_imm,load1,store1,load1,store1")
a54e3e7b 6453 (set_attr "predicable" "yes")
fd711051 6454 (set_attr "predicable_short_it" "yes,yes,yes,no,no,no,no,no,no")
6455 (set_attr "arch" "t2,any,any,t2,any,t2,t2,any,any")
6456 (set_attr "length" "2,4,4,2,4,2,2,4,4")]
cffb2a26 6457)
6458
9b8516be 6459;; HFmode moves
6460(define_expand "movhf"
6461 [(set (match_operand:HF 0 "general_operand" "")
6462 (match_operand:HF 1 "general_operand" ""))]
6463 "TARGET_EITHER"
6464 "
6465 if (TARGET_32BIT)
6466 {
0438d37f 6467 if (MEM_P (operands[0]))
9b8516be 6468 operands[1] = force_reg (HFmode, operands[1]);
6469 }
6470 else /* TARGET_THUMB1 */
6471 {
6472 if (can_create_pseudo_p ())
6473 {
0438d37f 6474 if (!REG_P (operands[0]))
9b8516be 6475 operands[1] = force_reg (HFmode, operands[1]);
6476 }
6477 }
6478 "
6479)
6480
6481(define_insn "*arm32_movhf"
6482 [(set (match_operand:HF 0 "nonimmediate_operand" "=r,m,r,r")
6483 (match_operand:HF 1 "general_operand" " m,r,r,F"))]
7c36fe71 6484 "TARGET_32BIT && !(TARGET_HARD_FLOAT && TARGET_FP16) && !arm_restrict_it
9b8516be 6485 && ( s_register_operand (operands[0], HFmode)
6486 || s_register_operand (operands[1], HFmode))"
6487 "*
6488 switch (which_alternative)
6489 {
6490 case 0: /* ARM register from memory */
6491 return \"ldr%(h%)\\t%0, %1\\t%@ __fp16\";
6492 case 1: /* memory from ARM register */
6493 return \"str%(h%)\\t%1, %0\\t%@ __fp16\";
6494 case 2: /* ARM register from ARM register */
6495 return \"mov%?\\t%0, %1\\t%@ __fp16\";
6496 case 3: /* ARM register from constant */
6497 {
6498 REAL_VALUE_TYPE r;
6499 long bits;
6500 rtx ops[4];
6501
6502 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
6503 bits = real_to_target (NULL, &r, HFmode);
6504 ops[0] = operands[0];
6505 ops[1] = GEN_INT (bits);
6506 ops[2] = GEN_INT (bits & 0xff00);
6507 ops[3] = GEN_INT (bits & 0x00ff);
6508
6509 if (arm_arch_thumb2)
6510 output_asm_insn (\"movw%?\\t%0, %1\", ops);
6511 else
6512 output_asm_insn (\"mov%?\\t%0, %2\;orr%?\\t%0, %0, %3\", ops);
6513 return \"\";
6514 }
6515 default:
6516 gcc_unreachable ();
6517 }
6518 "
6519 [(set_attr "conds" "unconditional")
ad4fc3c0 6520 (set_attr "type" "load1,store1,mov_reg,multiple")
9b8516be 6521 (set_attr "length" "4,4,4,8")
d2a518d1 6522 (set_attr "predicable" "yes")]
9b8516be 6523)
6524
87b22bf7 6525(define_expand "movsf"
6526 [(set (match_operand:SF 0 "general_operand" "")
6527 (match_operand:SF 1 "general_operand" ""))]
cffb2a26 6528 "TARGET_EITHER"
87b22bf7 6529 "
25f905c2 6530 if (TARGET_32BIT)
cffb2a26 6531 {
0438d37f 6532 if (MEM_P (operands[0]))
cffb2a26 6533 operands[1] = force_reg (SFmode, operands[1]);
6534 }
25f905c2 6535 else /* TARGET_THUMB1 */
cffb2a26 6536 {
e1ba4a27 6537 if (can_create_pseudo_p ())
cffb2a26 6538 {
0438d37f 6539 if (!REG_P (operands[0]))
cffb2a26 6540 operands[1] = force_reg (SFmode, operands[1]);
6541 }
6542 }
6543 "
6544)
6545
03d440a6 6546;; Transform a floating-point move of a constant into a core register into
6547;; an SImode operation.
cffb2a26 6548(define_split
03d440a6 6549 [(set (match_operand:SF 0 "arm_general_register_operand" "")
cffb2a26 6550 (match_operand:SF 1 "immediate_operand" ""))]
339034d0 6551 "TARGET_EITHER
cffb2a26 6552 && reload_completed
0438d37f 6553 && CONST_DOUBLE_P (operands[1])"
cffb2a26 6554 [(set (match_dup 2) (match_dup 3))]
6555 "
6556 operands[2] = gen_lowpart (SImode, operands[0]);
6557 operands[3] = gen_lowpart (SImode, operands[1]);
6558 if (operands[2] == 0 || operands[3] == 0)
6559 FAIL;
215b30b3 6560 "
6561)
87b22bf7 6562
cffb2a26 6563(define_insn "*arm_movsf_soft_insn"
6564 [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,m")
6565 (match_operand:SF 1 "general_operand" "r,mE,r"))]
cde1623a 6566 "TARGET_32BIT
cffb2a26 6567 && TARGET_SOFT_FLOAT
0438d37f 6568 && (!MEM_P (operands[0])
215b30b3 6569 || register_operand (operands[1], SFmode))"
9a1112d7 6570 "@
6571 mov%?\\t%0, %1
6572 ldr%?\\t%0, %1\\t%@ float
6573 str%?\\t%1, %0\\t%@ float"
cde1623a 6574 [(set_attr "predicable" "yes")
7c36fe71 6575 (set_attr "predicable_short_it" "no")
1aed5204 6576 (set_attr "type" "mov_reg,load1,store1")
42e1de19 6577 (set_attr "arm_pool_range" "*,4096,*")
6578 (set_attr "thumb2_pool_range" "*,4094,*")
cde1623a 6579 (set_attr "arm_neg_pool_range" "*,4084,*")
6580 (set_attr "thumb2_neg_pool_range" "*,0,*")]
cffb2a26 6581)
6582
9c08d1fa 6583(define_expand "movdf"
87b22bf7 6584 [(set (match_operand:DF 0 "general_operand" "")
6585 (match_operand:DF 1 "general_operand" ""))]
cffb2a26 6586 "TARGET_EITHER"
9c08d1fa 6587 "
25f905c2 6588 if (TARGET_32BIT)
cffb2a26 6589 {
0438d37f 6590 if (MEM_P (operands[0]))
cffb2a26 6591 operands[1] = force_reg (DFmode, operands[1]);
6592 }
6593 else /* TARGET_THUMB */
6594 {
e1ba4a27 6595 if (can_create_pseudo_p ())
cffb2a26 6596 {
0438d37f 6597 if (!REG_P (operands[0]))
cffb2a26 6598 operands[1] = force_reg (DFmode, operands[1]);
6599 }
6600 }
6601 "
6602)
b11cae9e 6603
9c08d1fa 6604;; Reloading a df mode value stored in integer regs to memory can require a
6605;; scratch reg.
6606(define_expand "reload_outdf"
cffb2a26 6607 [(match_operand:DF 0 "arm_reload_memory_operand" "=o")
87b22bf7 6608 (match_operand:DF 1 "s_register_operand" "r")
6609 (match_operand:SI 2 "s_register_operand" "=&r")]
06adefdc 6610 "TARGET_THUMB2"
87b22bf7 6611 "
215b30b3 6612 {
6613 enum rtx_code code = GET_CODE (XEXP (operands[0], 0));
f7fbdd4a 6614
215b30b3 6615 if (code == REG)
6616 operands[2] = XEXP (operands[0], 0);
6617 else if (code == POST_INC || code == PRE_DEC)
6618 {
6619 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
6620 operands[1] = gen_rtx_SUBREG (DImode, operands[1], 0);
6621 emit_insn (gen_movdi (operands[0], operands[1]));
6622 DONE;
6623 }
6624 else if (code == PRE_INC)
6625 {
6626 rtx reg = XEXP (XEXP (operands[0], 0), 0);
f7fbdd4a 6627
215b30b3 6628 emit_insn (gen_addsi3 (reg, reg, GEN_INT (8)));
6629 operands[2] = reg;
6630 }
6631 else if (code == POST_DEC)
6632 operands[2] = XEXP (XEXP (operands[0], 0), 0);
6633 else
6634 emit_insn (gen_addsi3 (operands[2], XEXP (XEXP (operands[0], 0), 0),
6635 XEXP (XEXP (operands[0], 0), 1)));
f7fbdd4a 6636
788fcce0 6637 emit_insn (gen_rtx_SET (VOIDmode,
6638 replace_equiv_address (operands[0], operands[2]),
215b30b3 6639 operands[1]));
f7fbdd4a 6640
215b30b3 6641 if (code == POST_DEC)
6642 emit_insn (gen_addsi3 (operands[2], operands[2], GEN_INT (-8)));
6643
6644 DONE;
6645 }"
6646)
9c08d1fa 6647
9a1112d7 6648(define_insn "*movdf_soft_insn"
353cf59a 6649 [(set (match_operand:DF 0 "nonimmediate_soft_df_operand" "=r,r,r,q,m")
6650 (match_operand:DF 1 "soft_df_operand" "rDa,Db,Dc,mF,q"))]
cde1623a 6651 "TARGET_32BIT && TARGET_SOFT_FLOAT
b2778788 6652 && ( register_operand (operands[0], DFmode)
6653 || register_operand (operands[1], DFmode))"
d51f92df 6654 "*
6655 switch (which_alternative)
6656 {
6657 case 0:
6658 case 1:
6659 case 2:
6660 return \"#\";
6661 default:
26ff80c0 6662 return output_move_double (operands, true, NULL);
d51f92df 6663 }
6664 "
359a6e9f 6665 [(set_attr "length" "8,12,16,8,8")
1b7da4ac 6666 (set_attr "type" "multiple,multiple,multiple,load2,store2")
42e1de19 6667 (set_attr "arm_pool_range" "*,*,*,1020,*")
6668 (set_attr "thumb2_pool_range" "*,*,*,1018,*")
8848d797 6669 (set_attr "arm_neg_pool_range" "*,*,*,1004,*")
cde1623a 6670 (set_attr "thumb2_neg_pool_range" "*,*,*,0,*")]
cffb2a26 6671)
b11cae9e 6672\f
b11cae9e 6673
9c08d1fa 6674;; load- and store-multiple insns
6675;; The arm can load/store any set of registers, provided that they are in
320ea44d 6676;; ascending order, but these expanders assume a contiguous set.
b11cae9e 6677
9c08d1fa 6678(define_expand "load_multiple"
6679 [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
6680 (match_operand:SI 1 "" ""))
6681 (use (match_operand:SI 2 "" ""))])]
25f905c2 6682 "TARGET_32BIT"
9580c25f 6683{
6684 HOST_WIDE_INT offset = 0;
6685
bd5b4116 6686 /* Support only fixed point registers. */
0438d37f 6687 if (!CONST_INT_P (operands[2])
9c08d1fa 6688 || INTVAL (operands[2]) > 14
6689 || INTVAL (operands[2]) < 2
0438d37f 6690 || !MEM_P (operands[1])
6691 || !REG_P (operands[0])
bd5b4116 6692 || REGNO (operands[0]) > (LAST_ARM_REGNUM - 1)
6693 || REGNO (operands[0]) + INTVAL (operands[2]) > LAST_ARM_REGNUM)
9c08d1fa 6694 FAIL;
6695
6696 operands[3]
320ea44d 6697 = arm_gen_load_multiple (arm_regs_in_sequence + REGNO (operands[0]),
6698 INTVAL (operands[2]),
f082f1c4 6699 force_reg (SImode, XEXP (operands[1], 0)),
320ea44d 6700 FALSE, operands[1], &offset);
9580c25f 6701})
b11cae9e 6702
9c08d1fa 6703(define_expand "store_multiple"
6704 [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
6705 (match_operand:SI 1 "" ""))
6706 (use (match_operand:SI 2 "" ""))])]
25f905c2 6707 "TARGET_32BIT"
9580c25f 6708{
6709 HOST_WIDE_INT offset = 0;
6710
674a8f0b 6711 /* Support only fixed point registers. */
0438d37f 6712 if (!CONST_INT_P (operands[2])
9c08d1fa 6713 || INTVAL (operands[2]) > 14
6714 || INTVAL (operands[2]) < 2
0438d37f 6715 || !REG_P (operands[1])
6716 || !MEM_P (operands[0])
bd5b4116 6717 || REGNO (operands[1]) > (LAST_ARM_REGNUM - 1)
6718 || REGNO (operands[1]) + INTVAL (operands[2]) > LAST_ARM_REGNUM)
9c08d1fa 6719 FAIL;
6720
6721 operands[3]
320ea44d 6722 = arm_gen_store_multiple (arm_regs_in_sequence + REGNO (operands[1]),
6723 INTVAL (operands[2]),
f082f1c4 6724 force_reg (SImode, XEXP (operands[0], 0)),
320ea44d 6725 FALSE, operands[0], &offset);
9580c25f 6726})
b11cae9e 6727
9c08d1fa 6728
6729;; Move a block of memory if it is word aligned and MORE than 2 words long.
6730;; We could let this apply for blocks of less than this, but it clobbers so
6731;; many registers that there is then probably a better way.
6732
008c057d 6733(define_expand "movmemqi"
34191dd1 6734 [(match_operand:BLK 0 "general_operand" "")
6735 (match_operand:BLK 1 "general_operand" "")
6736 (match_operand:SI 2 "const_int_operand" "")
6737 (match_operand:SI 3 "const_int_operand" "")]
ae51a965 6738 ""
9c08d1fa 6739 "
25f905c2 6740 if (TARGET_32BIT)
cffb2a26 6741 {
ae51a965 6742 if (TARGET_LDRD && current_tune->prefer_ldrd_strd
6743 && !optimize_function_for_size_p (cfun))
6744 {
6745 if (gen_movmem_ldrd_strd (operands))
6746 DONE;
6747 FAIL;
6748 }
6749
008c057d 6750 if (arm_gen_movmemqi (operands))
cffb2a26 6751 DONE;
6752 FAIL;
6753 }
25f905c2 6754 else /* TARGET_THUMB1 */
cffb2a26 6755 {
6756 if ( INTVAL (operands[3]) != 4
6757 || INTVAL (operands[2]) > 48)
6758 FAIL;
6759
008c057d 6760 thumb_expand_movmemqi (operands);
cffb2a26 6761 DONE;
6762 }
6763 "
6764)
9c08d1fa 6765\f
b11cae9e 6766
341940e8 6767;; Compare & branch insns
8d232dc7 6768;; The range calculations are based as follows:
341940e8 6769;; For forward branches, the address calculation returns the address of
6770;; the next instruction. This is 2 beyond the branch instruction.
6771;; For backward branches, the address calculation returns the address of
6772;; the first instruction in this pattern (cmp). This is 2 before the branch
6773;; instruction for the shortest sequence, and 4 before the branch instruction
6774;; if we have to jump around an unconditional branch.
6775;; To the basic branch range the PC offset must be added (this is +4).
6776;; So for forward branches we have
6777;; (pos_range - pos_base_offs + pc_offs) = (pos_range - 2 + 4).
6778;; And for backward branches we have
6779;; (neg_range - neg_base_offs + pc_offs) = (neg_range - (-2 or -4) + 4).
6780;;
6781;; For a 'b' pos_range = 2046, neg_range = -2048 giving (-2040->2048).
6782;; For a 'b<cond>' pos_range = 254, neg_range = -256 giving (-250 ->256).
cffb2a26 6783
aeac46d4 6784(define_expand "cbranchsi4"
6785 [(set (pc) (if_then_else
aa06947a 6786 (match_operator 0 "expandable_comparison_operator"
aeac46d4 6787 [(match_operand:SI 1 "s_register_operand" "")
6788 (match_operand:SI 2 "nonmemory_operand" "")])
6789 (label_ref (match_operand 3 "" ""))
6790 (pc)))]
f9aa4160 6791 "TARGET_EITHER"
aeac46d4 6792 "
74f4459c 6793 if (!TARGET_THUMB1)
6794 {
f9aa4160 6795 if (!arm_validize_comparison (&operands[0], &operands[1], &operands[2]))
6796 FAIL;
74f4459c 6797 emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
6798 operands[3]));
6799 DONE;
6800 }
25f905c2 6801 if (thumb1_cmpneg_operand (operands[2], SImode))
aeac46d4 6802 {
6803 emit_jump_insn (gen_cbranchsi4_scratch (NULL, operands[1], operands[2],
6804 operands[3], operands[0]));
6805 DONE;
6806 }
25f905c2 6807 if (!thumb1_cmp_operand (operands[2], SImode))
aeac46d4 6808 operands[2] = force_reg (SImode, operands[2]);
6809 ")
6810
74f4459c 6811(define_expand "cbranchsf4"
6812 [(set (pc) (if_then_else
aa06947a 6813 (match_operator 0 "expandable_comparison_operator"
74f4459c 6814 [(match_operand:SF 1 "s_register_operand" "")
6815 (match_operand:SF 2 "arm_float_compare_operand" "")])
6816 (label_ref (match_operand 3 "" ""))
6817 (pc)))]
6818 "TARGET_32BIT && TARGET_HARD_FLOAT"
6819 "emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
6820 operands[3])); DONE;"
6821)
6822
6823(define_expand "cbranchdf4"
6824 [(set (pc) (if_then_else
aa06947a 6825 (match_operator 0 "expandable_comparison_operator"
74f4459c 6826 [(match_operand:DF 1 "s_register_operand" "")
6827 (match_operand:DF 2 "arm_float_compare_operand" "")])
6828 (label_ref (match_operand 3 "" ""))
6829 (pc)))]
a50d7267 6830 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
74f4459c 6831 "emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
6832 operands[3])); DONE;"
6833)
6834
74f4459c 6835(define_expand "cbranchdi4"
6836 [(set (pc) (if_then_else
aa06947a 6837 (match_operator 0 "expandable_comparison_operator"
b8eae306 6838 [(match_operand:DI 1 "s_register_operand" "")
a8045a4f 6839 (match_operand:DI 2 "cmpdi_operand" "")])
74f4459c 6840 (label_ref (match_operand 3 "" ""))
6841 (pc)))]
a8045a4f 6842 "TARGET_32BIT"
6843 "{
0438d37f 6844 if (!arm_validize_comparison (&operands[0], &operands[1], &operands[2]))
f9aa4160 6845 FAIL;
6846 emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
a8045a4f 6847 operands[3]));
6848 DONE;
6849 }"
74f4459c 6850)
6851
9c08d1fa 6852;; Comparison and test insns
6853
cffb2a26 6854(define_insn "*arm_cmpsi_insn"
bd5b4116 6855 [(set (reg:CC CC_REGNUM)
f9f234ec 6856 (compare:CC (match_operand:SI 0 "s_register_operand" "l,r,r,r,r")
6857 (match_operand:SI 1 "arm_add_operand" "Py,r,r,I,L")))]
25f905c2 6858 "TARGET_32BIT"
5565501b 6859 "@
a6864a24 6860 cmp%?\\t%0, %1
6861 cmp%?\\t%0, %1
aea4c774 6862 cmp%?\\t%0, %1
f9f234ec 6863 cmp%?\\t%0, %1
aea4c774 6864 cmn%?\\t%0, #%n1"
a6864a24 6865 [(set_attr "conds" "set")
f9f234ec 6866 (set_attr "arch" "t2,t2,any,any,any")
6867 (set_attr "length" "2,2,4,4,4")
65f68e55 6868 (set_attr "predicable" "yes")
f9f234ec 6869 (set_attr "predicable_short_it" "yes,yes,yes,no,no")
6870 (set_attr "type" "alus_imm,alus_reg,alus_reg,alus_imm,alus_imm")]
cffb2a26 6871)
b11cae9e 6872
d5d4dc8d 6873(define_insn "*cmpsi_shiftsi"
bd5b4116 6874 [(set (reg:CC CC_REGNUM)
d82e788e 6875 (compare:CC (match_operand:SI 0 "s_register_operand" "r,r,r")
cffb2a26 6876 (match_operator:SI 3 "shift_operator"
d82e788e 6877 [(match_operand:SI 1 "s_register_operand" "r,r,r")
6878 (match_operand:SI 2 "shift_amount_operand" "M,r,M")])))]
d5d4dc8d 6879 "TARGET_32BIT"
f9f234ec 6880 "cmp\\t%0, %1%S3"
344495ea 6881 [(set_attr "conds" "set")
331beb1a 6882 (set_attr "shift" "1")
d82e788e 6883 (set_attr "arch" "32,a,a")
6884 (set_attr "type" "alus_shift_imm,alu_shift_reg,alus_shift_imm")])
b11cae9e 6885
d5d4dc8d 6886(define_insn "*cmpsi_shiftsi_swp"
bd5b4116 6887 [(set (reg:CC_SWP CC_REGNUM)
aea4c774 6888 (compare:CC_SWP (match_operator:SI 3 "shift_operator"
d82e788e 6889 [(match_operand:SI 1 "s_register_operand" "r,r,r")
6890 (match_operand:SI 2 "shift_amount_operand" "M,r,M")])
6891 (match_operand:SI 0 "s_register_operand" "r,r,r")))]
d5d4dc8d 6892 "TARGET_32BIT"
aea4c774 6893 "cmp%?\\t%0, %1%S3"
344495ea 6894 [(set_attr "conds" "set")
331beb1a 6895 (set_attr "shift" "1")
d82e788e 6896 (set_attr "arch" "32,a,a")
6897 (set_attr "type" "alus_shift_imm,alu_shift_reg,alus_shift_imm")])
b11cae9e 6898
25f905c2 6899(define_insn "*arm_cmpsi_negshiftsi_si"
aed179ae 6900 [(set (reg:CC_Z CC_REGNUM)
6901 (compare:CC_Z
6902 (neg:SI (match_operator:SI 1 "shift_operator"
6903 [(match_operand:SI 2 "s_register_operand" "r")
6904 (match_operand:SI 3 "reg_or_int_operand" "rM")]))
6905 (match_operand:SI 0 "s_register_operand" "r")))]
cffb2a26 6906 "TARGET_ARM"
aed179ae 6907 "cmn%?\\t%0, %2%S1"
344495ea 6908 [(set_attr "conds" "set")
aed179ae 6909 (set (attr "type") (if_then_else (match_operand 3 "const_int_operand" "")
d82e788e 6910 (const_string "alus_shift_imm")
6911 (const_string "alus_shift_reg")))
596e5e8f 6912 (set_attr "predicable" "yes")]
0d66636f 6913)
b11cae9e 6914
a8045a4f 6915;; DImode comparisons. The generic code generates branches that
6916;; if-conversion can not reduce to a conditional compare, so we do
6917;; that directly.
6918
ba6a3b2f 6919(define_insn_and_split "*arm_cmpdi_insn"
a8045a4f 6920 [(set (reg:CC_NCV CC_REGNUM)
6921 (compare:CC_NCV (match_operand:DI 0 "s_register_operand" "r")
6922 (match_operand:DI 1 "arm_di_operand" "rDi")))
6923 (clobber (match_scratch:SI 2 "=r"))]
b805622c 6924 "TARGET_32BIT"
ba6a3b2f 6925 "#" ; "cmp\\t%Q0, %Q1\;sbcs\\t%2, %R0, %R1"
6926 "&& reload_completed"
6927 [(set (reg:CC CC_REGNUM)
6928 (compare:CC (match_dup 0) (match_dup 1)))
6929 (parallel [(set (reg:CC CC_REGNUM)
6930 (compare:CC (match_dup 3) (match_dup 4)))
6931 (set (match_dup 2)
6932 (minus:SI (match_dup 5)
6933 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))])]
6934 {
6935 operands[3] = gen_highpart (SImode, operands[0]);
6936 operands[0] = gen_lowpart (SImode, operands[0]);
6937 if (CONST_INT_P (operands[1]))
6938 {
6939 operands[4] = GEN_INT (~INTVAL (gen_highpart_mode (SImode,
6940 DImode,
6941 operands[1])));
6942 operands[5] = gen_rtx_PLUS (SImode, operands[3], operands[4]);
6943 }
6944 else
6945 {
6946 operands[4] = gen_highpart (SImode, operands[1]);
6947 operands[5] = gen_rtx_MINUS (SImode, operands[3], operands[4]);
6948 }
6949 operands[1] = gen_lowpart (SImode, operands[1]);
6950 operands[2] = gen_lowpart (SImode, operands[2]);
6951 }
a8045a4f 6952 [(set_attr "conds" "set")
1b7da4ac 6953 (set_attr "length" "8")
6954 (set_attr "type" "multiple")]
a8045a4f 6955)
6956
ba6a3b2f 6957(define_insn_and_split "*arm_cmpdi_unsigned"
a8045a4f 6958 [(set (reg:CC_CZ CC_REGNUM)
1a86364b 6959 (compare:CC_CZ (match_operand:DI 0 "s_register_operand" "l,r,r,r")
6960 (match_operand:DI 1 "arm_di_operand" "Py,r,Di,rDi")))]
7c36fe71 6961
48a98053 6962 "TARGET_32BIT"
ba6a3b2f 6963 "#" ; "cmp\\t%R0, %R1\;it eq\;cmpeq\\t%Q0, %Q1"
6964 "&& reload_completed"
6965 [(set (reg:CC CC_REGNUM)
6966 (compare:CC (match_dup 2) (match_dup 3)))
6967 (cond_exec (eq:SI (reg:CC CC_REGNUM) (const_int 0))
6968 (set (reg:CC CC_REGNUM)
6969 (compare:CC (match_dup 0) (match_dup 1))))]
6970 {
6971 operands[2] = gen_highpart (SImode, operands[0]);
6972 operands[0] = gen_lowpart (SImode, operands[0]);
6973 if (CONST_INT_P (operands[1]))
6974 operands[3] = gen_highpart_mode (SImode, DImode, operands[1]);
6975 else
6976 operands[3] = gen_highpart (SImode, operands[1]);
6977 operands[1] = gen_lowpart (SImode, operands[1]);
6978 }
a8045a4f 6979 [(set_attr "conds" "set")
1a86364b 6980 (set_attr "enabled_for_depr_it" "yes,yes,no,*")
6981 (set_attr "arch" "t2,t2,t2,a")
6982 (set_attr "length" "6,6,10,8")
1b7da4ac 6983 (set_attr "type" "multiple")]
a8045a4f 6984)
6985
6986(define_insn "*arm_cmpdi_zero"
6987 [(set (reg:CC_Z CC_REGNUM)
6988 (compare:CC_Z (match_operand:DI 0 "s_register_operand" "r")
6989 (const_int 0)))
6990 (clobber (match_scratch:SI 1 "=r"))]
6991 "TARGET_32BIT"
6992 "orr%.\\t%1, %Q0, %R0"
1b7da4ac 6993 [(set_attr "conds" "set")
6994 (set_attr "type" "logics_reg")]
a8045a4f 6995)
6996
9c08d1fa 6997; This insn allows redundant compares to be removed by cse, nothing should
6998; ever appear in the output file since (set (reg x) (reg x)) is a no-op that
6999; is deleted later on. The match_dup will match the mode here, so that
7000; mode changes of the condition codes aren't lost by this even though we don't
7001; specify what they are.
7002
8a18b90c 7003(define_insn "*deleted_compare"
9c08d1fa 7004 [(set (match_operand 0 "cc_register" "") (match_dup 0))]
25f905c2 7005 "TARGET_32BIT"
40dbec34 7006 "\\t%@ deleted compare"
cffb2a26 7007 [(set_attr "conds" "set")
1b7da4ac 7008 (set_attr "length" "0")
7009 (set_attr "type" "no_insn")]
cffb2a26 7010)
9c08d1fa 7011
7012\f
7013;; Conditional branch insns
7014
74f4459c 7015(define_expand "cbranch_cc"
9c08d1fa 7016 [(set (pc)
74f4459c 7017 (if_then_else (match_operator 0 "" [(match_operand 1 "" "")
7018 (match_operand 2 "" "")])
7019 (label_ref (match_operand 3 "" ""))
9c08d1fa 7020 (pc)))]
25f905c2 7021 "TARGET_32BIT"
74f4459c 7022 "operands[1] = arm_gen_compare_reg (GET_CODE (operands[0]),
e1b93706 7023 operands[1], operands[2], NULL_RTX);
74f4459c 7024 operands[2] = const0_rtx;"
8fa3ba89 7025)
7026
7027;;
7028;; Patterns to match conditional branch insns.
7029;;
7030
ffcc986d 7031(define_insn "arm_cond_branch"
9c08d1fa 7032 [(set (pc)
8fa3ba89 7033 (if_then_else (match_operator 1 "arm_comparison_operator"
8a18b90c 7034 [(match_operand 2 "cc_register" "") (const_int 0)])
9c08d1fa 7035 (label_ref (match_operand 0 "" ""))
7036 (pc)))]
25f905c2 7037 "TARGET_32BIT"
d75350ce 7038 "*
9c08d1fa 7039 if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
cffb2a26 7040 {
7041 arm_ccfsm_state += 2;
7042 return \"\";
7043 }
e2348bcb 7044 return \"b%d1\\t%l0\";
cffb2a26 7045 "
a2cd141b 7046 [(set_attr "conds" "use")
a6864a24 7047 (set_attr "type" "branch")
7048 (set (attr "length")
7049 (if_then_else
0bf497f5 7050 (and (match_test "TARGET_THUMB2")
a6864a24 7051 (and (ge (minus (match_dup 0) (pc)) (const_int -250))
7052 (le (minus (match_dup 0) (pc)) (const_int 256))))
7053 (const_int 2)
7054 (const_int 4)))]
cffb2a26 7055)
d75350ce 7056
cffb2a26 7057(define_insn "*arm_cond_branch_reversed"
9c08d1fa 7058 [(set (pc)
8fa3ba89 7059 (if_then_else (match_operator 1 "arm_comparison_operator"
8a18b90c 7060 [(match_operand 2 "cc_register" "") (const_int 0)])
9c08d1fa 7061 (pc)
7062 (label_ref (match_operand 0 "" ""))))]
25f905c2 7063 "TARGET_32BIT"
d75350ce 7064 "*
9c08d1fa 7065 if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
cffb2a26 7066 {
7067 arm_ccfsm_state += 2;
7068 return \"\";
7069 }
e2348bcb 7070 return \"b%D1\\t%l0\";
cffb2a26 7071 "
a2cd141b 7072 [(set_attr "conds" "use")
a6864a24 7073 (set_attr "type" "branch")
7074 (set (attr "length")
7075 (if_then_else
0bf497f5 7076 (and (match_test "TARGET_THUMB2")
a6864a24 7077 (and (ge (minus (match_dup 0) (pc)) (const_int -250))
7078 (le (minus (match_dup 0) (pc)) (const_int 256))))
7079 (const_int 2)
7080 (const_int 4)))]
cffb2a26 7081)
7082
b11cae9e 7083\f
9c08d1fa 7084
7085; scc insns
7086
74f4459c 7087(define_expand "cstore_cc"
7db9af5d 7088 [(set (match_operand:SI 0 "s_register_operand" "")
74f4459c 7089 (match_operator:SI 1 "" [(match_operand 2 "" "")
7090 (match_operand 3 "" "")]))]
25f905c2 7091 "TARGET_32BIT"
74f4459c 7092 "operands[2] = arm_gen_compare_reg (GET_CODE (operands[1]),
e1b93706 7093 operands[2], operands[3], NULL_RTX);
74f4459c 7094 operands[3] = const0_rtx;"
8fa3ba89 7095)
7096
a3b84066 7097(define_insn_and_split "*mov_scc"
9c08d1fa 7098 [(set (match_operand:SI 0 "s_register_operand" "=r")
8fa3ba89 7099 (match_operator:SI 1 "arm_comparison_operator"
8a18b90c 7100 [(match_operand 2 "cc_register" "") (const_int 0)]))]
cffb2a26 7101 "TARGET_ARM"
a3b84066 7102 "#" ; "mov%D1\\t%0, #0\;mov%d1\\t%0, #1"
7103 "TARGET_ARM"
7104 [(set (match_dup 0)
7105 (if_then_else:SI (match_dup 1)
7106 (const_int 1)
7107 (const_int 0)))]
7108 ""
cffb2a26 7109 [(set_attr "conds" "use")
1b7da4ac 7110 (set_attr "length" "8")
7111 (set_attr "type" "multiple")]
cffb2a26 7112)
9c08d1fa 7113
a3b84066 7114(define_insn_and_split "*mov_negscc"
9c08d1fa 7115 [(set (match_operand:SI 0 "s_register_operand" "=r")
8fa3ba89 7116 (neg:SI (match_operator:SI 1 "arm_comparison_operator"
8a18b90c 7117 [(match_operand 2 "cc_register" "") (const_int 0)])))]
cffb2a26 7118 "TARGET_ARM"
a3b84066 7119 "#" ; "mov%D1\\t%0, #0\;mvn%d1\\t%0, #0"
7120 "TARGET_ARM"
7121 [(set (match_dup 0)
7122 (if_then_else:SI (match_dup 1)
7123 (match_dup 3)
7124 (const_int 0)))]
7125 {
7126 operands[3] = GEN_INT (~0);
7127 }
cffb2a26 7128 [(set_attr "conds" "use")
1b7da4ac 7129 (set_attr "length" "8")
7130 (set_attr "type" "multiple")]
cffb2a26 7131)
9c08d1fa 7132
a3b84066 7133(define_insn_and_split "*mov_notscc"
9c08d1fa 7134 [(set (match_operand:SI 0 "s_register_operand" "=r")
8fa3ba89 7135 (not:SI (match_operator:SI 1 "arm_comparison_operator"
8a18b90c 7136 [(match_operand 2 "cc_register" "") (const_int 0)])))]
cffb2a26 7137 "TARGET_ARM"
a3b84066 7138 "#" ; "mvn%D1\\t%0, #0\;mvn%d1\\t%0, #1"
7139 "TARGET_ARM"
7140 [(set (match_dup 0)
7141 (if_then_else:SI (match_dup 1)
7142 (match_dup 3)
7143 (match_dup 4)))]
7144 {
7145 operands[3] = GEN_INT (~1);
7146 operands[4] = GEN_INT (~0);
7147 }
cffb2a26 7148 [(set_attr "conds" "use")
1b7da4ac 7149 (set_attr "length" "8")
7150 (set_attr "type" "multiple")]
cffb2a26 7151)
9c08d1fa 7152
595d88b5 7153(define_expand "cstoresi4"
7154 [(set (match_operand:SI 0 "s_register_operand" "")
aa06947a 7155 (match_operator:SI 1 "expandable_comparison_operator"
595d88b5 7156 [(match_operand:SI 2 "s_register_operand" "")
7157 (match_operand:SI 3 "reg_or_int_operand" "")]))]
74f4459c 7158 "TARGET_32BIT || TARGET_THUMB1"
595d88b5 7159 "{
7160 rtx op3, scratch, scratch2;
7161
74f4459c 7162 if (!TARGET_THUMB1)
7163 {
7164 if (!arm_add_operand (operands[3], SImode))
7165 operands[3] = force_reg (SImode, operands[3]);
7166 emit_insn (gen_cstore_cc (operands[0], operands[1],
7167 operands[2], operands[3]));
7168 DONE;
7169 }
7170
595d88b5 7171 if (operands[3] == const0_rtx)
7172 {
7173 switch (GET_CODE (operands[1]))
7174 {
7175 case EQ:
25f905c2 7176 emit_insn (gen_cstoresi_eq0_thumb1 (operands[0], operands[2]));
595d88b5 7177 break;
7178
7179 case NE:
25f905c2 7180 emit_insn (gen_cstoresi_ne0_thumb1 (operands[0], operands[2]));
595d88b5 7181 break;
7182
7183 case LE:
7184 scratch = expand_binop (SImode, add_optab, operands[2], constm1_rtx,
7185 NULL_RTX, 0, OPTAB_WIDEN);
7186 scratch = expand_binop (SImode, ior_optab, operands[2], scratch,
7187 NULL_RTX, 0, OPTAB_WIDEN);
7188 expand_binop (SImode, lshr_optab, scratch, GEN_INT (31),
7189 operands[0], 1, OPTAB_WIDEN);
7190 break;
7191
7192 case GE:
7193 scratch = expand_unop (SImode, one_cmpl_optab, operands[2],
7194 NULL_RTX, 1);
7195 expand_binop (SImode, lshr_optab, scratch, GEN_INT (31),
7196 NULL_RTX, 1, OPTAB_WIDEN);
7197 break;
7198
7199 case GT:
7200 scratch = expand_binop (SImode, ashr_optab, operands[2],
7201 GEN_INT (31), NULL_RTX, 0, OPTAB_WIDEN);
7202 scratch = expand_binop (SImode, sub_optab, scratch, operands[2],
7203 NULL_RTX, 0, OPTAB_WIDEN);
7204 expand_binop (SImode, lshr_optab, scratch, GEN_INT (31), operands[0],
7205 0, OPTAB_WIDEN);
7206 break;
7207
7208 /* LT is handled by generic code. No need for unsigned with 0. */
7209 default:
7210 FAIL;
7211 }
7212 DONE;
7213 }
7214
7215 switch (GET_CODE (operands[1]))
7216 {
7217 case EQ:
7218 scratch = expand_binop (SImode, sub_optab, operands[2], operands[3],
7219 NULL_RTX, 0, OPTAB_WIDEN);
25f905c2 7220 emit_insn (gen_cstoresi_eq0_thumb1 (operands[0], scratch));
595d88b5 7221 break;
7222
7223 case NE:
7224 scratch = expand_binop (SImode, sub_optab, operands[2], operands[3],
7225 NULL_RTX, 0, OPTAB_WIDEN);
25f905c2 7226 emit_insn (gen_cstoresi_ne0_thumb1 (operands[0], scratch));
595d88b5 7227 break;
7228
7229 case LE:
7230 op3 = force_reg (SImode, operands[3]);
7231
7232 scratch = expand_binop (SImode, lshr_optab, operands[2], GEN_INT (31),
7233 NULL_RTX, 1, OPTAB_WIDEN);
7234 scratch2 = expand_binop (SImode, ashr_optab, op3, GEN_INT (31),
7235 NULL_RTX, 0, OPTAB_WIDEN);
25f905c2 7236 emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch2,
595d88b5 7237 op3, operands[2]));
7238 break;
7239
7240 case GE:
7241 op3 = operands[3];
25f905c2 7242 if (!thumb1_cmp_operand (op3, SImode))
595d88b5 7243 op3 = force_reg (SImode, op3);
7244 scratch = expand_binop (SImode, ashr_optab, operands[2], GEN_INT (31),
7245 NULL_RTX, 0, OPTAB_WIDEN);
7246 scratch2 = expand_binop (SImode, lshr_optab, op3, GEN_INT (31),
7247 NULL_RTX, 1, OPTAB_WIDEN);
25f905c2 7248 emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch2,
595d88b5 7249 operands[2], op3));
7250 break;
7251
7252 case LEU:
7253 op3 = force_reg (SImode, operands[3]);
7254 scratch = force_reg (SImode, const0_rtx);
25f905c2 7255 emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch,
595d88b5 7256 op3, operands[2]));
7257 break;
7258
7259 case GEU:
7260 op3 = operands[3];
25f905c2 7261 if (!thumb1_cmp_operand (op3, SImode))
595d88b5 7262 op3 = force_reg (SImode, op3);
7263 scratch = force_reg (SImode, const0_rtx);
25f905c2 7264 emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch,
595d88b5 7265 operands[2], op3));
7266 break;
7267
7268 case LTU:
7269 op3 = operands[3];
25f905c2 7270 if (!thumb1_cmp_operand (op3, SImode))
595d88b5 7271 op3 = force_reg (SImode, op3);
7272 scratch = gen_reg_rtx (SImode);
408b7ae5 7273 emit_insn (gen_cstoresi_ltu_thumb1 (operands[0], operands[2], op3));
595d88b5 7274 break;
7275
7276 case GTU:
7277 op3 = force_reg (SImode, operands[3]);
7278 scratch = gen_reg_rtx (SImode);
408b7ae5 7279 emit_insn (gen_cstoresi_ltu_thumb1 (operands[0], op3, operands[2]));
595d88b5 7280 break;
7281
7282 /* No good sequences for GT, LT. */
7283 default:
7284 FAIL;
7285 }
7286 DONE;
7287}")
7288
74f4459c 7289(define_expand "cstoresf4"
7290 [(set (match_operand:SI 0 "s_register_operand" "")
aa06947a 7291 (match_operator:SI 1 "expandable_comparison_operator"
74f4459c 7292 [(match_operand:SF 2 "s_register_operand" "")
7293 (match_operand:SF 3 "arm_float_compare_operand" "")]))]
7294 "TARGET_32BIT && TARGET_HARD_FLOAT"
7295 "emit_insn (gen_cstore_cc (operands[0], operands[1],
7296 operands[2], operands[3])); DONE;"
7297)
7298
7299(define_expand "cstoredf4"
7300 [(set (match_operand:SI 0 "s_register_operand" "")
aa06947a 7301 (match_operator:SI 1 "expandable_comparison_operator"
74f4459c 7302 [(match_operand:DF 2 "s_register_operand" "")
7303 (match_operand:DF 3 "arm_float_compare_operand" "")]))]
d63ed457 7304 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
74f4459c 7305 "emit_insn (gen_cstore_cc (operands[0], operands[1],
7306 operands[2], operands[3])); DONE;"
7307)
7308
74f4459c 7309(define_expand "cstoredi4"
7310 [(set (match_operand:SI 0 "s_register_operand" "")
aa06947a 7311 (match_operator:SI 1 "expandable_comparison_operator"
b8eae306 7312 [(match_operand:DI 2 "s_register_operand" "")
a8045a4f 7313 (match_operand:DI 3 "cmpdi_operand" "")]))]
7314 "TARGET_32BIT"
7315 "{
f9aa4160 7316 if (!arm_validize_comparison (&operands[1],
7317 &operands[2],
7318 &operands[3]))
7319 FAIL;
7320 emit_insn (gen_cstore_cc (operands[0], operands[1], operands[2],
a8045a4f 7321 operands[3]));
7322 DONE;
7323 }"
74f4459c 7324)
7325
9c08d1fa 7326\f
39b5e676 7327;; Conditional move insns
7328
7329(define_expand "movsicc"
8a18b90c 7330 [(set (match_operand:SI 0 "s_register_operand" "")
aa06947a 7331 (if_then_else:SI (match_operand 1 "expandable_comparison_operator" "")
aea4c774 7332 (match_operand:SI 2 "arm_not_operand" "")
8a18b90c 7333 (match_operand:SI 3 "arm_not_operand" "")))]
25f905c2 7334 "TARGET_32BIT"
39b5e676 7335 "
215b30b3 7336 {
f9aa4160 7337 enum rtx_code code;
278b301d 7338 rtx ccreg;
7339
f9aa4160 7340 if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0),
7341 &XEXP (operands[1], 1)))
278b301d 7342 FAIL;
f9aa4160 7343
7344 code = GET_CODE (operands[1]);
74f4459c 7345 ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
e1b93706 7346 XEXP (operands[1], 1), NULL_RTX);
29bb088d 7347 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
215b30b3 7348 }"
7349)
39b5e676 7350
7351(define_expand "movsfcc"
8a18b90c 7352 [(set (match_operand:SF 0 "s_register_operand" "")
4df97ffc 7353 (if_then_else:SF (match_operand 1 "arm_cond_move_operator" "")
8a18b90c 7354 (match_operand:SF 2 "s_register_operand" "")
d86c91f6 7355 (match_operand:SF 3 "s_register_operand" "")))]
19f6bf8d 7356 "TARGET_32BIT && TARGET_HARD_FLOAT"
39b5e676 7357 "
215b30b3 7358 {
7359 enum rtx_code code = GET_CODE (operands[1]);
7360 rtx ccreg;
f082f1c4 7361
f9aa4160 7362 if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0),
7363 &XEXP (operands[1], 1)))
7364 FAIL;
39b5e676 7365
f9aa4160 7366 code = GET_CODE (operands[1]);
74f4459c 7367 ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
e1b93706 7368 XEXP (operands[1], 1), NULL_RTX);
29bb088d 7369 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
215b30b3 7370 }"
7371)
39b5e676 7372
7373(define_expand "movdfcc"
8a18b90c 7374 [(set (match_operand:DF 0 "s_register_operand" "")
4df97ffc 7375 (if_then_else:DF (match_operand 1 "arm_cond_move_operator" "")
8a18b90c 7376 (match_operand:DF 2 "s_register_operand" "")
d86c91f6 7377 (match_operand:DF 3 "s_register_operand" "")))]
994606f8 7378 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
39b5e676 7379 "
215b30b3 7380 {
7381 enum rtx_code code = GET_CODE (operands[1]);
278b301d 7382 rtx ccreg;
39b5e676 7383
f9aa4160 7384 if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0),
7385 &XEXP (operands[1], 1)))
7386 FAIL;
7387 code = GET_CODE (operands[1]);
74f4459c 7388 ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
e1b93706 7389 XEXP (operands[1], 1), NULL_RTX);
29bb088d 7390 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
215b30b3 7391 }"
7392)
39b5e676 7393
91cb50d2 7394(define_insn "*cmov<mode>"
7395 [(set (match_operand:SDF 0 "s_register_operand" "=<F_constraint>")
7396 (if_then_else:SDF (match_operator 1 "arm_vsel_comparison_operator"
7397 [(match_operand 2 "cc_register" "") (const_int 0)])
7398 (match_operand:SDF 3 "s_register_operand"
7399 "<F_constraint>")
7400 (match_operand:SDF 4 "s_register_operand"
7401 "<F_constraint>")))]
7402 "TARGET_HARD_FLOAT && TARGET_FPU_ARMV8 <vfp_double_cond>"
7403 "*
7404 {
7405 enum arm_cond_code code = maybe_get_arm_condition_code (operands[1]);
7406 switch (code)
7407 {
7408 case ARM_GE:
7409 case ARM_GT:
7410 case ARM_EQ:
7411 case ARM_VS:
7412 return \"vsel%d1.<V_if_elem>\\t%<V_reg>0, %<V_reg>3, %<V_reg>4\";
7413 case ARM_LT:
7414 case ARM_LE:
7415 case ARM_NE:
7416 case ARM_VC:
7417 return \"vsel%D1.<V_if_elem>\\t%<V_reg>0, %<V_reg>4, %<V_reg>3\";
7418 default:
7419 gcc_unreachable ();
7420 }
7421 return \"\";
7422 }"
7423 [(set_attr "conds" "use")
7424 (set_attr "type" "f_sel<vfp_type>")]
7425)
7426
190efb17 7427(define_insn_and_split "*movsicc_insn"
f082f1c4 7428 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r,r,r,r,r")
8a18b90c 7429 (if_then_else:SI
8fa3ba89 7430 (match_operator 3 "arm_comparison_operator"
8a18b90c 7431 [(match_operand 4 "cc_register" "") (const_int 0)])
f082f1c4 7432 (match_operand:SI 1 "arm_not_operand" "0,0,rI,K,rI,rI,K,K")
7433 (match_operand:SI 2 "arm_not_operand" "rI,K,0,0,rI,K,rI,K")))]
cffb2a26 7434 "TARGET_ARM"
39b5e676 7435 "@
8a18b90c 7436 mov%D3\\t%0, %2
7437 mvn%D3\\t%0, #%B2
f082f1c4 7438 mov%d3\\t%0, %1
7439 mvn%d3\\t%0, #%B1
190efb17 7440 #
7441 #
7442 #
7443 #"
7444 ; alt4: mov%d3\\t%0, %1\;mov%D3\\t%0, %2
7445 ; alt5: mov%d3\\t%0, %1\;mvn%D3\\t%0, #%B2
7446 ; alt6: mvn%d3\\t%0, #%B1\;mov%D3\\t%0, %2
7447 ; alt7: mvn%d3\\t%0, #%B1\;mvn%D3\\t%0, #%B2"
7448 "&& reload_completed"
7449 [(const_int 0)]
7450 {
7451 enum rtx_code rev_code;
7452 enum machine_mode mode;
7453 rtx rev_cond;
7454
7455 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
7456 operands[3],
7457 gen_rtx_SET (VOIDmode,
7458 operands[0],
7459 operands[1])));
7460
7461 rev_code = GET_CODE (operands[3]);
7462 mode = GET_MODE (operands[4]);
7463 if (mode == CCFPmode || mode == CCFPEmode)
7464 rev_code = reverse_condition_maybe_unordered (rev_code);
7465 else
7466 rev_code = reverse_condition (rev_code);
7467
7468 rev_cond = gen_rtx_fmt_ee (rev_code,
7469 VOIDmode,
7470 operands[4],
7471 const0_rtx);
7472 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
7473 rev_cond,
7474 gen_rtx_SET (VOIDmode,
7475 operands[0],
7476 operands[2])));
7477 DONE;
7478 }
f082f1c4 7479 [(set_attr "length" "4,4,4,4,8,8,8,8")
d2a518d1 7480 (set_attr "conds" "use")
65f68e55 7481 (set_attr_alternative "type"
7482 [(if_then_else (match_operand 2 "const_int_operand" "")
1aed5204 7483 (const_string "mov_imm")
7484 (const_string "mov_reg"))
7485 (const_string "mvn_imm")
65f68e55 7486 (if_then_else (match_operand 1 "const_int_operand" "")
1aed5204 7487 (const_string "mov_imm")
7488 (const_string "mov_reg"))
7489 (const_string "mvn_imm")
7490 (const_string "mov_reg")
7491 (const_string "mov_reg")
7492 (const_string "mov_reg")
7493 (const_string "mov_reg")])]
215b30b3 7494)
39b5e676 7495
39b5e676 7496(define_insn "*movsfcc_soft_insn"
f082f1c4 7497 [(set (match_operand:SF 0 "s_register_operand" "=r,r")
8fa3ba89 7498 (if_then_else:SF (match_operator 3 "arm_comparison_operator"
8a18b90c 7499 [(match_operand 4 "cc_register" "") (const_int 0)])
f082f1c4 7500 (match_operand:SF 1 "s_register_operand" "0,r")
7501 (match_operand:SF 2 "s_register_operand" "r,0")))]
cffb2a26 7502 "TARGET_ARM && TARGET_SOFT_FLOAT"
f082f1c4 7503 "@
7504 mov%D3\\t%0, %2
7505 mov%d3\\t%0, %1"
d2a518d1 7506 [(set_attr "conds" "use")
1aed5204 7507 (set_attr "type" "mov_reg")]
8fa3ba89 7508)
39b5e676 7509
39b5e676 7510\f
9c08d1fa 7511;; Jump and linkage insns
7512
cffb2a26 7513(define_expand "jump"
9c08d1fa 7514 [(set (pc)
7515 (label_ref (match_operand 0 "" "")))]
cffb2a26 7516 "TARGET_EITHER"
9c08d1fa 7517 ""
cffb2a26 7518)
7519
7520(define_insn "*arm_jump"
7521 [(set (pc)
7522 (label_ref (match_operand 0 "" "")))]
25f905c2 7523 "TARGET_32BIT"
9c08d1fa 7524 "*
0d66636f 7525 {
7526 if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
7527 {
7528 arm_ccfsm_state += 2;
7529 return \"\";
7530 }
7531 return \"b%?\\t%l0\";
7532 }
7533 "
a6864a24 7534 [(set_attr "predicable" "yes")
7535 (set (attr "length")
7536 (if_then_else
0bf497f5 7537 (and (match_test "TARGET_THUMB2")
a6864a24 7538 (and (ge (minus (match_dup 0) (pc)) (const_int -2044))
7539 (le (minus (match_dup 0) (pc)) (const_int 2048))))
7540 (const_int 2)
1b7da4ac 7541 (const_int 4)))
7542 (set_attr "type" "branch")]
0d66636f 7543)
9c08d1fa 7544
d3373b54 7545(define_expand "call"
7546 [(parallel [(call (match_operand 0 "memory_operand" "")
7547 (match_operand 1 "general_operand" ""))
cffb2a26 7548 (use (match_operand 2 "" ""))
bd5b4116 7549 (clobber (reg:SI LR_REGNUM))])]
cffb2a26 7550 "TARGET_EITHER"
6c4c2133 7551 "
7552 {
bac7fc85 7553 rtx callee, pat;
bbe777ea 7554
bbe777ea 7555 /* In an untyped call, we can get NULL for operand 2. */
7556 if (operands[2] == NULL_RTX)
7557 operands[2] = const0_rtx;
7558
de55252a 7559 /* Decide if we should generate indirect calls by loading the
85c36fd1 7560 32-bit address of the callee into a register before performing the
de55252a 7561 branch and link. */
7562 callee = XEXP (operands[0], 0);
7563 if (GET_CODE (callee) == SYMBOL_REF
7564 ? arm_is_long_call_p (SYMBOL_REF_DECL (callee))
7565 : !REG_P (callee))
bbe777ea 7566 XEXP (operands[0], 0) = force_reg (Pmode, callee);
bac7fc85 7567
7568 pat = gen_call_internal (operands[0], operands[1], operands[2]);
ca373797 7569 arm_emit_call_insn (pat, XEXP (operands[0], 0), false);
bac7fc85 7570 DONE;
6c4c2133 7571 }"
7572)
d3373b54 7573
bac7fc85 7574(define_expand "call_internal"
7575 [(parallel [(call (match_operand 0 "memory_operand" "")
7576 (match_operand 1 "general_operand" ""))
7577 (use (match_operand 2 "" ""))
7578 (clobber (reg:SI LR_REGNUM))])])
7579
f1039640 7580(define_insn "*call_reg_armv5"
d3373b54 7581 [(call (mem:SI (match_operand:SI 0 "s_register_operand" "r"))
cffb2a26 7582 (match_operand 1 "" ""))
7583 (use (match_operand 2 "" ""))
bd5b4116 7584 (clobber (reg:SI LR_REGNUM))]
33ae7c4b 7585 "TARGET_ARM && arm_arch5 && !SIBLING_CALL_P (insn)"
f1039640 7586 "blx%?\\t%0"
7587 [(set_attr "type" "call")]
7588)
7589
7590(define_insn "*call_reg_arm"
7591 [(call (mem:SI (match_operand:SI 0 "s_register_operand" "r"))
7592 (match_operand 1 "" ""))
7593 (use (match_operand 2 "" ""))
7594 (clobber (reg:SI LR_REGNUM))]
33ae7c4b 7595 "TARGET_ARM && !arm_arch5 && !SIBLING_CALL_P (insn)"
9c08d1fa 7596 "*
5565501b 7597 return output_call (operands);
cffb2a26 7598 "
7599 ;; length is worst case, normally it is only two
7600 [(set_attr "length" "12")
7601 (set_attr "type" "call")]
7602)
9c08d1fa 7603
89504fc1 7604
7605;; Note: not used for armv5+ because the sequence used (ldr pc, ...) is not
7606;; considered a function call by the branch predictor of some cores (PR40887).
7607;; Falls back to blx rN (*call_reg_armv5).
7608
f7fbdd4a 7609(define_insn "*call_mem"
a3c63a9d 7610 [(call (mem:SI (match_operand:SI 0 "call_memory_operand" "m"))
cffb2a26 7611 (match_operand 1 "" ""))
7612 (use (match_operand 2 "" ""))
bd5b4116 7613 (clobber (reg:SI LR_REGNUM))]
33ae7c4b 7614 "TARGET_ARM && !arm_arch5 && !SIBLING_CALL_P (insn)"
9c08d1fa 7615 "*
5565501b 7616 return output_call_mem (operands);
cffb2a26 7617 "
7618 [(set_attr "length" "12")
7619 (set_attr "type" "call")]
7620)
7621
d3373b54 7622(define_expand "call_value"
e0698af7 7623 [(parallel [(set (match_operand 0 "" "")
7624 (call (match_operand 1 "memory_operand" "")
7625 (match_operand 2 "general_operand" "")))
cffb2a26 7626 (use (match_operand 3 "" ""))
bd5b4116 7627 (clobber (reg:SI LR_REGNUM))])]
cffb2a26 7628 "TARGET_EITHER"
6c4c2133 7629 "
7630 {
bac7fc85 7631 rtx pat, callee;
bbe777ea 7632
7633 /* In an untyped call, we can get NULL for operand 2. */
7634 if (operands[3] == 0)
7635 operands[3] = const0_rtx;
7636
de55252a 7637 /* Decide if we should generate indirect calls by loading the
7638 32-bit address of the callee into a register before performing the
7639 branch and link. */
7640 callee = XEXP (operands[1], 0);
7641 if (GET_CODE (callee) == SYMBOL_REF
7642 ? arm_is_long_call_p (SYMBOL_REF_DECL (callee))
7643 : !REG_P (callee))
78fe751b 7644 XEXP (operands[1], 0) = force_reg (Pmode, callee);
bac7fc85 7645
7646 pat = gen_call_value_internal (operands[0], operands[1],
7647 operands[2], operands[3]);
ca373797 7648 arm_emit_call_insn (pat, XEXP (operands[1], 0), false);
bac7fc85 7649 DONE;
6c4c2133 7650 }"
7651)
d3373b54 7652
bac7fc85 7653(define_expand "call_value_internal"
7654 [(parallel [(set (match_operand 0 "" "")
7655 (call (match_operand 1 "memory_operand" "")
7656 (match_operand 2 "general_operand" "")))
7657 (use (match_operand 3 "" ""))
7658 (clobber (reg:SI LR_REGNUM))])])
7659
f1039640 7660(define_insn "*call_value_reg_armv5"
27ed6835 7661 [(set (match_operand 0 "" "")
755eb2b4 7662 (call (mem:SI (match_operand:SI 1 "s_register_operand" "r"))
cffb2a26 7663 (match_operand 2 "" "")))
bbe777ea 7664 (use (match_operand 3 "" ""))
bd5b4116 7665 (clobber (reg:SI LR_REGNUM))]
33ae7c4b 7666 "TARGET_ARM && arm_arch5 && !SIBLING_CALL_P (insn)"
f1039640 7667 "blx%?\\t%1"
7668 [(set_attr "type" "call")]
7669)
7670
7671(define_insn "*call_value_reg_arm"
7672 [(set (match_operand 0 "" "")
7673 (call (mem:SI (match_operand:SI 1 "s_register_operand" "r"))
7674 (match_operand 2 "" "")))
7675 (use (match_operand 3 "" ""))
7676 (clobber (reg:SI LR_REGNUM))]
33ae7c4b 7677 "TARGET_ARM && !arm_arch5 && !SIBLING_CALL_P (insn)"
9c08d1fa 7678 "*
215b30b3 7679 return output_call (&operands[1]);
cffb2a26 7680 "
7681 [(set_attr "length" "12")
7682 (set_attr "type" "call")]
7683)
9c08d1fa 7684
89504fc1 7685;; Note: see *call_mem
7686
f7fbdd4a 7687(define_insn "*call_value_mem"
27ed6835 7688 [(set (match_operand 0 "" "")
a3c63a9d 7689 (call (mem:SI (match_operand:SI 1 "call_memory_operand" "m"))
cffb2a26 7690 (match_operand 2 "" "")))
bbe777ea 7691 (use (match_operand 3 "" ""))
bd5b4116 7692 (clobber (reg:SI LR_REGNUM))]
33ae7c4b 7693 "TARGET_ARM && !arm_arch5 && (!CONSTANT_ADDRESS_P (XEXP (operands[1], 0)))
7694 && !SIBLING_CALL_P (insn)"
9c08d1fa 7695 "*
215b30b3 7696 return output_call_mem (&operands[1]);
cffb2a26 7697 "
7698 [(set_attr "length" "12")
7699 (set_attr "type" "call")]
7700)
9c08d1fa 7701
7702;; Allow calls to SYMBOL_REFs specially as they are not valid general addresses
7703;; The 'a' causes the operand to be treated as an address, i.e. no '#' output.
7704
f7fbdd4a 7705(define_insn "*call_symbol"
27ed6835 7706 [(call (mem:SI (match_operand:SI 0 "" ""))
cffb2a26 7707 (match_operand 1 "" ""))
bbe777ea 7708 (use (match_operand 2 "" ""))
bd5b4116 7709 (clobber (reg:SI LR_REGNUM))]
d68c2c10 7710 "TARGET_32BIT
33ae7c4b 7711 && !SIBLING_CALL_P (insn)
cffb2a26 7712 && (GET_CODE (operands[0]) == SYMBOL_REF)
de55252a 7713 && !arm_is_long_call_p (SYMBOL_REF_DECL (operands[0]))"
6ebaa29d 7714 "*
7715 {
55c1e470 7716 return NEED_PLT_RELOC ? \"bl%?\\t%a0(PLT)\" : \"bl%?\\t%a0\";
6ebaa29d 7717 }"
cffb2a26 7718 [(set_attr "type" "call")]
7719)
9c08d1fa 7720
f7fbdd4a 7721(define_insn "*call_value_symbol"
ccd90aaa 7722 [(set (match_operand 0 "" "")
27ed6835 7723 (call (mem:SI (match_operand:SI 1 "" ""))
dd6d7504 7724 (match_operand:SI 2 "" "")))
bbe777ea 7725 (use (match_operand 3 "" ""))
bd5b4116 7726 (clobber (reg:SI LR_REGNUM))]
d68c2c10 7727 "TARGET_32BIT
33ae7c4b 7728 && !SIBLING_CALL_P (insn)
cffb2a26 7729 && (GET_CODE (operands[1]) == SYMBOL_REF)
de55252a 7730 && !arm_is_long_call_p (SYMBOL_REF_DECL (operands[1]))"
6ebaa29d 7731 "*
7732 {
55c1e470 7733 return NEED_PLT_RELOC ? \"bl%?\\t%a1(PLT)\" : \"bl%?\\t%a1\";
6ebaa29d 7734 }"
cffb2a26 7735 [(set_attr "type" "call")]
7736)
7737
ca373797 7738(define_expand "sibcall_internal"
7739 [(parallel [(call (match_operand 0 "memory_operand" "")
7740 (match_operand 1 "general_operand" ""))
7741 (return)
7742 (use (match_operand 2 "" ""))])])
7743
1c494086 7744;; We may also be able to do sibcalls for Thumb, but it's much harder...
7745(define_expand "sibcall"
7746 [(parallel [(call (match_operand 0 "memory_operand" "")
7747 (match_operand 1 "general_operand" ""))
2ba80634 7748 (return)
7749 (use (match_operand 2 "" ""))])]
d68c2c10 7750 "TARGET_32BIT"
1c494086 7751 "
7752 {
ca373797 7753 rtx pat;
7754
3112c3f7 7755 if ((!REG_P (XEXP (operands[0], 0))
7756 && GET_CODE (XEXP (operands[0], 0)) != SYMBOL_REF)
7757 || (GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
7758 && arm_is_long_call_p (SYMBOL_REF_DECL (XEXP (operands[0], 0)))))
33ae7c4b 7759 XEXP (operands[0], 0) = force_reg (SImode, XEXP (operands[0], 0));
7760
1c494086 7761 if (operands[2] == NULL_RTX)
7762 operands[2] = const0_rtx;
ca373797 7763
7764 pat = gen_sibcall_internal (operands[0], operands[1], operands[2]);
7765 arm_emit_call_insn (pat, operands[0], true);
7766 DONE;
1c494086 7767 }"
7768)
7769
ca373797 7770(define_expand "sibcall_value_internal"
7771 [(parallel [(set (match_operand 0 "" "")
7772 (call (match_operand 1 "memory_operand" "")
7773 (match_operand 2 "general_operand" "")))
7774 (return)
7775 (use (match_operand 3 "" ""))])])
7776
1c494086 7777(define_expand "sibcall_value"
ccd90aaa 7778 [(parallel [(set (match_operand 0 "" "")
1c494086 7779 (call (match_operand 1 "memory_operand" "")
7780 (match_operand 2 "general_operand" "")))
2ba80634 7781 (return)
7782 (use (match_operand 3 "" ""))])]
d68c2c10 7783 "TARGET_32BIT"
1c494086 7784 "
7785 {
ca373797 7786 rtx pat;
7787
3112c3f7 7788 if ((!REG_P (XEXP (operands[1], 0))
7789 && GET_CODE (XEXP (operands[1], 0)) != SYMBOL_REF)
7790 || (GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
7791 && arm_is_long_call_p (SYMBOL_REF_DECL (XEXP (operands[1], 0)))))
33ae7c4b 7792 XEXP (operands[1], 0) = force_reg (SImode, XEXP (operands[1], 0));
7793
1c494086 7794 if (operands[3] == NULL_RTX)
7795 operands[3] = const0_rtx;
ca373797 7796
7797 pat = gen_sibcall_value_internal (operands[0], operands[1],
7798 operands[2], operands[3]);
7799 arm_emit_call_insn (pat, operands[1], true);
7800 DONE;
1c494086 7801 }"
7802)
7803
7804(define_insn "*sibcall_insn"
84ce8e5c 7805 [(call (mem:SI (match_operand:SI 0 "call_insn_operand" "Cs, US"))
1c494086 7806 (match_operand 1 "" ""))
2ba80634 7807 (return)
7808 (use (match_operand 2 "" ""))]
33ae7c4b 7809 "TARGET_32BIT && SIBLING_CALL_P (insn)"
1c494086 7810 "*
33ae7c4b 7811 if (which_alternative == 1)
7812 return NEED_PLT_RELOC ? \"b%?\\t%a0(PLT)\" : \"b%?\\t%a0\";
7813 else
7814 {
7815 if (arm_arch5 || arm_arch4t)
947d113e 7816 return \"bx%?\\t%0\\t%@ indirect register sibling call\";
33ae7c4b 7817 else
7818 return \"mov%?\\t%|pc, %0\\t%@ indirect register sibling call\";
7819 }
1c494086 7820 "
7821 [(set_attr "type" "call")]
7822)
7823
7824(define_insn "*sibcall_value_insn"
84ce8e5c 7825 [(set (match_operand 0 "" "")
7826 (call (mem:SI (match_operand:SI 1 "call_insn_operand" "Cs,US"))
1c494086 7827 (match_operand 2 "" "")))
2ba80634 7828 (return)
7829 (use (match_operand 3 "" ""))]
33ae7c4b 7830 "TARGET_32BIT && SIBLING_CALL_P (insn)"
1c494086 7831 "*
33ae7c4b 7832 if (which_alternative == 1)
7833 return NEED_PLT_RELOC ? \"b%?\\t%a1(PLT)\" : \"b%?\\t%a1\";
7834 else
7835 {
7836 if (arm_arch5 || arm_arch4t)
84ce8e5c 7837 return \"bx%?\\t%1\";
33ae7c4b 7838 else
7839 return \"mov%?\\t%|pc, %1\\t@ indirect sibling call \";
7840 }
1c494086 7841 "
7842 [(set_attr "type" "call")]
7843)
7844
0686440e 7845(define_expand "<return_str>return"
7846 [(returns)]
8cba51a5 7847 "(TARGET_ARM || (TARGET_THUMB2
7848 && ARM_FUNC_TYPE (arm_current_func_type ()) == ARM_FT_NORMAL
7849 && !IS_STACKALIGN (arm_current_func_type ())))
0686440e 7850 <return_cond_false>"
8cba51a5 7851 "
7852 {
7853 if (TARGET_THUMB2)
7854 {
0686440e 7855 thumb2_expand_return (<return_simple_p>);
8cba51a5 7856 DONE;
7857 }
7858 }
7859 "
7860)
d68c2c10 7861
9c08d1fa 7862;; Often the return insn will be the same as loading from memory, so set attr
d68c2c10 7863(define_insn "*arm_return"
9c08d1fa 7864 [(return)]
cffb2a26 7865 "TARGET_ARM && USE_RETURN_INSN (FALSE)"
9c08d1fa 7866 "*
9c08d1fa 7867 {
cffb2a26 7868 if (arm_ccfsm_state == 2)
7869 {
7870 arm_ccfsm_state += 2;
7871 return \"\";
7872 }
e2549f81 7873 return output_return_instruction (const_true_rtx, true, false, false);
cffb2a26 7874 }"
a2cd141b 7875 [(set_attr "type" "load1")
755eb2b4 7876 (set_attr "length" "12")
0d66636f 7877 (set_attr "predicable" "yes")]
cffb2a26 7878)
9c08d1fa 7879
0686440e 7880(define_insn "*cond_<return_str>return"
9c08d1fa 7881 [(set (pc)
8fa3ba89 7882 (if_then_else (match_operator 0 "arm_comparison_operator"
8a18b90c 7883 [(match_operand 1 "cc_register" "") (const_int 0)])
0686440e 7884 (returns)
9c08d1fa 7885 (pc)))]
0686440e 7886 "TARGET_ARM <return_cond_true>"
9c08d1fa 7887 "*
8fa3ba89 7888 {
7889 if (arm_ccfsm_state == 2)
7890 {
7891 arm_ccfsm_state += 2;
7892 return \"\";
7893 }
0686440e 7894 return output_return_instruction (operands[0], true, false,
7895 <return_simple_p>);
8fa3ba89 7896 }"
7897 [(set_attr "conds" "use")
755eb2b4 7898 (set_attr "length" "12")
a2cd141b 7899 (set_attr "type" "load1")]
8fa3ba89 7900)
9c08d1fa 7901
0686440e 7902(define_insn "*cond_<return_str>return_inverted"
9c08d1fa 7903 [(set (pc)
8fa3ba89 7904 (if_then_else (match_operator 0 "arm_comparison_operator"
8a18b90c 7905 [(match_operand 1 "cc_register" "") (const_int 0)])
9c08d1fa 7906 (pc)
0686440e 7907 (returns)))]
7908 "TARGET_ARM <return_cond_true>"
9c08d1fa 7909 "*
8fa3ba89 7910 {
7911 if (arm_ccfsm_state == 2)
7912 {
7913 arm_ccfsm_state += 2;
7914 return \"\";
7915 }
0686440e 7916 return output_return_instruction (operands[0], true, true,
7917 <return_simple_p>);
8fa3ba89 7918 }"
7919 [(set_attr "conds" "use")
37a1317b 7920 (set_attr "length" "12")
a2cd141b 7921 (set_attr "type" "load1")]
8fa3ba89 7922)
9c08d1fa 7923
e2549f81 7924(define_insn "*arm_simple_return"
7925 [(simple_return)]
7926 "TARGET_ARM"
7927 "*
7928 {
7929 if (arm_ccfsm_state == 2)
7930 {
7931 arm_ccfsm_state += 2;
7932 return \"\";
7933 }
7934 return output_return_instruction (const_true_rtx, true, false, true);
7935 }"
7936 [(set_attr "type" "branch")
7937 (set_attr "length" "4")
7938 (set_attr "predicable" "yes")]
7939)
7940
68121397 7941;; Generate a sequence of instructions to determine if the processor is
7942;; in 26-bit or 32-bit mode, and return the appropriate return address
7943;; mask.
7944
7945(define_expand "return_addr_mask"
7946 [(set (match_dup 1)
7947 (compare:CC_NOOV (unspec [(const_int 0)] UNSPEC_CHECK_ARCH)
7948 (const_int 0)))
7949 (set (match_operand:SI 0 "s_register_operand" "")
7950 (if_then_else:SI (eq (match_dup 1) (const_int 0))
7951 (const_int -1)
7952 (const_int 67108860)))] ; 0x03fffffc
7953 "TARGET_ARM"
7954 "
62eddbd4 7955 operands[1] = gen_rtx_REG (CC_NOOVmode, CC_REGNUM);
68121397 7956 ")
7957
7958(define_insn "*check_arch2"
7959 [(set (match_operand:CC_NOOV 0 "cc_register" "")
7960 (compare:CC_NOOV (unspec [(const_int 0)] UNSPEC_CHECK_ARCH)
7961 (const_int 0)))]
7962 "TARGET_ARM"
7963 "teq\\t%|r0, %|r0\;teq\\t%|pc, %|pc"
7964 [(set_attr "length" "8")
1b7da4ac 7965 (set_attr "conds" "set")
7966 (set_attr "type" "multiple")]
68121397 7967)
7968
9c08d1fa 7969;; Call subroutine returning any type.
7970
7971(define_expand "untyped_call"
7972 [(parallel [(call (match_operand 0 "" "")
7973 (const_int 0))
7974 (match_operand 1 "" "")
7975 (match_operand 2 "" "")])]
ccd90aaa 7976 "TARGET_EITHER"
9c08d1fa 7977 "
215b30b3 7978 {
7979 int i;
ccd90aaa 7980 rtx par = gen_rtx_PARALLEL (VOIDmode,
7981 rtvec_alloc (XVECLEN (operands[2], 0)));
7982 rtx addr = gen_reg_rtx (Pmode);
7983 rtx mem;
7984 int size = 0;
9c08d1fa 7985
ccd90aaa 7986 emit_move_insn (addr, XEXP (operands[1], 0));
7987 mem = change_address (operands[1], BLKmode, addr);
9c08d1fa 7988
215b30b3 7989 for (i = 0; i < XVECLEN (operands[2], 0); i++)
7990 {
ccd90aaa 7991 rtx src = SET_SRC (XVECEXP (operands[2], 0, i));
9c08d1fa 7992
ccd90aaa 7993 /* Default code only uses r0 as a return value, but we could
7994 be using anything up to 4 registers. */
7995 if (REGNO (src) == R0_REGNUM)
7996 src = gen_rtx_REG (TImode, R0_REGNUM);
7997
7998 XVECEXP (par, 0, i) = gen_rtx_EXPR_LIST (VOIDmode, src,
7999 GEN_INT (size));
8000 size += GET_MODE_SIZE (GET_MODE (src));
8001 }
8002
8003 emit_call_insn (GEN_CALL_VALUE (par, operands[0], const0_rtx, NULL,
8004 const0_rtx));
8005
8006 size = 0;
8007
8008 for (i = 0; i < XVECLEN (par, 0); i++)
8009 {
8010 HOST_WIDE_INT offset = 0;
8011 rtx reg = XEXP (XVECEXP (par, 0, i), 0);
8012
8013 if (size != 0)
29c05e22 8014 emit_move_insn (addr, plus_constant (Pmode, addr, size));
ccd90aaa 8015
8016 mem = change_address (mem, GET_MODE (reg), NULL);
8017 if (REGNO (reg) == R0_REGNUM)
8018 {
8019 /* On thumb we have to use a write-back instruction. */
320ea44d 8020 emit_insn (arm_gen_store_multiple (arm_regs_in_sequence, 4, addr,
8021 TARGET_THUMB ? TRUE : FALSE, mem, &offset));
ccd90aaa 8022 size = TARGET_ARM ? 16 : 0;
8023 }
8024 else
8025 {
8026 emit_move_insn (mem, reg);
8027 size = GET_MODE_SIZE (GET_MODE (reg));
8028 }
215b30b3 8029 }
9c08d1fa 8030
215b30b3 8031 /* The optimizer does not know that the call sets the function value
8032 registers we stored in the result block. We avoid problems by
8033 claiming that all hard registers are used and clobbered at this
8034 point. */
8035 emit_insn (gen_blockage ());
8036
8037 DONE;
8038 }"
8039)
9c08d1fa 8040
ccd90aaa 8041(define_expand "untyped_return"
8042 [(match_operand:BLK 0 "memory_operand" "")
8043 (match_operand 1 "" "")]
8044 "TARGET_EITHER"
8045 "
8046 {
8047 int i;
8048 rtx addr = gen_reg_rtx (Pmode);
8049 rtx mem;
8050 int size = 0;
8051
8052 emit_move_insn (addr, XEXP (operands[0], 0));
8053 mem = change_address (operands[0], BLKmode, addr);
8054
8055 for (i = 0; i < XVECLEN (operands[1], 0); i++)
8056 {
8057 HOST_WIDE_INT offset = 0;
8058 rtx reg = SET_DEST (XVECEXP (operands[1], 0, i));
8059
8060 if (size != 0)
29c05e22 8061 emit_move_insn (addr, plus_constant (Pmode, addr, size));
ccd90aaa 8062
8063 mem = change_address (mem, GET_MODE (reg), NULL);
8064 if (REGNO (reg) == R0_REGNUM)
8065 {
8066 /* On thumb we have to use a write-back instruction. */
320ea44d 8067 emit_insn (arm_gen_load_multiple (arm_regs_in_sequence, 4, addr,
8068 TARGET_THUMB ? TRUE : FALSE, mem, &offset));
ccd90aaa 8069 size = TARGET_ARM ? 16 : 0;
8070 }
8071 else
8072 {
8073 emit_move_insn (reg, mem);
8074 size = GET_MODE_SIZE (GET_MODE (reg));
8075 }
8076 }
8077
8078 /* Emit USE insns before the return. */
8079 for (i = 0; i < XVECLEN (operands[1], 0); i++)
18b42941 8080 emit_use (SET_DEST (XVECEXP (operands[1], 0, i)));
ccd90aaa 8081
8082 /* Construct the return. */
8083 expand_naked_return ();
8084
8085 DONE;
8086 }"
8087)
8088
9c08d1fa 8089;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
8090;; all of memory. This blocks insns from being moved across this point.
8091
8092(define_insn "blockage"
e1159bbe 8093 [(unspec_volatile [(const_int 0)] VUNSPEC_BLOCKAGE)]
cffb2a26 8094 "TARGET_EITHER"
9c08d1fa 8095 ""
cffb2a26 8096 [(set_attr "length" "0")
8097 (set_attr "type" "block")]
8098)
9c08d1fa 8099
f7fbdd4a 8100(define_expand "casesi"
8101 [(match_operand:SI 0 "s_register_operand" "") ; index to jump on
aea4c774 8102 (match_operand:SI 1 "const_int_operand" "") ; lower bound
8103 (match_operand:SI 2 "const_int_operand" "") ; total range
f7fbdd4a 8104 (match_operand:SI 3 "" "") ; table label
8105 (match_operand:SI 4 "" "")] ; Out of range label
e6ac8414 8106 "TARGET_32BIT || optimize_size || flag_pic"
f7fbdd4a 8107 "
215b30b3 8108 {
e6ac8414 8109 enum insn_code code;
215b30b3 8110 if (operands[1] != const0_rtx)
8111 {
e6ac8414 8112 rtx reg = gen_reg_rtx (SImode);
f7fbdd4a 8113
215b30b3 8114 emit_insn (gen_addsi3 (reg, operands[0],
d022fa24 8115 gen_int_mode (-INTVAL (operands[1]),
8116 SImode)));
215b30b3 8117 operands[0] = reg;
8118 }
9c08d1fa 8119
25f905c2 8120 if (TARGET_ARM)
e6ac8414 8121 code = CODE_FOR_arm_casesi_internal;
3db2019b 8122 else if (TARGET_THUMB1)
e6ac8414 8123 code = CODE_FOR_thumb1_casesi_internal_pic;
25f905c2 8124 else if (flag_pic)
e6ac8414 8125 code = CODE_FOR_thumb2_casesi_internal_pic;
25f905c2 8126 else
e6ac8414 8127 code = CODE_FOR_thumb2_casesi_internal;
8128
8129 if (!insn_data[(int) code].operand[1].predicate(operands[2], SImode))
8130 operands[2] = force_reg (SImode, operands[2]);
8131
8132 emit_jump_insn (GEN_FCN ((int) code) (operands[0], operands[2],
8133 operands[3], operands[4]));
215b30b3 8134 DONE;
8135 }"
8136)
f7fbdd4a 8137
f082f1c4 8138;; The USE in this pattern is needed to tell flow analysis that this is
8139;; a CASESI insn. It has no other purpose.
25f905c2 8140(define_insn "arm_casesi_internal"
f082f1c4 8141 [(parallel [(set (pc)
8142 (if_then_else
8143 (leu (match_operand:SI 0 "s_register_operand" "r")
8144 (match_operand:SI 1 "arm_rhs_operand" "rI"))
8145 (mem:SI (plus:SI (mult:SI (match_dup 0) (const_int 4))
8146 (label_ref (match_operand 2 "" ""))))
8147 (label_ref (match_operand 3 "" ""))))
bd5b4116 8148 (clobber (reg:CC CC_REGNUM))
f082f1c4 8149 (use (label_ref (match_dup 2)))])]
cffb2a26 8150 "TARGET_ARM"
f7fbdd4a 8151 "*
0d66636f 8152 if (flag_pic)
8153 return \"cmp\\t%0, %1\;addls\\t%|pc, %|pc, %0, asl #2\;b\\t%l3\";
8154 return \"cmp\\t%0, %1\;ldrls\\t%|pc, [%|pc, %0, asl #2]\;b\\t%l3\";
8155 "
8156 [(set_attr "conds" "clob")
1b7da4ac 8157 (set_attr "length" "12")
8158 (set_attr "type" "multiple")]
0d66636f 8159)
9c08d1fa 8160
cffb2a26 8161(define_expand "indirect_jump"
9c08d1fa 8162 [(set (pc)
cffb2a26 8163 (match_operand:SI 0 "s_register_operand" ""))]
8164 "TARGET_EITHER"
25f905c2 8165 "
8166 /* Thumb-2 doesn't have mov pc, reg. Explicitly set the low bit of the
8167 address and use bx. */
8168 if (TARGET_THUMB2)
8169 {
8170 rtx tmp;
8171 tmp = gen_reg_rtx (SImode);
8172 emit_insn (gen_iorsi3 (tmp, operands[0], GEN_INT(1)));
8173 operands[0] = tmp;
8174 }
8175 "
cffb2a26 8176)
8177
f1039640 8178;; NB Never uses BX.
cffb2a26 8179(define_insn "*arm_indirect_jump"
8180 [(set (pc)
8181 (match_operand:SI 0 "s_register_operand" "r"))]
8182 "TARGET_ARM"
8183 "mov%?\\t%|pc, %0\\t%@ indirect register jump"
1b7da4ac 8184 [(set_attr "predicable" "yes")
8185 (set_attr "type" "branch")]
cffb2a26 8186)
9c08d1fa 8187
f7fbdd4a 8188(define_insn "*load_indirect_jump"
9c08d1fa 8189 [(set (pc)
8190 (match_operand:SI 0 "memory_operand" "m"))]
cffb2a26 8191 "TARGET_ARM"
8192 "ldr%?\\t%|pc, %0\\t%@ indirect memory jump"
a2cd141b 8193 [(set_attr "type" "load1")
61a2d04c 8194 (set_attr "pool_range" "4096")
8195 (set_attr "neg_pool_range" "4084")
0d66636f 8196 (set_attr "predicable" "yes")]
cffb2a26 8197)
8198
9c08d1fa 8199\f
8200;; Misc insns
8201
8202(define_insn "nop"
8203 [(const_int 0)]
cffb2a26 8204 "TARGET_EITHER"
8205 "*
25f905c2 8206 if (TARGET_UNIFIED_ASM)
8207 return \"nop\";
cffb2a26 8208 if (TARGET_ARM)
8209 return \"mov%?\\t%|r0, %|r0\\t%@ nop\";
8210 return \"mov\\tr8, r8\";
8211 "
8212 [(set (attr "length")
8213 (if_then_else (eq_attr "is_thumb" "yes")
8214 (const_int 2)
1b7da4ac 8215 (const_int 4)))
8216 (set_attr "type" "mov_reg")]
cffb2a26 8217)
8218
ad9d4399 8219(define_insn "trap"
8220 [(trap_if (const_int 1) (const_int 0))]
8221 ""
8222 "*
8223 if (TARGET_ARM)
8224 return \".inst\\t0xe7f000f0\";
8225 else
8226 return \".inst\\t0xdeff\";
8227 "
8228 [(set (attr "length")
8229 (if_then_else (eq_attr "is_thumb" "yes")
8230 (const_int 2)
8231 (const_int 4)))
8232 (set_attr "type" "trap")
8233 (set_attr "conds" "unconditional")]
8234)
8235
9c08d1fa 8236\f
8237;; Patterns to allow combination of arithmetic, cond code and shifts
8238
0abea32c 8239(define_insn "*<arith_shift_insn>_multsi"
8240 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8241 (shiftable_ops:SI
8242 (mult:SI (match_operand:SI 2 "s_register_operand" "r,r")
8243 (match_operand:SI 3 "power_of_two_operand" ""))
8244 (match_operand:SI 1 "s_register_operand" "rk,<t2_binop0>")))]
d5d4dc8d 8245 "TARGET_32BIT"
0abea32c 8246 "<arith_shift_insn>%?\\t%0, %1, %2, lsl %b3"
8247 [(set_attr "predicable" "yes")
8248 (set_attr "predicable_short_it" "no")
8249 (set_attr "shift" "4")
8250 (set_attr "arch" "a,t2")
8251 (set_attr "type" "alu_shift_imm")])
8252
8253(define_insn "*<arith_shift_insn>_shiftsi"
8254 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
8255 (shiftable_ops:SI
8256 (match_operator:SI 2 "shift_nomul_operator"
8257 [(match_operand:SI 3 "s_register_operand" "r,r,r")
8258 (match_operand:SI 4 "shift_amount_operand" "M,M,r")])
8259 (match_operand:SI 1 "s_register_operand" "rk,<t2_binop0>,rk")))]
8260 "TARGET_32BIT && GET_CODE (operands[3]) != MULT"
8261 "<arith_shift_insn>%?\\t%0, %1, %3%S2"
344495ea 8262 [(set_attr "predicable" "yes")
74ef923b 8263 (set_attr "predicable_short_it" "no")
331beb1a 8264 (set_attr "shift" "4")
0abea32c 8265 (set_attr "arch" "a,t2,a")
8266 (set_attr "type" "alu_shift_imm,alu_shift_imm,alu_shift_reg")])
9c08d1fa 8267
d7863cfe 8268(define_split
8269 [(set (match_operand:SI 0 "s_register_operand" "")
8270 (match_operator:SI 1 "shiftable_operator"
8271 [(match_operator:SI 2 "shiftable_operator"
8272 [(match_operator:SI 3 "shift_operator"
8273 [(match_operand:SI 4 "s_register_operand" "")
8274 (match_operand:SI 5 "reg_or_int_operand" "")])
8275 (match_operand:SI 6 "s_register_operand" "")])
8276 (match_operand:SI 7 "arm_rhs_operand" "")]))
8277 (clobber (match_operand:SI 8 "s_register_operand" ""))]
d5d4dc8d 8278 "TARGET_32BIT"
d7863cfe 8279 [(set (match_dup 8)
8280 (match_op_dup 2 [(match_op_dup 3 [(match_dup 4) (match_dup 5)])
8281 (match_dup 6)]))
8282 (set (match_dup 0)
8283 (match_op_dup 1 [(match_dup 8) (match_dup 7)]))]
8284 "")
8285
f7fbdd4a 8286(define_insn "*arith_shiftsi_compare0"
bd5b4116 8287 [(set (reg:CC_NOOV CC_REGNUM)
d5d4dc8d 8288 (compare:CC_NOOV
8289 (match_operator:SI 1 "shiftable_operator"
8290 [(match_operator:SI 3 "shift_operator"
8291 [(match_operand:SI 4 "s_register_operand" "r,r")
8292 (match_operand:SI 5 "shift_amount_operand" "M,r")])
8293 (match_operand:SI 2 "s_register_operand" "r,r")])
8294 (const_int 0)))
8295 (set (match_operand:SI 0 "s_register_operand" "=r,r")
9c08d1fa 8296 (match_op_dup 1 [(match_op_dup 3 [(match_dup 4) (match_dup 5)])
8297 (match_dup 2)]))]
d5d4dc8d 8298 "TARGET_32BIT"
25f905c2 8299 "%i1%.\\t%0, %2, %4%S3"
344495ea 8300 [(set_attr "conds" "set")
331beb1a 8301 (set_attr "shift" "4")
d5d4dc8d 8302 (set_attr "arch" "32,a")
d82e788e 8303 (set_attr "type" "alus_shift_imm,alus_shift_reg")])
9c08d1fa 8304
f7fbdd4a 8305(define_insn "*arith_shiftsi_compare0_scratch"
bd5b4116 8306 [(set (reg:CC_NOOV CC_REGNUM)
d5d4dc8d 8307 (compare:CC_NOOV
8308 (match_operator:SI 1 "shiftable_operator"
8309 [(match_operator:SI 3 "shift_operator"
8310 [(match_operand:SI 4 "s_register_operand" "r,r")
8311 (match_operand:SI 5 "shift_amount_operand" "M,r")])
8312 (match_operand:SI 2 "s_register_operand" "r,r")])
8313 (const_int 0)))
8314 (clobber (match_scratch:SI 0 "=r,r"))]
8315 "TARGET_32BIT"
25f905c2 8316 "%i1%.\\t%0, %2, %4%S3"
344495ea 8317 [(set_attr "conds" "set")
331beb1a 8318 (set_attr "shift" "4")
d5d4dc8d 8319 (set_attr "arch" "32,a")
d82e788e 8320 (set_attr "type" "alus_shift_imm,alus_shift_reg")])
9c08d1fa 8321
f7fbdd4a 8322(define_insn "*sub_shiftsi"
d5d4dc8d 8323 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8324 (minus:SI (match_operand:SI 1 "s_register_operand" "r,r")
9c08d1fa 8325 (match_operator:SI 2 "shift_operator"
d5d4dc8d 8326 [(match_operand:SI 3 "s_register_operand" "r,r")
8327 (match_operand:SI 4 "shift_amount_operand" "M,r")])))]
8328 "TARGET_32BIT"
6c4c2133 8329 "sub%?\\t%0, %1, %3%S2"
344495ea 8330 [(set_attr "predicable" "yes")
331beb1a 8331 (set_attr "shift" "3")
d5d4dc8d 8332 (set_attr "arch" "32,a")
d82e788e 8333 (set_attr "type" "alus_shift_imm,alus_shift_reg")])
9c08d1fa 8334
f7fbdd4a 8335(define_insn "*sub_shiftsi_compare0"
bd5b4116 8336 [(set (reg:CC_NOOV CC_REGNUM)
40dbec34 8337 (compare:CC_NOOV
d82e788e 8338 (minus:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
40dbec34 8339 (match_operator:SI 2 "shift_operator"
d82e788e 8340 [(match_operand:SI 3 "s_register_operand" "r,r,r")
8341 (match_operand:SI 4 "shift_amount_operand" "M,r,M")]))
40dbec34 8342 (const_int 0)))
d82e788e 8343 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
d5d4dc8d 8344 (minus:SI (match_dup 1)
8345 (match_op_dup 2 [(match_dup 3) (match_dup 4)])))]
8346 "TARGET_32BIT"
25f905c2 8347 "sub%.\\t%0, %1, %3%S2"
344495ea 8348 [(set_attr "conds" "set")
a2cd141b 8349 (set_attr "shift" "3")
d82e788e 8350 (set_attr "arch" "32,a,a")
8351 (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")])
9c08d1fa 8352
f7fbdd4a 8353(define_insn "*sub_shiftsi_compare0_scratch"
bd5b4116 8354 [(set (reg:CC_NOOV CC_REGNUM)
40dbec34 8355 (compare:CC_NOOV
d82e788e 8356 (minus:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
40dbec34 8357 (match_operator:SI 2 "shift_operator"
d82e788e 8358 [(match_operand:SI 3 "s_register_operand" "r,r,r")
8359 (match_operand:SI 4 "shift_amount_operand" "M,r,M")]))
40dbec34 8360 (const_int 0)))
d82e788e 8361 (clobber (match_scratch:SI 0 "=r,r,r"))]
d5d4dc8d 8362 "TARGET_32BIT"
25f905c2 8363 "sub%.\\t%0, %1, %3%S2"
344495ea 8364 [(set_attr "conds" "set")
a2cd141b 8365 (set_attr "shift" "3")
d82e788e 8366 (set_attr "arch" "32,a,a")
8367 (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")])
9c08d1fa 8368\f
8369
190efb17 8370(define_insn_and_split "*and_scc"
9c08d1fa 8371 [(set (match_operand:SI 0 "s_register_operand" "=r")
8fa3ba89 8372 (and:SI (match_operator:SI 1 "arm_comparison_operator"
190efb17 8373 [(match_operand 2 "cc_register" "") (const_int 0)])
8374 (match_operand:SI 3 "s_register_operand" "r")))]
cffb2a26 8375 "TARGET_ARM"
190efb17 8376 "#" ; "mov%D1\\t%0, #0\;and%d1\\t%0, %3, #1"
8377 "&& reload_completed"
8378 [(cond_exec (match_dup 5) (set (match_dup 0) (const_int 0)))
8379 (cond_exec (match_dup 4) (set (match_dup 0)
8380 (and:SI (match_dup 3) (const_int 1))))]
8381 {
8382 enum machine_mode mode = GET_MODE (operands[2]);
8383 enum rtx_code rc = GET_CODE (operands[1]);
8384
8385 /* Note that operands[4] is the same as operands[1],
8386 but with VOIDmode as the result. */
8387 operands[4] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
8388 if (mode == CCFPmode || mode == CCFPEmode)
8389 rc = reverse_condition_maybe_unordered (rc);
8390 else
8391 rc = reverse_condition (rc);
8392 operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
8393 }
8fa3ba89 8394 [(set_attr "conds" "use")
1b7da4ac 8395 (set_attr "type" "multiple")
8fa3ba89 8396 (set_attr "length" "8")]
8397)
9c08d1fa 8398
190efb17 8399(define_insn_and_split "*ior_scc"
9c08d1fa 8400 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
190efb17 8401 (ior:SI (match_operator:SI 1 "arm_comparison_operator"
8402 [(match_operand 2 "cc_register" "") (const_int 0)])
8403 (match_operand:SI 3 "s_register_operand" "0,?r")))]
cffb2a26 8404 "TARGET_ARM"
e2348bcb 8405 "@
190efb17 8406 orr%d1\\t%0, %3, #1
8407 #"
8408 "&& reload_completed
8409 && REGNO (operands [0]) != REGNO (operands[3])"
8410 ;; && which_alternative == 1
8411 ; mov%D1\\t%0, %3\;orr%d1\\t%0, %3, #1
8412 [(cond_exec (match_dup 5) (set (match_dup 0) (match_dup 3)))
8413 (cond_exec (match_dup 4) (set (match_dup 0)
8414 (ior:SI (match_dup 3) (const_int 1))))]
8415 {
8416 enum machine_mode mode = GET_MODE (operands[2]);
8417 enum rtx_code rc = GET_CODE (operands[1]);
8418
8419 /* Note that operands[4] is the same as operands[1],
8420 but with VOIDmode as the result. */
8421 operands[4] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
8422 if (mode == CCFPmode || mode == CCFPEmode)
8423 rc = reverse_condition_maybe_unordered (rc);
8424 else
8425 rc = reverse_condition (rc);
8426 operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
8427 }
8fa3ba89 8428 [(set_attr "conds" "use")
1b7da4ac 8429 (set_attr "length" "4,8")
8430 (set_attr "type" "logic_imm,multiple")]
8fa3ba89 8431)
9c08d1fa 8432
2df9477b 8433; A series of splitters for the compare_scc pattern below. Note that
8434; order is important.
8435(define_split
8436 [(set (match_operand:SI 0 "s_register_operand" "")
8437 (lt:SI (match_operand:SI 1 "s_register_operand" "")
8438 (const_int 0)))
8439 (clobber (reg:CC CC_REGNUM))]
8440 "TARGET_32BIT && reload_completed"
8441 [(set (match_dup 0) (lshiftrt:SI (match_dup 1) (const_int 31)))])
8442
8443(define_split
8444 [(set (match_operand:SI 0 "s_register_operand" "")
8445 (ge:SI (match_operand:SI 1 "s_register_operand" "")
8446 (const_int 0)))
8447 (clobber (reg:CC CC_REGNUM))]
8448 "TARGET_32BIT && reload_completed"
8449 [(set (match_dup 0) (not:SI (match_dup 1)))
8450 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 31)))])
8451
98562479 8452(define_split
8453 [(set (match_operand:SI 0 "s_register_operand" "")
8454 (eq:SI (match_operand:SI 1 "s_register_operand" "")
8455 (const_int 0)))
8456 (clobber (reg:CC CC_REGNUM))]
8457 "arm_arch5 && TARGET_32BIT"
8458 [(set (match_dup 0) (clz:SI (match_dup 1)))
8459 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 5)))]
8460)
8461
2df9477b 8462(define_split
8463 [(set (match_operand:SI 0 "s_register_operand" "")
8464 (eq:SI (match_operand:SI 1 "s_register_operand" "")
8465 (const_int 0)))
8466 (clobber (reg:CC CC_REGNUM))]
8467 "TARGET_32BIT && reload_completed"
8468 [(parallel
080c0b9a 8469 [(set (reg:CC CC_REGNUM)
8470 (compare:CC (const_int 1) (match_dup 1)))
2df9477b 8471 (set (match_dup 0)
8472 (minus:SI (const_int 1) (match_dup 1)))])
080c0b9a 8473 (cond_exec (ltu:CC (reg:CC CC_REGNUM) (const_int 0))
2df9477b 8474 (set (match_dup 0) (const_int 0)))])
8475
8476(define_split
8477 [(set (match_operand:SI 0 "s_register_operand" "")
8478 (ne:SI (match_operand:SI 1 "s_register_operand" "")
8479 (match_operand:SI 2 "const_int_operand" "")))
8480 (clobber (reg:CC CC_REGNUM))]
8481 "TARGET_32BIT && reload_completed"
8482 [(parallel
8483 [(set (reg:CC CC_REGNUM)
8484 (compare:CC (match_dup 1) (match_dup 2)))
8485 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 3)))])
8486 (cond_exec (ne:CC (reg:CC CC_REGNUM) (const_int 0))
8487 (set (match_dup 0) (const_int 1)))]
8488{
8489 operands[3] = GEN_INT (-INTVAL (operands[2]));
8490})
8491
8492(define_split
8493 [(set (match_operand:SI 0 "s_register_operand" "")
8494 (ne:SI (match_operand:SI 1 "s_register_operand" "")
8495 (match_operand:SI 2 "arm_add_operand" "")))
8496 (clobber (reg:CC CC_REGNUM))]
8497 "TARGET_32BIT && reload_completed"
8498 [(parallel
8499 [(set (reg:CC_NOOV CC_REGNUM)
8500 (compare:CC_NOOV (minus:SI (match_dup 1) (match_dup 2))
8501 (const_int 0)))
8502 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
8503 (cond_exec (ne:CC_NOOV (reg:CC_NOOV CC_REGNUM) (const_int 0))
8504 (set (match_dup 0) (const_int 1)))])
8505
8506(define_insn_and_split "*compare_scc"
fd711051 8507 [(set (match_operand:SI 0 "s_register_operand" "=Ts,Ts")
8fa3ba89 8508 (match_operator:SI 1 "arm_comparison_operator"
5565501b 8509 [(match_operand:SI 2 "s_register_operand" "r,r")
8510 (match_operand:SI 3 "arm_add_operand" "rI,L")]))
bd5b4116 8511 (clobber (reg:CC CC_REGNUM))]
2df9477b 8512 "TARGET_32BIT"
8513 "#"
8514 "&& reload_completed"
8515 [(set (reg:CC CC_REGNUM) (compare:CC (match_dup 2) (match_dup 3)))
8516 (cond_exec (match_dup 4) (set (match_dup 0) (const_int 0)))
8517 (cond_exec (match_dup 5) (set (match_dup 0) (const_int 1)))]
8518{
8519 rtx tmp1;
8520 enum machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
8521 operands[2], operands[3]);
8522 enum rtx_code rc = GET_CODE (operands[1]);
e2348bcb 8523
2df9477b 8524 tmp1 = gen_rtx_REG (mode, CC_REGNUM);
080c0b9a 8525
2df9477b 8526 operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, tmp1, const0_rtx);
8527 if (mode == CCFPmode || mode == CCFPEmode)
8528 rc = reverse_condition_maybe_unordered (rc);
8529 else
8530 rc = reverse_condition (rc);
8531 operands[4] = gen_rtx_fmt_ee (rc, VOIDmode, tmp1, const0_rtx);
1b7da4ac 8532}
8533 [(set_attr "type" "multiple")]
8534)
9c08d1fa 8535
080c0b9a 8536;; Attempt to improve the sequence generated by the compare_scc splitters
8537;; not to use conditional execution.
98562479 8538
8539;; Rd = (eq (reg1) (const_int0)) // ARMv5
8540;; clz Rd, reg1
8541;; lsr Rd, Rd, #5
080c0b9a 8542(define_peephole2
8543 [(set (reg:CC CC_REGNUM)
8544 (compare:CC (match_operand:SI 1 "register_operand" "")
98562479 8545 (const_int 0)))
8546 (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
8547 (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
8548 (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
8549 (set (match_dup 0) (const_int 1)))]
8550 "arm_arch5 && TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)"
8551 [(set (match_dup 0) (clz:SI (match_dup 1)))
8552 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 5)))]
8553)
8554
8555;; Rd = (eq (reg1) (const_int0)) // !ARMv5
8556;; negs Rd, reg1
8557;; adc Rd, Rd, reg1
8558(define_peephole2
8559 [(set (reg:CC CC_REGNUM)
8560 (compare:CC (match_operand:SI 1 "register_operand" "")
8561 (const_int 0)))
080c0b9a 8562 (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
8563 (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
8564 (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
8565 (set (match_dup 0) (const_int 1)))
98562479 8566 (match_scratch:SI 2 "r")]
8567 "TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)"
922b6913 8568 [(parallel
8569 [(set (reg:CC CC_REGNUM)
98562479 8570 (compare:CC (const_int 0) (match_dup 1)))
8571 (set (match_dup 2) (minus:SI (const_int 0) (match_dup 1)))])
8572 (set (match_dup 0)
8573 (plus:SI (plus:SI (match_dup 1) (match_dup 2))
8574 (geu:SI (reg:CC CC_REGNUM) (const_int 0))))]
8575)
8576
31991287 8577;; Rd = (eq (reg1) (reg2/imm)) // ARMv5 and optimising for speed.
98562479 8578;; sub Rd, Reg1, reg2
8579;; clz Rd, Rd
8580;; lsr Rd, Rd, #5
8581(define_peephole2
8582 [(set (reg:CC CC_REGNUM)
8583 (compare:CC (match_operand:SI 1 "register_operand" "")
8584 (match_operand:SI 2 "arm_rhs_operand" "")))
8585 (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
8586 (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
8587 (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
8588 (set (match_dup 0) (const_int 1)))]
31991287 8589 "arm_arch5 && TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)
8590 && !(TARGET_THUMB2 && optimize_insn_for_size_p ())"
98562479 8591 [(set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))
8592 (set (match_dup 0) (clz:SI (match_dup 0)))
8593 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 5)))]
8594)
8595
8596
31991287 8597;; Rd = (eq (reg1) (reg2)) // ! ARMv5 or optimising for size.
98562479 8598;; sub T1, Reg1, reg2
8599;; negs Rd, T1
8600;; adc Rd, Rd, T1
8601(define_peephole2
8602 [(set (reg:CC CC_REGNUM)
8603 (compare:CC (match_operand:SI 1 "register_operand" "")
8604 (match_operand:SI 2 "arm_rhs_operand" "")))
8605 (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
8606 (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
8607 (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
8608 (set (match_dup 0) (const_int 1)))
8609 (match_scratch:SI 3 "r")]
8610 "TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)"
31991287 8611 [(set (match_dup 3) (match_dup 4))
080c0b9a 8612 (parallel
8613 [(set (reg:CC CC_REGNUM)
8614 (compare:CC (const_int 0) (match_dup 3)))
8615 (set (match_dup 0) (minus:SI (const_int 0) (match_dup 3)))])
98562479 8616 (set (match_dup 0)
8617 (plus:SI (plus:SI (match_dup 0) (match_dup 3))
8618 (geu:SI (reg:CC CC_REGNUM) (const_int 0))))]
31991287 8619 "
8620 if (CONST_INT_P (operands[2]))
8621 operands[4] = plus_constant (SImode, operands[1], -INTVAL (operands[2]));
8622 else
8623 operands[4] = gen_rtx_MINUS (SImode, operands[1], operands[2]);
8624 ")
080c0b9a 8625
f7fbdd4a 8626(define_insn "*cond_move"
9c08d1fa 8627 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
aea4c774 8628 (if_then_else:SI (match_operator 3 "equality_operator"
8fa3ba89 8629 [(match_operator 4 "arm_comparison_operator"
8a18b90c 8630 [(match_operand 5 "cc_register" "") (const_int 0)])
aea4c774 8631 (const_int 0)])
8632 (match_operand:SI 1 "arm_rhs_operand" "0,rI,?rI")
8633 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))]
cffb2a26 8634 "TARGET_ARM"
9c08d1fa 8635 "*
8fa3ba89 8636 if (GET_CODE (operands[3]) == NE)
8637 {
8638 if (which_alternative != 1)
8639 output_asm_insn (\"mov%D4\\t%0, %2\", operands);
8640 if (which_alternative != 0)
8641 output_asm_insn (\"mov%d4\\t%0, %1\", operands);
8642 return \"\";
8643 }
8644 if (which_alternative != 0)
8645 output_asm_insn (\"mov%D4\\t%0, %1\", operands);
8646 if (which_alternative != 1)
8647 output_asm_insn (\"mov%d4\\t%0, %2\", operands);
8648 return \"\";
8649 "
8650 [(set_attr "conds" "use")
1b7da4ac 8651 (set_attr "type" "mov_reg,mov_reg,multiple")
8fa3ba89 8652 (set_attr "length" "4,4,8")]
8653)
9c08d1fa 8654
f7fbdd4a 8655(define_insn "*cond_arith"
9c08d1fa 8656 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8657 (match_operator:SI 5 "shiftable_operator"
8fa3ba89 8658 [(match_operator:SI 4 "arm_comparison_operator"
9c08d1fa 8659 [(match_operand:SI 2 "s_register_operand" "r,r")
8660 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
8661 (match_operand:SI 1 "s_register_operand" "0,?r")]))
bd5b4116 8662 (clobber (reg:CC CC_REGNUM))]
cffb2a26 8663 "TARGET_ARM"
9c08d1fa 8664 "*
8fa3ba89 8665 if (GET_CODE (operands[4]) == LT && operands[3] == const0_rtx)
8666 return \"%i5\\t%0, %1, %2, lsr #31\";
40dbec34 8667
8fa3ba89 8668 output_asm_insn (\"cmp\\t%2, %3\", operands);
8669 if (GET_CODE (operands[5]) == AND)
8670 output_asm_insn (\"mov%D4\\t%0, #0\", operands);
8671 else if (GET_CODE (operands[5]) == MINUS)
8672 output_asm_insn (\"rsb%D4\\t%0, %1, #0\", operands);
8673 else if (which_alternative != 0)
8674 output_asm_insn (\"mov%D4\\t%0, %1\", operands);
8675 return \"%i5%d4\\t%0, %1, #1\";
8676 "
8677 [(set_attr "conds" "clob")
1b7da4ac 8678 (set_attr "length" "12")
8679 (set_attr "type" "multiple")]
8fa3ba89 8680)
9c08d1fa 8681
f7fbdd4a 8682(define_insn "*cond_sub"
9c08d1fa 8683 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8684 (minus:SI (match_operand:SI 1 "s_register_operand" "0,?r")
8fa3ba89 8685 (match_operator:SI 4 "arm_comparison_operator"
9c08d1fa 8686 [(match_operand:SI 2 "s_register_operand" "r,r")
8687 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))
bd5b4116 8688 (clobber (reg:CC CC_REGNUM))]
cffb2a26 8689 "TARGET_ARM"
9c08d1fa 8690 "*
8fa3ba89 8691 output_asm_insn (\"cmp\\t%2, %3\", operands);
8692 if (which_alternative != 0)
8693 output_asm_insn (\"mov%D4\\t%0, %1\", operands);
8694 return \"sub%d4\\t%0, %1, #1\";
8695 "
8696 [(set_attr "conds" "clob")
1b7da4ac 8697 (set_attr "length" "8,12")
8698 (set_attr "type" "multiple")]
8fa3ba89 8699)
9c08d1fa 8700
aea4c774 8701(define_insn "*cmp_ite0"
cffb2a26 8702 [(set (match_operand 6 "dominant_cc_register" "")
aea4c774 8703 (compare
8704 (if_then_else:SI
8fa3ba89 8705 (match_operator 4 "arm_comparison_operator"
2ff91fec 8706 [(match_operand:SI 0 "s_register_operand"
8707 "l,l,l,r,r,r,r,r,r")
8708 (match_operand:SI 1 "arm_add_operand"
8709 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
8fa3ba89 8710 (match_operator:SI 5 "arm_comparison_operator"
2ff91fec 8711 [(match_operand:SI 2 "s_register_operand"
8712 "l,r,r,l,l,r,r,r,r")
8713 (match_operand:SI 3 "arm_add_operand"
8714 "lPy,rI,L,lPy,lPy,rI,rI,L,L")])
aea4c774 8715 (const_int 0))
8716 (const_int 0)))]
2ff91fec 8717 "TARGET_32BIT"
9c08d1fa 8718 "*
aea4c774 8719 {
2ff91fec 8720 static const char * const cmp1[NUM_OF_COND_CMP][2] =
8721 {
8722 {\"cmp%d5\\t%0, %1\",
8723 \"cmp%d4\\t%2, %3\"},
8724 {\"cmn%d5\\t%0, #%n1\",
8725 \"cmp%d4\\t%2, %3\"},
8726 {\"cmp%d5\\t%0, %1\",
8727 \"cmn%d4\\t%2, #%n3\"},
8728 {\"cmn%d5\\t%0, #%n1\",
8729 \"cmn%d4\\t%2, #%n3\"}
8730 };
8731 static const char * const cmp2[NUM_OF_COND_CMP][2] =
8732 {
8733 {\"cmp\\t%2, %3\",
8734 \"cmp\\t%0, %1\"},
8735 {\"cmp\\t%2, %3\",
8736 \"cmn\\t%0, #%n1\"},
8737 {\"cmn\\t%2, #%n3\",
8738 \"cmp\\t%0, %1\"},
8739 {\"cmn\\t%2, #%n3\",
8740 \"cmn\\t%0, #%n1\"}
8741 };
8742 static const char * const ite[2] =
8fa3ba89 8743 {
2ff91fec 8744 \"it\\t%d5\",
8745 \"it\\t%d4\"
8fa3ba89 8746 };
2ff91fec 8747 static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
8748 CMP_CMP, CMN_CMP, CMP_CMP,
8749 CMN_CMP, CMP_CMN, CMN_CMN};
8fa3ba89 8750 int swap =
8751 comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4]));
8752
2ff91fec 8753 output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
8754 if (TARGET_THUMB2) {
8755 output_asm_insn (ite[swap], operands);
8756 }
8757 output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
8758 return \"\";
8fa3ba89 8759 }"
8760 [(set_attr "conds" "set")
2ff91fec 8761 (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
1b7da4ac 8762 (set_attr "type" "multiple")
2ff91fec 8763 (set_attr_alternative "length"
8764 [(const_int 6)
8765 (const_int 8)
8766 (const_int 8)
8767 (const_int 8)
8768 (const_int 8)
8769 (if_then_else (eq_attr "is_thumb" "no")
8770 (const_int 8)
8771 (const_int 10))
8772 (if_then_else (eq_attr "is_thumb" "no")
8773 (const_int 8)
8774 (const_int 10))
8775 (if_then_else (eq_attr "is_thumb" "no")
8776 (const_int 8)
8777 (const_int 10))
8778 (if_then_else (eq_attr "is_thumb" "no")
8779 (const_int 8)
8780 (const_int 10))])]
8fa3ba89 8781)
9c08d1fa 8782
aea4c774 8783(define_insn "*cmp_ite1"
cffb2a26 8784 [(set (match_operand 6 "dominant_cc_register" "")
aea4c774 8785 (compare
8786 (if_then_else:SI
8fa3ba89 8787 (match_operator 4 "arm_comparison_operator"
2ff91fec 8788 [(match_operand:SI 0 "s_register_operand"
8789 "l,l,l,r,r,r,r,r,r")
8790 (match_operand:SI 1 "arm_add_operand"
8791 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
8fa3ba89 8792 (match_operator:SI 5 "arm_comparison_operator"
2ff91fec 8793 [(match_operand:SI 2 "s_register_operand"
8794 "l,r,r,l,l,r,r,r,r")
8795 (match_operand:SI 3 "arm_add_operand"
8796 "lPy,rI,L,lPy,lPy,rI,rI,L,L")])
aea4c774 8797 (const_int 1))
8798 (const_int 0)))]
2ff91fec 8799 "TARGET_32BIT"
9c08d1fa 8800 "*
9c08d1fa 8801 {
2ff91fec 8802 static const char * const cmp1[NUM_OF_COND_CMP][2] =
8803 {
8804 {\"cmp\\t%0, %1\",
8805 \"cmp\\t%2, %3\"},
8806 {\"cmn\\t%0, #%n1\",
8807 \"cmp\\t%2, %3\"},
8808 {\"cmp\\t%0, %1\",
8809 \"cmn\\t%2, #%n3\"},
8810 {\"cmn\\t%0, #%n1\",
8811 \"cmn\\t%2, #%n3\"}
8812 };
8813 static const char * const cmp2[NUM_OF_COND_CMP][2] =
215b30b3 8814 {
2ff91fec 8815 {\"cmp%d4\\t%2, %3\",
8816 \"cmp%D5\\t%0, %1\"},
8817 {\"cmp%d4\\t%2, %3\",
8818 \"cmn%D5\\t%0, #%n1\"},
8819 {\"cmn%d4\\t%2, #%n3\",
8820 \"cmp%D5\\t%0, %1\"},
8821 {\"cmn%d4\\t%2, #%n3\",
8822 \"cmn%D5\\t%0, #%n1\"}
215b30b3 8823 };
2ff91fec 8824 static const char * const ite[2] =
8825 {
8826 \"it\\t%d4\",
8827 \"it\\t%D5\"
8828 };
8829 static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
8830 CMP_CMP, CMN_CMP, CMP_CMP,
8831 CMN_CMP, CMP_CMN, CMN_CMN};
215b30b3 8832 int swap =
8833 comparison_dominates_p (GET_CODE (operands[5]),
8834 reverse_condition (GET_CODE (operands[4])));
8835
2ff91fec 8836 output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
8837 if (TARGET_THUMB2) {
8838 output_asm_insn (ite[swap], operands);
8839 }
8840 output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
8841 return \"\";
215b30b3 8842 }"
8fa3ba89 8843 [(set_attr "conds" "set")
2ff91fec 8844 (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
8845 (set_attr_alternative "length"
8846 [(const_int 6)
8847 (const_int 8)
8848 (const_int 8)
8849 (const_int 8)
8850 (const_int 8)
8851 (if_then_else (eq_attr "is_thumb" "no")
8852 (const_int 8)
8853 (const_int 10))
8854 (if_then_else (eq_attr "is_thumb" "no")
8855 (const_int 8)
8856 (const_int 10))
8857 (if_then_else (eq_attr "is_thumb" "no")
8858 (const_int 8)
8859 (const_int 10))
8860 (if_then_else (eq_attr "is_thumb" "no")
8861 (const_int 8)
1b7da4ac 8862 (const_int 10))])
8863 (set_attr "type" "multiple")]
8fa3ba89 8864)
9c08d1fa 8865
f6c53574 8866(define_insn "*cmp_and"
8867 [(set (match_operand 6 "dominant_cc_register" "")
8868 (compare
8869 (and:SI
8870 (match_operator 4 "arm_comparison_operator"
2ff91fec 8871 [(match_operand:SI 0 "s_register_operand"
8872 "l,l,l,r,r,r,r,r,r")
8873 (match_operand:SI 1 "arm_add_operand"
8874 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
f6c53574 8875 (match_operator:SI 5 "arm_comparison_operator"
2ff91fec 8876 [(match_operand:SI 2 "s_register_operand"
8877 "l,r,r,l,l,r,r,r,r")
8878 (match_operand:SI 3 "arm_add_operand"
8879 "lPy,rI,L,lPy,lPy,rI,rI,L,L")]))
f6c53574 8880 (const_int 0)))]
2ff91fec 8881 "TARGET_32BIT"
f6c53574 8882 "*
8883 {
2ff91fec 8884 static const char *const cmp1[NUM_OF_COND_CMP][2] =
f6c53574 8885 {
2ff91fec 8886 {\"cmp%d5\\t%0, %1\",
8887 \"cmp%d4\\t%2, %3\"},
8888 {\"cmn%d5\\t%0, #%n1\",
8889 \"cmp%d4\\t%2, %3\"},
8890 {\"cmp%d5\\t%0, %1\",
8891 \"cmn%d4\\t%2, #%n3\"},
8892 {\"cmn%d5\\t%0, #%n1\",
8893 \"cmn%d4\\t%2, #%n3\"}
f6c53574 8894 };
2ff91fec 8895 static const char *const cmp2[NUM_OF_COND_CMP][2] =
8896 {
8897 {\"cmp\\t%2, %3\",
8898 \"cmp\\t%0, %1\"},
8899 {\"cmp\\t%2, %3\",
8900 \"cmn\\t%0, #%n1\"},
8901 {\"cmn\\t%2, #%n3\",
8902 \"cmp\\t%0, %1\"},
8903 {\"cmn\\t%2, #%n3\",
8904 \"cmn\\t%0, #%n1\"}
8905 };
8906 static const char *const ite[2] =
8907 {
8908 \"it\\t%d5\",
8909 \"it\\t%d4\"
8910 };
8911 static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
8912 CMP_CMP, CMN_CMP, CMP_CMP,
8913 CMN_CMP, CMP_CMN, CMN_CMN};
f6c53574 8914 int swap =
8915 comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4]));
8916
2ff91fec 8917 output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
8918 if (TARGET_THUMB2) {
8919 output_asm_insn (ite[swap], operands);
8920 }
8921 output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
8922 return \"\";
f6c53574 8923 }"
8924 [(set_attr "conds" "set")
8925 (set_attr "predicable" "no")
2ff91fec 8926 (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
8927 (set_attr_alternative "length"
8928 [(const_int 6)
8929 (const_int 8)
8930 (const_int 8)
8931 (const_int 8)
8932 (const_int 8)
8933 (if_then_else (eq_attr "is_thumb" "no")
8934 (const_int 8)
8935 (const_int 10))
8936 (if_then_else (eq_attr "is_thumb" "no")
8937 (const_int 8)
8938 (const_int 10))
8939 (if_then_else (eq_attr "is_thumb" "no")
8940 (const_int 8)
8941 (const_int 10))
8942 (if_then_else (eq_attr "is_thumb" "no")
8943 (const_int 8)
1b7da4ac 8944 (const_int 10))])
8945 (set_attr "type" "multiple")]
f6c53574 8946)
8947
8948(define_insn "*cmp_ior"
8949 [(set (match_operand 6 "dominant_cc_register" "")
8950 (compare
8951 (ior:SI
8952 (match_operator 4 "arm_comparison_operator"
2ff91fec 8953 [(match_operand:SI 0 "s_register_operand"
8954 "l,l,l,r,r,r,r,r,r")
8955 (match_operand:SI 1 "arm_add_operand"
8956 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
f6c53574 8957 (match_operator:SI 5 "arm_comparison_operator"
2ff91fec 8958 [(match_operand:SI 2 "s_register_operand"
8959 "l,r,r,l,l,r,r,r,r")
8960 (match_operand:SI 3 "arm_add_operand"
8961 "lPy,rI,L,lPy,lPy,rI,rI,L,L")]))
f6c53574 8962 (const_int 0)))]
2ff91fec 8963 "TARGET_32BIT"
f6c53574 8964 "*
f6c53574 8965 {
2ff91fec 8966 static const char *const cmp1[NUM_OF_COND_CMP][2] =
8967 {
8968 {\"cmp\\t%0, %1\",
8969 \"cmp\\t%2, %3\"},
8970 {\"cmn\\t%0, #%n1\",
8971 \"cmp\\t%2, %3\"},
8972 {\"cmp\\t%0, %1\",
8973 \"cmn\\t%2, #%n3\"},
8974 {\"cmn\\t%0, #%n1\",
8975 \"cmn\\t%2, #%n3\"}
8976 };
8977 static const char *const cmp2[NUM_OF_COND_CMP][2] =
8978 {
8979 {\"cmp%D4\\t%2, %3\",
8980 \"cmp%D5\\t%0, %1\"},
8981 {\"cmp%D4\\t%2, %3\",
8982 \"cmn%D5\\t%0, #%n1\"},
8983 {\"cmn%D4\\t%2, #%n3\",
8984 \"cmp%D5\\t%0, %1\"},
8985 {\"cmn%D4\\t%2, #%n3\",
8986 \"cmn%D5\\t%0, #%n1\"}
8987 };
8988 static const char *const ite[2] =
8989 {
8990 \"it\\t%D4\",
8991 \"it\\t%D5\"
8992 };
8993 static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
8994 CMP_CMP, CMN_CMP, CMP_CMP,
8995 CMN_CMP, CMP_CMN, CMN_CMN};
8996 int swap =
8997 comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4]));
8998
8999 output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
9000 if (TARGET_THUMB2) {
9001 output_asm_insn (ite[swap], operands);
9002 }
9003 output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
9004 return \"\";
9005 }
9006 "
f6c53574 9007 [(set_attr "conds" "set")
2ff91fec 9008 (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
9009 (set_attr_alternative "length"
9010 [(const_int 6)
9011 (const_int 8)
9012 (const_int 8)
9013 (const_int 8)
9014 (const_int 8)
9015 (if_then_else (eq_attr "is_thumb" "no")
9016 (const_int 8)
9017 (const_int 10))
9018 (if_then_else (eq_attr "is_thumb" "no")
9019 (const_int 8)
9020 (const_int 10))
9021 (if_then_else (eq_attr "is_thumb" "no")
9022 (const_int 8)
9023 (const_int 10))
9024 (if_then_else (eq_attr "is_thumb" "no")
9025 (const_int 8)
1b7da4ac 9026 (const_int 10))])
9027 (set_attr "type" "multiple")]
f6c53574 9028)
9029
3c5afce6 9030(define_insn_and_split "*ior_scc_scc"
fd711051 9031 [(set (match_operand:SI 0 "s_register_operand" "=Ts")
3c5afce6 9032 (ior:SI (match_operator:SI 3 "arm_comparison_operator"
9033 [(match_operand:SI 1 "s_register_operand" "r")
9034 (match_operand:SI 2 "arm_add_operand" "rIL")])
9035 (match_operator:SI 6 "arm_comparison_operator"
9036 [(match_operand:SI 4 "s_register_operand" "r")
9037 (match_operand:SI 5 "arm_add_operand" "rIL")])))
9038 (clobber (reg:CC CC_REGNUM))]
2ff91fec 9039 "TARGET_32BIT
3c5afce6 9040 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_OR_Y)
9041 != CCmode)"
9042 "#"
2ff91fec 9043 "TARGET_32BIT && reload_completed"
3c5afce6 9044 [(set (match_dup 7)
9045 (compare
9046 (ior:SI
9047 (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9048 (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9049 (const_int 0)))
9050 (set (match_dup 0) (ne:SI (match_dup 7) (const_int 0)))]
9051 "operands[7]
9052 = gen_rtx_REG (arm_select_dominance_cc_mode (operands[3], operands[6],
9053 DOM_CC_X_OR_Y),
601f584c 9054 CC_REGNUM);"
9055 [(set_attr "conds" "clob")
1b7da4ac 9056 (set_attr "length" "16")
9057 (set_attr "type" "multiple")]
9058)
601f584c 9059
9060; If the above pattern is followed by a CMP insn, then the compare is
9061; redundant, since we can rework the conditional instruction that follows.
9062(define_insn_and_split "*ior_scc_scc_cmp"
9063 [(set (match_operand 0 "dominant_cc_register" "")
9064 (compare (ior:SI (match_operator:SI 3 "arm_comparison_operator"
9065 [(match_operand:SI 1 "s_register_operand" "r")
9066 (match_operand:SI 2 "arm_add_operand" "rIL")])
9067 (match_operator:SI 6 "arm_comparison_operator"
9068 [(match_operand:SI 4 "s_register_operand" "r")
9069 (match_operand:SI 5 "arm_add_operand" "rIL")]))
9070 (const_int 0)))
fd711051 9071 (set (match_operand:SI 7 "s_register_operand" "=Ts")
601f584c 9072 (ior:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9073 (match_op_dup 6 [(match_dup 4) (match_dup 5)])))]
2ff91fec 9074 "TARGET_32BIT"
601f584c 9075 "#"
2ff91fec 9076 "TARGET_32BIT && reload_completed"
601f584c 9077 [(set (match_dup 0)
9078 (compare
9079 (ior:SI
9080 (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9081 (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9082 (const_int 0)))
9083 (set (match_dup 7) (ne:SI (match_dup 0) (const_int 0)))]
9084 ""
9085 [(set_attr "conds" "set")
1b7da4ac 9086 (set_attr "length" "16")
9087 (set_attr "type" "multiple")]
9088)
3c5afce6 9089
9090(define_insn_and_split "*and_scc_scc"
fd711051 9091 [(set (match_operand:SI 0 "s_register_operand" "=Ts")
3c5afce6 9092 (and:SI (match_operator:SI 3 "arm_comparison_operator"
9093 [(match_operand:SI 1 "s_register_operand" "r")
9094 (match_operand:SI 2 "arm_add_operand" "rIL")])
9095 (match_operator:SI 6 "arm_comparison_operator"
9096 [(match_operand:SI 4 "s_register_operand" "r")
9097 (match_operand:SI 5 "arm_add_operand" "rIL")])))
9098 (clobber (reg:CC CC_REGNUM))]
2ff91fec 9099 "TARGET_32BIT
3c5afce6 9100 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y)
9101 != CCmode)"
9102 "#"
2ff91fec 9103 "TARGET_32BIT && reload_completed
601f584c 9104 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y)
9105 != CCmode)"
3c5afce6 9106 [(set (match_dup 7)
9107 (compare
9108 (and:SI
9109 (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9110 (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9111 (const_int 0)))
9112 (set (match_dup 0) (ne:SI (match_dup 7) (const_int 0)))]
9113 "operands[7]
9114 = gen_rtx_REG (arm_select_dominance_cc_mode (operands[3], operands[6],
9115 DOM_CC_X_AND_Y),
601f584c 9116 CC_REGNUM);"
9117 [(set_attr "conds" "clob")
1b7da4ac 9118 (set_attr "length" "16")
9119 (set_attr "type" "multiple")]
9120)
601f584c 9121
9122; If the above pattern is followed by a CMP insn, then the compare is
9123; redundant, since we can rework the conditional instruction that follows.
9124(define_insn_and_split "*and_scc_scc_cmp"
9125 [(set (match_operand 0 "dominant_cc_register" "")
9126 (compare (and:SI (match_operator:SI 3 "arm_comparison_operator"
9127 [(match_operand:SI 1 "s_register_operand" "r")
9128 (match_operand:SI 2 "arm_add_operand" "rIL")])
9129 (match_operator:SI 6 "arm_comparison_operator"
9130 [(match_operand:SI 4 "s_register_operand" "r")
9131 (match_operand:SI 5 "arm_add_operand" "rIL")]))
9132 (const_int 0)))
fd711051 9133 (set (match_operand:SI 7 "s_register_operand" "=Ts")
601f584c 9134 (and:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9135 (match_op_dup 6 [(match_dup 4) (match_dup 5)])))]
2ff91fec 9136 "TARGET_32BIT"
601f584c 9137 "#"
2ff91fec 9138 "TARGET_32BIT && reload_completed"
601f584c 9139 [(set (match_dup 0)
9140 (compare
9141 (and:SI
9142 (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9143 (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9144 (const_int 0)))
9145 (set (match_dup 7) (ne:SI (match_dup 0) (const_int 0)))]
9146 ""
9147 [(set_attr "conds" "set")
1b7da4ac 9148 (set_attr "length" "16")
9149 (set_attr "type" "multiple")]
9150)
601f584c 9151
9152;; If there is no dominance in the comparison, then we can still save an
9153;; instruction in the AND case, since we can know that the second compare
9154;; need only zero the value if false (if true, then the value is already
9155;; correct).
9156(define_insn_and_split "*and_scc_scc_nodom"
fd711051 9157 [(set (match_operand:SI 0 "s_register_operand" "=&Ts,&Ts,&Ts")
601f584c 9158 (and:SI (match_operator:SI 3 "arm_comparison_operator"
9159 [(match_operand:SI 1 "s_register_operand" "r,r,0")
9160 (match_operand:SI 2 "arm_add_operand" "rIL,0,rIL")])
9161 (match_operator:SI 6 "arm_comparison_operator"
9162 [(match_operand:SI 4 "s_register_operand" "r,r,r")
9163 (match_operand:SI 5 "arm_add_operand" "rIL,rIL,rIL")])))
9164 (clobber (reg:CC CC_REGNUM))]
2ff91fec 9165 "TARGET_32BIT
601f584c 9166 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y)
9167 == CCmode)"
9168 "#"
2ff91fec 9169 "TARGET_32BIT && reload_completed"
601f584c 9170 [(parallel [(set (match_dup 0)
9171 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
9172 (clobber (reg:CC CC_REGNUM))])
9173 (set (match_dup 7) (match_op_dup 8 [(match_dup 4) (match_dup 5)]))
9174 (set (match_dup 0)
9175 (if_then_else:SI (match_op_dup 6 [(match_dup 7) (const_int 0)])
9176 (match_dup 0)
9177 (const_int 0)))]
9178 "operands[7] = gen_rtx_REG (SELECT_CC_MODE (GET_CODE (operands[6]),
9179 operands[4], operands[5]),
9180 CC_REGNUM);
9181 operands[8] = gen_rtx_COMPARE (GET_MODE (operands[7]), operands[4],
9182 operands[5]);"
9183 [(set_attr "conds" "clob")
1b7da4ac 9184 (set_attr "length" "20")
9185 (set_attr "type" "multiple")]
9186)
3c5afce6 9187
3a0bdee0 9188(define_split
9189 [(set (reg:CC_NOOV CC_REGNUM)
9190 (compare:CC_NOOV (ior:SI
9191 (and:SI (match_operand:SI 0 "s_register_operand" "")
9192 (const_int 1))
b0694be0 9193 (match_operator:SI 1 "arm_comparison_operator"
3a0bdee0 9194 [(match_operand:SI 2 "s_register_operand" "")
9195 (match_operand:SI 3 "arm_add_operand" "")]))
9196 (const_int 0)))
9197 (clobber (match_operand:SI 4 "s_register_operand" ""))]
9198 "TARGET_ARM"
9199 [(set (match_dup 4)
9200 (ior:SI (match_op_dup 1 [(match_dup 2) (match_dup 3)])
9201 (match_dup 0)))
9202 (set (reg:CC_NOOV CC_REGNUM)
9203 (compare:CC_NOOV (and:SI (match_dup 4) (const_int 1))
9204 (const_int 0)))]
9205 "")
9206
9207(define_split
9208 [(set (reg:CC_NOOV CC_REGNUM)
9209 (compare:CC_NOOV (ior:SI
b0694be0 9210 (match_operator:SI 1 "arm_comparison_operator"
3a0bdee0 9211 [(match_operand:SI 2 "s_register_operand" "")
9212 (match_operand:SI 3 "arm_add_operand" "")])
9213 (and:SI (match_operand:SI 0 "s_register_operand" "")
9214 (const_int 1)))
9215 (const_int 0)))
9216 (clobber (match_operand:SI 4 "s_register_operand" ""))]
9217 "TARGET_ARM"
9218 [(set (match_dup 4)
9219 (ior:SI (match_op_dup 1 [(match_dup 2) (match_dup 3)])
9220 (match_dup 0)))
9221 (set (reg:CC_NOOV CC_REGNUM)
9222 (compare:CC_NOOV (and:SI (match_dup 4) (const_int 1))
9223 (const_int 0)))]
9224 "")
25f905c2 9225;; ??? The conditional patterns above need checking for Thumb-2 usefulness
3a0bdee0 9226
190efb17 9227(define_insn_and_split "*negscc"
9c08d1fa 9228 [(set (match_operand:SI 0 "s_register_operand" "=r")
8fa3ba89 9229 (neg:SI (match_operator 3 "arm_comparison_operator"
9c08d1fa 9230 [(match_operand:SI 1 "s_register_operand" "r")
9231 (match_operand:SI 2 "arm_rhs_operand" "rI")])))
bd5b4116 9232 (clobber (reg:CC CC_REGNUM))]
cffb2a26 9233 "TARGET_ARM"
190efb17 9234 "#"
9235 "&& reload_completed"
9236 [(const_int 0)]
9237 {
9238 rtx cc_reg = gen_rtx_REG (CCmode, CC_REGNUM);
e2348bcb 9239
190efb17 9240 if (GET_CODE (operands[3]) == LT && operands[2] == const0_rtx)
9241 {
9242 /* Emit mov\\t%0, %1, asr #31 */
9243 emit_insn (gen_rtx_SET (VOIDmode,
9244 operands[0],
9245 gen_rtx_ASHIFTRT (SImode,
9246 operands[1],
9247 GEN_INT (31))));
9248 DONE;
9249 }
9250 else if (GET_CODE (operands[3]) == NE)
9251 {
9252 /* Emit subs\\t%0, %1, %2\;mvnne\\t%0, #0 */
9253 if (CONST_INT_P (operands[2]))
9254 emit_insn (gen_cmpsi2_addneg (operands[0], operands[1], operands[2],
9255 GEN_INT (- INTVAL (operands[2]))));
9256 else
9257 emit_insn (gen_subsi3_compare (operands[0], operands[1], operands[2]));
9258
9259 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
9260 gen_rtx_NE (SImode,
9261 cc_reg,
9262 const0_rtx),
9263 gen_rtx_SET (SImode,
9264 operands[0],
9265 GEN_INT (~0))));
9266 DONE;
9267 }
9268 else
9269 {
9270 /* Emit: cmp\\t%1, %2\;mov%D3\\t%0, #0\;mvn%d3\\t%0, #0 */
9271 emit_insn (gen_rtx_SET (VOIDmode,
9272 cc_reg,
9273 gen_rtx_COMPARE (CCmode, operands[1], operands[2])));
9274 enum rtx_code rc = GET_CODE (operands[3]);
9275
9276 rc = reverse_condition (rc);
9277 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
9278 gen_rtx_fmt_ee (rc,
9279 VOIDmode,
9280 cc_reg,
9281 const0_rtx),
9282 gen_rtx_SET (VOIDmode, operands[0], const0_rtx)));
9283 rc = GET_CODE (operands[3]);
9284 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
9285 gen_rtx_fmt_ee (rc,
9286 VOIDmode,
9287 cc_reg,
9288 const0_rtx),
9289 gen_rtx_SET (VOIDmode,
9290 operands[0],
9291 GEN_INT (~0))));
9292 DONE;
9293 }
9294 FAIL;
9295 }
8fa3ba89 9296 [(set_attr "conds" "clob")
1b7da4ac 9297 (set_attr "length" "12")
9298 (set_attr "type" "multiple")]
8fa3ba89 9299)
9c08d1fa 9300
90404b57 9301(define_insn_and_split "movcond_addsi"
9302 [(set (match_operand:SI 0 "s_register_operand" "=r,l,r")
9303 (if_then_else:SI
9304 (match_operator 5 "comparison_operator"
9305 [(plus:SI (match_operand:SI 3 "s_register_operand" "r,r,r")
9306 (match_operand:SI 4 "arm_add_operand" "rIL,rIL,rIL"))
9307 (const_int 0)])
9308 (match_operand:SI 1 "arm_rhs_operand" "rI,rPy,r")
9309 (match_operand:SI 2 "arm_rhs_operand" "rI,rPy,r")))
9310 (clobber (reg:CC CC_REGNUM))]
9311 "TARGET_32BIT"
9312 "#"
9313 "&& reload_completed"
9314 [(set (reg:CC_NOOV CC_REGNUM)
9315 (compare:CC_NOOV
9316 (plus:SI (match_dup 3)
9317 (match_dup 4))
9318 (const_int 0)))
9319 (set (match_dup 0) (match_dup 1))
9320 (cond_exec (match_dup 6)
9321 (set (match_dup 0) (match_dup 2)))]
9322 "
9323 {
9324 enum machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[5]),
9325 operands[3], operands[4]);
9326 enum rtx_code rc = GET_CODE (operands[5]);
9327
9328 operands[6] = gen_rtx_REG (mode, CC_REGNUM);
9329 gcc_assert (!(mode == CCFPmode || mode == CCFPEmode));
9330 rc = reverse_condition (rc);
9331
9332 operands[6] = gen_rtx_fmt_ee (rc, VOIDmode, operands[6], const0_rtx);
9333 }
9334 "
9335 [(set_attr "conds" "clob")
1b7da4ac 9336 (set_attr "enabled_for_depr_it" "no,yes,yes")
9337 (set_attr "type" "multiple")]
90404b57 9338)
9339
9c08d1fa 9340(define_insn "movcond"
9341 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
5565501b 9342 (if_then_else:SI
8fa3ba89 9343 (match_operator 5 "arm_comparison_operator"
5565501b 9344 [(match_operand:SI 3 "s_register_operand" "r,r,r")
9345 (match_operand:SI 4 "arm_add_operand" "rIL,rIL,rIL")])
9346 (match_operand:SI 1 "arm_rhs_operand" "0,rI,?rI")
9347 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
bd5b4116 9348 (clobber (reg:CC CC_REGNUM))]
cffb2a26 9349 "TARGET_ARM"
9c08d1fa 9350 "*
9351 if (GET_CODE (operands[5]) == LT
9352 && (operands[4] == const0_rtx))
9353 {
0438d37f 9354 if (which_alternative != 1 && REG_P (operands[1]))
9c08d1fa 9355 {
9c08d1fa 9356 if (operands[2] == const0_rtx)
e2348bcb 9357 return \"and\\t%0, %1, %3, asr #31\";
9358 return \"ands\\t%0, %1, %3, asr #32\;movcc\\t%0, %2\";
9c08d1fa 9359 }
0438d37f 9360 else if (which_alternative != 0 && REG_P (operands[2]))
9c08d1fa 9361 {
9c08d1fa 9362 if (operands[1] == const0_rtx)
e2348bcb 9363 return \"bic\\t%0, %2, %3, asr #31\";
9364 return \"bics\\t%0, %2, %3, asr #32\;movcs\\t%0, %1\";
9c08d1fa 9365 }
9366 /* The only case that falls through to here is when both ops 1 & 2
674a8f0b 9367 are constants. */
9c08d1fa 9368 }
e2348bcb 9369
9c08d1fa 9370 if (GET_CODE (operands[5]) == GE
9371 && (operands[4] == const0_rtx))
9372 {
0438d37f 9373 if (which_alternative != 1 && REG_P (operands[1]))
9c08d1fa 9374 {
9c08d1fa 9375 if (operands[2] == const0_rtx)
e2348bcb 9376 return \"bic\\t%0, %1, %3, asr #31\";
9377 return \"bics\\t%0, %1, %3, asr #32\;movcs\\t%0, %2\";
9c08d1fa 9378 }
0438d37f 9379 else if (which_alternative != 0 && REG_P (operands[2]))
9c08d1fa 9380 {
9c08d1fa 9381 if (operands[1] == const0_rtx)
e2348bcb 9382 return \"and\\t%0, %2, %3, asr #31\";
9383 return \"ands\\t%0, %2, %3, asr #32\;movcc\\t%0, %1\";
9c08d1fa 9384 }
9385 /* The only case that falls through to here is when both ops 1 & 2
674a8f0b 9386 are constants. */
9c08d1fa 9387 }
0438d37f 9388 if (CONST_INT_P (operands[4])
9c08d1fa 9389 && !const_ok_for_arm (INTVAL (operands[4])))
e2348bcb 9390 output_asm_insn (\"cmn\\t%3, #%n4\", operands);
9c08d1fa 9391 else
e2348bcb 9392 output_asm_insn (\"cmp\\t%3, %4\", operands);
9c08d1fa 9393 if (which_alternative != 0)
e2348bcb 9394 output_asm_insn (\"mov%d5\\t%0, %1\", operands);
9c08d1fa 9395 if (which_alternative != 1)
e2348bcb 9396 output_asm_insn (\"mov%D5\\t%0, %2\", operands);
9c08d1fa 9397 return \"\";
215b30b3 9398 "
8fa3ba89 9399 [(set_attr "conds" "clob")
1b7da4ac 9400 (set_attr "length" "8,8,12")
9401 (set_attr "type" "multiple")]
8fa3ba89 9402)
9c08d1fa 9403
25f905c2 9404;; ??? The patterns below need checking for Thumb-2 usefulness.
9405
8a18b90c 9406(define_insn "*ifcompare_plus_move"
9407 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8fa3ba89 9408 (if_then_else:SI (match_operator 6 "arm_comparison_operator"
8a18b90c 9409 [(match_operand:SI 4 "s_register_operand" "r,r")
9410 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
9411 (plus:SI
9412 (match_operand:SI 2 "s_register_operand" "r,r")
9413 (match_operand:SI 3 "arm_add_operand" "rIL,rIL"))
129a2fe4 9414 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))
bd5b4116 9415 (clobber (reg:CC CC_REGNUM))]
cffb2a26 9416 "TARGET_ARM"
8a18b90c 9417 "#"
8fa3ba89 9418 [(set_attr "conds" "clob")
1b7da4ac 9419 (set_attr "length" "8,12")
9420 (set_attr "type" "multiple")]
8fa3ba89 9421)
8a18b90c 9422
9423(define_insn "*if_plus_move"
129a2fe4 9424 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r")
8a18b90c 9425 (if_then_else:SI
8fa3ba89 9426 (match_operator 4 "arm_comparison_operator"
8a18b90c 9427 [(match_operand 5 "cc_register" "") (const_int 0)])
9428 (plus:SI
129a2fe4 9429 (match_operand:SI 2 "s_register_operand" "r,r,r,r")
9430 (match_operand:SI 3 "arm_add_operand" "rI,L,rI,L"))
9431 (match_operand:SI 1 "arm_rhs_operand" "0,0,?rI,?rI")))]
cffb2a26 9432 "TARGET_ARM"
8a18b90c 9433 "@
9434 add%d4\\t%0, %2, %3
9435 sub%d4\\t%0, %2, #%n3
9436 add%d4\\t%0, %2, %3\;mov%D4\\t%0, %1
129a2fe4 9437 sub%d4\\t%0, %2, #%n3\;mov%D4\\t%0, %1"
8fa3ba89 9438 [(set_attr "conds" "use")
9439 (set_attr "length" "4,4,8,8")
65f68e55 9440 (set_attr_alternative "type"
9441 [(if_then_else (match_operand 3 "const_int_operand" "")
d82e788e 9442 (const_string "alu_imm" )
1b7da4ac 9443 (const_string "alu_reg"))
d82e788e 9444 (const_string "alu_imm")
1b7da4ac 9445 (const_string "alu_reg")
9446 (const_string "alu_reg")])]
8fa3ba89 9447)
8a18b90c 9448
9449(define_insn "*ifcompare_move_plus"
5565501b 9450 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8fa3ba89 9451 (if_then_else:SI (match_operator 6 "arm_comparison_operator"
8a18b90c 9452 [(match_operand:SI 4 "s_register_operand" "r,r")
9453 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
129a2fe4 9454 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
8a18b90c 9455 (plus:SI
9456 (match_operand:SI 2 "s_register_operand" "r,r")
9457 (match_operand:SI 3 "arm_add_operand" "rIL,rIL"))))
bd5b4116 9458 (clobber (reg:CC CC_REGNUM))]
cffb2a26 9459 "TARGET_ARM"
8a18b90c 9460 "#"
8fa3ba89 9461 [(set_attr "conds" "clob")
1b7da4ac 9462 (set_attr "length" "8,12")
9463 (set_attr "type" "multiple")]
8fa3ba89 9464)
8a18b90c 9465
9466(define_insn "*if_move_plus"
129a2fe4 9467 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r")
8a18b90c 9468 (if_then_else:SI
8fa3ba89 9469 (match_operator 4 "arm_comparison_operator"
8a18b90c 9470 [(match_operand 5 "cc_register" "") (const_int 0)])
129a2fe4 9471 (match_operand:SI 1 "arm_rhs_operand" "0,0,?rI,?rI")
8a18b90c 9472 (plus:SI
129a2fe4 9473 (match_operand:SI 2 "s_register_operand" "r,r,r,r")
9474 (match_operand:SI 3 "arm_add_operand" "rI,L,rI,L"))))]
cffb2a26 9475 "TARGET_ARM"
8a18b90c 9476 "@
9477 add%D4\\t%0, %2, %3
9478 sub%D4\\t%0, %2, #%n3
9479 add%D4\\t%0, %2, %3\;mov%d4\\t%0, %1
129a2fe4 9480 sub%D4\\t%0, %2, #%n3\;mov%d4\\t%0, %1"
8fa3ba89 9481 [(set_attr "conds" "use")
9482 (set_attr "length" "4,4,8,8")
1b7da4ac 9483 (set_attr "type" "alu_reg,alu_imm,multiple,multiple")]
8fa3ba89 9484)
8a18b90c 9485
9486(define_insn "*ifcompare_arith_arith"
9487 [(set (match_operand:SI 0 "s_register_operand" "=r")
8fa3ba89 9488 (if_then_else:SI (match_operator 9 "arm_comparison_operator"
8a18b90c 9489 [(match_operand:SI 5 "s_register_operand" "r")
9490 (match_operand:SI 6 "arm_add_operand" "rIL")])
9c08d1fa 9491 (match_operator:SI 8 "shiftable_operator"
8a18b90c 9492 [(match_operand:SI 1 "s_register_operand" "r")
9493 (match_operand:SI 2 "arm_rhs_operand" "rI")])
9c08d1fa 9494 (match_operator:SI 7 "shiftable_operator"
8a18b90c 9495 [(match_operand:SI 3 "s_register_operand" "r")
9496 (match_operand:SI 4 "arm_rhs_operand" "rI")])))
bd5b4116 9497 (clobber (reg:CC CC_REGNUM))]
cffb2a26 9498 "TARGET_ARM"
8a18b90c 9499 "#"
8fa3ba89 9500 [(set_attr "conds" "clob")
1b7da4ac 9501 (set_attr "length" "12")
9502 (set_attr "type" "multiple")]
8fa3ba89 9503)
9c08d1fa 9504
8a18b90c 9505(define_insn "*if_arith_arith"
9506 [(set (match_operand:SI 0 "s_register_operand" "=r")
8fa3ba89 9507 (if_then_else:SI (match_operator 5 "arm_comparison_operator"
8a18b90c 9508 [(match_operand 8 "cc_register" "") (const_int 0)])
9509 (match_operator:SI 6 "shiftable_operator"
9510 [(match_operand:SI 1 "s_register_operand" "r")
9511 (match_operand:SI 2 "arm_rhs_operand" "rI")])
9512 (match_operator:SI 7 "shiftable_operator"
9513 [(match_operand:SI 3 "s_register_operand" "r")
9514 (match_operand:SI 4 "arm_rhs_operand" "rI")])))]
cffb2a26 9515 "TARGET_ARM"
8a18b90c 9516 "%I6%d5\\t%0, %1, %2\;%I7%D5\\t%0, %3, %4"
8fa3ba89 9517 [(set_attr "conds" "use")
1b7da4ac 9518 (set_attr "length" "8")
9519 (set_attr "type" "multiple")]
8fa3ba89 9520)
8a18b90c 9521
f7fbdd4a 9522(define_insn "*ifcompare_arith_move"
9c08d1fa 9523 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8fa3ba89 9524 (if_then_else:SI (match_operator 6 "arm_comparison_operator"
9c08d1fa 9525 [(match_operand:SI 2 "s_register_operand" "r,r")
5565501b 9526 (match_operand:SI 3 "arm_add_operand" "rIL,rIL")])
9c08d1fa 9527 (match_operator:SI 7 "shiftable_operator"
9528 [(match_operand:SI 4 "s_register_operand" "r,r")
9529 (match_operand:SI 5 "arm_rhs_operand" "rI,rI")])
129a2fe4 9530 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))
bd5b4116 9531 (clobber (reg:CC CC_REGNUM))]
cffb2a26 9532 "TARGET_ARM"
9c08d1fa 9533 "*
9c08d1fa 9534 /* If we have an operation where (op x 0) is the identity operation and
01cc3b75 9535 the conditional operator is LT or GE and we are comparing against zero and
674a8f0b 9536 everything is in registers then we can do this in two instructions. */
9c08d1fa 9537 if (operands[3] == const0_rtx
9538 && GET_CODE (operands[7]) != AND
0438d37f 9539 && REG_P (operands[5])
9540 && REG_P (operands[1])
9c08d1fa 9541 && REGNO (operands[1]) == REGNO (operands[4])
9542 && REGNO (operands[4]) != REGNO (operands[0]))
9543 {
9544 if (GET_CODE (operands[6]) == LT)
40dbec34 9545 return \"and\\t%0, %5, %2, asr #31\;%I7\\t%0, %4, %0\";
9c08d1fa 9546 else if (GET_CODE (operands[6]) == GE)
40dbec34 9547 return \"bic\\t%0, %5, %2, asr #31\;%I7\\t%0, %4, %0\";
9c08d1fa 9548 }
0438d37f 9549 if (CONST_INT_P (operands[3])
9c08d1fa 9550 && !const_ok_for_arm (INTVAL (operands[3])))
e2348bcb 9551 output_asm_insn (\"cmn\\t%2, #%n3\", operands);
9c08d1fa 9552 else
e2348bcb 9553 output_asm_insn (\"cmp\\t%2, %3\", operands);
40dbec34 9554 output_asm_insn (\"%I7%d6\\t%0, %4, %5\", operands);
9c08d1fa 9555 if (which_alternative != 0)
129a2fe4 9556 return \"mov%D6\\t%0, %1\";
9c08d1fa 9557 return \"\";
215b30b3 9558 "
8fa3ba89 9559 [(set_attr "conds" "clob")
1b7da4ac 9560 (set_attr "length" "8,12")
9561 (set_attr "type" "multiple")]
8fa3ba89 9562)
9c08d1fa 9563
8a18b90c 9564(define_insn "*if_arith_move"
129a2fe4 9565 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8fa3ba89 9566 (if_then_else:SI (match_operator 4 "arm_comparison_operator"
8a18b90c 9567 [(match_operand 6 "cc_register" "") (const_int 0)])
9568 (match_operator:SI 5 "shiftable_operator"
129a2fe4 9569 [(match_operand:SI 2 "s_register_operand" "r,r")
9570 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
9571 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))]
cffb2a26 9572 "TARGET_ARM"
8a18b90c 9573 "@
9574 %I5%d4\\t%0, %2, %3
129a2fe4 9575 %I5%d4\\t%0, %2, %3\;mov%D4\\t%0, %1"
8fa3ba89 9576 [(set_attr "conds" "use")
9577 (set_attr "length" "4,8")
1b7da4ac 9578 (set_attr "type" "alu_shift_reg,multiple")]
8fa3ba89 9579)
8a18b90c 9580
f7fbdd4a 9581(define_insn "*ifcompare_move_arith"
9c08d1fa 9582 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8fa3ba89 9583 (if_then_else:SI (match_operator 6 "arm_comparison_operator"
9c08d1fa 9584 [(match_operand:SI 4 "s_register_operand" "r,r")
5565501b 9585 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
129a2fe4 9586 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
9c08d1fa 9587 (match_operator:SI 7 "shiftable_operator"
9588 [(match_operand:SI 2 "s_register_operand" "r,r")
9589 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))
bd5b4116 9590 (clobber (reg:CC CC_REGNUM))]
cffb2a26 9591 "TARGET_ARM"
9c08d1fa 9592 "*
9c08d1fa 9593 /* If we have an operation where (op x 0) is the identity operation and
01cc3b75 9594 the conditional operator is LT or GE and we are comparing against zero and
9c08d1fa 9595 everything is in registers then we can do this in two instructions */
9596 if (operands[5] == const0_rtx
9597 && GET_CODE (operands[7]) != AND
0438d37f 9598 && REG_P (operands[3])
9599 && REG_P (operands[1])
9c08d1fa 9600 && REGNO (operands[1]) == REGNO (operands[2])
9601 && REGNO (operands[2]) != REGNO (operands[0]))
9602 {
9603 if (GET_CODE (operands[6]) == GE)
40dbec34 9604 return \"and\\t%0, %3, %4, asr #31\;%I7\\t%0, %2, %0\";
9c08d1fa 9605 else if (GET_CODE (operands[6]) == LT)
40dbec34 9606 return \"bic\\t%0, %3, %4, asr #31\;%I7\\t%0, %2, %0\";
9c08d1fa 9607 }
40dbec34 9608
0438d37f 9609 if (CONST_INT_P (operands[5])
9c08d1fa 9610 && !const_ok_for_arm (INTVAL (operands[5])))
e2348bcb 9611 output_asm_insn (\"cmn\\t%4, #%n5\", operands);
9c08d1fa 9612 else
e2348bcb 9613 output_asm_insn (\"cmp\\t%4, %5\", operands);
40dbec34 9614
9c08d1fa 9615 if (which_alternative != 0)
129a2fe4 9616 output_asm_insn (\"mov%d6\\t%0, %1\", operands);
40dbec34 9617 return \"%I7%D6\\t%0, %2, %3\";
215b30b3 9618 "
8fa3ba89 9619 [(set_attr "conds" "clob")
1b7da4ac 9620 (set_attr "length" "8,12")
9621 (set_attr "type" "multiple")]
8fa3ba89 9622)
9c08d1fa 9623
8a18b90c 9624(define_insn "*if_move_arith"
129a2fe4 9625 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8a18b90c 9626 (if_then_else:SI
8fa3ba89 9627 (match_operator 4 "arm_comparison_operator"
8a18b90c 9628 [(match_operand 6 "cc_register" "") (const_int 0)])
129a2fe4 9629 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
8a18b90c 9630 (match_operator:SI 5 "shiftable_operator"
129a2fe4 9631 [(match_operand:SI 2 "s_register_operand" "r,r")
9632 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))]
cffb2a26 9633 "TARGET_ARM"
8a18b90c 9634 "@
9635 %I5%D4\\t%0, %2, %3
129a2fe4 9636 %I5%D4\\t%0, %2, %3\;mov%d4\\t%0, %1"
8fa3ba89 9637 [(set_attr "conds" "use")
9638 (set_attr "length" "4,8")
1b7da4ac 9639 (set_attr "type" "alu_shift_reg,multiple")]
8fa3ba89 9640)
8a18b90c 9641
9642(define_insn "*ifcompare_move_not"
9c08d1fa 9643 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8a18b90c 9644 (if_then_else:SI
8fa3ba89 9645 (match_operator 5 "arm_comparison_operator"
8a18b90c 9646 [(match_operand:SI 3 "s_register_operand" "r,r")
9647 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
9648 (match_operand:SI 1 "arm_not_operand" "0,?rIK")
9649 (not:SI
9650 (match_operand:SI 2 "s_register_operand" "r,r"))))
bd5b4116 9651 (clobber (reg:CC CC_REGNUM))]
cffb2a26 9652 "TARGET_ARM"
8a18b90c 9653 "#"
8fa3ba89 9654 [(set_attr "conds" "clob")
1b7da4ac 9655 (set_attr "length" "8,12")
9656 (set_attr "type" "multiple")]
8fa3ba89 9657)
9c08d1fa 9658
8a18b90c 9659(define_insn "*if_move_not"
9660 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9661 (if_then_else:SI
8fa3ba89 9662 (match_operator 4 "arm_comparison_operator"
8a18b90c 9663 [(match_operand 3 "cc_register" "") (const_int 0)])
9664 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")
9665 (not:SI (match_operand:SI 2 "s_register_operand" "r,r,r"))))]
cffb2a26 9666 "TARGET_ARM"
8a18b90c 9667 "@
9668 mvn%D4\\t%0, %2
9669 mov%d4\\t%0, %1\;mvn%D4\\t%0, %2
9670 mvn%d4\\t%0, #%B1\;mvn%D4\\t%0, %2"
8fa3ba89 9671 [(set_attr "conds" "use")
1aed5204 9672 (set_attr "type" "mvn_reg")
1b7da4ac 9673 (set_attr "length" "4,8,8")
9674 (set_attr "type" "mvn_reg,multiple,multiple")]
8fa3ba89 9675)
8a18b90c 9676
9677(define_insn "*ifcompare_not_move"
9c08d1fa 9678 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8a18b90c 9679 (if_then_else:SI
8fa3ba89 9680 (match_operator 5 "arm_comparison_operator"
8a18b90c 9681 [(match_operand:SI 3 "s_register_operand" "r,r")
9682 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
9683 (not:SI
9684 (match_operand:SI 2 "s_register_operand" "r,r"))
9685 (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
bd5b4116 9686 (clobber (reg:CC CC_REGNUM))]
cffb2a26 9687 "TARGET_ARM"
8a18b90c 9688 "#"
8fa3ba89 9689 [(set_attr "conds" "clob")
1b7da4ac 9690 (set_attr "length" "8,12")
9691 (set_attr "type" "multiple")]
8fa3ba89 9692)
9c08d1fa 9693
8a18b90c 9694(define_insn "*if_not_move"
9695 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9696 (if_then_else:SI
8fa3ba89 9697 (match_operator 4 "arm_comparison_operator"
8a18b90c 9698 [(match_operand 3 "cc_register" "") (const_int 0)])
9699 (not:SI (match_operand:SI 2 "s_register_operand" "r,r,r"))
9700 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")))]
cffb2a26 9701 "TARGET_ARM"
8a18b90c 9702 "@
9703 mvn%d4\\t%0, %2
9704 mov%D4\\t%0, %1\;mvn%d4\\t%0, %2
9705 mvn%D4\\t%0, #%B1\;mvn%d4\\t%0, %2"
8fa3ba89 9706 [(set_attr "conds" "use")
1b7da4ac 9707 (set_attr "type" "mvn_reg,multiple,multiple")
8fa3ba89 9708 (set_attr "length" "4,8,8")]
9709)
8a18b90c 9710
9711(define_insn "*ifcompare_shift_move"
9c08d1fa 9712 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8a18b90c 9713 (if_then_else:SI
8fa3ba89 9714 (match_operator 6 "arm_comparison_operator"
8a18b90c 9715 [(match_operand:SI 4 "s_register_operand" "r,r")
9716 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
9717 (match_operator:SI 7 "shift_operator"
9718 [(match_operand:SI 2 "s_register_operand" "r,r")
9719 (match_operand:SI 3 "arm_rhs_operand" "rM,rM")])
9720 (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
bd5b4116 9721 (clobber (reg:CC CC_REGNUM))]
cffb2a26 9722 "TARGET_ARM"
9c08d1fa 9723 "#"
8fa3ba89 9724 [(set_attr "conds" "clob")
1b7da4ac 9725 (set_attr "length" "8,12")
9726 (set_attr "type" "multiple")]
8fa3ba89 9727)
9c08d1fa 9728
8a18b90c 9729(define_insn "*if_shift_move"
9730 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9731 (if_then_else:SI
8fa3ba89 9732 (match_operator 5 "arm_comparison_operator"
8a18b90c 9733 [(match_operand 6 "cc_register" "") (const_int 0)])
9734 (match_operator:SI 4 "shift_operator"
9735 [(match_operand:SI 2 "s_register_operand" "r,r,r")
9736 (match_operand:SI 3 "arm_rhs_operand" "rM,rM,rM")])
9737 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")))]
cffb2a26 9738 "TARGET_ARM"
5565501b 9739 "@
8a18b90c 9740 mov%d5\\t%0, %2%S4
9741 mov%D5\\t%0, %1\;mov%d5\\t%0, %2%S4
9742 mvn%D5\\t%0, #%B1\;mov%d5\\t%0, %2%S4"
8fa3ba89 9743 [(set_attr "conds" "use")
331beb1a 9744 (set_attr "shift" "2")
a2cd141b 9745 (set_attr "length" "4,8,8")
1b7da4ac 9746 (set_attr "type" "mov_shift_reg,multiple,multiple")]
8fa3ba89 9747)
5565501b 9748
8a18b90c 9749(define_insn "*ifcompare_move_shift"
9750 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5565501b 9751 (if_then_else:SI
8fa3ba89 9752 (match_operator 6 "arm_comparison_operator"
8a18b90c 9753 [(match_operand:SI 4 "s_register_operand" "r,r")
9754 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
9755 (match_operand:SI 1 "arm_not_operand" "0,?rIK")
5565501b 9756 (match_operator:SI 7 "shift_operator"
8a18b90c 9757 [(match_operand:SI 2 "s_register_operand" "r,r")
9758 (match_operand:SI 3 "arm_rhs_operand" "rM,rM")])))
bd5b4116 9759 (clobber (reg:CC CC_REGNUM))]
cffb2a26 9760 "TARGET_ARM"
8a18b90c 9761 "#"
8fa3ba89 9762 [(set_attr "conds" "clob")
1b7da4ac 9763 (set_attr "length" "8,12")
9764 (set_attr "type" "multiple")]
8fa3ba89 9765)
5565501b 9766
8a18b90c 9767(define_insn "*if_move_shift"
9768 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
5565501b 9769 (if_then_else:SI
8fa3ba89 9770 (match_operator 5 "arm_comparison_operator"
8a18b90c 9771 [(match_operand 6 "cc_register" "") (const_int 0)])
9772 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")
9773 (match_operator:SI 4 "shift_operator"
9774 [(match_operand:SI 2 "s_register_operand" "r,r,r")
9775 (match_operand:SI 3 "arm_rhs_operand" "rM,rM,rM")])))]
cffb2a26 9776 "TARGET_ARM"
5565501b 9777 "@
8a18b90c 9778 mov%D5\\t%0, %2%S4
9779 mov%d5\\t%0, %1\;mov%D5\\t%0, %2%S4
9780 mvn%d5\\t%0, #%B1\;mov%D5\\t%0, %2%S4"
8fa3ba89 9781 [(set_attr "conds" "use")
331beb1a 9782 (set_attr "shift" "2")
a2cd141b 9783 (set_attr "length" "4,8,8")
1b7da4ac 9784 (set_attr "type" "mov_shift_reg,multiple,multiple")]
8fa3ba89 9785)
9c08d1fa 9786
f7fbdd4a 9787(define_insn "*ifcompare_shift_shift"
8a18b90c 9788 [(set (match_operand:SI 0 "s_register_operand" "=r")
5565501b 9789 (if_then_else:SI
8fa3ba89 9790 (match_operator 7 "arm_comparison_operator"
8a18b90c 9791 [(match_operand:SI 5 "s_register_operand" "r")
9792 (match_operand:SI 6 "arm_add_operand" "rIL")])
5565501b 9793 (match_operator:SI 8 "shift_operator"
8a18b90c 9794 [(match_operand:SI 1 "s_register_operand" "r")
9795 (match_operand:SI 2 "arm_rhs_operand" "rM")])
5565501b 9796 (match_operator:SI 9 "shift_operator"
8a18b90c 9797 [(match_operand:SI 3 "s_register_operand" "r")
9798 (match_operand:SI 4 "arm_rhs_operand" "rM")])))
bd5b4116 9799 (clobber (reg:CC CC_REGNUM))]
cffb2a26 9800 "TARGET_ARM"
8a18b90c 9801 "#"
8fa3ba89 9802 [(set_attr "conds" "clob")
1b7da4ac 9803 (set_attr "length" "12")
9804 (set_attr "type" "multiple")]
8fa3ba89 9805)
9c08d1fa 9806
8a18b90c 9807(define_insn "*if_shift_shift"
9808 [(set (match_operand:SI 0 "s_register_operand" "=r")
9809 (if_then_else:SI
8fa3ba89 9810 (match_operator 5 "arm_comparison_operator"
8a18b90c 9811 [(match_operand 8 "cc_register" "") (const_int 0)])
9812 (match_operator:SI 6 "shift_operator"
9813 [(match_operand:SI 1 "s_register_operand" "r")
9814 (match_operand:SI 2 "arm_rhs_operand" "rM")])
9815 (match_operator:SI 7 "shift_operator"
9816 [(match_operand:SI 3 "s_register_operand" "r")
9817 (match_operand:SI 4 "arm_rhs_operand" "rM")])))]
cffb2a26 9818 "TARGET_ARM"
8a18b90c 9819 "mov%d5\\t%0, %1%S6\;mov%D5\\t%0, %3%S7"
8fa3ba89 9820 [(set_attr "conds" "use")
331beb1a 9821 (set_attr "shift" "1")
a2cd141b 9822 (set_attr "length" "8")
9823 (set (attr "type") (if_then_else
9824 (and (match_operand 2 "const_int_operand" "")
9825 (match_operand 4 "const_int_operand" ""))
1aed5204 9826 (const_string "mov_shift")
9827 (const_string "mov_shift_reg")))]
8fa3ba89 9828)
8a18b90c 9829
f7fbdd4a 9830(define_insn "*ifcompare_not_arith"
8a18b90c 9831 [(set (match_operand:SI 0 "s_register_operand" "=r")
5565501b 9832 (if_then_else:SI
8fa3ba89 9833 (match_operator 6 "arm_comparison_operator"
8a18b90c 9834 [(match_operand:SI 4 "s_register_operand" "r")
9835 (match_operand:SI 5 "arm_add_operand" "rIL")])
9836 (not:SI (match_operand:SI 1 "s_register_operand" "r"))
5565501b 9837 (match_operator:SI 7 "shiftable_operator"
8a18b90c 9838 [(match_operand:SI 2 "s_register_operand" "r")
9839 (match_operand:SI 3 "arm_rhs_operand" "rI")])))
bd5b4116 9840 (clobber (reg:CC CC_REGNUM))]
cffb2a26 9841 "TARGET_ARM"
8a18b90c 9842 "#"
8fa3ba89 9843 [(set_attr "conds" "clob")
1b7da4ac 9844 (set_attr "length" "12")
9845 (set_attr "type" "multiple")]
8fa3ba89 9846)
9c08d1fa 9847
8a18b90c 9848(define_insn "*if_not_arith"
9849 [(set (match_operand:SI 0 "s_register_operand" "=r")
9850 (if_then_else:SI
8fa3ba89 9851 (match_operator 5 "arm_comparison_operator"
8a18b90c 9852 [(match_operand 4 "cc_register" "") (const_int 0)])
9853 (not:SI (match_operand:SI 1 "s_register_operand" "r"))
9854 (match_operator:SI 6 "shiftable_operator"
9855 [(match_operand:SI 2 "s_register_operand" "r")
9856 (match_operand:SI 3 "arm_rhs_operand" "rI")])))]
cffb2a26 9857 "TARGET_ARM"
8a18b90c 9858 "mvn%d5\\t%0, %1\;%I6%D5\\t%0, %2, %3"
8fa3ba89 9859 [(set_attr "conds" "use")
1aed5204 9860 (set_attr "type" "mvn_reg")
8fa3ba89 9861 (set_attr "length" "8")]
9862)
8a18b90c 9863
9864(define_insn "*ifcompare_arith_not"
9865 [(set (match_operand:SI 0 "s_register_operand" "=r")
5565501b 9866 (if_then_else:SI
8fa3ba89 9867 (match_operator 6 "arm_comparison_operator"
8a18b90c 9868 [(match_operand:SI 4 "s_register_operand" "r")
9869 (match_operand:SI 5 "arm_add_operand" "rIL")])
5565501b 9870 (match_operator:SI 7 "shiftable_operator"
8a18b90c 9871 [(match_operand:SI 2 "s_register_operand" "r")
9872 (match_operand:SI 3 "arm_rhs_operand" "rI")])
9873 (not:SI (match_operand:SI 1 "s_register_operand" "r"))))
bd5b4116 9874 (clobber (reg:CC CC_REGNUM))]
cffb2a26 9875 "TARGET_ARM"
8a18b90c 9876 "#"
8fa3ba89 9877 [(set_attr "conds" "clob")
1b7da4ac 9878 (set_attr "length" "12")
9879 (set_attr "type" "multiple")]
8fa3ba89 9880)
9c08d1fa 9881
8a18b90c 9882(define_insn "*if_arith_not"
9883 [(set (match_operand:SI 0 "s_register_operand" "=r")
9884 (if_then_else:SI
8fa3ba89 9885 (match_operator 5 "arm_comparison_operator"
8a18b90c 9886 [(match_operand 4 "cc_register" "") (const_int 0)])
9887 (match_operator:SI 6 "shiftable_operator"
9888 [(match_operand:SI 2 "s_register_operand" "r")
9889 (match_operand:SI 3 "arm_rhs_operand" "rI")])
9890 (not:SI (match_operand:SI 1 "s_register_operand" "r"))))]
cffb2a26 9891 "TARGET_ARM"
8a18b90c 9892 "mvn%D5\\t%0, %1\;%I6%d5\\t%0, %2, %3"
8fa3ba89 9893 [(set_attr "conds" "use")
1b7da4ac 9894 (set_attr "type" "multiple")
8fa3ba89 9895 (set_attr "length" "8")]
9896)
8a18b90c 9897
f7fbdd4a 9898(define_insn "*ifcompare_neg_move"
8a18b90c 9899 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5565501b 9900 (if_then_else:SI
8fa3ba89 9901 (match_operator 5 "arm_comparison_operator"
8a18b90c 9902 [(match_operand:SI 3 "s_register_operand" "r,r")
9903 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
9904 (neg:SI (match_operand:SI 2 "s_register_operand" "r,r"))
9905 (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
bd5b4116 9906 (clobber (reg:CC CC_REGNUM))]
cffb2a26 9907 "TARGET_ARM"
8a18b90c 9908 "#"
8fa3ba89 9909 [(set_attr "conds" "clob")
1b7da4ac 9910 (set_attr "length" "8,12")
9911 (set_attr "type" "multiple")]
8fa3ba89 9912)
8a18b90c 9913
9914(define_insn "*if_neg_move"
9915 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9916 (if_then_else:SI
8fa3ba89 9917 (match_operator 4 "arm_comparison_operator"
8a18b90c 9918 [(match_operand 3 "cc_register" "") (const_int 0)])
9919 (neg:SI (match_operand:SI 2 "s_register_operand" "r,r,r"))
9920 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")))]
cffb2a26 9921 "TARGET_ARM"
8a18b90c 9922 "@
9923 rsb%d4\\t%0, %2, #0
9924 mov%D4\\t%0, %1\;rsb%d4\\t%0, %2, #0
9925 mvn%D4\\t%0, #%B1\;rsb%d4\\t%0, %2, #0"
8fa3ba89 9926 [(set_attr "conds" "use")
1b7da4ac 9927 (set_attr "length" "4,8,8")
9928 (set_attr "type" "logic_shift_imm,multiple,multiple")]
8fa3ba89 9929)
9c08d1fa 9930
f7fbdd4a 9931(define_insn "*ifcompare_move_neg"
8a18b90c 9932 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5565501b 9933 (if_then_else:SI
8fa3ba89 9934 (match_operator 5 "arm_comparison_operator"
8a18b90c 9935 [(match_operand:SI 3 "s_register_operand" "r,r")
9936 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
9937 (match_operand:SI 1 "arm_not_operand" "0,?rIK")
9938 (neg:SI (match_operand:SI 2 "s_register_operand" "r,r"))))
bd5b4116 9939 (clobber (reg:CC CC_REGNUM))]
cffb2a26 9940 "TARGET_ARM"
8a18b90c 9941 "#"
8fa3ba89 9942 [(set_attr "conds" "clob")
1b7da4ac 9943 (set_attr "length" "8,12")
9944 (set_attr "type" "multiple")]
8fa3ba89 9945)
8a18b90c 9946
9947(define_insn "*if_move_neg"
9948 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9949 (if_then_else:SI
8fa3ba89 9950 (match_operator 4 "arm_comparison_operator"
8a18b90c 9951 [(match_operand 3 "cc_register" "") (const_int 0)])
9952 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")
9953 (neg:SI (match_operand:SI 2 "s_register_operand" "r,r,r"))))]
cffb2a26 9954 "TARGET_ARM"
8a18b90c 9955 "@
9956 rsb%D4\\t%0, %2, #0
9957 mov%d4\\t%0, %1\;rsb%D4\\t%0, %2, #0
9958 mvn%d4\\t%0, #%B1\;rsb%D4\\t%0, %2, #0"
0d66636f 9959 [(set_attr "conds" "use")
1b7da4ac 9960 (set_attr "length" "4,8,8")
9961 (set_attr "type" "logic_shift_imm,multiple,multiple")]
0d66636f 9962)
9c08d1fa 9963
f7fbdd4a 9964(define_insn "*arith_adjacentmem"
9c08d1fa 9965 [(set (match_operand:SI 0 "s_register_operand" "=r")
9966 (match_operator:SI 1 "shiftable_operator"
9967 [(match_operand:SI 2 "memory_operand" "m")
9968 (match_operand:SI 3 "memory_operand" "m")]))
9969 (clobber (match_scratch:SI 4 "=r"))]
cffb2a26 9970 "TARGET_ARM && adjacent_mem_locations (operands[2], operands[3])"
9c08d1fa 9971 "*
215b30b3 9972 {
9973 rtx ldm[3];
9974 rtx arith[4];
94dee231 9975 rtx base_reg;
9976 HOST_WIDE_INT val1 = 0, val2 = 0;
9c08d1fa 9977
215b30b3 9978 if (REGNO (operands[0]) > REGNO (operands[4]))
9979 {
9980 ldm[1] = operands[4];
9981 ldm[2] = operands[0];
9982 }
9983 else
9984 {
9985 ldm[1] = operands[0];
9986 ldm[2] = operands[4];
9987 }
94dee231 9988
9989 base_reg = XEXP (operands[2], 0);
9990
9991 if (!REG_P (base_reg))
9992 {
9993 val1 = INTVAL (XEXP (base_reg, 1));
9994 base_reg = XEXP (base_reg, 0);
9995 }
9996
9997 if (!REG_P (XEXP (operands[3], 0)))
215b30b3 9998 val2 = INTVAL (XEXP (XEXP (operands[3], 0), 1));
94dee231 9999
215b30b3 10000 arith[0] = operands[0];
10001 arith[3] = operands[1];
94dee231 10002
215b30b3 10003 if (val1 < val2)
10004 {
10005 arith[1] = ldm[1];
10006 arith[2] = ldm[2];
10007 }
10008 else
10009 {
10010 arith[1] = ldm[2];
10011 arith[2] = ldm[1];
10012 }
94dee231 10013
10014 ldm[0] = base_reg;
10015 if (val1 !=0 && val2 != 0)
215b30b3 10016 {
cdb1295a 10017 rtx ops[3];
10018
94dee231 10019 if (val1 == 4 || val2 == 4)
10020 /* Other val must be 8, since we know they are adjacent and neither
10021 is zero. */
25f905c2 10022 output_asm_insn (\"ldm%(ib%)\\t%0, {%1, %2}\", ldm);
cdb1295a 10023 else if (const_ok_for_arm (val1) || const_ok_for_arm (-val1))
94dee231 10024 {
94dee231 10025 ldm[0] = ops[0] = operands[4];
10026 ops[1] = base_reg;
10027 ops[2] = GEN_INT (val1);
10028 output_add_immediate (ops);
10029 if (val1 < val2)
25f905c2 10030 output_asm_insn (\"ldm%(ia%)\\t%0, {%1, %2}\", ldm);
94dee231 10031 else
25f905c2 10032 output_asm_insn (\"ldm%(da%)\\t%0, {%1, %2}\", ldm);
94dee231 10033 }
cdb1295a 10034 else
10035 {
10036 /* Offset is out of range for a single add, so use two ldr. */
10037 ops[0] = ldm[1];
10038 ops[1] = base_reg;
10039 ops[2] = GEN_INT (val1);
10040 output_asm_insn (\"ldr%?\\t%0, [%1, %2]\", ops);
10041 ops[0] = ldm[2];
10042 ops[2] = GEN_INT (val2);
10043 output_asm_insn (\"ldr%?\\t%0, [%1, %2]\", ops);
10044 }
215b30b3 10045 }
94dee231 10046 else if (val1 != 0)
215b30b3 10047 {
215b30b3 10048 if (val1 < val2)
25f905c2 10049 output_asm_insn (\"ldm%(da%)\\t%0, {%1, %2}\", ldm);
215b30b3 10050 else
25f905c2 10051 output_asm_insn (\"ldm%(ia%)\\t%0, {%1, %2}\", ldm);
215b30b3 10052 }
10053 else
10054 {
215b30b3 10055 if (val1 < val2)
25f905c2 10056 output_asm_insn (\"ldm%(ia%)\\t%0, {%1, %2}\", ldm);
215b30b3 10057 else
25f905c2 10058 output_asm_insn (\"ldm%(da%)\\t%0, {%1, %2}\", ldm);
215b30b3 10059 }
10060 output_asm_insn (\"%I3%?\\t%0, %1, %2\", arith);
10061 return \"\";
10062 }"
10063 [(set_attr "length" "12")
10064 (set_attr "predicable" "yes")
a2cd141b 10065 (set_attr "type" "load1")]
215b30b3 10066)
9c08d1fa 10067
9c08d1fa 10068; This pattern is never tried by combine, so do it as a peephole
10069
a0f94409 10070(define_peephole2
372575c7 10071 [(set (match_operand:SI 0 "arm_general_register_operand" "")
10072 (match_operand:SI 1 "arm_general_register_operand" ""))
bd5b4116 10073 (set (reg:CC CC_REGNUM)
aea4c774 10074 (compare:CC (match_dup 1) (const_int 0)))]
372575c7 10075 "TARGET_ARM"
a0f94409 10076 [(parallel [(set (reg:CC CC_REGNUM) (compare:CC (match_dup 1) (const_int 0)))
10077 (set (match_dup 0) (match_dup 1))])]
10078 ""
0d66636f 10079)
9c08d1fa 10080
9c08d1fa 10081(define_split
10082 [(set (match_operand:SI 0 "s_register_operand" "")
10083 (and:SI (ge:SI (match_operand:SI 1 "s_register_operand" "")
10084 (const_int 0))
8fa3ba89 10085 (neg:SI (match_operator:SI 2 "arm_comparison_operator"
9c08d1fa 10086 [(match_operand:SI 3 "s_register_operand" "")
10087 (match_operand:SI 4 "arm_rhs_operand" "")]))))
10088 (clobber (match_operand:SI 5 "s_register_operand" ""))]
cffb2a26 10089 "TARGET_ARM"
9c08d1fa 10090 [(set (match_dup 5) (not:SI (ashiftrt:SI (match_dup 1) (const_int 31))))
10091 (set (match_dup 0) (and:SI (match_op_dup 2 [(match_dup 3) (match_dup 4)])
10092 (match_dup 5)))]
215b30b3 10093 ""
10094)
9c08d1fa 10095
aea4c774 10096;; This split can be used because CC_Z mode implies that the following
10097;; branch will be an equality, or an unsigned inequality, so the sign
10098;; extension is not needed.
9c08d1fa 10099
aea4c774 10100(define_split
bd5b4116 10101 [(set (reg:CC_Z CC_REGNUM)
aea4c774 10102 (compare:CC_Z
10103 (ashift:SI (subreg:SI (match_operand:QI 0 "memory_operand" "") 0)
9c08d1fa 10104 (const_int 24))
aea4c774 10105 (match_operand 1 "const_int_operand" "")))
10106 (clobber (match_scratch:SI 2 ""))]
cffb2a26 10107 "TARGET_ARM
10108 && (((unsigned HOST_WIDE_INT) INTVAL (operands[1]))
10109 == (((unsigned HOST_WIDE_INT) INTVAL (operands[1])) >> 24) << 24)"
aea4c774 10110 [(set (match_dup 2) (zero_extend:SI (match_dup 0)))
bd5b4116 10111 (set (reg:CC CC_REGNUM) (compare:CC (match_dup 2) (match_dup 1)))]
aea4c774 10112 "
9c08d1fa 10113 operands[1] = GEN_INT (((unsigned long) INTVAL (operands[1])) >> 24);
215b30b3 10114 "
10115)
25f905c2 10116;; ??? Check the patterns above for Thumb-2 usefulness
9c08d1fa 10117
87b22bf7 10118(define_expand "prologue"
10119 [(clobber (const_int 0))]
cffb2a26 10120 "TARGET_EITHER"
25f905c2 10121 "if (TARGET_32BIT)
cffb2a26 10122 arm_expand_prologue ();
10123 else
25f905c2 10124 thumb1_expand_prologue ();
87b22bf7 10125 DONE;
cffb2a26 10126 "
10127)
87b22bf7 10128
56d27660 10129(define_expand "epilogue"
4c44712e 10130 [(clobber (const_int 0))]
cffb2a26 10131 "TARGET_EITHER"
56d27660 10132 "
18d50ae6 10133 if (crtl->calls_eh_return)
fb94f18b 10134 emit_insn (gen_force_register_use (gen_rtx_REG (Pmode, 2)));
25f905c2 10135 if (TARGET_THUMB1)
c3635784 10136 {
10137 thumb1_expand_epilogue ();
10138 emit_jump_insn (gen_rtx_UNSPEC_VOLATILE (VOIDmode,
10139 gen_rtvec (1, ret_rtx), VUNSPEC_EPILOGUE));
10140 }
10141 else if (HAVE_return)
10142 {
10143 /* HAVE_return is testing for USE_RETURN_INSN (FALSE). Hence,
10144 no need for explicit testing again. */
10145 emit_jump_insn (gen_return ());
10146 }
10147 else if (TARGET_32BIT)
10148 {
10149 arm_expand_epilogue (true);
10150 }
cffb2a26 10151 DONE;
10152 "
10153)
56d27660 10154
ef5651d0 10155;; Note - although unspec_volatile's USE all hard registers,
10156;; USEs are ignored after relaod has completed. Thus we need
10157;; to add an unspec of the link register to ensure that flow
10158;; does not think that it is unused by the sibcall branch that
10159;; will replace the standard function epilogue.
c3635784 10160(define_expand "sibcall_epilogue"
fb94f18b 10161 [(parallel [(unspec:SI [(reg:SI LR_REGNUM)] UNSPEC_REGISTER_USE)
c3635784 10162 (unspec_volatile [(return)] VUNSPEC_EPILOGUE)])]
10163 "TARGET_32BIT"
10164 "
10165 arm_expand_epilogue (false);
10166 DONE;
10167 "
1c494086 10168)
10169
cffb2a26 10170(define_expand "eh_epilogue"
7db9af5d 10171 [(use (match_operand:SI 0 "register_operand" ""))
10172 (use (match_operand:SI 1 "register_operand" ""))
10173 (use (match_operand:SI 2 "register_operand" ""))]
cffb2a26 10174 "TARGET_EITHER"
10175 "
215b30b3 10176 {
10177 cfun->machine->eh_epilogue_sp_ofs = operands[1];
0438d37f 10178 if (!REG_P (operands[2]) || REGNO (operands[2]) != 2)
215b30b3 10179 {
10180 rtx ra = gen_rtx_REG (Pmode, 2);
10181
10182 emit_move_insn (ra, operands[2]);
10183 operands[2] = ra;
10184 }
5cf3595a 10185 /* This is a hack -- we may have crystalized the function type too
10186 early. */
10187 cfun->machine->func_type = 0;
215b30b3 10188 }"
10189)
56d27660 10190
9c08d1fa 10191;; This split is only used during output to reduce the number of patterns
10192;; that need assembler instructions adding to them. We allowed the setting
10193;; of the conditions to be implicit during rtl generation so that
10194;; the conditional compare patterns would work. However this conflicts to
8a18b90c 10195;; some extent with the conditional data operations, so we have to split them
9c08d1fa 10196;; up again here.
10197
25f905c2 10198;; ??? Need to audit these splitters for Thumb-2. Why isn't normal
10199;; conditional execution sufficient?
10200
9c08d1fa 10201(define_split
10202 [(set (match_operand:SI 0 "s_register_operand" "")
8fa3ba89 10203 (if_then_else:SI (match_operator 1 "arm_comparison_operator"
10204 [(match_operand 2 "" "") (match_operand 3 "" "")])
10205 (match_dup 0)
10206 (match_operand 4 "" "")))
bd5b4116 10207 (clobber (reg:CC CC_REGNUM))]
ac8b093b 10208 "TARGET_ARM && reload_completed"
8fa3ba89 10209 [(set (match_dup 5) (match_dup 6))
10210 (cond_exec (match_dup 7)
10211 (set (match_dup 0) (match_dup 4)))]
10212 "
10213 {
10214 enum machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
10215 operands[2], operands[3]);
10216 enum rtx_code rc = GET_CODE (operands[1]);
10217
bd5b4116 10218 operands[5] = gen_rtx_REG (mode, CC_REGNUM);
8fa3ba89 10219 operands[6] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
10220 if (mode == CCFPmode || mode == CCFPEmode)
10221 rc = reverse_condition_maybe_unordered (rc);
10222 else
10223 rc = reverse_condition (rc);
10224
10225 operands[7] = gen_rtx_fmt_ee (rc, VOIDmode, operands[5], const0_rtx);
10226 }"
10227)
10228
10229(define_split
10230 [(set (match_operand:SI 0 "s_register_operand" "")
10231 (if_then_else:SI (match_operator 1 "arm_comparison_operator"
10232 [(match_operand 2 "" "") (match_operand 3 "" "")])
10233 (match_operand 4 "" "")
10234 (match_dup 0)))
bd5b4116 10235 (clobber (reg:CC CC_REGNUM))]
ac8b093b 10236 "TARGET_ARM && reload_completed"
8fa3ba89 10237 [(set (match_dup 5) (match_dup 6))
10238 (cond_exec (match_op_dup 1 [(match_dup 5) (const_int 0)])
10239 (set (match_dup 0) (match_dup 4)))]
10240 "
10241 {
10242 enum machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
10243 operands[2], operands[3]);
10244
bd5b4116 10245 operands[5] = gen_rtx_REG (mode, CC_REGNUM);
8fa3ba89 10246 operands[6] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
10247 }"
10248)
10249
10250(define_split
10251 [(set (match_operand:SI 0 "s_register_operand" "")
10252 (if_then_else:SI (match_operator 1 "arm_comparison_operator"
9c08d1fa 10253 [(match_operand 2 "" "") (match_operand 3 "" "")])
10254 (match_operand 4 "" "")
10255 (match_operand 5 "" "")))
bd5b4116 10256 (clobber (reg:CC CC_REGNUM))]
ac8b093b 10257 "TARGET_ARM && reload_completed"
8fa3ba89 10258 [(set (match_dup 6) (match_dup 7))
10259 (cond_exec (match_op_dup 1 [(match_dup 6) (const_int 0)])
10260 (set (match_dup 0) (match_dup 4)))
10261 (cond_exec (match_dup 8)
10262 (set (match_dup 0) (match_dup 5)))]
10263 "
10264 {
10265 enum machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
10266 operands[2], operands[3]);
10267 enum rtx_code rc = GET_CODE (operands[1]);
10268
bd5b4116 10269 operands[6] = gen_rtx_REG (mode, CC_REGNUM);
8fa3ba89 10270 operands[7] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
10271 if (mode == CCFPmode || mode == CCFPEmode)
10272 rc = reverse_condition_maybe_unordered (rc);
10273 else
10274 rc = reverse_condition (rc);
10275
10276 operands[8] = gen_rtx_fmt_ee (rc, VOIDmode, operands[6], const0_rtx);
10277 }"
10278)
10279
cffb2a26 10280(define_split
10281 [(set (match_operand:SI 0 "s_register_operand" "")
8fa3ba89 10282 (if_then_else:SI (match_operator 1 "arm_comparison_operator"
cffb2a26 10283 [(match_operand:SI 2 "s_register_operand" "")
10284 (match_operand:SI 3 "arm_add_operand" "")])
10285 (match_operand:SI 4 "arm_rhs_operand" "")
10286 (not:SI
10287 (match_operand:SI 5 "s_register_operand" ""))))
bd5b4116 10288 (clobber (reg:CC CC_REGNUM))]
ac8b093b 10289 "TARGET_ARM && reload_completed"
cffb2a26 10290 [(set (match_dup 6) (match_dup 7))
f6c53574 10291 (cond_exec (match_op_dup 1 [(match_dup 6) (const_int 0)])
10292 (set (match_dup 0) (match_dup 4)))
10293 (cond_exec (match_dup 8)
10294 (set (match_dup 0) (not:SI (match_dup 5))))]
cffb2a26 10295 "
215b30b3 10296 {
10297 enum machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
10298 operands[2], operands[3]);
f6c53574 10299 enum rtx_code rc = GET_CODE (operands[1]);
cffb2a26 10300
bd5b4116 10301 operands[6] = gen_rtx_REG (mode, CC_REGNUM);
1a83b3ff 10302 operands[7] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
f6c53574 10303 if (mode == CCFPmode || mode == CCFPEmode)
10304 rc = reverse_condition_maybe_unordered (rc);
10305 else
10306 rc = reverse_condition (rc);
10307
10308 operands[8] = gen_rtx_fmt_ee (rc, VOIDmode, operands[6], const0_rtx);
215b30b3 10309 }"
10310)
cffb2a26 10311
10312(define_insn "*cond_move_not"
10313 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8fa3ba89 10314 (if_then_else:SI (match_operator 4 "arm_comparison_operator"
cffb2a26 10315 [(match_operand 3 "cc_register" "") (const_int 0)])
10316 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
10317 (not:SI
10318 (match_operand:SI 2 "s_register_operand" "r,r"))))]
10319 "TARGET_ARM"
10320 "@
10321 mvn%D4\\t%0, %2
10322 mov%d4\\t%0, %1\;mvn%D4\\t%0, %2"
0d66636f 10323 [(set_attr "conds" "use")
1b7da4ac 10324 (set_attr "type" "mvn_reg,multiple")
0d66636f 10325 (set_attr "length" "4,8")]
10326)
cffb2a26 10327
9c08d1fa 10328;; The next two patterns occur when an AND operation is followed by a
10329;; scc insn sequence
10330
f7fbdd4a 10331(define_insn "*sign_extract_onebit"
9c08d1fa 10332 [(set (match_operand:SI 0 "s_register_operand" "=r")
10333 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
10334 (const_int 1)
ed750274 10335 (match_operand:SI 2 "const_int_operand" "n")))
10336 (clobber (reg:CC CC_REGNUM))]
cffb2a26 10337 "TARGET_ARM"
9c08d1fa 10338 "*
0d66636f 10339 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
10340 output_asm_insn (\"ands\\t%0, %1, %2\", operands);
10341 return \"mvnne\\t%0, #0\";
10342 "
10343 [(set_attr "conds" "clob")
1b7da4ac 10344 (set_attr "length" "8")
10345 (set_attr "type" "multiple")]
0d66636f 10346)
9c08d1fa 10347
f7fbdd4a 10348(define_insn "*not_signextract_onebit"
9c08d1fa 10349 [(set (match_operand:SI 0 "s_register_operand" "=r")
10350 (not:SI
10351 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
10352 (const_int 1)
ed750274 10353 (match_operand:SI 2 "const_int_operand" "n"))))
10354 (clobber (reg:CC CC_REGNUM))]
cffb2a26 10355 "TARGET_ARM"
9c08d1fa 10356 "*
0d66636f 10357 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
10358 output_asm_insn (\"tst\\t%1, %2\", operands);
10359 output_asm_insn (\"mvneq\\t%0, #0\", operands);
10360 return \"movne\\t%0, #0\";
10361 "
10362 [(set_attr "conds" "clob")
1b7da4ac 10363 (set_attr "length" "12")
10364 (set_attr "type" "multiple")]
0d66636f 10365)
25f905c2 10366;; ??? The above patterns need auditing for Thumb-2
87b22bf7 10367
0d66636f 10368;; Push multiple registers to the stack. Registers are in parallel (use ...)
10369;; expressions. For simplicity, the first register is also in the unspec
10370;; part.
08508cbf 10371;; To avoid the usage of GNU extension, the length attribute is computed
10372;; in a C function arm_attr_length_push_multi.
f7fbdd4a 10373(define_insn "*push_multi"
87b22bf7 10374 [(match_parallel 2 "multi_register_push"
7571d3f7 10375 [(set (match_operand:BLK 0 "push_mult_memory_operand" "")
3cc80a30 10376 (unspec:BLK [(match_operand:SI 1 "s_register_operand" "")]
e1159bbe 10377 UNSPEC_PUSH_MULT))])]
7571d3f7 10378 ""
87b22bf7 10379 "*
215b30b3 10380 {
10381 int num_saves = XVECLEN (operands[2], 0);
ed593f11 10382
215b30b3 10383 /* For the StrongARM at least it is faster to
25f905c2 10384 use STR to store only a single register.
542d5028 10385 In Thumb mode always use push, and the assembler will pick
10386 something appropriate. */
25f905c2 10387 if (num_saves == 1 && TARGET_ARM)
61309563 10388 output_asm_insn (\"str%?\\t%1, [%m0, #-4]!\", operands);
215b30b3 10389 else
10390 {
10391 int i;
10392 char pattern[100];
ed593f11 10393
25f905c2 10394 if (TARGET_ARM)
61309563 10395 strcpy (pattern, \"stm%(fd%)\\t%m0!, {%1\");
10396 else if (TARGET_THUMB2)
10397 strcpy (pattern, \"push%?\\t{%1\");
25f905c2 10398 else
10399 strcpy (pattern, \"push\\t{%1\");
215b30b3 10400
6079f055 10401 for (i = 1; i < num_saves; i++)
215b30b3 10402 {
10403 strcat (pattern, \", %|\");
10404 strcat (pattern,
10405 reg_names[REGNO (XEXP (XVECEXP (operands[2], 0, i), 0))]);
10406 }
10407
10408 strcat (pattern, \"}\");
10409 output_asm_insn (pattern, operands);
10410 }
10411
10412 return \"\";
10413 }"
a6864a24 10414 [(set_attr "type" "store4")
10415 (set (attr "length")
08508cbf 10416 (symbol_ref "arm_attr_length_push_multi (operands[2], operands[1])"))]
215b30b3 10417)
f7fbdd4a 10418
4c58c898 10419(define_insn "stack_tie"
10420 [(set (mem:BLK (scratch))
aaa37ad6 10421 (unspec:BLK [(match_operand:SI 0 "s_register_operand" "rk")
10422 (match_operand:SI 1 "s_register_operand" "rk")]
4c58c898 10423 UNSPEC_PRLG_STK))]
10424 ""
10425 ""
1b7da4ac 10426 [(set_attr "length" "0")
10427 (set_attr "type" "block")]
4c58c898 10428)
10429
426be8c5 10430;; Pop (as used in epilogue RTL)
10431;;
10432(define_insn "*load_multiple_with_writeback"
10433 [(match_parallel 0 "load_multiple_operation"
10434 [(set (match_operand:SI 1 "s_register_operand" "+rk")
10435 (plus:SI (match_dup 1)
809003b3 10436 (match_operand:SI 2 "const_int_I_operand" "I")))
426be8c5 10437 (set (match_operand:SI 3 "s_register_operand" "=rk")
10438 (mem:SI (match_dup 1)))
10439 ])]
10440 "TARGET_32BIT && (reload_in_progress || reload_completed)"
10441 "*
10442 {
10443 arm_output_multireg_pop (operands, /*return_pc=*/false,
10444 /*cond=*/const_true_rtx,
10445 /*reverse=*/false,
10446 /*update=*/true);
10447 return \"\";
10448 }
10449 "
10450 [(set_attr "type" "load4")
10451 (set_attr "predicable" "yes")]
10452)
10453
10454;; Pop with return (as used in epilogue RTL)
10455;;
10456;; This instruction is generated when the registers are popped at the end of
10457;; epilogue. Here, instead of popping the value into LR and then generating
10458;; jump to LR, value is popped into PC directly. Hence, the pattern is combined
10459;; with (return).
10460(define_insn "*pop_multiple_with_writeback_and_return"
10461 [(match_parallel 0 "pop_multiple_return"
10462 [(return)
10463 (set (match_operand:SI 1 "s_register_operand" "+rk")
10464 (plus:SI (match_dup 1)
809003b3 10465 (match_operand:SI 2 "const_int_I_operand" "I")))
426be8c5 10466 (set (match_operand:SI 3 "s_register_operand" "=rk")
10467 (mem:SI (match_dup 1)))
10468 ])]
10469 "TARGET_32BIT && (reload_in_progress || reload_completed)"
10470 "*
10471 {
10472 arm_output_multireg_pop (operands, /*return_pc=*/true,
10473 /*cond=*/const_true_rtx,
10474 /*reverse=*/false,
10475 /*update=*/true);
10476 return \"\";
10477 }
10478 "
10479 [(set_attr "type" "load4")
10480 (set_attr "predicable" "yes")]
10481)
10482
10483(define_insn "*pop_multiple_with_return"
10484 [(match_parallel 0 "pop_multiple_return"
10485 [(return)
10486 (set (match_operand:SI 2 "s_register_operand" "=rk")
10487 (mem:SI (match_operand:SI 1 "s_register_operand" "rk")))
10488 ])]
10489 "TARGET_32BIT && (reload_in_progress || reload_completed)"
10490 "*
10491 {
10492 arm_output_multireg_pop (operands, /*return_pc=*/true,
10493 /*cond=*/const_true_rtx,
10494 /*reverse=*/false,
10495 /*update=*/false);
10496 return \"\";
10497 }
10498 "
10499 [(set_attr "type" "load4")
10500 (set_attr "predicable" "yes")]
10501)
10502
10503;; Load into PC and return
10504(define_insn "*ldr_with_return"
10505 [(return)
10506 (set (reg:SI PC_REGNUM)
10507 (mem:SI (post_inc:SI (match_operand:SI 0 "s_register_operand" "+rk"))))]
10508 "TARGET_32BIT && (reload_in_progress || reload_completed)"
10509 "ldr%?\t%|pc, [%0], #4"
10510 [(set_attr "type" "load1")
10511 (set_attr "predicable" "yes")]
10512)
1a0b0f12 10513;; Pop for floating point registers (as used in epilogue RTL)
10514(define_insn "*vfp_pop_multiple_with_writeback"
10515 [(match_parallel 0 "pop_multiple_fp"
10516 [(set (match_operand:SI 1 "s_register_operand" "+rk")
10517 (plus:SI (match_dup 1)
809003b3 10518 (match_operand:SI 2 "const_int_I_operand" "I")))
2f2163a4 10519 (set (match_operand:DF 3 "vfp_hard_register_operand" "")
1a0b0f12 10520 (mem:DF (match_dup 1)))])]
10521 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
10522 "*
10523 {
10524 int num_regs = XVECLEN (operands[0], 0);
10525 char pattern[100];
10526 rtx op_list[2];
10527 strcpy (pattern, \"fldmfdd\\t\");
10528 strcat (pattern, reg_names[REGNO (SET_DEST (XVECEXP (operands[0], 0, 0)))]);
10529 strcat (pattern, \"!, {\");
10530 op_list[0] = XEXP (XVECEXP (operands[0], 0, 1), 0);
10531 strcat (pattern, \"%P0\");
10532 if ((num_regs - 1) > 1)
10533 {
10534 strcat (pattern, \"-%P1\");
10535 op_list [1] = XEXP (XVECEXP (operands[0], 0, num_regs - 1), 0);
10536 }
10537
10538 strcat (pattern, \"}\");
10539 output_asm_insn (pattern, op_list);
10540 return \"\";
10541 }
10542 "
10543 [(set_attr "type" "load4")
10544 (set_attr "conds" "unconditional")
10545 (set_attr "predicable" "no")]
10546)
10547
f7fbdd4a 10548;; Special patterns for dealing with the constant pool
10549
cffb2a26 10550(define_insn "align_4"
e1159bbe 10551 [(unspec_volatile [(const_int 0)] VUNSPEC_ALIGN)]
cffb2a26 10552 "TARGET_EITHER"
f7fbdd4a 10553 "*
cffb2a26 10554 assemble_align (32);
f7fbdd4a 10555 return \"\";
cffb2a26 10556 "
1b7da4ac 10557 [(set_attr "type" "no_insn")]
cffb2a26 10558)
f7fbdd4a 10559
755eb2b4 10560(define_insn "align_8"
10561 [(unspec_volatile [(const_int 0)] VUNSPEC_ALIGN8)]
f9273c43 10562 "TARGET_EITHER"
755eb2b4 10563 "*
10564 assemble_align (64);
10565 return \"\";
10566 "
1b7da4ac 10567 [(set_attr "type" "no_insn")]
755eb2b4 10568)
10569
cffb2a26 10570(define_insn "consttable_end"
e1159bbe 10571 [(unspec_volatile [(const_int 0)] VUNSPEC_POOL_END)]
cffb2a26 10572 "TARGET_EITHER"
f7fbdd4a 10573 "*
cffb2a26 10574 making_const_table = FALSE;
f7fbdd4a 10575 return \"\";
cffb2a26 10576 "
1b7da4ac 10577 [(set_attr "type" "no_insn")]
cffb2a26 10578)
f7fbdd4a 10579
cffb2a26 10580(define_insn "consttable_4"
e1159bbe 10581 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_4)]
cffb2a26 10582 "TARGET_EITHER"
10583 "*
10584 {
9b8516be 10585 rtx x = operands[0];
cffb2a26 10586 making_const_table = TRUE;
9b8516be 10587 switch (GET_MODE_CLASS (GET_MODE (x)))
cffb2a26 10588 {
10589 case MODE_FLOAT:
9b8516be 10590 if (GET_MODE (x) == HFmode)
10591 arm_emit_fp16_const (x);
10592 else
10593 {
10594 REAL_VALUE_TYPE r;
10595 REAL_VALUE_FROM_CONST_DOUBLE (r, x);
10596 assemble_real (r, GET_MODE (x), BITS_PER_WORD);
10597 }
10598 break;
cffb2a26 10599 default:
7b04c5d5 10600 /* XXX: Sometimes gcc does something really dumb and ends up with
10601 a HIGH in a constant pool entry, usually because it's trying to
10602 load into a VFP register. We know this will always be used in
10603 combination with a LO_SUM which ignores the high bits, so just
10604 strip off the HIGH. */
10605 if (GET_CODE (x) == HIGH)
10606 x = XEXP (x, 0);
9b8516be 10607 assemble_integer (x, 4, BITS_PER_WORD, 1);
10608 mark_symbol_refs_as_used (x);
cffb2a26 10609 break;
10610 }
10611 return \"\";
10612 }"
1b7da4ac 10613 [(set_attr "length" "4")
10614 (set_attr "type" "no_insn")]
cffb2a26 10615)
10616
10617(define_insn "consttable_8"
e1159bbe 10618 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_8)]
cffb2a26 10619 "TARGET_EITHER"
10620 "*
10621 {
10622 making_const_table = TRUE;
10623 switch (GET_MODE_CLASS (GET_MODE (operands[0])))
10624 {
10625 case MODE_FLOAT:
10626 {
badfe841 10627 REAL_VALUE_TYPE r;
10628 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[0]);
10629 assemble_real (r, GET_MODE (operands[0]), BITS_PER_WORD);
cffb2a26 10630 break;
10631 }
10632 default:
09d688ff 10633 assemble_integer (operands[0], 8, BITS_PER_WORD, 1);
cffb2a26 10634 break;
10635 }
10636 return \"\";
10637 }"
1b7da4ac 10638 [(set_attr "length" "8")
10639 (set_attr "type" "no_insn")]
cffb2a26 10640)
10641
d98a3884 10642(define_insn "consttable_16"
10643 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_16)]
10644 "TARGET_EITHER"
10645 "*
10646 {
10647 making_const_table = TRUE;
10648 switch (GET_MODE_CLASS (GET_MODE (operands[0])))
10649 {
10650 case MODE_FLOAT:
10651 {
10652 REAL_VALUE_TYPE r;
10653 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[0]);
10654 assemble_real (r, GET_MODE (operands[0]), BITS_PER_WORD);
10655 break;
10656 }
10657 default:
10658 assemble_integer (operands[0], 16, BITS_PER_WORD, 1);
10659 break;
10660 }
10661 return \"\";
10662 }"
1b7da4ac 10663 [(set_attr "length" "16")
10664 (set_attr "type" "no_insn")]
d98a3884 10665)
10666
331beb1a 10667;; V5 Instructions,
10668
8f4be2be 10669(define_insn "clzsi2"
10670 [(set (match_operand:SI 0 "s_register_operand" "=r")
10671 (clz:SI (match_operand:SI 1 "s_register_operand" "r")))]
25f905c2 10672 "TARGET_32BIT && arm_arch5"
ee7cbe0e 10673 "clz%?\\t%0, %1"
bcaec148 10674 [(set_attr "predicable" "yes")
bebe9bbb 10675 (set_attr "type" "clz")])
331beb1a 10676
099ad98b 10677(define_insn "rbitsi2"
10678 [(set (match_operand:SI 0 "s_register_operand" "=r")
10679 (unspec:SI [(match_operand:SI 1 "s_register_operand" "r")] UNSPEC_RBIT))]
10680 "TARGET_32BIT && arm_arch_thumb2"
10681 "rbit%?\\t%0, %1"
10682 [(set_attr "predicable" "yes")
bebe9bbb 10683 (set_attr "type" "clz")])
099ad98b 10684
10685(define_expand "ctzsi2"
10686 [(set (match_operand:SI 0 "s_register_operand" "")
10687 (ctz:SI (match_operand:SI 1 "s_register_operand" "")))]
10688 "TARGET_32BIT && arm_arch_thumb2"
10689 "
30191172 10690 {
10691 rtx tmp = gen_reg_rtx (SImode);
10692 emit_insn (gen_rbitsi2 (tmp, operands[1]));
10693 emit_insn (gen_clzsi2 (operands[0], tmp));
10694 }
099ad98b 10695 DONE;
10696 "
10697)
10698
e1159bbe 10699;; V5E instructions.
331beb1a 10700
10701(define_insn "prefetch"
f4e79814 10702 [(prefetch (match_operand:SI 0 "address_operand" "p")
10703 (match_operand:SI 1 "" "")
10704 (match_operand:SI 2 "" ""))]
25f905c2 10705 "TARGET_32BIT && arm_arch5e"
1b7da4ac 10706 "pld\\t%a0"
10707 [(set_attr "type" "load1")]
10708)
331beb1a 10709
0d66636f 10710;; General predication pattern
10711
10712(define_cond_exec
10713 [(match_operator 0 "arm_comparison_operator"
10714 [(match_operand 1 "cc_register" "")
10715 (const_int 0)])]
25f905c2 10716 "TARGET_32BIT"
0d66636f 10717 ""
c7a58118 10718[(set_attr "predicated" "yes")]
0d66636f 10719)
10720
fb94f18b 10721(define_insn "force_register_use"
10722 [(unspec:SI [(match_operand:SI 0 "register_operand" "")] UNSPEC_REGISTER_USE)]
063a05c7 10723 ""
fb94f18b 10724 "%@ %0 needed"
1b7da4ac 10725 [(set_attr "length" "0")
10726 (set_attr "type" "no_insn")]
063a05c7 10727)
7db9af5d 10728
4c44712e 10729
10730;; Patterns for exception handling
10731
10732(define_expand "eh_return"
10733 [(use (match_operand 0 "general_operand" ""))]
10734 "TARGET_EITHER"
10735 "
10736 {
25f905c2 10737 if (TARGET_32BIT)
4c44712e 10738 emit_insn (gen_arm_eh_return (operands[0]));
10739 else
10740 emit_insn (gen_thumb_eh_return (operands[0]));
10741 DONE;
10742 }"
10743)
10744
10745;; We can't expand this before we know where the link register is stored.
10746(define_insn_and_split "arm_eh_return"
10747 [(unspec_volatile [(match_operand:SI 0 "s_register_operand" "r")]
10748 VUNSPEC_EH_RETURN)
10749 (clobber (match_scratch:SI 1 "=&r"))]
10750 "TARGET_ARM"
10751 "#"
10752 "&& reload_completed"
10753 [(const_int 0)]
10754 "
10755 {
10756 arm_set_return_address (operands[0], operands[1]);
10757 DONE;
10758 }"
10759)
10760
f655717d 10761\f
10762;; TLS support
10763
10764(define_insn "load_tp_hard"
10765 [(set (match_operand:SI 0 "register_operand" "=r")
10766 (unspec:SI [(const_int 0)] UNSPEC_TLS))]
10767 "TARGET_HARD_TP"
10768 "mrc%?\\tp15, 0, %0, c13, c0, 3\\t@ load_tp_hard"
1b7da4ac 10769 [(set_attr "predicable" "yes")
4b5d7374 10770 (set_attr "type" "mrs")]
f655717d 10771)
10772
10773;; Doesn't clobber R1-R3. Must use r0 for the first operand.
10774(define_insn "load_tp_soft"
10775 [(set (reg:SI 0) (unspec:SI [(const_int 0)] UNSPEC_TLS))
10776 (clobber (reg:SI LR_REGNUM))
10777 (clobber (reg:SI IP_REGNUM))
10778 (clobber (reg:CC CC_REGNUM))]
10779 "TARGET_SOFT_TP"
10780 "bl\\t__aeabi_read_tp\\t@ load_tp_soft"
1b7da4ac 10781 [(set_attr "conds" "clob")
10782 (set_attr "type" "branch")]
f655717d 10783)
10784
f41e4452 10785;; tls descriptor call
10786(define_insn "tlscall"
10787 [(set (reg:SI R0_REGNUM)
10788 (unspec:SI [(reg:SI R0_REGNUM)
10789 (match_operand:SI 0 "" "X")
10790 (match_operand 1 "" "")] UNSPEC_TLS))
10791 (clobber (reg:SI R1_REGNUM))
10792 (clobber (reg:SI LR_REGNUM))
10793 (clobber (reg:SI CC_REGNUM))]
10794 "TARGET_GNU2_TLS"
10795 {
10796 targetm.asm_out.internal_label (asm_out_file, "LPIC",
10797 INTVAL (operands[1]));
10798 return "bl\\t%c0(tlscall)";
10799 }
10800 [(set_attr "conds" "clob")
1b7da4ac 10801 (set_attr "length" "4")
10802 (set_attr "type" "branch")]
f41e4452 10803)
10804
1fe0edab 10805;; For thread pointer builtin
10806(define_expand "get_thread_pointersi"
10807 [(match_operand:SI 0 "s_register_operand" "=r")]
10808 ""
10809 "
10810 {
10811 arm_load_tp (operands[0]);
10812 DONE;
10813 }")
10814
f41e4452 10815;;
10816
aabe09ac 10817;; We only care about the lower 16 bits of the constant
10818;; being inserted into the upper 16 bits of the register.
eca5c984 10819(define_insn "*arm_movtas_ze"
10820 [(set (zero_extract:SI (match_operand:SI 0 "s_register_operand" "+r")
10821 (const_int 16)
10822 (const_int 16))
10823 (match_operand:SI 1 "const_int_operand" ""))]
181ab277 10824 "arm_arch_thumb2"
aabe09ac 10825 "movt%?\t%0, %L1"
eca5c984 10826 [(set_attr "predicable" "yes")
7c36fe71 10827 (set_attr "predicable_short_it" "no")
1b7da4ac 10828 (set_attr "length" "4")
10829 (set_attr "type" "mov_imm")]
eca5c984 10830)
10831
c0fc3696 10832(define_insn "*arm_rev"
a486b499 10833 [(set (match_operand:SI 0 "s_register_operand" "=l,l,r")
10834 (bswap:SI (match_operand:SI 1 "s_register_operand" "l,l,r")))]
10835 "arm_arch6"
10836 "@
10837 rev\t%0, %1
10838 rev%?\t%0, %1
10839 rev%?\t%0, %1"
10840 [(set_attr "arch" "t1,t2,32")
1b7da4ac 10841 (set_attr "length" "2,2,4")
10842 (set_attr "type" "rev")]
ff82f757 10843)
10844
10845(define_expand "arm_legacy_rev"
10846 [(set (match_operand:SI 2 "s_register_operand" "")
10847 (xor:SI (rotatert:SI (match_operand:SI 1 "s_register_operand" "")
10848 (const_int 16))
10849 (match_dup 1)))
10850 (set (match_dup 2)
10851 (lshiftrt:SI (match_dup 2)
10852 (const_int 8)))
10853 (set (match_operand:SI 3 "s_register_operand" "")
10854 (rotatert:SI (match_dup 1)
10855 (const_int 8)))
10856 (set (match_dup 2)
10857 (and:SI (match_dup 2)
10858 (const_int -65281)))
10859 (set (match_operand:SI 0 "s_register_operand" "")
10860 (xor:SI (match_dup 3)
10861 (match_dup 2)))]
10862 "TARGET_32BIT"
10863 ""
10864)
10865
10866;; Reuse temporaries to keep register pressure down.
10867(define_expand "thumb_legacy_rev"
10868 [(set (match_operand:SI 2 "s_register_operand" "")
10869 (ashift:SI (match_operand:SI 1 "s_register_operand" "")
10870 (const_int 24)))
10871 (set (match_operand:SI 3 "s_register_operand" "")
10872 (lshiftrt:SI (match_dup 1)
10873 (const_int 24)))
10874 (set (match_dup 3)
10875 (ior:SI (match_dup 3)
10876 (match_dup 2)))
10877 (set (match_operand:SI 4 "s_register_operand" "")
10878 (const_int 16))
10879 (set (match_operand:SI 5 "s_register_operand" "")
10880 (rotatert:SI (match_dup 1)
10881 (match_dup 4)))
10882 (set (match_dup 2)
10883 (ashift:SI (match_dup 5)
10884 (const_int 24)))
10885 (set (match_dup 5)
10886 (lshiftrt:SI (match_dup 5)
10887 (const_int 24)))
10888 (set (match_dup 5)
10889 (ior:SI (match_dup 5)
10890 (match_dup 2)))
10891 (set (match_dup 5)
10892 (rotatert:SI (match_dup 5)
10893 (match_dup 4)))
10894 (set (match_operand:SI 0 "s_register_operand" "")
10895 (ior:SI (match_dup 5)
10896 (match_dup 3)))]
10897 "TARGET_THUMB"
10898 ""
10899)
10900
10901(define_expand "bswapsi2"
10902 [(set (match_operand:SI 0 "s_register_operand" "=r")
10903 (bswap:SI (match_operand:SI 1 "s_register_operand" "r")))]
8d1af482 10904"TARGET_EITHER && (arm_arch6 || !optimize_size)"
ff82f757 10905"
8d1af482 10906 if (!arm_arch6)
10907 {
10908 rtx op2 = gen_reg_rtx (SImode);
10909 rtx op3 = gen_reg_rtx (SImode);
ff82f757 10910
8d1af482 10911 if (TARGET_THUMB)
10912 {
10913 rtx op4 = gen_reg_rtx (SImode);
10914 rtx op5 = gen_reg_rtx (SImode);
ff82f757 10915
8d1af482 10916 emit_insn (gen_thumb_legacy_rev (operands[0], operands[1],
10917 op2, op3, op4, op5));
10918 }
10919 else
10920 {
10921 emit_insn (gen_arm_legacy_rev (operands[0], operands[1],
10922 op2, op3));
10923 }
ff82f757 10924
8d1af482 10925 DONE;
10926 }
ff82f757 10927 "
10928)
10929
a486b499 10930;; bswap16 patterns: use revsh and rev16 instructions for the signed
10931;; and unsigned variants, respectively. For rev16, expose
10932;; byte-swapping in the lower 16 bits only.
10933(define_insn "*arm_revsh"
10934 [(set (match_operand:SI 0 "s_register_operand" "=l,l,r")
10935 (sign_extend:SI (bswap:HI (match_operand:HI 1 "s_register_operand" "l,l,r"))))]
10936 "arm_arch6"
10937 "@
10938 revsh\t%0, %1
10939 revsh%?\t%0, %1
10940 revsh%?\t%0, %1"
10941 [(set_attr "arch" "t1,t2,32")
1b7da4ac 10942 (set_attr "length" "2,2,4")
10943 (set_attr "type" "rev")]
a486b499 10944)
10945
10946(define_insn "*arm_rev16"
10947 [(set (match_operand:HI 0 "s_register_operand" "=l,l,r")
10948 (bswap:HI (match_operand:HI 1 "s_register_operand" "l,l,r")))]
10949 "arm_arch6"
10950 "@
10951 rev16\t%0, %1
10952 rev16%?\t%0, %1
10953 rev16%?\t%0, %1"
10954 [(set_attr "arch" "t1,t2,32")
1b7da4ac 10955 (set_attr "length" "2,2,4")
10956 (set_attr "type" "rev")]
09f69e55 10957)
10958
10959;; There are no canonicalisation rules for the position of the lshiftrt, ashift
10960;; operations within an IOR/AND RTX, therefore we have two patterns matching
10961;; each valid permutation.
10962
10963(define_insn "arm_rev16si2"
10964 [(set (match_operand:SI 0 "register_operand" "=l,l,r")
10965 (ior:SI (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "l,l,r")
10966 (const_int 8))
10967 (match_operand:SI 3 "const_int_operand" "n,n,n"))
10968 (and:SI (lshiftrt:SI (match_dup 1)
10969 (const_int 8))
10970 (match_operand:SI 2 "const_int_operand" "n,n,n"))))]
10971 "arm_arch6
10972 && aarch_rev16_shleft_mask_imm_p (operands[3], SImode)
10973 && aarch_rev16_shright_mask_imm_p (operands[2], SImode)"
10974 "rev16\\t%0, %1"
10975 [(set_attr "arch" "t1,t2,32")
10976 (set_attr "length" "2,2,4")
10977 (set_attr "type" "rev")]
10978)
10979
10980(define_insn "arm_rev16si2_alt"
10981 [(set (match_operand:SI 0 "register_operand" "=l,l,r")
10982 (ior:SI (and:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" "l,l,r")
10983 (const_int 8))
10984 (match_operand:SI 2 "const_int_operand" "n,n,n"))
10985 (and:SI (ashift:SI (match_dup 1)
10986 (const_int 8))
10987 (match_operand:SI 3 "const_int_operand" "n,n,n"))))]
10988 "arm_arch6
10989 && aarch_rev16_shleft_mask_imm_p (operands[3], SImode)
10990 && aarch_rev16_shright_mask_imm_p (operands[2], SImode)"
10991 "rev16\\t%0, %1"
10992 [(set_attr "arch" "t1,t2,32")
10993 (set_attr "length" "2,2,4")
10994 (set_attr "type" "rev")]
a486b499 10995)
10996
10997(define_expand "bswaphi2"
10998 [(set (match_operand:HI 0 "s_register_operand" "=r")
10999 (bswap:HI (match_operand:HI 1 "s_register_operand" "r")))]
11000"arm_arch6"
11001""
11002)
11003
1653cf17 11004;; Patterns for LDRD/STRD in Thumb2 mode
11005
11006(define_insn "*thumb2_ldrd"
11007 [(set (match_operand:SI 0 "s_register_operand" "=r")
11008 (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "rk")
11009 (match_operand:SI 2 "ldrd_strd_offset_operand" "Do"))))
11010 (set (match_operand:SI 3 "s_register_operand" "=r")
11011 (mem:SI (plus:SI (match_dup 1)
11012 (match_operand:SI 4 "const_int_operand" ""))))]
11013 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11014 && current_tune->prefer_ldrd_strd
11015 && ((INTVAL (operands[2]) + 4) == INTVAL (operands[4]))
11016 && (operands_ok_ldrd_strd (operands[0], operands[3],
11017 operands[1], INTVAL (operands[2]),
11018 false, true))"
11019 "ldrd%?\t%0, %3, [%1, %2]"
11020 [(set_attr "type" "load2")
d952d547 11021 (set_attr "predicable" "yes")
11022 (set_attr "predicable_short_it" "no")])
1653cf17 11023
11024(define_insn "*thumb2_ldrd_base"
11025 [(set (match_operand:SI 0 "s_register_operand" "=r")
11026 (mem:SI (match_operand:SI 1 "s_register_operand" "rk")))
11027 (set (match_operand:SI 2 "s_register_operand" "=r")
11028 (mem:SI (plus:SI (match_dup 1)
11029 (const_int 4))))]
11030 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11031 && current_tune->prefer_ldrd_strd
11032 && (operands_ok_ldrd_strd (operands[0], operands[2],
11033 operands[1], 0, false, true))"
11034 "ldrd%?\t%0, %2, [%1]"
11035 [(set_attr "type" "load2")
d952d547 11036 (set_attr "predicable" "yes")
11037 (set_attr "predicable_short_it" "no")])
1653cf17 11038
11039(define_insn "*thumb2_ldrd_base_neg"
11040 [(set (match_operand:SI 0 "s_register_operand" "=r")
11041 (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "rk")
11042 (const_int -4))))
11043 (set (match_operand:SI 2 "s_register_operand" "=r")
11044 (mem:SI (match_dup 1)))]
11045 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11046 && current_tune->prefer_ldrd_strd
11047 && (operands_ok_ldrd_strd (operands[0], operands[2],
11048 operands[1], -4, false, true))"
11049 "ldrd%?\t%0, %2, [%1, #-4]"
11050 [(set_attr "type" "load2")
d952d547 11051 (set_attr "predicable" "yes")
11052 (set_attr "predicable_short_it" "no")])
1653cf17 11053
11054(define_insn "*thumb2_strd"
11055 [(set (mem:SI (plus:SI (match_operand:SI 0 "s_register_operand" "rk")
11056 (match_operand:SI 1 "ldrd_strd_offset_operand" "Do")))
11057 (match_operand:SI 2 "s_register_operand" "r"))
11058 (set (mem:SI (plus:SI (match_dup 0)
11059 (match_operand:SI 3 "const_int_operand" "")))
11060 (match_operand:SI 4 "s_register_operand" "r"))]
11061 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11062 && current_tune->prefer_ldrd_strd
11063 && ((INTVAL (operands[1]) + 4) == INTVAL (operands[3]))
11064 && (operands_ok_ldrd_strd (operands[2], operands[4],
11065 operands[0], INTVAL (operands[1]),
11066 false, false))"
11067 "strd%?\t%2, %4, [%0, %1]"
11068 [(set_attr "type" "store2")
d952d547 11069 (set_attr "predicable" "yes")
11070 (set_attr "predicable_short_it" "no")])
1653cf17 11071
11072(define_insn "*thumb2_strd_base"
11073 [(set (mem:SI (match_operand:SI 0 "s_register_operand" "rk"))
11074 (match_operand:SI 1 "s_register_operand" "r"))
11075 (set (mem:SI (plus:SI (match_dup 0)
11076 (const_int 4)))
11077 (match_operand:SI 2 "s_register_operand" "r"))]
11078 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11079 && current_tune->prefer_ldrd_strd
11080 && (operands_ok_ldrd_strd (operands[1], operands[2],
11081 operands[0], 0, false, false))"
11082 "strd%?\t%1, %2, [%0]"
11083 [(set_attr "type" "store2")
d952d547 11084 (set_attr "predicable" "yes")
11085 (set_attr "predicable_short_it" "no")])
1653cf17 11086
11087(define_insn "*thumb2_strd_base_neg"
11088 [(set (mem:SI (plus:SI (match_operand:SI 0 "s_register_operand" "rk")
11089 (const_int -4)))
11090 (match_operand:SI 1 "s_register_operand" "r"))
11091 (set (mem:SI (match_dup 0))
11092 (match_operand:SI 2 "s_register_operand" "r"))]
11093 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11094 && current_tune->prefer_ldrd_strd
11095 && (operands_ok_ldrd_strd (operands[1], operands[2],
11096 operands[0], -4, false, false))"
11097 "strd%?\t%1, %2, [%0, #-4]"
11098 [(set_attr "type" "store2")
d952d547 11099 (set_attr "predicable" "yes")
11100 (set_attr "predicable_short_it" "no")])
1653cf17 11101
2a0c73f2 11102;; ARMv8 CRC32 instructions.
11103(define_insn "<crc_variant>"
11104 [(set (match_operand:SI 0 "s_register_operand" "=r")
11105 (unspec:SI [(match_operand:SI 1 "s_register_operand" "r")
11106 (match_operand:<crc_mode> 2 "s_register_operand" "r")]
11107 CRC))]
11108 "TARGET_CRC32"
11109 "<crc_variant>\\t%0, %1, %2"
11110 [(set_attr "type" "crc")
11111 (set_attr "conds" "unconditional")]
11112)
1653cf17 11113
353cf59a 11114;; Load the load/store double peephole optimizations.
11115(include "ldrdstrd.md")
11116
320ea44d 11117;; Load the load/store multiple patterns
11118(include "ldmstm.md")
426be8c5 11119
11120;; Patterns in ldmstm.md don't cover more than 4 registers. This pattern covers
11121;; large lists without explicit writeback generated for APCS_FRAME epilogue.
11122(define_insn "*load_multiple"
11123 [(match_parallel 0 "load_multiple_operation"
11124 [(set (match_operand:SI 2 "s_register_operand" "=rk")
11125 (mem:SI (match_operand:SI 1 "s_register_operand" "rk")))
11126 ])]
11127 "TARGET_32BIT"
11128 "*
11129 {
11130 arm_output_multireg_pop (operands, /*return_pc=*/false,
11131 /*cond=*/const_true_rtx,
11132 /*reverse=*/false,
11133 /*update=*/false);
11134 return \"\";
11135 }
11136 "
11137 [(set_attr "predicable" "yes")]
11138)
11139
d98a3884 11140;; Vector bits common to IWMMXT and Neon
11141(include "vec-common.md")
755eb2b4 11142;; Load the Intel Wireless Multimedia Extension patterns
11143(include "iwmmxt.md")
a2cd141b 11144;; Load the VFP co-processor patterns
11145(include "vfp.md")
bc360af8 11146;; Thumb-1 patterns
11147(include "thumb1.md")
25f905c2 11148;; Thumb-2 patterns
11149(include "thumb2.md")
d98a3884 11150;; Neon patterns
11151(include "neon.md")
e84fdf6e 11152;; Crypto patterns
11153(include "crypto.md")
06df6b17 11154;; Synchronization Primitives
11155(include "sync.md")
bbbe4599 11156;; Fixed-point patterns
11157(include "arm-fixed.md")