]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/config/arm/arm.md
* config/arm/arm.c (output_move_neon): Handle REG explicitly.
[thirdparty/gcc.git] / gcc / config / arm / arm.md
CommitLineData
129a2fe4 1;;- Machine description for ARM for GNU compiler
3aea1f79 2;; Copyright (C) 1991-2014 Free Software Foundation, Inc.
b11cae9e 3;; Contributed by Pieter `Tiggr' Schoenmakers (rcpieter@win.tue.nl)
f082f1c4 4;; and Martin Simmons (@harleqn.co.uk).
129a2fe4 5;; More major hacks by Richard Earnshaw (rearnsha@arm.com).
b11cae9e 6
acf6ed70 7;; This file is part of GCC.
b11cae9e 8
acf6ed70 9;; GCC is free software; you can redistribute it and/or modify it
10;; under the terms of the GNU General Public License as published
038d1e19 11;; by the Free Software Foundation; either version 3, or (at your
acf6ed70 12;; option) any later version.
b11cae9e 13
acf6ed70 14;; GCC is distributed in the hope that it will be useful, but WITHOUT
15;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
16;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
17;; License for more details.
b11cae9e 18
19;; You should have received a copy of the GNU General Public License
038d1e19 20;; along with GCC; see the file COPYING3. If not see
21;; <http://www.gnu.org/licenses/>.
b11cae9e 22
23;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
24
cb860649 25;; Beware of splitting Thumb1 patterns that output multiple
26;; assembly instructions, in particular instruction such as SBC and
27;; ADC which consume flags. For example, in the pattern thumb_subdi3
28;; below, the output SUB implicitly sets the flags (assembled to SUBS)
29;; and then the Carry flag is used by SBC to compute the correct
30;; result. If we split thumb_subdi3 pattern into two separate RTL
31;; insns (using define_insn_and_split), the scheduler might place
32;; other RTL insns between SUB and SBC, possibly modifying the Carry
33;; flag used by SBC. This might happen because most Thumb1 patterns
34;; for flag-setting instructions do not have explicit RTL for setting
35;; or clobbering the flags. Instead, they have the attribute "conds"
36;; with value "set" or "clob". However, this attribute is not used to
37;; identify dependencies and therefore the scheduler might reorder
38;; these instruction. Currenly, this problem cannot happen because
39;; there are no separate Thumb1 patterns for individual instruction
40;; that consume flags (except conditional execution, which is treated
41;; differently). In particular there is no Thumb1 armv6-m pattern for
42;; sbc or adc.
43
9c08d1fa 44\f
e1159bbe 45;;---------------------------------------------------------------------------
46;; Constants
47
bffbb863 48;; Register numbers -- All machine registers should be defined here
e1159bbe 49(define_constants
bffbb863 50 [(R0_REGNUM 0) ; First CORE register
51 (R1_REGNUM 1) ; Second CORE register
52 (IP_REGNUM 12) ; Scratch register
53 (SP_REGNUM 13) ; Stack pointer
54 (LR_REGNUM 14) ; Return address register
55 (PC_REGNUM 15) ; Program counter
56 (LAST_ARM_REGNUM 15) ;
57 (CC_REGNUM 100) ; Condition code pseudo register
58 (VFPCC_REGNUM 101) ; VFP Condition code pseudo register
e1159bbe 59 ]
60)
3c5afce6 61;; 3rd operand to select_dominance_cc_mode
62(define_constants
63 [(DOM_CC_X_AND_Y 0)
64 (DOM_CC_NX_OR_Y 1)
65 (DOM_CC_X_OR_Y 2)
66 ]
67)
2ff91fec 68;; conditional compare combination
69(define_constants
70 [(CMP_CMP 0)
71 (CMN_CMP 1)
72 (CMP_CMN 2)
73 (CMN_CMN 3)
74 (NUM_OF_COND_CMP 4)
75 ]
76)
e1159bbe 77
b11cae9e 78\f
e1159bbe 79;;---------------------------------------------------------------------------
9c08d1fa 80;; Attributes
81
a651f34d 82;; Processor type. This is created automatically from arm-cores.def.
83(include "arm-tune.md")
84
861033d5 85;; Instruction classification types
86(include "types.md")
87
215b30b3 88; IS_THUMB is set to 'yes' when we are generating Thumb code, and 'no' when
89; generating ARM code. This is used to control the length of some insn
90; patterns that share the same RTL in both ARM and Thumb code.
1c494086 91(define_attr "is_thumb" "no,yes" (const (symbol_ref "thumb_code")))
cffb2a26 92
ef51b8e1 93; IS_ARCH6 is set to 'yes' when we are generating code form ARMv6.
94(define_attr "is_arch6" "no,yes" (const (symbol_ref "arm_arch6")))
95
747b7458 96; IS_THUMB1 is set to 'yes' iff we are generating Thumb-1 code.
97(define_attr "is_thumb1" "no,yes" (const (symbol_ref "thumb1_code")))
98
c7a58118 99; We use this attribute to disable alternatives that can produce 32-bit
100; instructions inside an IT-block in Thumb2 state. ARMv8 deprecates IT blocks
101; that contain 32-bit instructions.
102(define_attr "enabled_for_depr_it" "no,yes" (const_string "yes"))
103
104; This attribute is used to disable a predicated alternative when we have
105; arm_restrict_it.
106(define_attr "predicable_short_it" "no,yes" (const_string "yes"))
107
331beb1a 108;; Operand number of an input operand that is shifted. Zero if the
109;; given instruction does not shift one of its input operands.
331beb1a 110(define_attr "shift" "" (const_int 0))
111
3d91c5d6 112; Floating Point Unit. If we only have floating point emulation, then there
113; is no point in scheduling the floating point insns. (Well, for best
114; performance we should try and group them together).
bffbb863 115(define_attr "fpu" "none,vfp"
c7f506fd 116 (const (symbol_ref "arm_fpu_attr")))
3d91c5d6 117
c7a58118 118(define_attr "predicated" "yes,no" (const_string "no"))
119
094e994f 120; LENGTH of an instruction (in bytes)
06df6b17 121(define_attr "length" ""
e1b93706 122 (const_int 4))
9c08d1fa 123
d5d4dc8d 124; The architecture which supports the instruction (or alternative).
125; This can be "a" for ARM, "t" for either of the Thumbs, "32" for
126; TARGET_32BIT, "t1" or "t2" to specify a specific Thumb mode. "v6"
127; for ARM or Thumb-2 with arm_arch6, and nov6 for ARM without
128; arm_arch6. This attribute is used to compute attribute "enabled",
129; use type "any" to enable an alternative in all cases.
21cc9773 130(define_attr "arch" "any,a,t,32,t1,t2,v6,nov6,neon_for_64bits,avoid_neon_for_64bits,iwmmxt,iwmmxt2,armv6_or_vfpv3"
d5d4dc8d 131 (const_string "any"))
132
133(define_attr "arch_enabled" "no,yes"
134 (cond [(eq_attr "arch" "any")
135 (const_string "yes")
136
137 (and (eq_attr "arch" "a")
0bf497f5 138 (match_test "TARGET_ARM"))
d5d4dc8d 139 (const_string "yes")
140
141 (and (eq_attr "arch" "t")
0bf497f5 142 (match_test "TARGET_THUMB"))
d5d4dc8d 143 (const_string "yes")
144
145 (and (eq_attr "arch" "t1")
0bf497f5 146 (match_test "TARGET_THUMB1"))
d5d4dc8d 147 (const_string "yes")
148
149 (and (eq_attr "arch" "t2")
0bf497f5 150 (match_test "TARGET_THUMB2"))
d5d4dc8d 151 (const_string "yes")
152
153 (and (eq_attr "arch" "32")
0bf497f5 154 (match_test "TARGET_32BIT"))
d5d4dc8d 155 (const_string "yes")
156
157 (and (eq_attr "arch" "v6")
0bf497f5 158 (match_test "TARGET_32BIT && arm_arch6"))
d5d4dc8d 159 (const_string "yes")
160
161 (and (eq_attr "arch" "nov6")
0bf497f5 162 (match_test "TARGET_32BIT && !arm_arch6"))
a651f34d 163 (const_string "yes")
164
b6779ddc 165 (and (eq_attr "arch" "avoid_neon_for_64bits")
166 (match_test "TARGET_NEON")
167 (not (match_test "TARGET_PREFER_NEON_64BITS")))
a651f34d 168 (const_string "yes")
169
b6779ddc 170 (and (eq_attr "arch" "neon_for_64bits")
171 (match_test "TARGET_NEON")
172 (match_test "TARGET_PREFER_NEON_64BITS"))
6b8f7c28 173 (const_string "yes")
174
175 (and (eq_attr "arch" "iwmmxt2")
176 (match_test "TARGET_REALLY_IWMMXT2"))
21cc9773 177 (const_string "yes")
178
179 (and (eq_attr "arch" "armv6_or_vfpv3")
180 (match_test "arm_arch6 || TARGET_VFP3"))
181 (const_string "yes")
182 ]
6b8f7c28 183
d5d4dc8d 184 (const_string "no")))
185
aa06c51c 186(define_attr "opt" "any,speed,size"
187 (const_string "any"))
188
189(define_attr "opt_enabled" "no,yes"
190 (cond [(eq_attr "opt" "any")
191 (const_string "yes")
192
193 (and (eq_attr "opt" "speed")
194 (match_test "optimize_function_for_speed_p (cfun)"))
195 (const_string "yes")
196
197 (and (eq_attr "opt" "size")
198 (match_test "optimize_function_for_size_p (cfun)"))
199 (const_string "yes")]
200 (const_string "no")))
201
861033d5 202(define_attr "use_literal_pool" "no,yes"
203 (cond [(and (eq_attr "type" "f_loads,f_loadd")
204 (match_test "CONSTANT_P (operands[1])"))
205 (const_string "yes")]
206 (const_string "no")))
207
d5d4dc8d 208; Enable all alternatives that are both arch_enabled and insn_enabled.
951a3f72 209; FIXME:: opt_enabled has been temporarily removed till the time we have
210; an attribute that allows the use of such alternatives.
211; This depends on caching of speed_p, size_p on a per
212; alternative basis. The problem is that the enabled attribute
213; cannot depend on any state that is not cached or is not constant
214; for a compilation unit. We probably need a generic "hot/cold"
215; alternative which if implemented can help with this. We disable this
216; until such a time as this is implemented and / or the improvements or
217; regressions with removing this attribute are double checked.
218; See ashldi3_neon and <shift>di3_neon in neon.md.
219
93b431d9 220 (define_attr "enabled" "no,yes"
0abea32c 221 (cond [(and (eq_attr "predicable_short_it" "no")
c7a58118 222 (and (eq_attr "predicated" "yes")
223 (match_test "arm_restrict_it")))
224 (const_string "no")
225
226 (and (eq_attr "enabled_for_depr_it" "no")
227 (match_test "arm_restrict_it"))
228 (const_string "no")
229
861033d5 230 (and (eq_attr "use_literal_pool" "yes")
231 (match_test "arm_disable_literal_pool"))
232 (const_string "no")
233
aa06c51c 234 (eq_attr "arch_enabled" "no")
aa06c51c 235 (const_string "no")]
236 (const_string "yes")))
d5d4dc8d 237
56d27660 238; POOL_RANGE is how far away from a constant pool entry that this insn
239; can be placed. If the distance is zero, then this insn will never
240; reference the pool.
42e1de19 241; Note that for Thumb constant pools the PC value is rounded down to the
242; nearest multiple of four. Therefore, THUMB2_POOL_RANGE (and POOL_RANGE for
243; Thumb insns) should be set to <max_range> - 2.
cffb2a26 244; NEG_POOL_RANGE is nonzero for insns that can reference a constant pool entry
8848d797 245; before its address. It is set to <max_range> - (8 + <data_size>).
cde1623a 246(define_attr "arm_pool_range" "" (const_int 0))
247(define_attr "thumb2_pool_range" "" (const_int 0))
248(define_attr "arm_neg_pool_range" "" (const_int 0))
249(define_attr "thumb2_neg_pool_range" "" (const_int 0))
250
251(define_attr "pool_range" ""
252 (cond [(eq_attr "is_thumb" "yes") (attr "thumb2_pool_range")]
253 (attr "arm_pool_range")))
254(define_attr "neg_pool_range" ""
255 (cond [(eq_attr "is_thumb" "yes") (attr "thumb2_neg_pool_range")]
256 (attr "arm_neg_pool_range")))
56d27660 257
215b30b3 258; An assembler sequence may clobber the condition codes without us knowing.
4d7a8451 259; If such an insn references the pool, then we have no way of knowing how,
260; so use the most conservative value for pool_range.
9c08d1fa 261(define_asm_attributes
4d7a8451 262 [(set_attr "conds" "clob")
263 (set_attr "length" "4")
264 (set_attr "pool_range" "250")])
9c08d1fa 265
9888ad6d 266; Load scheduling, set from the arm_ld_sched variable
4c834714 267; initialized by arm_option_override()
9888ad6d 268(define_attr "ldsched" "no,yes" (const (symbol_ref "arm_ld_sched")))
849170fd 269
f7fbdd4a 270; condition codes: this one is used by final_prescan_insn to speed up
271; conditionalizing instructions. It saves having to scan the rtl to see if
272; it uses or alters the condition codes.
215b30b3 273;
f7fbdd4a 274; USE means that the condition codes are used by the insn in the process of
215b30b3 275; outputting code, this means (at present) that we can't use the insn in
276; inlined branches
277;
f7fbdd4a 278; SET means that the purpose of the insn is to set the condition codes in a
215b30b3 279; well defined manner.
280;
f7fbdd4a 281; CLOB means that the condition codes are altered in an undefined manner, if
215b30b3 282; they are altered at all
283;
ad6d3e2a 284; UNCONDITIONAL means the instruction can not be conditionally executed and
285; that the instruction does not use or alter the condition codes.
c52acdd2 286;
ad6d3e2a 287; NOCOND means that the instruction does not use or alter the condition
288; codes but can be converted into a conditionally exectuted instruction.
f7fbdd4a 289
b0694be0 290(define_attr "conds" "use,set,clob,unconditional,nocond"
747b7458 291 (if_then_else
292 (ior (eq_attr "is_thumb1" "yes")
293 (eq_attr "type" "call"))
c1a66faf 294 (const_string "clob")
32093010 295 (if_then_else (eq_attr "is_neon_type" "no")
52432540 296 (const_string "nocond")
297 (const_string "unconditional"))))
f7fbdd4a 298
215b30b3 299; Predicable means that the insn can be conditionally executed based on
300; an automatically added predicate (additional patterns are generated by
301; gen...). We default to 'no' because no Thumb patterns match this rule
302; and not all ARM patterns do.
0d66636f 303(define_attr "predicable" "no,yes" (const_string "no"))
304
129a2fe4 305; Only model the write buffer for ARM6 and ARM7. Earlier processors don't
306; have one. Later ones, such as StrongARM, have write-back caches, so don't
8d232dc7 307; suffer blockages enough to warrant modelling this (and it can adversely
129a2fe4 308; affect the schedule).
74a71f7d 309(define_attr "model_wbuf" "no,yes" (const (symbol_ref "arm_tune_wbuf")))
129a2fe4 310
215b30b3 311; WRITE_CONFLICT implies that a read following an unrelated write is likely
312; to stall the processor. Used with model_wbuf above.
9c08d1fa 313(define_attr "write_conflict" "no,yes"
314 (if_then_else (eq_attr "type"
96854199 315 "block,call,load1")
9c08d1fa 316 (const_string "yes")
317 (const_string "no")))
318
215b30b3 319; Classify the insns into those that take one cycle and those that take more
320; than one on the main cpu execution unit.
f7fbdd4a 321(define_attr "core_cycles" "single,multi"
322 (if_then_else (eq_attr "type"
112eda6f 323 "adc_imm, adc_reg, adcs_imm, adcs_reg, adr, alu_ext, alu_imm, alu_sreg,\
324 alu_shift_imm, alu_shift_reg, alu_dsp_reg, alus_ext, alus_imm, alus_sreg,\
d82e788e 325 alus_shift_imm, alus_shift_reg, bfm, csel, rev, logic_imm, logic_reg,\
326 logic_shift_imm, logic_shift_reg, logics_imm, logics_reg,\
327 logics_shift_imm, logics_shift_reg, extend, shift_imm, float, fcsel,\
7cb6c048 328 wmmx_wor, wmmx_wxor, wmmx_wand, wmmx_wandn, wmmx_wmov, wmmx_tmcrr,\
329 wmmx_tmrrc, wmmx_wldr, wmmx_wstr, wmmx_tmcr, wmmx_tmrc, wmmx_wadd,\
330 wmmx_wsub, wmmx_wmul, wmmx_wmac, wmmx_wavg2, wmmx_tinsr, wmmx_textrm,\
331 wmmx_wshufh, wmmx_wcmpeq, wmmx_wcmpgt, wmmx_wmax, wmmx_wmin, wmmx_wpack,\
332 wmmx_wunpckih, wmmx_wunpckil, wmmx_wunpckeh, wmmx_wunpckel, wmmx_wror,\
333 wmmx_wsra, wmmx_wsrl, wmmx_wsll, wmmx_wmadd, wmmx_tmia, wmmx_tmiaph,\
334 wmmx_tmiaxy, wmmx_tbcst, wmmx_tmovmsk, wmmx_wacc, wmmx_waligni,\
335 wmmx_walignr, wmmx_tandc, wmmx_textrc, wmmx_torc, wmmx_torvsc, wmmx_wsad,\
336 wmmx_wabs, wmmx_wabsdiff, wmmx_waddsubhx, wmmx_wsubaddhx, wmmx_wavg4,\
337 wmmx_wmulw, wmmx_wqmulm, wmmx_wqmulwm, wmmx_waddbhus, wmmx_wqmiaxy,\
338 wmmx_wmiaxy, wmmx_wmiawxy, wmmx_wmerge")
f7fbdd4a 339 (const_string "single")
340 (const_string "multi")))
341
cffb2a26 342;; FAR_JUMP is "yes" if a BL instruction is used to generate a branch to a
215b30b3 343;; distant label. Only applicable to Thumb code.
cffb2a26 344(define_attr "far_jump" "yes,no" (const_string "no"))
345
d51f92df 346
25f905c2 347;; The number of machine instructions this pattern expands to.
348;; Used for Thumb-2 conditional execution.
349(define_attr "ce_count" "" (const_int 1))
350
4182b724 351;;---------------------------------------------------------------------------
352;; Unspecs
353
354(include "unspecs.md")
355
d51f92df 356;;---------------------------------------------------------------------------
fd781bb2 357;; Mode iterators
d51f92df 358
3de0dec6 359(include "iterators.md")
03770691 360
d51f92df 361;;---------------------------------------------------------------------------
362;; Predicates
363
9c9db025 364(include "predicates.md")
234f6557 365(include "constraints.md")
9c9db025 366
a2cd141b 367;;---------------------------------------------------------------------------
368;; Pipeline descriptions
215b30b3 369
e3879fd0 370(define_attr "tune_cortexr4" "yes,no"
371 (const (if_then_else
7d3cda8c 372 (eq_attr "tune" "cortexr4,cortexr4f,cortexr5")
e3879fd0 373 (const_string "yes")
374 (const_string "no"))))
375
a2cd141b 376;; True if the generic scheduling description should be used.
377
378(define_attr "generic_sched" "yes,no"
2546d93a 379 (const (if_then_else
25b10f06 380 (ior (eq_attr "tune" "fa526,fa626,fa606te,fa626te,fmp626,fa726te,arm926ejs,arm1020e,arm1026ejs,arm1136js,arm1136jfs,cortexa5,cortexa7,cortexa8,cortexa9,cortexa12,cortexa15,cortexa53,cortexm4,marvell_pj4")
2546d93a 381 (eq_attr "tune_cortexr4" "yes"))
4d5cb40d 382 (const_string "no")
383 (const_string "yes"))))
384
c0e1af52 385(define_attr "generic_vfp" "yes,no"
386 (const (if_then_else
387 (and (eq_attr "fpu" "vfp")
43e4f6e8 388 (eq_attr "tune" "!arm1020e,arm1022e,cortexa5,cortexa7,cortexa8,cortexa9,cortexa53,cortexm4,marvell_pj4")
e3879fd0 389 (eq_attr "tune_cortexr4" "no"))
c0e1af52 390 (const_string "yes")
391 (const_string "no"))))
392
6b8f7c28 393(include "marvell-f-iwmmxt.md")
a2cd141b 394(include "arm-generic.md")
395(include "arm926ejs.md")
c0e1af52 396(include "arm1020e.md")
a2cd141b 397(include "arm1026ejs.md")
398(include "arm1136jfs.md")
0e266d06 399(include "fa526.md")
400(include "fa606te.md")
401(include "fa626te.md")
402(include "fmp626.md")
403(include "fa726te.md")
3f1e069f 404(include "cortex-a5.md")
d6b7f019 405(include "cortex-a7.md")
bcaec148 406(include "cortex-a8.md")
036068af 407(include "cortex-a9.md")
65f2f758 408(include "cortex-a15.md")
da10bc87 409(include "cortex-a53.md")
934a1e72 410(include "cortex-r4.md")
e3879fd0 411(include "cortex-r4f.md")
2546d93a 412(include "cortex-m4.md")
413(include "cortex-m4-fpu.md")
55e3ada8 414(include "vfp11.md")
ea7d210b 415(include "marvell-pj4.md")
3586df96 416
9c08d1fa 417\f
215b30b3 418;;---------------------------------------------------------------------------
e1159bbe 419;; Insn patterns
420;;
a0f94409 421;; Addition insns.
215b30b3 422
9c08d1fa 423;; Note: For DImode insns, there is normally no reason why operands should
424;; not be in the same register, what we don't want is for something being
425;; written to partially overlap something that is an input.
426
cffb2a26 427(define_expand "adddi3"
428 [(parallel
215b30b3 429 [(set (match_operand:DI 0 "s_register_operand" "")
cffb2a26 430 (plus:DI (match_operand:DI 1 "s_register_operand" "")
10e5ccd5 431 (match_operand:DI 2 "arm_adddi_operand" "")))
bd5b4116 432 (clobber (reg:CC CC_REGNUM))])]
cffb2a26 433 "TARGET_EITHER"
434 "
25f905c2 435 if (TARGET_THUMB1)
cffb2a26 436 {
0438d37f 437 if (!REG_P (operands[1]))
bc5a93af 438 operands[1] = force_reg (DImode, operands[1]);
0438d37f 439 if (!REG_P (operands[2]))
bc5a93af 440 operands[2] = force_reg (DImode, operands[2]);
cffb2a26 441 }
442 "
443)
444
a0f94409 445(define_insn_and_split "*arm_adddi3"
10e5ccd5 446 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r,&r,&r,&r")
447 (plus:DI (match_operand:DI 1 "s_register_operand" "%0, 0, r, 0, r")
448 (match_operand:DI 2 "arm_adddi_operand" "r, 0, r, Dd, Dd")))
bd5b4116 449 (clobber (reg:CC CC_REGNUM))]
b805622c 450 "TARGET_32BIT && !TARGET_NEON"
33782ec7 451 "#"
94829feb 452 "TARGET_32BIT && reload_completed
453 && ! (TARGET_NEON && IS_VFP_REGNUM (REGNO (operands[0])))"
a0f94409 454 [(parallel [(set (reg:CC_C CC_REGNUM)
455 (compare:CC_C (plus:SI (match_dup 1) (match_dup 2))
456 (match_dup 1)))
457 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
080c0b9a 458 (set (match_dup 3) (plus:SI (plus:SI (match_dup 4) (match_dup 5))
459 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
a0f94409 460 "
461 {
462 operands[3] = gen_highpart (SImode, operands[0]);
463 operands[0] = gen_lowpart (SImode, operands[0]);
464 operands[4] = gen_highpart (SImode, operands[1]);
465 operands[1] = gen_lowpart (SImode, operands[1]);
10e5ccd5 466 operands[5] = gen_highpart_mode (SImode, DImode, operands[2]);
a0f94409 467 operands[2] = gen_lowpart (SImode, operands[2]);
468 }"
cffb2a26 469 [(set_attr "conds" "clob")
1b7da4ac 470 (set_attr "length" "8")
471 (set_attr "type" "multiple")]
cffb2a26 472)
9c08d1fa 473
a0f94409 474(define_insn_and_split "*adddi_sesidi_di"
9c08d1fa 475 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
476 (plus:DI (sign_extend:DI
97499065 477 (match_operand:SI 2 "s_register_operand" "r,r"))
e5fea38e 478 (match_operand:DI 1 "s_register_operand" "0,r")))
bd5b4116 479 (clobber (reg:CC CC_REGNUM))]
b805622c 480 "TARGET_32BIT"
33782ec7 481 "#"
25f905c2 482 "TARGET_32BIT && reload_completed"
a0f94409 483 [(parallel [(set (reg:CC_C CC_REGNUM)
484 (compare:CC_C (plus:SI (match_dup 1) (match_dup 2))
485 (match_dup 1)))
486 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
080c0b9a 487 (set (match_dup 3) (plus:SI (plus:SI (ashiftrt:SI (match_dup 2)
a0f94409 488 (const_int 31))
080c0b9a 489 (match_dup 4))
490 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
a0f94409 491 "
492 {
493 operands[3] = gen_highpart (SImode, operands[0]);
494 operands[0] = gen_lowpart (SImode, operands[0]);
495 operands[4] = gen_highpart (SImode, operands[1]);
496 operands[1] = gen_lowpart (SImode, operands[1]);
497 operands[2] = gen_lowpart (SImode, operands[2]);
498 }"
215b30b3 499 [(set_attr "conds" "clob")
1b7da4ac 500 (set_attr "length" "8")
501 (set_attr "type" "multiple")]
215b30b3 502)
9c08d1fa 503
a0f94409 504(define_insn_and_split "*adddi_zesidi_di"
9c08d1fa 505 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
506 (plus:DI (zero_extend:DI
97499065 507 (match_operand:SI 2 "s_register_operand" "r,r"))
e5fea38e 508 (match_operand:DI 1 "s_register_operand" "0,r")))
a0f94409 509 (clobber (reg:CC CC_REGNUM))]
b805622c 510 "TARGET_32BIT"
33782ec7 511 "#"
25f905c2 512 "TARGET_32BIT && reload_completed"
a0f94409 513 [(parallel [(set (reg:CC_C CC_REGNUM)
514 (compare:CC_C (plus:SI (match_dup 1) (match_dup 2))
515 (match_dup 1)))
516 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
080c0b9a 517 (set (match_dup 3) (plus:SI (plus:SI (match_dup 4) (const_int 0))
518 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
a0f94409 519 "
520 {
521 operands[3] = gen_highpart (SImode, operands[0]);
522 operands[0] = gen_lowpart (SImode, operands[0]);
523 operands[4] = gen_highpart (SImode, operands[1]);
524 operands[1] = gen_lowpart (SImode, operands[1]);
525 operands[2] = gen_lowpart (SImode, operands[2]);
526 }"
cffb2a26 527 [(set_attr "conds" "clob")
1b7da4ac 528 (set_attr "length" "8")
529 (set_attr "type" "multiple")]
cffb2a26 530)
b11cae9e 531
87b22bf7 532(define_expand "addsi3"
cffb2a26 533 [(set (match_operand:SI 0 "s_register_operand" "")
87b22bf7 534 (plus:SI (match_operand:SI 1 "s_register_operand" "")
535 (match_operand:SI 2 "reg_or_int_operand" "")))]
cffb2a26 536 "TARGET_EITHER"
87b22bf7 537 "
0438d37f 538 if (TARGET_32BIT && CONST_INT_P (operands[2]))
87b22bf7 539 {
96f57e36 540 arm_split_constant (PLUS, SImode, NULL_RTX,
541 INTVAL (operands[2]), operands[0], operands[1],
e1ba4a27 542 optimize && can_create_pseudo_p ());
87b22bf7 543 DONE;
544 }
cffb2a26 545 "
546)
87b22bf7 547
5bd751ff 548; If there is a scratch available, this will be faster than synthesizing the
a0f94409 549; addition.
550(define_peephole2
551 [(match_scratch:SI 3 "r")
372575c7 552 (set (match_operand:SI 0 "arm_general_register_operand" "")
553 (plus:SI (match_operand:SI 1 "arm_general_register_operand" "")
cffb2a26 554 (match_operand:SI 2 "const_int_operand" "")))]
25f905c2 555 "TARGET_32BIT &&
a0f94409 556 !(const_ok_for_arm (INTVAL (operands[2]))
557 || const_ok_for_arm (-INTVAL (operands[2])))
558 && const_ok_for_arm (~INTVAL (operands[2]))"
559 [(set (match_dup 3) (match_dup 2))
560 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 3)))]
561 ""
562)
87b22bf7 563
2f02c19f 564;; The r/r/k alternative is required when reloading the address
565;; (plus (reg rN) (reg sp)) into (reg rN). In this case reload will
566;; put the duplicated register first, and not try the commutative version.
a0f94409 567(define_insn_and_split "*arm_addsi3"
7c36fe71 568 [(set (match_operand:SI 0 "s_register_operand" "=rk,l,l ,l ,r ,k ,r,r ,k ,r ,k,k,r ,k ,r")
569 (plus:SI (match_operand:SI 1 "s_register_operand" "%0 ,l,0 ,l ,rk,k ,r,rk,k ,rk,k,r,rk,k ,rk")
570 (match_operand:SI 2 "reg_or_int_operand" "rk ,l,Py,Pd,rI,rI,k,Pj,Pj,L ,L,L,PJ,PJ,?n")))]
25f905c2 571 "TARGET_32BIT"
5565501b 572 "@
c24d855d 573 add%?\\t%0, %0, %2
5565501b 574 add%?\\t%0, %1, %2
a0b3420a 575 add%?\\t%0, %1, %2
7c36fe71 576 add%?\\t%0, %1, %2
577 add%?\\t%0, %1, %2
aaa37ad6 578 add%?\\t%0, %1, %2
2f02c19f 579 add%?\\t%0, %2, %1
d5cbae34 580 addw%?\\t%0, %1, %2
581 addw%?\\t%0, %1, %2
aaa37ad6 582 sub%?\\t%0, %1, #%n2
87b22bf7 583 sub%?\\t%0, %1, #%n2
d7757711 584 sub%?\\t%0, %1, #%n2
d5cbae34 585 subw%?\\t%0, %1, #%n2
586 subw%?\\t%0, %1, #%n2
87b22bf7 587 #"
a3ffc315 588 "TARGET_32BIT
0438d37f 589 && CONST_INT_P (operands[2])
d5cbae34 590 && !const_ok_for_op (INTVAL (operands[2]), PLUS)
a3ffc315 591 && (reload_completed || !arm_eliminable_register (operands[1]))"
a0f94409 592 [(clobber (const_int 0))]
593 "
96f57e36 594 arm_split_constant (PLUS, SImode, curr_insn,
595 INTVAL (operands[2]), operands[0],
a0f94409 596 operands[1], 0);
597 DONE;
598 "
7c36fe71 599 [(set_attr "length" "2,4,4,4,4,4,4,4,4,4,4,4,4,4,16")
d5cbae34 600 (set_attr "predicable" "yes")
7c36fe71 601 (set_attr "predicable_short_it" "yes,yes,yes,yes,no,no,no,no,no,no,no,no,no,no,no")
602 (set_attr "arch" "t2,t2,t2,t2,*,*,*,t2,t2,*,*,a,t2,t2,*")
65f68e55 603 (set (attr "type") (if_then_else (match_operand 2 "const_int_operand" "")
d82e788e 604 (const_string "alu_imm")
112eda6f 605 (const_string "alu_sreg")))
65f68e55 606 ]
cffb2a26 607)
608
90c2bcf0 609(define_insn "addsi3_compare0"
bd5b4116 610 [(set (reg:CC_NOOV CC_REGNUM)
5565501b 611 (compare:CC_NOOV
65f68e55 612 (plus:SI (match_operand:SI 1 "s_register_operand" "r, r,r")
613 (match_operand:SI 2 "arm_add_operand" "I,L,r"))
5565501b 614 (const_int 0)))
65f68e55 615 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9c08d1fa 616 (plus:SI (match_dup 1) (match_dup 2)))]
ec792a7b 617 "TARGET_ARM"
5565501b 618 "@
25f905c2 619 add%.\\t%0, %1, %2
65f68e55 620 sub%.\\t%0, %1, #%n2
621 add%.\\t%0, %1, %2"
622 [(set_attr "conds" "set")
112eda6f 623 (set_attr "type" "alus_imm,alus_imm,alus_sreg")]
cffb2a26 624)
9c08d1fa 625
aea4c774 626(define_insn "*addsi3_compare0_scratch"
bd5b4116 627 [(set (reg:CC_NOOV CC_REGNUM)
aea4c774 628 (compare:CC_NOOV
65f68e55 629 (plus:SI (match_operand:SI 0 "s_register_operand" "r, r, r")
630 (match_operand:SI 1 "arm_add_operand" "I,L, r"))
aea4c774 631 (const_int 0)))]
ec792a7b 632 "TARGET_ARM"
cffb2a26 633 "@
634 cmn%?\\t%0, %1
65f68e55 635 cmp%?\\t%0, #%n1
636 cmn%?\\t%0, %1"
596e5e8f 637 [(set_attr "conds" "set")
65f68e55 638 (set_attr "predicable" "yes")
112eda6f 639 (set_attr "type" "alus_imm,alus_imm,alus_sreg")]
0d66636f 640)
cffb2a26 641
aed179ae 642(define_insn "*compare_negsi_si"
643 [(set (reg:CC_Z CC_REGNUM)
644 (compare:CC_Z
7c36fe71 645 (neg:SI (match_operand:SI 0 "s_register_operand" "l,r"))
646 (match_operand:SI 1 "s_register_operand" "l,r")))]
25f905c2 647 "TARGET_32BIT"
aed179ae 648 "cmn%?\\t%1, %0"
596e5e8f 649 [(set_attr "conds" "set")
7c36fe71 650 (set_attr "predicable" "yes")
651 (set_attr "arch" "t2,*")
652 (set_attr "length" "2,4")
1b7da4ac 653 (set_attr "predicable_short_it" "yes,no")
112eda6f 654 (set_attr "type" "alus_sreg")]
0d66636f 655)
aea4c774 656
203c488f 657;; This is the canonicalization of addsi3_compare0_for_combiner when the
658;; addend is a constant.
190efb17 659(define_insn "cmpsi2_addneg"
203c488f 660 [(set (reg:CC CC_REGNUM)
661 (compare:CC
662 (match_operand:SI 1 "s_register_operand" "r,r")
2a977b78 663 (match_operand:SI 2 "arm_addimm_operand" "L,I")))
203c488f 664 (set (match_operand:SI 0 "s_register_operand" "=r,r")
665 (plus:SI (match_dup 1)
2a977b78 666 (match_operand:SI 3 "arm_addimm_operand" "I,L")))]
25f905c2 667 "TARGET_32BIT && INTVAL (operands[2]) == -INTVAL (operands[3])"
203c488f 668 "@
2a977b78 669 add%.\\t%0, %1, %3
670 sub%.\\t%0, %1, #%n3"
1b7da4ac 671 [(set_attr "conds" "set")
112eda6f 672 (set_attr "type" "alus_sreg")]
203c488f 673)
674
675;; Convert the sequence
676;; sub rd, rn, #1
677;; cmn rd, #1 (equivalent to cmp rd, #-1)
678;; bne dest
679;; into
680;; subs rd, rn, #1
681;; bcs dest ((unsigned)rn >= 1)
682;; similarly for the beq variant using bcc.
683;; This is a common looping idiom (while (n--))
684(define_peephole2
372575c7 685 [(set (match_operand:SI 0 "arm_general_register_operand" "")
686 (plus:SI (match_operand:SI 1 "arm_general_register_operand" "")
203c488f 687 (const_int -1)))
688 (set (match_operand 2 "cc_register" "")
689 (compare (match_dup 0) (const_int -1)))
690 (set (pc)
691 (if_then_else (match_operator 3 "equality_operator"
692 [(match_dup 2) (const_int 0)])
693 (match_operand 4 "" "")
694 (match_operand 5 "" "")))]
25f905c2 695 "TARGET_32BIT && peep2_reg_dead_p (3, operands[2])"
203c488f 696 [(parallel[
697 (set (match_dup 2)
698 (compare:CC
699 (match_dup 1) (const_int 1)))
700 (set (match_dup 0) (plus:SI (match_dup 1) (const_int -1)))])
701 (set (pc)
702 (if_then_else (match_op_dup 3 [(match_dup 2) (const_int 0)])
703 (match_dup 4)
704 (match_dup 5)))]
705 "operands[2] = gen_rtx_REG (CCmode, CC_REGNUM);
706 operands[3] = gen_rtx_fmt_ee ((GET_CODE (operands[3]) == NE
707 ? GEU : LTU),
708 VOIDmode,
709 operands[2], const0_rtx);"
710)
711
ebcc79bc 712;; The next four insns work because they compare the result with one of
713;; the operands, and we know that the use of the condition code is
714;; either GEU or LTU, so we can use the carry flag from the addition
715;; instead of doing the compare a second time.
716(define_insn "*addsi3_compare_op1"
bd5b4116 717 [(set (reg:CC_C CC_REGNUM)
ebcc79bc 718 (compare:CC_C
65f68e55 719 (plus:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
720 (match_operand:SI 2 "arm_add_operand" "I,L,r"))
ebcc79bc 721 (match_dup 1)))
65f68e55 722 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
ebcc79bc 723 (plus:SI (match_dup 1) (match_dup 2)))]
25f905c2 724 "TARGET_32BIT"
ebcc79bc 725 "@
25f905c2 726 add%.\\t%0, %1, %2
65f68e55 727 sub%.\\t%0, %1, #%n2
728 add%.\\t%0, %1, %2"
729 [(set_attr "conds" "set")
112eda6f 730 (set_attr "type" "alus_imm,alus_imm,alus_sreg")]
0d66636f 731)
ebcc79bc 732
733(define_insn "*addsi3_compare_op2"
bd5b4116 734 [(set (reg:CC_C CC_REGNUM)
ebcc79bc 735 (compare:CC_C
65f68e55 736 (plus:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
737 (match_operand:SI 2 "arm_add_operand" "I,L,r"))
ebcc79bc 738 (match_dup 2)))
65f68e55 739 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9c08d1fa 740 (plus:SI (match_dup 1) (match_dup 2)))]
25f905c2 741 "TARGET_32BIT"
5565501b 742 "@
65f68e55 743 add%.\\t%0, %1, %2
25f905c2 744 add%.\\t%0, %1, %2
745 sub%.\\t%0, %1, #%n2"
65f68e55 746 [(set_attr "conds" "set")
112eda6f 747 (set_attr "type" "alus_imm,alus_imm,alus_sreg")]
0d66636f 748)
9c08d1fa 749
ebcc79bc 750(define_insn "*compare_addsi2_op0"
bd5b4116 751 [(set (reg:CC_C CC_REGNUM)
7c36fe71 752 (compare:CC_C
753 (plus:SI (match_operand:SI 0 "s_register_operand" "l,l,r,r,r")
754 (match_operand:SI 1 "arm_add_operand" "Pv,l,I,L,r"))
755 (match_dup 0)))]
25f905c2 756 "TARGET_32BIT"
ebcc79bc 757 "@
7c36fe71 758 cmp%?\\t%0, #%n1
759 cmn%?\\t%0, %1
ebcc79bc 760 cmn%?\\t%0, %1
65f68e55 761 cmp%?\\t%0, #%n1
762 cmn%?\\t%0, %1"
596e5e8f 763 [(set_attr "conds" "set")
65f68e55 764 (set_attr "predicable" "yes")
7c36fe71 765 (set_attr "arch" "t2,t2,*,*,*")
766 (set_attr "predicable_short_it" "yes,yes,no,no,no")
767 (set_attr "length" "2,2,4,4,4")
112eda6f 768 (set_attr "type" "alus_imm,alus_sreg,alus_imm,alus_imm,alus_sreg")]
0d66636f 769)
ebcc79bc 770
771(define_insn "*compare_addsi2_op1"
bd5b4116 772 [(set (reg:CC_C CC_REGNUM)
7c36fe71 773 (compare:CC_C
774 (plus:SI (match_operand:SI 0 "s_register_operand" "l,l,r,r,r")
775 (match_operand:SI 1 "arm_add_operand" "Pv,l,I,L,r"))
776 (match_dup 1)))]
25f905c2 777 "TARGET_32BIT"
ebcc79bc 778 "@
7c36fe71 779 cmp%?\\t%0, #%n1
780 cmn%?\\t%0, %1
ebcc79bc 781 cmn%?\\t%0, %1
65f68e55 782 cmp%?\\t%0, #%n1
783 cmn%?\\t%0, %1"
596e5e8f 784 [(set_attr "conds" "set")
65f68e55 785 (set_attr "predicable" "yes")
7c36fe71 786 (set_attr "arch" "t2,t2,*,*,*")
787 (set_attr "predicable_short_it" "yes,yes,no,no,no")
788 (set_attr "length" "2,2,4,4,4")
112eda6f 789 (set_attr "type" "alus_imm,alus_sreg,alus_imm,alus_imm,alus_sreg")]
7c36fe71 790 )
ebcc79bc 791
080c0b9a 792(define_insn "*addsi3_carryin_<optab>"
7c36fe71 793 [(set (match_operand:SI 0 "s_register_operand" "=l,r,r")
794 (plus:SI (plus:SI (match_operand:SI 1 "s_register_operand" "%l,r,r")
795 (match_operand:SI 2 "arm_not_operand" "0,rI,K"))
796 (LTUGEU:SI (reg:<cnb> CC_REGNUM) (const_int 0))))]
25f905c2 797 "TARGET_32BIT"
10e5ccd5 798 "@
a0b3420a 799 adc%?\\t%0, %1, %2
10e5ccd5 800 adc%?\\t%0, %1, %2
801 sbc%?\\t%0, %1, #%B2"
a7de272d 802 [(set_attr "conds" "use")
7c36fe71 803 (set_attr "predicable" "yes")
804 (set_attr "arch" "t2,*,*")
805 (set_attr "length" "4")
1b7da4ac 806 (set_attr "predicable_short_it" "yes,no,no")
807 (set_attr "type" "adc_reg,adc_reg,adc_imm")]
cffb2a26 808)
ebcc79bc 809
080c0b9a 810(define_insn "*addsi3_carryin_alt2_<optab>"
7c36fe71 811 [(set (match_operand:SI 0 "s_register_operand" "=l,r,r")
812 (plus:SI (plus:SI (LTUGEU:SI (reg:<cnb> CC_REGNUM) (const_int 0))
813 (match_operand:SI 1 "s_register_operand" "%l,r,r"))
814 (match_operand:SI 2 "arm_rhs_operand" "l,rI,K")))]
25f905c2 815 "TARGET_32BIT"
10e5ccd5 816 "@
a0b3420a 817 adc%?\\t%0, %1, %2
10e5ccd5 818 adc%?\\t%0, %1, %2
819 sbc%?\\t%0, %1, #%B2"
a7de272d 820 [(set_attr "conds" "use")
7c36fe71 821 (set_attr "predicable" "yes")
822 (set_attr "arch" "t2,*,*")
823 (set_attr "length" "4")
1b7da4ac 824 (set_attr "predicable_short_it" "yes,no,no")
825 (set_attr "type" "adc_reg,adc_reg,adc_imm")]
0d66636f 826)
ebcc79bc 827
080c0b9a 828(define_insn "*addsi3_carryin_shift_<optab>"
ebcc79bc 829 [(set (match_operand:SI 0 "s_register_operand" "=r")
080c0b9a 830 (plus:SI (plus:SI
831 (match_operator:SI 2 "shift_operator"
832 [(match_operand:SI 3 "s_register_operand" "r")
833 (match_operand:SI 4 "reg_or_int_operand" "rM")])
834 (match_operand:SI 1 "s_register_operand" "r"))
835 (LTUGEU:SI (reg:<cnb> CC_REGNUM) (const_int 0))))]
25f905c2 836 "TARGET_32BIT"
080c0b9a 837 "adc%?\\t%0, %1, %3%S2"
838 [(set_attr "conds" "use")
a7de272d 839 (set_attr "predicable" "yes")
7c36fe71 840 (set_attr "predicable_short_it" "no")
080c0b9a 841 (set (attr "type") (if_then_else (match_operand 4 "const_int_operand" "")
d82e788e 842 (const_string "alu_shift_imm")
843 (const_string "alu_shift_reg")))]
cffb2a26 844)
ebcc79bc 845
922b6913 846(define_insn "*addsi3_carryin_clobercc_<optab>"
847 [(set (match_operand:SI 0 "s_register_operand" "=r")
848 (plus:SI (plus:SI (match_operand:SI 1 "s_register_operand" "%r")
849 (match_operand:SI 2 "arm_rhs_operand" "rI"))
850 (LTUGEU:SI (reg:<cnb> CC_REGNUM) (const_int 0))))
851 (clobber (reg:CC CC_REGNUM))]
852 "TARGET_32BIT"
853 "adc%.\\t%0, %1, %2"
1b7da4ac 854 [(set_attr "conds" "set")
855 (set_attr "type" "adcs_reg")]
922b6913 856)
857
9154bd82 858(define_insn "*subsi3_carryin"
859 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
860 (minus:SI (minus:SI (match_operand:SI 1 "reg_or_int_operand" "r,I")
861 (match_operand:SI 2 "s_register_operand" "r,r"))
862 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
863 "TARGET_32BIT"
864 "@
865 sbc%?\\t%0, %1, %2
866 rsc%?\\t%0, %2, %1"
867 [(set_attr "conds" "use")
868 (set_attr "arch" "*,a")
7c36fe71 869 (set_attr "predicable" "yes")
1b7da4ac 870 (set_attr "predicable_short_it" "no")
871 (set_attr "type" "adc_reg,adc_imm")]
9154bd82 872)
873
874(define_insn "*subsi3_carryin_const"
875 [(set (match_operand:SI 0 "s_register_operand" "=r")
876 (minus:SI (plus:SI (match_operand:SI 1 "reg_or_int_operand" "r")
877 (match_operand:SI 2 "arm_not_operand" "K"))
878 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
879 "TARGET_32BIT"
880 "sbc\\t%0, %1, #%B2"
1b7da4ac 881 [(set_attr "conds" "use")
882 (set_attr "type" "adc_imm")]
9154bd82 883)
884
885(define_insn "*subsi3_carryin_compare"
886 [(set (reg:CC CC_REGNUM)
887 (compare:CC (match_operand:SI 1 "s_register_operand" "r")
888 (match_operand:SI 2 "s_register_operand" "r")))
889 (set (match_operand:SI 0 "s_register_operand" "=r")
890 (minus:SI (minus:SI (match_dup 1)
891 (match_dup 2))
892 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
893 "TARGET_32BIT"
894 "sbcs\\t%0, %1, %2"
1b7da4ac 895 [(set_attr "conds" "set")
896 (set_attr "type" "adcs_reg")]
9154bd82 897)
898
899(define_insn "*subsi3_carryin_compare_const"
900 [(set (reg:CC CC_REGNUM)
901 (compare:CC (match_operand:SI 1 "reg_or_int_operand" "r")
902 (match_operand:SI 2 "arm_not_operand" "K")))
903 (set (match_operand:SI 0 "s_register_operand" "=r")
904 (minus:SI (plus:SI (match_dup 1)
905 (match_dup 2))
906 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
907 "TARGET_32BIT"
908 "sbcs\\t%0, %1, #%B2"
1b7da4ac 909 [(set_attr "conds" "set")
910 (set_attr "type" "adcs_imm")]
9154bd82 911)
912
913(define_insn "*subsi3_carryin_shift"
914 [(set (match_operand:SI 0 "s_register_operand" "=r")
915 (minus:SI (minus:SI
916 (match_operand:SI 1 "s_register_operand" "r")
917 (match_operator:SI 2 "shift_operator"
918 [(match_operand:SI 3 "s_register_operand" "r")
919 (match_operand:SI 4 "reg_or_int_operand" "rM")]))
920 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
921 "TARGET_32BIT"
922 "sbc%?\\t%0, %1, %3%S2"
923 [(set_attr "conds" "use")
924 (set_attr "predicable" "yes")
925 (set (attr "type") (if_then_else (match_operand 4 "const_int_operand" "")
d82e788e 926 (const_string "alu_shift_imm")
927 (const_string "alu_shift_reg")))]
9154bd82 928)
929
930(define_insn "*rsbsi3_carryin_shift"
931 [(set (match_operand:SI 0 "s_register_operand" "=r")
932 (minus:SI (minus:SI
933 (match_operator:SI 2 "shift_operator"
934 [(match_operand:SI 3 "s_register_operand" "r")
935 (match_operand:SI 4 "reg_or_int_operand" "rM")])
936 (match_operand:SI 1 "s_register_operand" "r"))
937 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
938 "TARGET_ARM"
939 "rsc%?\\t%0, %1, %3%S2"
940 [(set_attr "conds" "use")
941 (set_attr "predicable" "yes")
942 (set (attr "type") (if_then_else (match_operand 4 "const_int_operand" "")
d82e788e 943 (const_string "alu_shift_imm")
944 (const_string "alu_shift_reg")))]
9154bd82 945)
946
d795fb69 947; transform ((x << y) - 1) to ~(~(x-1) << y) Where X is a constant.
948(define_split
949 [(set (match_operand:SI 0 "s_register_operand" "")
950 (plus:SI (ashift:SI (match_operand:SI 1 "const_int_operand" "")
951 (match_operand:SI 2 "s_register_operand" ""))
952 (const_int -1)))
953 (clobber (match_operand:SI 3 "s_register_operand" ""))]
25f905c2 954 "TARGET_32BIT"
d795fb69 955 [(set (match_dup 3) (match_dup 1))
956 (set (match_dup 0) (not:SI (ashift:SI (match_dup 3) (match_dup 2))))]
957 "
958 operands[1] = GEN_INT (~(INTVAL (operands[1]) - 1));
959")
960
604f3a0a 961(define_expand "addsf3"
962 [(set (match_operand:SF 0 "s_register_operand" "")
963 (plus:SF (match_operand:SF 1 "s_register_operand" "")
d86c91f6 964 (match_operand:SF 2 "s_register_operand" "")))]
25f905c2 965 "TARGET_32BIT && TARGET_HARD_FLOAT"
604f3a0a 966 "
604f3a0a 967")
968
604f3a0a 969(define_expand "adddf3"
970 [(set (match_operand:DF 0 "s_register_operand" "")
971 (plus:DF (match_operand:DF 1 "s_register_operand" "")
d86c91f6 972 (match_operand:DF 2 "s_register_operand" "")))]
a50d7267 973 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
604f3a0a 974 "
604f3a0a 975")
976
cffb2a26 977(define_expand "subdi3"
978 [(parallel
979 [(set (match_operand:DI 0 "s_register_operand" "")
980 (minus:DI (match_operand:DI 1 "s_register_operand" "")
981 (match_operand:DI 2 "s_register_operand" "")))
bd5b4116 982 (clobber (reg:CC CC_REGNUM))])]
cffb2a26 983 "TARGET_EITHER"
984 "
25f905c2 985 if (TARGET_THUMB1)
cffb2a26 986 {
0438d37f 987 if (!REG_P (operands[1]))
5aa8c5f0 988 operands[1] = force_reg (DImode, operands[1]);
0438d37f 989 if (!REG_P (operands[2]))
5aa8c5f0 990 operands[2] = force_reg (DImode, operands[2]);
cffb2a26 991 }
992 "
993)
994
2f9b23e3 995(define_insn_and_split "*arm_subdi3"
cffb2a26 996 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r,&r")
9c08d1fa 997 (minus:DI (match_operand:DI 1 "s_register_operand" "0,r,0")
998 (match_operand:DI 2 "s_register_operand" "r,0,0")))
bd5b4116 999 (clobber (reg:CC CC_REGNUM))]
94829feb 1000 "TARGET_32BIT && !TARGET_NEON"
2f9b23e3 1001 "#" ; "subs\\t%Q0, %Q1, %Q2\;sbc\\t%R0, %R1, %R2"
1002 "&& reload_completed"
1003 [(parallel [(set (reg:CC CC_REGNUM)
1004 (compare:CC (match_dup 1) (match_dup 2)))
1005 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
1006 (set (match_dup 3) (minus:SI (minus:SI (match_dup 4) (match_dup 5))
1007 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1008 {
1009 operands[3] = gen_highpart (SImode, operands[0]);
1010 operands[0] = gen_lowpart (SImode, operands[0]);
1011 operands[4] = gen_highpart (SImode, operands[1]);
1012 operands[1] = gen_lowpart (SImode, operands[1]);
1013 operands[5] = gen_highpart (SImode, operands[2]);
1014 operands[2] = gen_lowpart (SImode, operands[2]);
1015 }
cffb2a26 1016 [(set_attr "conds" "clob")
1b7da4ac 1017 (set_attr "length" "8")
1018 (set_attr "type" "multiple")]
cffb2a26 1019)
1020
2f9b23e3 1021(define_insn_and_split "*subdi_di_zesidi"
cffb2a26 1022 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
e5fea38e 1023 (minus:DI (match_operand:DI 1 "s_register_operand" "0,r")
9c08d1fa 1024 (zero_extend:DI
cffb2a26 1025 (match_operand:SI 2 "s_register_operand" "r,r"))))
bd5b4116 1026 (clobber (reg:CC CC_REGNUM))]
25f905c2 1027 "TARGET_32BIT"
2f9b23e3 1028 "#" ; "subs\\t%Q0, %Q1, %2\;sbc\\t%R0, %R1, #0"
1029 "&& reload_completed"
1030 [(parallel [(set (reg:CC CC_REGNUM)
1031 (compare:CC (match_dup 1) (match_dup 2)))
1032 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
1033 (set (match_dup 3) (minus:SI (plus:SI (match_dup 4) (match_dup 5))
1034 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1035 {
1036 operands[3] = gen_highpart (SImode, operands[0]);
1037 operands[0] = gen_lowpart (SImode, operands[0]);
1038 operands[4] = gen_highpart (SImode, operands[1]);
1039 operands[1] = gen_lowpart (SImode, operands[1]);
1040 operands[5] = GEN_INT (~0);
1041 }
cffb2a26 1042 [(set_attr "conds" "clob")
1b7da4ac 1043 (set_attr "length" "8")
1044 (set_attr "type" "multiple")]
cffb2a26 1045)
9c08d1fa 1046
2f9b23e3 1047(define_insn_and_split "*subdi_di_sesidi"
cffb2a26 1048 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
e5fea38e 1049 (minus:DI (match_operand:DI 1 "s_register_operand" "0,r")
9c08d1fa 1050 (sign_extend:DI
cffb2a26 1051 (match_operand:SI 2 "s_register_operand" "r,r"))))
bd5b4116 1052 (clobber (reg:CC CC_REGNUM))]
25f905c2 1053 "TARGET_32BIT"
2f9b23e3 1054 "#" ; "subs\\t%Q0, %Q1, %2\;sbc\\t%R0, %R1, %2, asr #31"
1055 "&& reload_completed"
1056 [(parallel [(set (reg:CC CC_REGNUM)
1057 (compare:CC (match_dup 1) (match_dup 2)))
1058 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
1059 (set (match_dup 3) (minus:SI (minus:SI (match_dup 4)
1060 (ashiftrt:SI (match_dup 2)
1061 (const_int 31)))
1062 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1063 {
1064 operands[3] = gen_highpart (SImode, operands[0]);
1065 operands[0] = gen_lowpart (SImode, operands[0]);
1066 operands[4] = gen_highpart (SImode, operands[1]);
1067 operands[1] = gen_lowpart (SImode, operands[1]);
1068 }
cffb2a26 1069 [(set_attr "conds" "clob")
1b7da4ac 1070 (set_attr "length" "8")
1071 (set_attr "type" "multiple")]
cffb2a26 1072)
9c08d1fa 1073
2f9b23e3 1074(define_insn_and_split "*subdi_zesidi_di"
cffb2a26 1075 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
9c08d1fa 1076 (minus:DI (zero_extend:DI
cffb2a26 1077 (match_operand:SI 2 "s_register_operand" "r,r"))
e5fea38e 1078 (match_operand:DI 1 "s_register_operand" "0,r")))
bd5b4116 1079 (clobber (reg:CC CC_REGNUM))]
cffb2a26 1080 "TARGET_ARM"
2f9b23e3 1081 "#" ; "rsbs\\t%Q0, %Q1, %2\;rsc\\t%R0, %R1, #0"
1082 ; is equivalent to:
1083 ; "subs\\t%Q0, %2, %Q1\;rsc\\t%R0, %R1, #0"
1084 "&& reload_completed"
1085 [(parallel [(set (reg:CC CC_REGNUM)
1086 (compare:CC (match_dup 2) (match_dup 1)))
1087 (set (match_dup 0) (minus:SI (match_dup 2) (match_dup 1)))])
1088 (set (match_dup 3) (minus:SI (minus:SI (const_int 0) (match_dup 4))
1089 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1090 {
1091 operands[3] = gen_highpart (SImode, operands[0]);
1092 operands[0] = gen_lowpart (SImode, operands[0]);
1093 operands[4] = gen_highpart (SImode, operands[1]);
1094 operands[1] = gen_lowpart (SImode, operands[1]);
1095 }
cffb2a26 1096 [(set_attr "conds" "clob")
1b7da4ac 1097 (set_attr "length" "8")
1098 (set_attr "type" "multiple")]
cffb2a26 1099)
9c08d1fa 1100
2f9b23e3 1101(define_insn_and_split "*subdi_sesidi_di"
cffb2a26 1102 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
9c08d1fa 1103 (minus:DI (sign_extend:DI
cffb2a26 1104 (match_operand:SI 2 "s_register_operand" "r,r"))
e5fea38e 1105 (match_operand:DI 1 "s_register_operand" "0,r")))
bd5b4116 1106 (clobber (reg:CC CC_REGNUM))]
cffb2a26 1107 "TARGET_ARM"
2f9b23e3 1108 "#" ; "rsbs\\t%Q0, %Q1, %2\;rsc\\t%R0, %R1, %2, asr #31"
1109 ; is equivalent to:
1110 ; "subs\\t%Q0, %2, %Q1\;rsc\\t%R0, %R1, %2, asr #31"
1111 "&& reload_completed"
1112 [(parallel [(set (reg:CC CC_REGNUM)
1113 (compare:CC (match_dup 2) (match_dup 1)))
1114 (set (match_dup 0) (minus:SI (match_dup 2) (match_dup 1)))])
1115 (set (match_dup 3) (minus:SI (minus:SI
1116 (ashiftrt:SI (match_dup 2)
1117 (const_int 31))
1118 (match_dup 4))
1119 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1120 {
1121 operands[3] = gen_highpart (SImode, operands[0]);
1122 operands[0] = gen_lowpart (SImode, operands[0]);
1123 operands[4] = gen_highpart (SImode, operands[1]);
1124 operands[1] = gen_lowpart (SImode, operands[1]);
1125 }
cffb2a26 1126 [(set_attr "conds" "clob")
1b7da4ac 1127 (set_attr "length" "8")
1128 (set_attr "type" "multiple")]
cffb2a26 1129)
9c08d1fa 1130
2f9b23e3 1131(define_insn_and_split "*subdi_zesidi_zesidi"
cffb2a26 1132 [(set (match_operand:DI 0 "s_register_operand" "=r")
9c08d1fa 1133 (minus:DI (zero_extend:DI
cffb2a26 1134 (match_operand:SI 1 "s_register_operand" "r"))
9c08d1fa 1135 (zero_extend:DI
cffb2a26 1136 (match_operand:SI 2 "s_register_operand" "r"))))
bd5b4116 1137 (clobber (reg:CC CC_REGNUM))]
25f905c2 1138 "TARGET_32BIT"
2f9b23e3 1139 "#" ; "subs\\t%Q0, %1, %2\;sbc\\t%R0, %1, %1"
1140 "&& reload_completed"
1141 [(parallel [(set (reg:CC CC_REGNUM)
1142 (compare:CC (match_dup 1) (match_dup 2)))
1143 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
1144 (set (match_dup 3) (minus:SI (minus:SI (match_dup 1) (match_dup 1))
1145 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1146 {
1147 operands[3] = gen_highpart (SImode, operands[0]);
1148 operands[0] = gen_lowpart (SImode, operands[0]);
1149 }
cffb2a26 1150 [(set_attr "conds" "clob")
1b7da4ac 1151 (set_attr "length" "8")
1152 (set_attr "type" "multiple")]
cffb2a26 1153)
b11cae9e 1154
87b22bf7 1155(define_expand "subsi3"
cffb2a26 1156 [(set (match_operand:SI 0 "s_register_operand" "")
87b22bf7 1157 (minus:SI (match_operand:SI 1 "reg_or_int_operand" "")
1158 (match_operand:SI 2 "s_register_operand" "")))]
cffb2a26 1159 "TARGET_EITHER"
87b22bf7 1160 "
0438d37f 1161 if (CONST_INT_P (operands[1]))
87b22bf7 1162 {
25f905c2 1163 if (TARGET_32BIT)
cffb2a26 1164 {
96f57e36 1165 arm_split_constant (MINUS, SImode, NULL_RTX,
1166 INTVAL (operands[1]), operands[0],
e1ba4a27 1167 operands[2], optimize && can_create_pseudo_p ());
cffb2a26 1168 DONE;
1169 }
25f905c2 1170 else /* TARGET_THUMB1 */
cffb2a26 1171 operands[1] = force_reg (SImode, operands[1]);
87b22bf7 1172 }
cffb2a26 1173 "
1174)
87b22bf7 1175
25f905c2 1176; ??? Check Thumb-2 split length
a0f94409 1177(define_insn_and_split "*arm_subsi3_insn"
7c36fe71 1178 [(set (match_operand:SI 0 "s_register_operand" "=l,l ,l ,l ,r ,r,r,rk,r")
1179 (minus:SI (match_operand:SI 1 "reg_or_int_operand" "l ,0 ,l ,Pz,rI,r,r,k ,?n")
1180 (match_operand:SI 2 "reg_or_int_operand" "l ,Py,Pd,l ,r ,I,r,r ,r")))]
25f905c2 1181 "TARGET_32BIT"
e2348bcb 1182 "@
7c36fe71 1183 sub%?\\t%0, %1, %2
1184 sub%?\\t%0, %2
1185 sub%?\\t%0, %1, %2
1186 rsb%?\\t%0, %2, %1
87b22bf7 1187 rsb%?\\t%0, %2, %1
aaa37ad6 1188 sub%?\\t%0, %1, %2
080c0b9a 1189 sub%?\\t%0, %1, %2
65f68e55 1190 sub%?\\t%0, %1, %2
87b22bf7 1191 #"
0438d37f 1192 "&& (CONST_INT_P (operands[1])
91a5e339 1193 && !const_ok_for_arm (INTVAL (operands[1])))"
87b22bf7 1194 [(clobber (const_int 0))]
1195 "
96f57e36 1196 arm_split_constant (MINUS, SImode, curr_insn,
1197 INTVAL (operands[1]), operands[0], operands[2], 0);
87b22bf7 1198 DONE;
cffb2a26 1199 "
7c36fe71 1200 [(set_attr "length" "4,4,4,4,4,4,4,4,16")
1201 (set_attr "arch" "t2,t2,t2,t2,*,*,*,*,*")
65f68e55 1202 (set_attr "predicable" "yes")
7c36fe71 1203 (set_attr "predicable_short_it" "yes,yes,yes,yes,no,no,no,no,no")
112eda6f 1204 (set_attr "type" "alu_sreg,alu_sreg,alu_sreg,alu_sreg,alu_imm,alu_imm,alu_sreg,alu_sreg,multiple")]
a0f94409 1205)
1206
1207(define_peephole2
1208 [(match_scratch:SI 3 "r")
372575c7 1209 (set (match_operand:SI 0 "arm_general_register_operand" "")
a0f94409 1210 (minus:SI (match_operand:SI 1 "const_int_operand" "")
372575c7 1211 (match_operand:SI 2 "arm_general_register_operand" "")))]
25f905c2 1212 "TARGET_32BIT
a0f94409 1213 && !const_ok_for_arm (INTVAL (operands[1]))
1214 && const_ok_for_arm (~INTVAL (operands[1]))"
1215 [(set (match_dup 3) (match_dup 1))
1216 (set (match_dup 0) (minus:SI (match_dup 3) (match_dup 2)))]
1217 ""
cffb2a26 1218)
b11cae9e 1219
f7fbdd4a 1220(define_insn "*subsi3_compare0"
bd5b4116 1221 [(set (reg:CC_NOOV CC_REGNUM)
215b30b3 1222 (compare:CC_NOOV
65f68e55 1223 (minus:SI (match_operand:SI 1 "arm_rhs_operand" "r,r,I")
1224 (match_operand:SI 2 "arm_rhs_operand" "I,r,r"))
215b30b3 1225 (const_int 0)))
65f68e55 1226 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9c08d1fa 1227 (minus:SI (match_dup 1) (match_dup 2)))]
25f905c2 1228 "TARGET_32BIT"
e2348bcb 1229 "@
65f68e55 1230 sub%.\\t%0, %1, %2
25f905c2 1231 sub%.\\t%0, %1, %2
1232 rsb%.\\t%0, %2, %1"
65f68e55 1233 [(set_attr "conds" "set")
112eda6f 1234 (set_attr "type" "alus_imm,alus_sreg,alus_sreg")]
cffb2a26 1235)
9c08d1fa 1236
190efb17 1237(define_insn "subsi3_compare"
080c0b9a 1238 [(set (reg:CC CC_REGNUM)
65f68e55 1239 (compare:CC (match_operand:SI 1 "arm_rhs_operand" "r,r,I")
1240 (match_operand:SI 2 "arm_rhs_operand" "I,r,r")))
1241 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
2df9477b 1242 (minus:SI (match_dup 1) (match_dup 2)))]
1243 "TARGET_32BIT"
1244 "@
65f68e55 1245 sub%.\\t%0, %1, %2
2df9477b 1246 sub%.\\t%0, %1, %2
1247 rsb%.\\t%0, %2, %1"
65f68e55 1248 [(set_attr "conds" "set")
112eda6f 1249 (set_attr "type" "alus_imm,alus_sreg,alus_sreg")]
2df9477b 1250)
1251
604f3a0a 1252(define_expand "subsf3"
1253 [(set (match_operand:SF 0 "s_register_operand" "")
d86c91f6 1254 (minus:SF (match_operand:SF 1 "s_register_operand" "")
1255 (match_operand:SF 2 "s_register_operand" "")))]
25f905c2 1256 "TARGET_32BIT && TARGET_HARD_FLOAT"
604f3a0a 1257 "
604f3a0a 1258")
1259
604f3a0a 1260(define_expand "subdf3"
1261 [(set (match_operand:DF 0 "s_register_operand" "")
d86c91f6 1262 (minus:DF (match_operand:DF 1 "s_register_operand" "")
1263 (match_operand:DF 2 "s_register_operand" "")))]
a50d7267 1264 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
604f3a0a 1265 "
604f3a0a 1266")
1267
b11cae9e 1268\f
1269;; Multiplication insns
1270
4422d91f 1271(define_expand "mulhi3"
1272 [(set (match_operand:HI 0 "s_register_operand" "")
1273 (mult:HI (match_operand:HI 1 "s_register_operand" "")
1274 (match_operand:HI 2 "s_register_operand" "")))]
1275 "TARGET_DSP_MULTIPLY"
1276 "
1277 {
1278 rtx result = gen_reg_rtx (SImode);
1279 emit_insn (gen_mulhisi3 (result, operands[1], operands[2]));
1280 emit_move_insn (operands[0], gen_lowpart (HImode, result));
1281 DONE;
1282 }"
1283)
1284
cffb2a26 1285(define_expand "mulsi3"
1286 [(set (match_operand:SI 0 "s_register_operand" "")
1287 (mult:SI (match_operand:SI 2 "s_register_operand" "")
1288 (match_operand:SI 1 "s_register_operand" "")))]
1289 "TARGET_EITHER"
1290 ""
1291)
1292
9c08d1fa 1293;; Use `&' and then `0' to prevent the operands 0 and 1 being the same
cffb2a26 1294(define_insn "*arm_mulsi3"
1295 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r")
9c08d1fa 1296 (mult:SI (match_operand:SI 2 "s_register_operand" "r,r")
e5fea38e 1297 (match_operand:SI 1 "s_register_operand" "%0,r")))]
58d7d654 1298 "TARGET_32BIT && !arm_arch6"
f7fbdd4a 1299 "mul%?\\t%0, %2, %1"
9da0ec36 1300 [(set_attr "type" "mul")
0d66636f 1301 (set_attr "predicable" "yes")]
cffb2a26 1302)
1303
58d7d654 1304(define_insn "*arm_mulsi3_v6"
d952d547 1305 [(set (match_operand:SI 0 "s_register_operand" "=l,l,r")
1306 (mult:SI (match_operand:SI 1 "s_register_operand" "0,l,r")
1307 (match_operand:SI 2 "s_register_operand" "l,0,r")))]
58d7d654 1308 "TARGET_32BIT && arm_arch6"
1309 "mul%?\\t%0, %1, %2"
9da0ec36 1310 [(set_attr "type" "mul")
d952d547 1311 (set_attr "predicable" "yes")
1312 (set_attr "arch" "t2,t2,*")
1313 (set_attr "length" "4")
1314 (set_attr "predicable_short_it" "yes,yes,no")]
58d7d654 1315)
1316
f7fbdd4a 1317(define_insn "*mulsi3_compare0"
bd5b4116 1318 [(set (reg:CC_NOOV CC_REGNUM)
9c08d1fa 1319 (compare:CC_NOOV (mult:SI
1320 (match_operand:SI 2 "s_register_operand" "r,r")
e5fea38e 1321 (match_operand:SI 1 "s_register_operand" "%0,r"))
9c08d1fa 1322 (const_int 0)))
1323 (set (match_operand:SI 0 "s_register_operand" "=&r,&r")
1324 (mult:SI (match_dup 2) (match_dup 1)))]
58d7d654 1325 "TARGET_ARM && !arm_arch6"
1326 "mul%.\\t%0, %2, %1"
1327 [(set_attr "conds" "set")
9da0ec36 1328 (set_attr "type" "muls")]
58d7d654 1329)
1330
1331(define_insn "*mulsi3_compare0_v6"
1332 [(set (reg:CC_NOOV CC_REGNUM)
1333 (compare:CC_NOOV (mult:SI
1334 (match_operand:SI 2 "s_register_operand" "r")
1335 (match_operand:SI 1 "s_register_operand" "r"))
1336 (const_int 0)))
1337 (set (match_operand:SI 0 "s_register_operand" "=r")
1338 (mult:SI (match_dup 2) (match_dup 1)))]
1339 "TARGET_ARM && arm_arch6 && optimize_size"
25f905c2 1340 "mul%.\\t%0, %2, %1"
cffb2a26 1341 [(set_attr "conds" "set")
9da0ec36 1342 (set_attr "type" "muls")]
cffb2a26 1343)
9c08d1fa 1344
f7fbdd4a 1345(define_insn "*mulsi_compare0_scratch"
bd5b4116 1346 [(set (reg:CC_NOOV CC_REGNUM)
9c08d1fa 1347 (compare:CC_NOOV (mult:SI
1348 (match_operand:SI 2 "s_register_operand" "r,r")
e5fea38e 1349 (match_operand:SI 1 "s_register_operand" "%0,r"))
9c08d1fa 1350 (const_int 0)))
1351 (clobber (match_scratch:SI 0 "=&r,&r"))]
58d7d654 1352 "TARGET_ARM && !arm_arch6"
1353 "mul%.\\t%0, %2, %1"
1354 [(set_attr "conds" "set")
9da0ec36 1355 (set_attr "type" "muls")]
58d7d654 1356)
1357
1358(define_insn "*mulsi_compare0_scratch_v6"
1359 [(set (reg:CC_NOOV CC_REGNUM)
1360 (compare:CC_NOOV (mult:SI
1361 (match_operand:SI 2 "s_register_operand" "r")
1362 (match_operand:SI 1 "s_register_operand" "r"))
1363 (const_int 0)))
1364 (clobber (match_scratch:SI 0 "=r"))]
1365 "TARGET_ARM && arm_arch6 && optimize_size"
25f905c2 1366 "mul%.\\t%0, %2, %1"
cffb2a26 1367 [(set_attr "conds" "set")
9da0ec36 1368 (set_attr "type" "muls")]
cffb2a26 1369)
9c08d1fa 1370
b11cae9e 1371;; Unnamed templates to match MLA instruction.
1372
f7fbdd4a 1373(define_insn "*mulsi3addsi"
9c08d1fa 1374 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r,&r")
c8f69309 1375 (plus:SI
9c08d1fa 1376 (mult:SI (match_operand:SI 2 "s_register_operand" "r,r,r,r")
e5fea38e 1377 (match_operand:SI 1 "s_register_operand" "%0,r,0,r"))
1378 (match_operand:SI 3 "s_register_operand" "r,r,0,0")))]
58d7d654 1379 "TARGET_32BIT && !arm_arch6"
1380 "mla%?\\t%0, %2, %1, %3"
9da0ec36 1381 [(set_attr "type" "mla")
58d7d654 1382 (set_attr "predicable" "yes")]
1383)
1384
1385(define_insn "*mulsi3addsi_v6"
1386 [(set (match_operand:SI 0 "s_register_operand" "=r")
1387 (plus:SI
1388 (mult:SI (match_operand:SI 2 "s_register_operand" "r")
1389 (match_operand:SI 1 "s_register_operand" "r"))
1390 (match_operand:SI 3 "s_register_operand" "r")))]
1391 "TARGET_32BIT && arm_arch6"
f7fbdd4a 1392 "mla%?\\t%0, %2, %1, %3"
9da0ec36 1393 [(set_attr "type" "mla")
d952d547 1394 (set_attr "predicable" "yes")
1395 (set_attr "predicable_short_it" "no")]
0d66636f 1396)
b11cae9e 1397
f7fbdd4a 1398(define_insn "*mulsi3addsi_compare0"
bd5b4116 1399 [(set (reg:CC_NOOV CC_REGNUM)
215b30b3 1400 (compare:CC_NOOV
1401 (plus:SI (mult:SI
1402 (match_operand:SI 2 "s_register_operand" "r,r,r,r")
e5fea38e 1403 (match_operand:SI 1 "s_register_operand" "%0,r,0,r"))
1404 (match_operand:SI 3 "s_register_operand" "r,r,0,0"))
215b30b3 1405 (const_int 0)))
9c08d1fa 1406 (set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r,&r")
1407 (plus:SI (mult:SI (match_dup 2) (match_dup 1))
1408 (match_dup 3)))]
58d7d654 1409 "TARGET_ARM && arm_arch6"
1410 "mla%.\\t%0, %2, %1, %3"
1411 [(set_attr "conds" "set")
9da0ec36 1412 (set_attr "type" "mlas")]
58d7d654 1413)
1414
1415(define_insn "*mulsi3addsi_compare0_v6"
1416 [(set (reg:CC_NOOV CC_REGNUM)
1417 (compare:CC_NOOV
1418 (plus:SI (mult:SI
1419 (match_operand:SI 2 "s_register_operand" "r")
1420 (match_operand:SI 1 "s_register_operand" "r"))
1421 (match_operand:SI 3 "s_register_operand" "r"))
1422 (const_int 0)))
1423 (set (match_operand:SI 0 "s_register_operand" "=r")
1424 (plus:SI (mult:SI (match_dup 2) (match_dup 1))
1425 (match_dup 3)))]
1426 "TARGET_ARM && arm_arch6 && optimize_size"
25f905c2 1427 "mla%.\\t%0, %2, %1, %3"
0d66636f 1428 [(set_attr "conds" "set")
9da0ec36 1429 (set_attr "type" "mlas")]
0d66636f 1430)
9c08d1fa 1431
f7fbdd4a 1432(define_insn "*mulsi3addsi_compare0_scratch"
bd5b4116 1433 [(set (reg:CC_NOOV CC_REGNUM)
215b30b3 1434 (compare:CC_NOOV
1435 (plus:SI (mult:SI
1436 (match_operand:SI 2 "s_register_operand" "r,r,r,r")
e5fea38e 1437 (match_operand:SI 1 "s_register_operand" "%0,r,0,r"))
215b30b3 1438 (match_operand:SI 3 "s_register_operand" "?r,r,0,0"))
1439 (const_int 0)))
9c08d1fa 1440 (clobber (match_scratch:SI 0 "=&r,&r,&r,&r"))]
58d7d654 1441 "TARGET_ARM && !arm_arch6"
1442 "mla%.\\t%0, %2, %1, %3"
1443 [(set_attr "conds" "set")
9da0ec36 1444 (set_attr "type" "mlas")]
58d7d654 1445)
1446
1447(define_insn "*mulsi3addsi_compare0_scratch_v6"
1448 [(set (reg:CC_NOOV CC_REGNUM)
1449 (compare:CC_NOOV
1450 (plus:SI (mult:SI
1451 (match_operand:SI 2 "s_register_operand" "r")
1452 (match_operand:SI 1 "s_register_operand" "r"))
1453 (match_operand:SI 3 "s_register_operand" "r"))
1454 (const_int 0)))
1455 (clobber (match_scratch:SI 0 "=r"))]
1456 "TARGET_ARM && arm_arch6 && optimize_size"
25f905c2 1457 "mla%.\\t%0, %2, %1, %3"
cffb2a26 1458 [(set_attr "conds" "set")
9da0ec36 1459 (set_attr "type" "mlas")]
cffb2a26 1460)
f7fbdd4a 1461
89545238 1462(define_insn "*mulsi3subsi"
1463 [(set (match_operand:SI 0 "s_register_operand" "=r")
1464 (minus:SI
1465 (match_operand:SI 3 "s_register_operand" "r")
1466 (mult:SI (match_operand:SI 2 "s_register_operand" "r")
1467 (match_operand:SI 1 "s_register_operand" "r"))))]
1468 "TARGET_32BIT && arm_arch_thumb2"
1469 "mls%?\\t%0, %2, %1, %3"
9da0ec36 1470 [(set_attr "type" "mla")
d952d547 1471 (set_attr "predicable" "yes")
1472 (set_attr "predicable_short_it" "no")]
89545238 1473)
1474
5cdca009 1475(define_expand "maddsidi4"
1476 [(set (match_operand:DI 0 "s_register_operand" "")
1477 (plus:DI
1478 (mult:DI
1479 (sign_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1480 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "")))
1481 (match_operand:DI 3 "s_register_operand" "")))]
1482 "TARGET_32BIT && arm_arch3m"
1483 "")
82b85d08 1484
1485(define_insn "*mulsidi3adddi"
fe8dbf85 1486 [(set (match_operand:DI 0 "s_register_operand" "=&r")
82b85d08 1487 (plus:DI
215b30b3 1488 (mult:DI
fe8dbf85 1489 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "%r"))
1490 (sign_extend:DI (match_operand:SI 3 "s_register_operand" "r")))
1491 (match_operand:DI 1 "s_register_operand" "0")))]
58d7d654 1492 "TARGET_32BIT && arm_arch3m && !arm_arch6"
1493 "smlal%?\\t%Q0, %R0, %3, %2"
9da0ec36 1494 [(set_attr "type" "smlal")
58d7d654 1495 (set_attr "predicable" "yes")]
1496)
1497
1498(define_insn "*mulsidi3adddi_v6"
1499 [(set (match_operand:DI 0 "s_register_operand" "=r")
1500 (plus:DI
1501 (mult:DI
1502 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r"))
1503 (sign_extend:DI (match_operand:SI 3 "s_register_operand" "r")))
1504 (match_operand:DI 1 "s_register_operand" "0")))]
1505 "TARGET_32BIT && arm_arch6"
fe8dbf85 1506 "smlal%?\\t%Q0, %R0, %3, %2"
9da0ec36 1507 [(set_attr "type" "smlal")
d952d547 1508 (set_attr "predicable" "yes")
1509 (set_attr "predicable_short_it" "no")]
0d66636f 1510)
82b85d08 1511
957788b0 1512;; 32x32->64 widening multiply.
1513;; As with mulsi3, the only difference between the v3-5 and v6+
1514;; versions of these patterns is the requirement that the output not
1515;; overlap the inputs, but that still means we have to have a named
1516;; expander and two different starred insns.
1517
1518(define_expand "mulsidi3"
1519 [(set (match_operand:DI 0 "s_register_operand" "")
1520 (mult:DI
1521 (sign_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1522 (sign_extend:DI (match_operand:SI 2 "s_register_operand" ""))))]
1523 "TARGET_32BIT && arm_arch3m"
1524 ""
1525)
1526
1527(define_insn "*mulsidi3_nov6"
f7fbdd4a 1528 [(set (match_operand:DI 0 "s_register_operand" "=&r")
215b30b3 1529 (mult:DI
1530 (sign_extend:DI (match_operand:SI 1 "s_register_operand" "%r"))
1531 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))]
58d7d654 1532 "TARGET_32BIT && arm_arch3m && !arm_arch6"
1533 "smull%?\\t%Q0, %R0, %1, %2"
9da0ec36 1534 [(set_attr "type" "smull")
58d7d654 1535 (set_attr "predicable" "yes")]
1536)
1537
957788b0 1538(define_insn "*mulsidi3_v6"
58d7d654 1539 [(set (match_operand:DI 0 "s_register_operand" "=r")
1540 (mult:DI
1541 (sign_extend:DI (match_operand:SI 1 "s_register_operand" "r"))
1542 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))]
1543 "TARGET_32BIT && arm_arch6"
97499065 1544 "smull%?\\t%Q0, %R0, %1, %2"
9da0ec36 1545 [(set_attr "type" "smull")
d952d547 1546 (set_attr "predicable" "yes")
1547 (set_attr "predicable_short_it" "no")]
0d66636f 1548)
f7fbdd4a 1549
957788b0 1550(define_expand "umulsidi3"
1551 [(set (match_operand:DI 0 "s_register_operand" "")
1552 (mult:DI
1553 (zero_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1554 (zero_extend:DI (match_operand:SI 2 "s_register_operand" ""))))]
1555 "TARGET_32BIT && arm_arch3m"
1556 ""
1557)
1558
1559(define_insn "*umulsidi3_nov6"
f7fbdd4a 1560 [(set (match_operand:DI 0 "s_register_operand" "=&r")
215b30b3 1561 (mult:DI
1562 (zero_extend:DI (match_operand:SI 1 "s_register_operand" "%r"))
1563 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))]
58d7d654 1564 "TARGET_32BIT && arm_arch3m && !arm_arch6"
1565 "umull%?\\t%Q0, %R0, %1, %2"
9da0ec36 1566 [(set_attr "type" "umull")
58d7d654 1567 (set_attr "predicable" "yes")]
1568)
1569
957788b0 1570(define_insn "*umulsidi3_v6"
58d7d654 1571 [(set (match_operand:DI 0 "s_register_operand" "=r")
1572 (mult:DI
1573 (zero_extend:DI (match_operand:SI 1 "s_register_operand" "r"))
1574 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))]
1575 "TARGET_32BIT && arm_arch6"
97499065 1576 "umull%?\\t%Q0, %R0, %1, %2"
9da0ec36 1577 [(set_attr "type" "umull")
d952d547 1578 (set_attr "predicable" "yes")
1579 (set_attr "predicable_short_it" "no")]
0d66636f 1580)
b11cae9e 1581
5cdca009 1582(define_expand "umaddsidi4"
1583 [(set (match_operand:DI 0 "s_register_operand" "")
1584 (plus:DI
1585 (mult:DI
1586 (zero_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1587 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "")))
1588 (match_operand:DI 3 "s_register_operand" "")))]
1589 "TARGET_32BIT && arm_arch3m"
1590 "")
82b85d08 1591
1592(define_insn "*umulsidi3adddi"
8ead09f9 1593 [(set (match_operand:DI 0 "s_register_operand" "=&r")
82b85d08 1594 (plus:DI
215b30b3 1595 (mult:DI
fe8dbf85 1596 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "%r"))
1597 (zero_extend:DI (match_operand:SI 3 "s_register_operand" "r")))
1598 (match_operand:DI 1 "s_register_operand" "0")))]
58d7d654 1599 "TARGET_32BIT && arm_arch3m && !arm_arch6"
1600 "umlal%?\\t%Q0, %R0, %3, %2"
9da0ec36 1601 [(set_attr "type" "umlal")
58d7d654 1602 (set_attr "predicable" "yes")]
1603)
1604
1605(define_insn "*umulsidi3adddi_v6"
1606 [(set (match_operand:DI 0 "s_register_operand" "=r")
1607 (plus:DI
1608 (mult:DI
1609 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r"))
1610 (zero_extend:DI (match_operand:SI 3 "s_register_operand" "r")))
1611 (match_operand:DI 1 "s_register_operand" "0")))]
1612 "TARGET_32BIT && arm_arch6"
fe8dbf85 1613 "umlal%?\\t%Q0, %R0, %3, %2"
9da0ec36 1614 [(set_attr "type" "umlal")
d952d547 1615 (set_attr "predicable" "yes")
1616 (set_attr "predicable_short_it" "no")]
0d66636f 1617)
82b85d08 1618
957788b0 1619(define_expand "smulsi3_highpart"
1620 [(parallel
1621 [(set (match_operand:SI 0 "s_register_operand" "")
1622 (truncate:SI
1623 (lshiftrt:DI
1624 (mult:DI
1625 (sign_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1626 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "")))
1627 (const_int 32))))
1628 (clobber (match_scratch:SI 3 ""))])]
1629 "TARGET_32BIT && arm_arch3m"
1630 ""
1631)
1632
1633(define_insn "*smulsi3_highpart_nov6"
f082f1c4 1634 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r")
1635 (truncate:SI
1636 (lshiftrt:DI
215b30b3 1637 (mult:DI
e5fea38e 1638 (sign_extend:DI (match_operand:SI 1 "s_register_operand" "%0,r"))
215b30b3 1639 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r,r")))
f082f1c4 1640 (const_int 32))))
1641 (clobber (match_scratch:SI 3 "=&r,&r"))]
58d7d654 1642 "TARGET_32BIT && arm_arch3m && !arm_arch6"
1643 "smull%?\\t%3, %0, %2, %1"
9da0ec36 1644 [(set_attr "type" "smull")
58d7d654 1645 (set_attr "predicable" "yes")]
1646)
1647
957788b0 1648(define_insn "*smulsi3_highpart_v6"
58d7d654 1649 [(set (match_operand:SI 0 "s_register_operand" "=r")
1650 (truncate:SI
1651 (lshiftrt:DI
1652 (mult:DI
1653 (sign_extend:DI (match_operand:SI 1 "s_register_operand" "r"))
1654 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r")))
1655 (const_int 32))))
1656 (clobber (match_scratch:SI 3 "=r"))]
1657 "TARGET_32BIT && arm_arch6"
f082f1c4 1658 "smull%?\\t%3, %0, %2, %1"
9da0ec36 1659 [(set_attr "type" "smull")
d952d547 1660 (set_attr "predicable" "yes")
1661 (set_attr "predicable_short_it" "no")]
cffb2a26 1662)
f082f1c4 1663
957788b0 1664(define_expand "umulsi3_highpart"
1665 [(parallel
1666 [(set (match_operand:SI 0 "s_register_operand" "")
1667 (truncate:SI
1668 (lshiftrt:DI
1669 (mult:DI
1670 (zero_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1671 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "")))
1672 (const_int 32))))
1673 (clobber (match_scratch:SI 3 ""))])]
1674 "TARGET_32BIT && arm_arch3m"
1675 ""
1676)
1677
1678(define_insn "*umulsi3_highpart_nov6"
f082f1c4 1679 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r")
1680 (truncate:SI
1681 (lshiftrt:DI
215b30b3 1682 (mult:DI
e5fea38e 1683 (zero_extend:DI (match_operand:SI 1 "s_register_operand" "%0,r"))
215b30b3 1684 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r,r")))
f082f1c4 1685 (const_int 32))))
1686 (clobber (match_scratch:SI 3 "=&r,&r"))]
58d7d654 1687 "TARGET_32BIT && arm_arch3m && !arm_arch6"
1688 "umull%?\\t%3, %0, %2, %1"
9da0ec36 1689 [(set_attr "type" "umull")
58d7d654 1690 (set_attr "predicable" "yes")]
1691)
1692
957788b0 1693(define_insn "*umulsi3_highpart_v6"
58d7d654 1694 [(set (match_operand:SI 0 "s_register_operand" "=r")
1695 (truncate:SI
1696 (lshiftrt:DI
1697 (mult:DI
1698 (zero_extend:DI (match_operand:SI 1 "s_register_operand" "r"))
1699 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r")))
1700 (const_int 32))))
1701 (clobber (match_scratch:SI 3 "=r"))]
1702 "TARGET_32BIT && arm_arch6"
f082f1c4 1703 "umull%?\\t%3, %0, %2, %1"
9da0ec36 1704 [(set_attr "type" "umull")
d952d547 1705 (set_attr "predicable" "yes")
1706 (set_attr "predicable_short_it" "no")]
cffb2a26 1707)
f082f1c4 1708
331beb1a 1709(define_insn "mulhisi3"
1710 [(set (match_operand:SI 0 "s_register_operand" "=r")
1711 (mult:SI (sign_extend:SI
1712 (match_operand:HI 1 "s_register_operand" "%r"))
1713 (sign_extend:SI
1714 (match_operand:HI 2 "s_register_operand" "r"))))]
25f905c2 1715 "TARGET_DSP_MULTIPLY"
61a2d04c 1716 "smulbb%?\\t%0, %1, %2"
9da0ec36 1717 [(set_attr "type" "smulxy")
fec538d9 1718 (set_attr "predicable" "yes")]
1719)
1720
1721(define_insn "*mulhisi3tb"
1722 [(set (match_operand:SI 0 "s_register_operand" "=r")
1723 (mult:SI (ashiftrt:SI
1724 (match_operand:SI 1 "s_register_operand" "r")
1725 (const_int 16))
1726 (sign_extend:SI
1727 (match_operand:HI 2 "s_register_operand" "r"))))]
25f905c2 1728 "TARGET_DSP_MULTIPLY"
fec538d9 1729 "smultb%?\\t%0, %1, %2"
9da0ec36 1730 [(set_attr "type" "smulxy")
d952d547 1731 (set_attr "predicable" "yes")
1732 (set_attr "predicable_short_it" "no")]
fec538d9 1733)
1734
1735(define_insn "*mulhisi3bt"
1736 [(set (match_operand:SI 0 "s_register_operand" "=r")
1737 (mult:SI (sign_extend:SI
1738 (match_operand:HI 1 "s_register_operand" "r"))
1739 (ashiftrt:SI
1740 (match_operand:SI 2 "s_register_operand" "r")
1741 (const_int 16))))]
25f905c2 1742 "TARGET_DSP_MULTIPLY"
fec538d9 1743 "smulbt%?\\t%0, %1, %2"
9da0ec36 1744 [(set_attr "type" "smulxy")
d952d547 1745 (set_attr "predicable" "yes")
1746 (set_attr "predicable_short_it" "no")]
fec538d9 1747)
1748
1749(define_insn "*mulhisi3tt"
1750 [(set (match_operand:SI 0 "s_register_operand" "=r")
1751 (mult:SI (ashiftrt:SI
1752 (match_operand:SI 1 "s_register_operand" "r")
1753 (const_int 16))
1754 (ashiftrt:SI
1755 (match_operand:SI 2 "s_register_operand" "r")
1756 (const_int 16))))]
25f905c2 1757 "TARGET_DSP_MULTIPLY"
fec538d9 1758 "smultt%?\\t%0, %1, %2"
9da0ec36 1759 [(set_attr "type" "smulxy")
d952d547 1760 (set_attr "predicable" "yes")
1761 (set_attr "predicable_short_it" "no")]
331beb1a 1762)
1763
5cdca009 1764(define_insn "maddhisi4"
331beb1a 1765 [(set (match_operand:SI 0 "s_register_operand" "=r")
cfa6c608 1766 (plus:SI (mult:SI (sign_extend:SI
1767 (match_operand:HI 1 "s_register_operand" "r"))
331beb1a 1768 (sign_extend:SI
cfa6c608 1769 (match_operand:HI 2 "s_register_operand" "r")))
1770 (match_operand:SI 3 "s_register_operand" "r")))]
25f905c2 1771 "TARGET_DSP_MULTIPLY"
5cdca009 1772 "smlabb%?\\t%0, %1, %2, %3"
9da0ec36 1773 [(set_attr "type" "smlaxy")
d952d547 1774 (set_attr "predicable" "yes")
1775 (set_attr "predicable_short_it" "no")]
331beb1a 1776)
1777
9a92f368 1778;; Note: there is no maddhisi4ibt because this one is canonical form
1779(define_insn "*maddhisi4tb"
1780 [(set (match_operand:SI 0 "s_register_operand" "=r")
1781 (plus:SI (mult:SI (ashiftrt:SI
1782 (match_operand:SI 1 "s_register_operand" "r")
1783 (const_int 16))
1784 (sign_extend:SI
1785 (match_operand:HI 2 "s_register_operand" "r")))
1786 (match_operand:SI 3 "s_register_operand" "r")))]
1787 "TARGET_DSP_MULTIPLY"
1788 "smlatb%?\\t%0, %1, %2, %3"
9da0ec36 1789 [(set_attr "type" "smlaxy")
d952d547 1790 (set_attr "predicable" "yes")
1791 (set_attr "predicable_short_it" "no")]
9a92f368 1792)
1793
1794(define_insn "*maddhisi4tt"
1795 [(set (match_operand:SI 0 "s_register_operand" "=r")
1796 (plus:SI (mult:SI (ashiftrt:SI
1797 (match_operand:SI 1 "s_register_operand" "r")
1798 (const_int 16))
1799 (ashiftrt:SI
1800 (match_operand:SI 2 "s_register_operand" "r")
1801 (const_int 16)))
1802 (match_operand:SI 3 "s_register_operand" "r")))]
1803 "TARGET_DSP_MULTIPLY"
1804 "smlatt%?\\t%0, %1, %2, %3"
9da0ec36 1805 [(set_attr "type" "smlaxy")
d952d547 1806 (set_attr "predicable" "yes")
1807 (set_attr "predicable_short_it" "no")]
9a92f368 1808)
1809
aff5fb4d 1810(define_insn "maddhidi4"
331beb1a 1811 [(set (match_operand:DI 0 "s_register_operand" "=r")
1812 (plus:DI
331beb1a 1813 (mult:DI (sign_extend:DI
d952d547 1814 (match_operand:HI 1 "s_register_operand" "r"))
331beb1a 1815 (sign_extend:DI
cfa6c608 1816 (match_operand:HI 2 "s_register_operand" "r")))
1817 (match_operand:DI 3 "s_register_operand" "0")))]
25f905c2 1818 "TARGET_DSP_MULTIPLY"
5cdca009 1819 "smlalbb%?\\t%Q0, %R0, %1, %2"
9da0ec36 1820 [(set_attr "type" "smlalxy")
d952d547 1821 (set_attr "predicable" "yes")
1822 (set_attr "predicable_short_it" "no")])
331beb1a 1823
9a92f368 1824;; Note: there is no maddhidi4ibt because this one is canonical form
1825(define_insn "*maddhidi4tb"
1826 [(set (match_operand:DI 0 "s_register_operand" "=r")
1827 (plus:DI
1828 (mult:DI (sign_extend:DI
1829 (ashiftrt:SI
1830 (match_operand:SI 1 "s_register_operand" "r")
1831 (const_int 16)))
1832 (sign_extend:DI
1833 (match_operand:HI 2 "s_register_operand" "r")))
1834 (match_operand:DI 3 "s_register_operand" "0")))]
1835 "TARGET_DSP_MULTIPLY"
1836 "smlaltb%?\\t%Q0, %R0, %1, %2"
9da0ec36 1837 [(set_attr "type" "smlalxy")
d952d547 1838 (set_attr "predicable" "yes")
1839 (set_attr "predicable_short_it" "no")])
9a92f368 1840
1841(define_insn "*maddhidi4tt"
1842 [(set (match_operand:DI 0 "s_register_operand" "=r")
1843 (plus:DI
1844 (mult:DI (sign_extend:DI
1845 (ashiftrt:SI
1846 (match_operand:SI 1 "s_register_operand" "r")
1847 (const_int 16)))
1848 (sign_extend:DI
1849 (ashiftrt:SI
1850 (match_operand:SI 2 "s_register_operand" "r")
1851 (const_int 16))))
1852 (match_operand:DI 3 "s_register_operand" "0")))]
1853 "TARGET_DSP_MULTIPLY"
1854 "smlaltt%?\\t%Q0, %R0, %1, %2"
9da0ec36 1855 [(set_attr "type" "smlalxy")
d952d547 1856 (set_attr "predicable" "yes")
1857 (set_attr "predicable_short_it" "no")])
9a92f368 1858
604f3a0a 1859(define_expand "mulsf3"
1860 [(set (match_operand:SF 0 "s_register_operand" "")
1861 (mult:SF (match_operand:SF 1 "s_register_operand" "")
d86c91f6 1862 (match_operand:SF 2 "s_register_operand" "")))]
25f905c2 1863 "TARGET_32BIT && TARGET_HARD_FLOAT"
604f3a0a 1864 "
604f3a0a 1865")
1866
604f3a0a 1867(define_expand "muldf3"
1868 [(set (match_operand:DF 0 "s_register_operand" "")
1869 (mult:DF (match_operand:DF 1 "s_register_operand" "")
d86c91f6 1870 (match_operand:DF 2 "s_register_operand" "")))]
a50d7267 1871 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
604f3a0a 1872 "
604f3a0a 1873")
b11cae9e 1874\f
1875;; Division insns
1876
7db9af5d 1877(define_expand "divsf3"
1878 [(set (match_operand:SF 0 "s_register_operand" "")
d86c91f6 1879 (div:SF (match_operand:SF 1 "s_register_operand" "")
1880 (match_operand:SF 2 "s_register_operand" "")))]
994606f8 1881 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
7db9af5d 1882 "")
9c08d1fa 1883
7db9af5d 1884(define_expand "divdf3"
1885 [(set (match_operand:DF 0 "s_register_operand" "")
d86c91f6 1886 (div:DF (match_operand:DF 1 "s_register_operand" "")
1887 (match_operand:DF 2 "s_register_operand" "")))]
994606f8 1888 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
7db9af5d 1889 "")
b11cae9e 1890\f
1891;; Boolean and,ior,xor insns
1892
f6ebffac 1893;; Split up double word logical operations
1894
1895;; Split up simple DImode logical operations. Simply perform the logical
1896;; operation on the upper and lower halves of the registers.
1897(define_split
1898 [(set (match_operand:DI 0 "s_register_operand" "")
1899 (match_operator:DI 6 "logical_binary_operator"
1900 [(match_operand:DI 1 "s_register_operand" "")
1901 (match_operand:DI 2 "s_register_operand" "")]))]
25f905c2 1902 "TARGET_32BIT && reload_completed
e2669ea7 1903 && ! (TARGET_NEON && IS_VFP_REGNUM (REGNO (operands[0])))
25f905c2 1904 && ! IS_IWMMXT_REGNUM (REGNO (operands[0]))"
f6ebffac 1905 [(set (match_dup 0) (match_op_dup:SI 6 [(match_dup 1) (match_dup 2)]))
1906 (set (match_dup 3) (match_op_dup:SI 6 [(match_dup 4) (match_dup 5)]))]
1907 "
215b30b3 1908 {
1909 operands[3] = gen_highpart (SImode, operands[0]);
1910 operands[0] = gen_lowpart (SImode, operands[0]);
1911 operands[4] = gen_highpart (SImode, operands[1]);
1912 operands[1] = gen_lowpart (SImode, operands[1]);
1913 operands[5] = gen_highpart (SImode, operands[2]);
1914 operands[2] = gen_lowpart (SImode, operands[2]);
1915 }"
1916)
f6ebffac 1917
f6ebffac 1918(define_split
1919 [(set (match_operand:DI 0 "s_register_operand" "")
1920 (match_operator:DI 6 "logical_binary_operator"
1921 [(sign_extend:DI (match_operand:SI 2 "s_register_operand" ""))
1922 (match_operand:DI 1 "s_register_operand" "")]))]
25f905c2 1923 "TARGET_32BIT && reload_completed"
f6ebffac 1924 [(set (match_dup 0) (match_op_dup:SI 6 [(match_dup 1) (match_dup 2)]))
1925 (set (match_dup 3) (match_op_dup:SI 6
1926 [(ashiftrt:SI (match_dup 2) (const_int 31))
1927 (match_dup 4)]))]
1928 "
215b30b3 1929 {
1930 operands[3] = gen_highpart (SImode, operands[0]);
1931 operands[0] = gen_lowpart (SImode, operands[0]);
1932 operands[4] = gen_highpart (SImode, operands[1]);
1933 operands[1] = gen_lowpart (SImode, operands[1]);
1934 operands[5] = gen_highpart (SImode, operands[2]);
1935 operands[2] = gen_lowpart (SImode, operands[2]);
1936 }"
1937)
f6ebffac 1938
f6ebffac 1939;; The zero extend of operand 2 means we can just copy the high part of
1940;; operand1 into operand0.
1941(define_split
1942 [(set (match_operand:DI 0 "s_register_operand" "")
1943 (ior:DI
1944 (zero_extend:DI (match_operand:SI 2 "s_register_operand" ""))
1945 (match_operand:DI 1 "s_register_operand" "")))]
25f905c2 1946 "TARGET_32BIT && operands[0] != operands[1] && reload_completed"
f6ebffac 1947 [(set (match_dup 0) (ior:SI (match_dup 1) (match_dup 2)))
1948 (set (match_dup 3) (match_dup 4))]
1949 "
215b30b3 1950 {
1951 operands[4] = gen_highpart (SImode, operands[1]);
1952 operands[3] = gen_highpart (SImode, operands[0]);
1953 operands[0] = gen_lowpart (SImode, operands[0]);
1954 operands[1] = gen_lowpart (SImode, operands[1]);
1955 }"
1956)
f6ebffac 1957
1958;; The zero extend of operand 2 means we can just copy the high part of
1959;; operand1 into operand0.
1960(define_split
1961 [(set (match_operand:DI 0 "s_register_operand" "")
1962 (xor:DI
1963 (zero_extend:DI (match_operand:SI 2 "s_register_operand" ""))
1964 (match_operand:DI 1 "s_register_operand" "")))]
25f905c2 1965 "TARGET_32BIT && operands[0] != operands[1] && reload_completed"
f6ebffac 1966 [(set (match_dup 0) (xor:SI (match_dup 1) (match_dup 2)))
1967 (set (match_dup 3) (match_dup 4))]
1968 "
215b30b3 1969 {
1970 operands[4] = gen_highpart (SImode, operands[1]);
1971 operands[3] = gen_highpart (SImode, operands[0]);
1972 operands[0] = gen_lowpart (SImode, operands[0]);
1973 operands[1] = gen_lowpart (SImode, operands[1]);
1974 }"
1975)
f6ebffac 1976
e2669ea7 1977(define_expand "anddi3"
1978 [(set (match_operand:DI 0 "s_register_operand" "")
1979 (and:DI (match_operand:DI 1 "s_register_operand" "")
1980 (match_operand:DI 2 "neon_inv_logic_op2" "")))]
1981 "TARGET_32BIT"
1982 ""
1983)
1984
f6bbdcf6 1985(define_insn_and_split "*anddi3_insn"
0a314dcd 1986 [(set (match_operand:DI 0 "s_register_operand" "=w,w ,&r,&r,&r,&r,?w,?w")
1987 (and:DI (match_operand:DI 1 "s_register_operand" "%w,0 ,0 ,r ,0 ,r ,w ,0")
1988 (match_operand:DI 2 "arm_anddi_operand_neon" "w ,DL,r ,r ,De,De,w ,DL")))]
f6bbdcf6 1989 "TARGET_32BIT && !TARGET_IWMMXT"
1990{
1991 switch (which_alternative)
1992 {
0a314dcd 1993 case 0: /* fall through */
1994 case 6: return "vand\t%P0, %P1, %P2";
1995 case 1: /* fall through */
1996 case 7: return neon_output_logic_immediate ("vand", &operands[2],
1997 DImode, 1, VALID_NEON_QREG_MODE (DImode));
f6bbdcf6 1998 case 2:
0a314dcd 1999 case 3:
2000 case 4:
f6bbdcf6 2001 case 5: /* fall through */
0a314dcd 2002 return "#";
f6bbdcf6 2003 default: gcc_unreachable ();
2004 }
2005}
0a314dcd 2006 "TARGET_32BIT && !TARGET_IWMMXT && reload_completed
2007 && !(IS_VFP_REGNUM (REGNO (operands[0])))"
f6bbdcf6 2008 [(set (match_dup 3) (match_dup 4))
2009 (set (match_dup 5) (match_dup 6))]
2010 "
2011 {
2012 operands[3] = gen_lowpart (SImode, operands[0]);
2013 operands[5] = gen_highpart (SImode, operands[0]);
2014
2015 operands[4] = simplify_gen_binary (AND, SImode,
2016 gen_lowpart (SImode, operands[1]),
2017 gen_lowpart (SImode, operands[2]));
2018 operands[6] = simplify_gen_binary (AND, SImode,
2019 gen_highpart (SImode, operands[1]),
2020 gen_highpart_mode (SImode, DImode, operands[2]));
2021
2022 }"
32093010 2023 [(set_attr "type" "neon_logic,neon_logic,multiple,multiple,\
2024 multiple,multiple,neon_logic,neon_logic")
0a314dcd 2025 (set_attr "arch" "neon_for_64bits,neon_for_64bits,*,*,*,*,
f6bbdcf6 2026 avoid_neon_for_64bits,avoid_neon_for_64bits")
0a314dcd 2027 (set_attr "length" "*,*,8,8,8,8,*,*")
2028 ]
215b30b3 2029)
b11cae9e 2030
a0f94409 2031(define_insn_and_split "*anddi_zesidi_di"
9c08d1fa 2032 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2033 (and:DI (zero_extend:DI
2034 (match_operand:SI 2 "s_register_operand" "r,r"))
e5fea38e 2035 (match_operand:DI 1 "s_register_operand" "0,r")))]
25f905c2 2036 "TARGET_32BIT"
f6ebffac 2037 "#"
25f905c2 2038 "TARGET_32BIT && reload_completed"
a0f94409 2039 ; The zero extend of operand 2 clears the high word of the output
2040 ; operand.
2041 [(set (match_dup 0) (and:SI (match_dup 1) (match_dup 2)))
2042 (set (match_dup 3) (const_int 0))]
2043 "
2044 {
2045 operands[3] = gen_highpart (SImode, operands[0]);
2046 operands[0] = gen_lowpart (SImode, operands[0]);
2047 operands[1] = gen_lowpart (SImode, operands[1]);
2048 }"
1b7da4ac 2049 [(set_attr "length" "8")
2050 (set_attr "type" "multiple")]
215b30b3 2051)
b11cae9e 2052
f7fbdd4a 2053(define_insn "*anddi_sesdi_di"
cffb2a26 2054 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
9c08d1fa 2055 (and:DI (sign_extend:DI
2056 (match_operand:SI 2 "s_register_operand" "r,r"))
e5fea38e 2057 (match_operand:DI 1 "s_register_operand" "0,r")))]
25f905c2 2058 "TARGET_32BIT"
f6ebffac 2059 "#"
1b7da4ac 2060 [(set_attr "length" "8")
2061 (set_attr "type" "multiple")]
cffb2a26 2062)
b11cae9e 2063
87b22bf7 2064(define_expand "andsi3"
cffb2a26 2065 [(set (match_operand:SI 0 "s_register_operand" "")
87b22bf7 2066 (and:SI (match_operand:SI 1 "s_register_operand" "")
2067 (match_operand:SI 2 "reg_or_int_operand" "")))]
cffb2a26 2068 "TARGET_EITHER"
87b22bf7 2069 "
25f905c2 2070 if (TARGET_32BIT)
87b22bf7 2071 {
0438d37f 2072 if (CONST_INT_P (operands[2]))
cffb2a26 2073 {
47b5b27b 2074 if (INTVAL (operands[2]) == 255 && arm_arch6)
2075 {
2076 operands[1] = convert_to_mode (QImode, operands[1], 1);
2077 emit_insn (gen_thumb2_zero_extendqisi2_v6 (operands[0],
2078 operands[1]));
2079 }
2080 else
2081 arm_split_constant (AND, SImode, NULL_RTX,
2082 INTVAL (operands[2]), operands[0],
2083 operands[1],
2084 optimize && can_create_pseudo_p ());
615caa51 2085
cffb2a26 2086 DONE;
2087 }
87b22bf7 2088 }
25f905c2 2089 else /* TARGET_THUMB1 */
cffb2a26 2090 {
0438d37f 2091 if (!CONST_INT_P (operands[2]))
923ffadb 2092 {
2093 rtx tmp = force_reg (SImode, operands[2]);
2094 if (rtx_equal_p (operands[0], operands[1]))
2095 operands[2] = tmp;
2096 else
2097 {
2098 operands[2] = operands[1];
2099 operands[1] = tmp;
2100 }
2101 }
cffb2a26 2102 else
2103 {
2104 int i;
2105
215b30b3 2106 if (((unsigned HOST_WIDE_INT) ~INTVAL (operands[2])) < 256)
cffb2a26 2107 {
215b30b3 2108 operands[2] = force_reg (SImode,
2109 GEN_INT (~INTVAL (operands[2])));
cffb2a26 2110
747b7458 2111 emit_insn (gen_thumb1_bicsi3 (operands[0], operands[2], operands[1]));
cffb2a26 2112
2113 DONE;
2114 }
87b22bf7 2115
cffb2a26 2116 for (i = 9; i <= 31; i++)
2117 {
2118 if ((((HOST_WIDE_INT) 1) << i) - 1 == INTVAL (operands[2]))
2119 {
2120 emit_insn (gen_extzv (operands[0], operands[1], GEN_INT (i),
2121 const0_rtx));
2122 DONE;
2123 }
215b30b3 2124 else if ((((HOST_WIDE_INT) 1) << i) - 1
2125 == ~INTVAL (operands[2]))
cffb2a26 2126 {
2127 rtx shift = GEN_INT (i);
2128 rtx reg = gen_reg_rtx (SImode);
2129
2130 emit_insn (gen_lshrsi3 (reg, operands[1], shift));
2131 emit_insn (gen_ashlsi3 (operands[0], reg, shift));
2132
2133 DONE;
2134 }
2135 }
2136
2137 operands[2] = force_reg (SImode, operands[2]);
2138 }
215b30b3 2139 }
2140 "
cffb2a26 2141)
2142
25f905c2 2143; ??? Check split length for Thumb-2
a0f94409 2144(define_insn_and_split "*arm_andsi3_insn"
29e234a3 2145 [(set (match_operand:SI 0 "s_register_operand" "=r,l,r,r,r")
2146 (and:SI (match_operand:SI 1 "s_register_operand" "%r,0,r,r,r")
2147 (match_operand:SI 2 "reg_or_int_operand" "I,l,K,r,?n")))]
25f905c2 2148 "TARGET_32BIT"
5565501b 2149 "@
29e234a3 2150 and%?\\t%0, %1, %2
5565501b 2151 and%?\\t%0, %1, %2
87b22bf7 2152 bic%?\\t%0, %1, #%B2
65f68e55 2153 and%?\\t%0, %1, %2
87b22bf7 2154 #"
25f905c2 2155 "TARGET_32BIT
0438d37f 2156 && CONST_INT_P (operands[2])
a0f94409 2157 && !(const_ok_for_arm (INTVAL (operands[2]))
2158 || const_ok_for_arm (~INTVAL (operands[2])))"
2159 [(clobber (const_int 0))]
2160 "
96f57e36 2161 arm_split_constant (AND, SImode, curr_insn,
2162 INTVAL (operands[2]), operands[0], operands[1], 0);
a0f94409 2163 DONE;
2164 "
29e234a3 2165 [(set_attr "length" "4,4,4,4,16")
65f68e55 2166 (set_attr "predicable" "yes")
29e234a3 2167 (set_attr "predicable_short_it" "no,yes,no,no,no")
d82e788e 2168 (set_attr "type" "logic_imm,logic_imm,logic_reg,logic_reg,logic_imm")]
cffb2a26 2169)
2170
f7fbdd4a 2171(define_insn "*andsi3_compare0"
bd5b4116 2172 [(set (reg:CC_NOOV CC_REGNUM)
5565501b 2173 (compare:CC_NOOV
65f68e55 2174 (and:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
2175 (match_operand:SI 2 "arm_not_operand" "I,K,r"))
5565501b 2176 (const_int 0)))
65f68e55 2177 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9c08d1fa 2178 (and:SI (match_dup 1) (match_dup 2)))]
25f905c2 2179 "TARGET_32BIT"
5565501b 2180 "@
25f905c2 2181 and%.\\t%0, %1, %2
65f68e55 2182 bic%.\\t%0, %1, #%B2
2183 and%.\\t%0, %1, %2"
2184 [(set_attr "conds" "set")
d82e788e 2185 (set_attr "type" "logics_imm,logics_imm,logics_reg")]
cffb2a26 2186)
9c08d1fa 2187
f7fbdd4a 2188(define_insn "*andsi3_compare0_scratch"
bd5b4116 2189 [(set (reg:CC_NOOV CC_REGNUM)
5565501b 2190 (compare:CC_NOOV
65f68e55 2191 (and:SI (match_operand:SI 0 "s_register_operand" "r,r,r")
2192 (match_operand:SI 1 "arm_not_operand" "I,K,r"))
5565501b 2193 (const_int 0)))
65f68e55 2194 (clobber (match_scratch:SI 2 "=X,r,X"))]
25f905c2 2195 "TARGET_32BIT"
5565501b 2196 "@
2197 tst%?\\t%0, %1
65f68e55 2198 bic%.\\t%2, %0, #%B1
2199 tst%?\\t%0, %1"
2200 [(set_attr "conds" "set")
d82e788e 2201 (set_attr "type" "logics_imm,logics_imm,logics_reg")]
0d66636f 2202)
9c08d1fa 2203
f7fbdd4a 2204(define_insn "*zeroextractsi_compare0_scratch"
bd5b4116 2205 [(set (reg:CC_NOOV CC_REGNUM)
9c08d1fa 2206 (compare:CC_NOOV (zero_extract:SI
2207 (match_operand:SI 0 "s_register_operand" "r")
d952d547 2208 (match_operand 1 "const_int_operand" "n")
206ee9a2 2209 (match_operand 2 "const_int_operand" "n"))
9c08d1fa 2210 (const_int 0)))]
25f905c2 2211 "TARGET_32BIT
cffb2a26 2212 && (INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) < 32
2213 && INTVAL (operands[1]) > 0
2214 && INTVAL (operands[1]) + (INTVAL (operands[2]) & 1) <= 8
2215 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32)"
9c08d1fa 2216 "*
5c49a439 2217 operands[1] = GEN_INT (((1 << INTVAL (operands[1])) - 1)
2218 << INTVAL (operands[2]));
40dbec34 2219 output_asm_insn (\"tst%?\\t%0, %1\", operands);
e2348bcb 2220 return \"\";
0d66636f 2221 "
596e5e8f 2222 [(set_attr "conds" "set")
65f68e55 2223 (set_attr "predicable" "yes")
d952d547 2224 (set_attr "predicable_short_it" "no")
d82e788e 2225 (set_attr "type" "logics_imm")]
0d66636f 2226)
9c08d1fa 2227
f4462328 2228(define_insn_and_split "*ne_zeroextractsi"
c4034607 2229 [(set (match_operand:SI 0 "s_register_operand" "=r")
2230 (ne:SI (zero_extract:SI
2231 (match_operand:SI 1 "s_register_operand" "r")
2232 (match_operand:SI 2 "const_int_operand" "n")
2233 (match_operand:SI 3 "const_int_operand" "n"))
3b8c7f7a 2234 (const_int 0)))
2235 (clobber (reg:CC CC_REGNUM))]
25f905c2 2236 "TARGET_32BIT
cffb2a26 2237 && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
2238 && INTVAL (operands[2]) > 0
2239 && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
2240 && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)"
f4462328 2241 "#"
25f905c2 2242 "TARGET_32BIT
f4462328 2243 && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
2244 && INTVAL (operands[2]) > 0
2245 && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
2246 && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)"
2247 [(parallel [(set (reg:CC_NOOV CC_REGNUM)
2248 (compare:CC_NOOV (and:SI (match_dup 1) (match_dup 2))
2249 (const_int 0)))
2250 (set (match_dup 0) (and:SI (match_dup 1) (match_dup 2)))])
2251 (set (match_dup 0)
2252 (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
2253 (match_dup 0) (const_int 1)))]
2254 "
2255 operands[2] = GEN_INT (((1 << INTVAL (operands[2])) - 1)
2256 << INTVAL (operands[3]));
2257 "
2258 [(set_attr "conds" "clob")
25f905c2 2259 (set (attr "length")
2260 (if_then_else (eq_attr "is_thumb" "yes")
2261 (const_int 12)
1b7da4ac 2262 (const_int 8)))
2263 (set_attr "type" "multiple")]
f4462328 2264)
2265
2266(define_insn_and_split "*ne_zeroextractsi_shifted"
2267 [(set (match_operand:SI 0 "s_register_operand" "=r")
2268 (ne:SI (zero_extract:SI
2269 (match_operand:SI 1 "s_register_operand" "r")
2270 (match_operand:SI 2 "const_int_operand" "n")
2271 (const_int 0))
2272 (const_int 0)))
2273 (clobber (reg:CC CC_REGNUM))]
2274 "TARGET_ARM"
2275 "#"
2276 "TARGET_ARM"
2277 [(parallel [(set (reg:CC_NOOV CC_REGNUM)
2278 (compare:CC_NOOV (ashift:SI (match_dup 1) (match_dup 2))
2279 (const_int 0)))
2280 (set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 2)))])
2281 (set (match_dup 0)
2282 (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
2283 (match_dup 0) (const_int 1)))]
2284 "
2285 operands[2] = GEN_INT (32 - INTVAL (operands[2]));
2286 "
2287 [(set_attr "conds" "clob")
1b7da4ac 2288 (set_attr "length" "8")
2289 (set_attr "type" "multiple")]
f4462328 2290)
2291
2292(define_insn_and_split "*ite_ne_zeroextractsi"
2293 [(set (match_operand:SI 0 "s_register_operand" "=r")
2294 (if_then_else:SI (ne (zero_extract:SI
2295 (match_operand:SI 1 "s_register_operand" "r")
2296 (match_operand:SI 2 "const_int_operand" "n")
2297 (match_operand:SI 3 "const_int_operand" "n"))
2298 (const_int 0))
2299 (match_operand:SI 4 "arm_not_operand" "rIK")
2300 (const_int 0)))
2301 (clobber (reg:CC CC_REGNUM))]
2302 "TARGET_ARM
2303 && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
2304 && INTVAL (operands[2]) > 0
2305 && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
f8d7bf2f 2306 && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)
2307 && !reg_overlap_mentioned_p (operands[0], operands[4])"
f4462328 2308 "#"
2309 "TARGET_ARM
2310 && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
2311 && INTVAL (operands[2]) > 0
2312 && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
f8d7bf2f 2313 && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)
2314 && !reg_overlap_mentioned_p (operands[0], operands[4])"
f4462328 2315 [(parallel [(set (reg:CC_NOOV CC_REGNUM)
2316 (compare:CC_NOOV (and:SI (match_dup 1) (match_dup 2))
2317 (const_int 0)))
2318 (set (match_dup 0) (and:SI (match_dup 1) (match_dup 2)))])
2319 (set (match_dup 0)
2320 (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
2321 (match_dup 0) (match_dup 4)))]
2322 "
c4034607 2323 operands[2] = GEN_INT (((1 << INTVAL (operands[2])) - 1)
f4462328 2324 << INTVAL (operands[3]));
2325 "
2326 [(set_attr "conds" "clob")
1b7da4ac 2327 (set_attr "length" "8")
2328 (set_attr "type" "multiple")]
f4462328 2329)
2330
2331(define_insn_and_split "*ite_ne_zeroextractsi_shifted"
2332 [(set (match_operand:SI 0 "s_register_operand" "=r")
2333 (if_then_else:SI (ne (zero_extract:SI
2334 (match_operand:SI 1 "s_register_operand" "r")
2335 (match_operand:SI 2 "const_int_operand" "n")
2336 (const_int 0))
2337 (const_int 0))
2338 (match_operand:SI 3 "arm_not_operand" "rIK")
2339 (const_int 0)))
2340 (clobber (reg:CC CC_REGNUM))]
f8d7bf2f 2341 "TARGET_ARM && !reg_overlap_mentioned_p (operands[0], operands[3])"
f4462328 2342 "#"
f8d7bf2f 2343 "TARGET_ARM && !reg_overlap_mentioned_p (operands[0], operands[3])"
f4462328 2344 [(parallel [(set (reg:CC_NOOV CC_REGNUM)
2345 (compare:CC_NOOV (ashift:SI (match_dup 1) (match_dup 2))
2346 (const_int 0)))
2347 (set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 2)))])
2348 (set (match_dup 0)
2349 (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
2350 (match_dup 0) (match_dup 3)))]
2351 "
2352 operands[2] = GEN_INT (32 - INTVAL (operands[2]));
0d66636f 2353 "
2354 [(set_attr "conds" "clob")
1b7da4ac 2355 (set_attr "length" "8")
2356 (set_attr "type" "multiple")]
215b30b3 2357)
9c08d1fa 2358
25f905c2 2359;; ??? Use Thumb-2 has bitfield insert/extract instructions.
d7863cfe 2360(define_split
2361 [(set (match_operand:SI 0 "s_register_operand" "")
2362 (match_operator:SI 1 "shiftable_operator"
2363 [(zero_extract:SI (match_operand:SI 2 "s_register_operand" "")
2364 (match_operand:SI 3 "const_int_operand" "")
2365 (match_operand:SI 4 "const_int_operand" ""))
2366 (match_operand:SI 5 "s_register_operand" "")]))
2367 (clobber (match_operand:SI 6 "s_register_operand" ""))]
2368 "TARGET_ARM"
2369 [(set (match_dup 6) (ashift:SI (match_dup 2) (match_dup 3)))
2370 (set (match_dup 0)
2371 (match_op_dup 1
2372 [(lshiftrt:SI (match_dup 6) (match_dup 4))
2373 (match_dup 5)]))]
2374 "{
2375 HOST_WIDE_INT temp = INTVAL (operands[3]);
2376
2377 operands[3] = GEN_INT (32 - temp - INTVAL (operands[4]));
2378 operands[4] = GEN_INT (32 - temp);
2379 }"
2380)
2381
d7863cfe 2382(define_split
2383 [(set (match_operand:SI 0 "s_register_operand" "")
2384 (match_operator:SI 1 "shiftable_operator"
2385 [(sign_extract:SI (match_operand:SI 2 "s_register_operand" "")
2386 (match_operand:SI 3 "const_int_operand" "")
2387 (match_operand:SI 4 "const_int_operand" ""))
2388 (match_operand:SI 5 "s_register_operand" "")]))
2389 (clobber (match_operand:SI 6 "s_register_operand" ""))]
2390 "TARGET_ARM"
2391 [(set (match_dup 6) (ashift:SI (match_dup 2) (match_dup 3)))
2392 (set (match_dup 0)
2393 (match_op_dup 1
2394 [(ashiftrt:SI (match_dup 6) (match_dup 4))
2395 (match_dup 5)]))]
2396 "{
2397 HOST_WIDE_INT temp = INTVAL (operands[3]);
2398
2399 operands[3] = GEN_INT (32 - temp - INTVAL (operands[4]));
2400 operands[4] = GEN_INT (32 - temp);
2401 }"
2402)
2403
a42059fd 2404;;; ??? This pattern is bogus. If operand3 has bits outside the range
2405;;; represented by the bitfield, then this will produce incorrect results.
2406;;; Somewhere, the value needs to be truncated. On targets like the m68k,
ceb2fe0f 2407;;; which have a real bit-field insert instruction, the truncation happens
2408;;; in the bit-field insert instruction itself. Since arm does not have a
2409;;; bit-field insert instruction, we would have to emit code here to truncate
a42059fd 2410;;; the value before we insert. This loses some of the advantage of having
2411;;; this insv pattern, so this pattern needs to be reevalutated.
2412
8a18b90c 2413(define_expand "insv"
eb04cafb 2414 [(set (zero_extract (match_operand 0 "nonimmediate_operand" "")
2415 (match_operand 1 "general_operand" "")
2416 (match_operand 2 "general_operand" ""))
2417 (match_operand 3 "reg_or_int_operand" ""))]
8b054d5a 2418 "TARGET_ARM || arm_arch_thumb2"
8a18b90c 2419 "
215b30b3 2420 {
2421 int start_bit = INTVAL (operands[2]);
2422 int width = INTVAL (operands[1]);
2423 HOST_WIDE_INT mask = (((HOST_WIDE_INT)1) << width) - 1;
2424 rtx target, subtarget;
2425
8b054d5a 2426 if (arm_arch_thumb2)
2427 {
eb04cafb 2428 if (unaligned_access && MEM_P (operands[0])
2429 && s_register_operand (operands[3], GET_MODE (operands[3]))
2430 && (width == 16 || width == 32) && (start_bit % BITS_PER_UNIT) == 0)
8b054d5a 2431 {
eb04cafb 2432 rtx base_addr;
2433
2434 if (BYTES_BIG_ENDIAN)
2435 start_bit = GET_MODE_BITSIZE (GET_MODE (operands[3])) - width
2436 - start_bit;
8b054d5a 2437
eb04cafb 2438 if (width == 32)
8b054d5a 2439 {
eb04cafb 2440 base_addr = adjust_address (operands[0], SImode,
2441 start_bit / BITS_PER_UNIT);
2442 emit_insn (gen_unaligned_storesi (base_addr, operands[3]));
8b054d5a 2443 }
eb04cafb 2444 else
2445 {
2446 rtx tmp = gen_reg_rtx (HImode);
8b054d5a 2447
eb04cafb 2448 base_addr = adjust_address (operands[0], HImode,
2449 start_bit / BITS_PER_UNIT);
2450 emit_move_insn (tmp, gen_lowpart (HImode, operands[3]));
2451 emit_insn (gen_unaligned_storehi (base_addr, tmp));
2452 }
2453 DONE;
8b054d5a 2454 }
eb04cafb 2455 else if (s_register_operand (operands[0], GET_MODE (operands[0])))
8b054d5a 2456 {
eb04cafb 2457 bool use_bfi = TRUE;
8b054d5a 2458
0438d37f 2459 if (CONST_INT_P (operands[3]))
eb04cafb 2460 {
2461 HOST_WIDE_INT val = INTVAL (operands[3]) & mask;
2462
2463 if (val == 0)
2464 {
2465 emit_insn (gen_insv_zero (operands[0], operands[1],
2466 operands[2]));
2467 DONE;
2468 }
2469
2470 /* See if the set can be done with a single orr instruction. */
2471 if (val == mask && const_ok_for_arm (val << start_bit))
2472 use_bfi = FALSE;
2473 }
2474
2475 if (use_bfi)
2476 {
0438d37f 2477 if (!REG_P (operands[3]))
eb04cafb 2478 operands[3] = force_reg (SImode, operands[3]);
2479
2480 emit_insn (gen_insv_t2 (operands[0], operands[1], operands[2],
2481 operands[3]));
2482 DONE;
2483 }
8b054d5a 2484 }
eb04cafb 2485 else
2486 FAIL;
8b054d5a 2487 }
2488
eb04cafb 2489 if (!s_register_operand (operands[0], GET_MODE (operands[0])))
2490 FAIL;
2491
3f8fde42 2492 target = copy_rtx (operands[0]);
215b30b3 2493 /* Avoid using a subreg as a subtarget, and avoid writing a paradoxical
2494 subreg as the final target. */
2495 if (GET_CODE (target) == SUBREG)
2496 {
2497 subtarget = gen_reg_rtx (SImode);
2498 if (GET_MODE_SIZE (GET_MODE (SUBREG_REG (target)))
2499 < GET_MODE_SIZE (SImode))
2500 target = SUBREG_REG (target);
2501 }
2502 else
2503 subtarget = target;
8a18b90c 2504
0438d37f 2505 if (CONST_INT_P (operands[3]))
215b30b3 2506 {
2507 /* Since we are inserting a known constant, we may be able to
2508 reduce the number of bits that we have to clear so that
2509 the mask becomes simple. */
2510 /* ??? This code does not check to see if the new mask is actually
2511 simpler. It may not be. */
2512 rtx op1 = gen_reg_rtx (SImode);
2513 /* ??? Truncate operand3 to fit in the bitfield. See comment before
2514 start of this pattern. */
2515 HOST_WIDE_INT op3_value = mask & INTVAL (operands[3]);
2516 HOST_WIDE_INT mask2 = ((mask & ~op3_value) << start_bit);
2517
c5b3a71b 2518 emit_insn (gen_andsi3 (op1, operands[0],
2519 gen_int_mode (~mask2, SImode)));
215b30b3 2520 emit_insn (gen_iorsi3 (subtarget, op1,
4292ca6b 2521 gen_int_mode (op3_value << start_bit, SImode)));
215b30b3 2522 }
2523 else if (start_bit == 0
2524 && !(const_ok_for_arm (mask)
2525 || const_ok_for_arm (~mask)))
2526 {
2527 /* A Trick, since we are setting the bottom bits in the word,
2528 we can shift operand[3] up, operand[0] down, OR them together
2529 and rotate the result back again. This takes 3 insns, and
5910bb95 2530 the third might be mergeable into another op. */
215b30b3 2531 /* The shift up copes with the possibility that operand[3] is
2532 wider than the bitfield. */
2533 rtx op0 = gen_reg_rtx (SImode);
2534 rtx op1 = gen_reg_rtx (SImode);
2535
2536 emit_insn (gen_ashlsi3 (op0, operands[3], GEN_INT (32 - width)));
2537 emit_insn (gen_lshrsi3 (op1, operands[0], operands[1]));
2538 emit_insn (gen_iorsi3 (op1, op1, op0));
2539 emit_insn (gen_rotlsi3 (subtarget, op1, operands[1]));
2540 }
2541 else if ((width + start_bit == 32)
2542 && !(const_ok_for_arm (mask)
2543 || const_ok_for_arm (~mask)))
2544 {
2545 /* Similar trick, but slightly less efficient. */
8a18b90c 2546
215b30b3 2547 rtx op0 = gen_reg_rtx (SImode);
2548 rtx op1 = gen_reg_rtx (SImode);
8a18b90c 2549
215b30b3 2550 emit_insn (gen_ashlsi3 (op0, operands[3], GEN_INT (32 - width)));
2551 emit_insn (gen_ashlsi3 (op1, operands[0], operands[1]));
2552 emit_insn (gen_lshrsi3 (op1, op1, operands[1]));
2553 emit_insn (gen_iorsi3 (subtarget, op1, op0));
2554 }
2555 else
2556 {
c5b3a71b 2557 rtx op0 = gen_int_mode (mask, SImode);
215b30b3 2558 rtx op1 = gen_reg_rtx (SImode);
2559 rtx op2 = gen_reg_rtx (SImode);
8a18b90c 2560
215b30b3 2561 if (!(const_ok_for_arm (mask) || const_ok_for_arm (~mask)))
2562 {
2563 rtx tmp = gen_reg_rtx (SImode);
8a18b90c 2564
215b30b3 2565 emit_insn (gen_movsi (tmp, op0));
2566 op0 = tmp;
2567 }
8a18b90c 2568
215b30b3 2569 /* Mask out any bits in operand[3] that are not needed. */
2570 emit_insn (gen_andsi3 (op1, operands[3], op0));
8a18b90c 2571
0438d37f 2572 if (CONST_INT_P (op0)
215b30b3 2573 && (const_ok_for_arm (mask << start_bit)
2574 || const_ok_for_arm (~(mask << start_bit))))
2575 {
c5b3a71b 2576 op0 = gen_int_mode (~(mask << start_bit), SImode);
215b30b3 2577 emit_insn (gen_andsi3 (op2, operands[0], op0));
2578 }
2579 else
2580 {
0438d37f 2581 if (CONST_INT_P (op0))
215b30b3 2582 {
2583 rtx tmp = gen_reg_rtx (SImode);
8a18b90c 2584
215b30b3 2585 emit_insn (gen_movsi (tmp, op0));
2586 op0 = tmp;
2587 }
2588
2589 if (start_bit != 0)
2590 emit_insn (gen_ashlsi3 (op0, op0, operands[2]));
a42059fd 2591
215b30b3 2592 emit_insn (gen_andsi_notsi_si (op2, operands[0], op0));
2593 }
8a18b90c 2594
215b30b3 2595 if (start_bit != 0)
2596 emit_insn (gen_ashlsi3 (op1, op1, operands[2]));
8a18b90c 2597
215b30b3 2598 emit_insn (gen_iorsi3 (subtarget, op1, op2));
2599 }
f082f1c4 2600
215b30b3 2601 if (subtarget != target)
2602 {
2603 /* If TARGET is still a SUBREG, then it must be wider than a word,
2604 so we must be careful only to set the subword we were asked to. */
2605 if (GET_CODE (target) == SUBREG)
2606 emit_move_insn (target, subtarget);
2607 else
2608 emit_move_insn (target, gen_lowpart (GET_MODE (target), subtarget));
2609 }
8a18b90c 2610
215b30b3 2611 DONE;
2612 }"
2613)
8a18b90c 2614
8b054d5a 2615(define_insn "insv_zero"
2616 [(set (zero_extract:SI (match_operand:SI 0 "s_register_operand" "+r")
809003b3 2617 (match_operand:SI 1 "const_int_M_operand" "M")
2618 (match_operand:SI 2 "const_int_M_operand" "M"))
8b054d5a 2619 (const_int 0))]
2620 "arm_arch_thumb2"
2621 "bfc%?\t%0, %2, %1"
2622 [(set_attr "length" "4")
d952d547 2623 (set_attr "predicable" "yes")
d82e788e 2624 (set_attr "predicable_short_it" "no")
2625 (set_attr "type" "bfm")]
8b054d5a 2626)
2627
2628(define_insn "insv_t2"
2629 [(set (zero_extract:SI (match_operand:SI 0 "s_register_operand" "+r")
809003b3 2630 (match_operand:SI 1 "const_int_M_operand" "M")
2631 (match_operand:SI 2 "const_int_M_operand" "M"))
8b054d5a 2632 (match_operand:SI 3 "s_register_operand" "r"))]
2633 "arm_arch_thumb2"
2634 "bfi%?\t%0, %3, %2, %1"
2635 [(set_attr "length" "4")
d952d547 2636 (set_attr "predicable" "yes")
d82e788e 2637 (set_attr "predicable_short_it" "no")
2638 (set_attr "type" "bfm")]
8b054d5a 2639)
2640
215b30b3 2641; constants for op 2 will never be given to these patterns.
a0f94409 2642(define_insn_and_split "*anddi_notdi_di"
9c08d1fa 2643 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
e5fea38e 2644 (and:DI (not:DI (match_operand:DI 1 "s_register_operand" "0,r"))
2645 (match_operand:DI 2 "s_register_operand" "r,0")))]
25f905c2 2646 "TARGET_32BIT"
f6ebffac 2647 "#"
e2669ea7 2648 "TARGET_32BIT && reload_completed
2649 && ! (TARGET_NEON && IS_VFP_REGNUM (REGNO (operands[0])))
2650 && ! IS_IWMMXT_REGNUM (REGNO (operands[0]))"
a0f94409 2651 [(set (match_dup 0) (and:SI (not:SI (match_dup 1)) (match_dup 2)))
2652 (set (match_dup 3) (and:SI (not:SI (match_dup 4)) (match_dup 5)))]
2653 "
2654 {
2655 operands[3] = gen_highpart (SImode, operands[0]);
2656 operands[0] = gen_lowpart (SImode, operands[0]);
2657 operands[4] = gen_highpart (SImode, operands[1]);
2658 operands[1] = gen_lowpart (SImode, operands[1]);
2659 operands[5] = gen_highpart (SImode, operands[2]);
2660 operands[2] = gen_lowpart (SImode, operands[2]);
2661 }"
0d66636f 2662 [(set_attr "length" "8")
1b7da4ac 2663 (set_attr "predicable" "yes")
2664 (set_attr "type" "multiple")]
0d66636f 2665)
d952d547 2666
a0f94409 2667(define_insn_and_split "*anddi_notzesidi_di"
9c08d1fa 2668 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2669 (and:DI (not:DI (zero_extend:DI
2670 (match_operand:SI 2 "s_register_operand" "r,r")))
e2348bcb 2671 (match_operand:DI 1 "s_register_operand" "0,?r")))]
25f905c2 2672 "TARGET_32BIT"
e2348bcb 2673 "@
97499065 2674 bic%?\\t%Q0, %Q1, %2
f6ebffac 2675 #"
a0f94409 2676 ; (not (zero_extend ...)) allows us to just copy the high word from
2677 ; operand1 to operand0.
25f905c2 2678 "TARGET_32BIT
a0f94409 2679 && reload_completed
2680 && operands[0] != operands[1]"
5a097f7d 2681 [(set (match_dup 0) (and:SI (not:SI (match_dup 2)) (match_dup 1)))
a0f94409 2682 (set (match_dup 3) (match_dup 4))]
2683 "
2684 {
2685 operands[3] = gen_highpart (SImode, operands[0]);
2686 operands[0] = gen_lowpart (SImode, operands[0]);
2687 operands[4] = gen_highpart (SImode, operands[1]);
2688 operands[1] = gen_lowpart (SImode, operands[1]);
2689 }"
0d66636f 2690 [(set_attr "length" "4,8")
d952d547 2691 (set_attr "predicable" "yes")
1b7da4ac 2692 (set_attr "predicable_short_it" "no")
2693 (set_attr "type" "multiple")]
0d66636f 2694)
d952d547 2695
d8cd5fa0 2696(define_insn_and_split "*anddi_notdi_zesidi"
2697 [(set (match_operand:DI 0 "s_register_operand" "=r")
2698 (and:DI (not:DI (match_operand:DI 2 "s_register_operand" "r"))
2699 (zero_extend:DI
2700 (match_operand:SI 1 "s_register_operand" "r"))))]
2701 "TARGET_32BIT"
2702 "#"
2703 "TARGET_32BIT && reload_completed"
2704 [(set (match_dup 0) (and:SI (not:SI (match_dup 2)) (match_dup 1)))
2705 (set (match_dup 3) (const_int 0))]
2706 "
2707 {
2708 operands[3] = gen_highpart (SImode, operands[0]);
2709 operands[0] = gen_lowpart (SImode, operands[0]);
2710 operands[2] = gen_lowpart (SImode, operands[2]);
2711 }"
2712 [(set_attr "length" "8")
2713 (set_attr "predicable" "yes")
2714 (set_attr "predicable_short_it" "no")
2715 (set_attr "type" "multiple")]
2716)
2717
a0f94409 2718(define_insn_and_split "*anddi_notsesidi_di"
9c08d1fa 2719 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2720 (and:DI (not:DI (sign_extend:DI
2721 (match_operand:SI 2 "s_register_operand" "r,r")))
5a097f7d 2722 (match_operand:DI 1 "s_register_operand" "0,r")))]
25f905c2 2723 "TARGET_32BIT"
f6ebffac 2724 "#"
25f905c2 2725 "TARGET_32BIT && reload_completed"
5a097f7d 2726 [(set (match_dup 0) (and:SI (not:SI (match_dup 2)) (match_dup 1)))
a0f94409 2727 (set (match_dup 3) (and:SI (not:SI
2728 (ashiftrt:SI (match_dup 2) (const_int 31)))
2729 (match_dup 4)))]
2730 "
2731 {
2732 operands[3] = gen_highpart (SImode, operands[0]);
2733 operands[0] = gen_lowpart (SImode, operands[0]);
2734 operands[4] = gen_highpart (SImode, operands[1]);
2735 operands[1] = gen_lowpart (SImode, operands[1]);
2736 }"
0d66636f 2737 [(set_attr "length" "8")
d952d547 2738 (set_attr "predicable" "yes")
1b7da4ac 2739 (set_attr "predicable_short_it" "no")
2740 (set_attr "type" "multiple")]
0d66636f 2741)
d952d547 2742
8a18b90c 2743(define_insn "andsi_notsi_si"
9c08d1fa 2744 [(set (match_operand:SI 0 "s_register_operand" "=r")
2745 (and:SI (not:SI (match_operand:SI 2 "s_register_operand" "r"))
2746 (match_operand:SI 1 "s_register_operand" "r")))]
25f905c2 2747 "TARGET_32BIT"
0d66636f 2748 "bic%?\\t%0, %1, %2"
d952d547 2749 [(set_attr "predicable" "yes")
1b7da4ac 2750 (set_attr "predicable_short_it" "no")
2751 (set_attr "type" "logic_reg")]
0d66636f 2752)
b11cae9e 2753
8a18b90c 2754(define_insn "andsi_not_shiftsi_si"
a2cd141b 2755 [(set (match_operand:SI 0 "s_register_operand" "=r")
2756 (and:SI (not:SI (match_operator:SI 4 "shift_operator"
2757 [(match_operand:SI 2 "s_register_operand" "r")
2758 (match_operand:SI 3 "arm_rhs_operand" "rM")]))
2759 (match_operand:SI 1 "s_register_operand" "r")))]
cffb2a26 2760 "TARGET_ARM"
6c4c2133 2761 "bic%?\\t%0, %1, %2%S4"
344495ea 2762 [(set_attr "predicable" "yes")
331beb1a 2763 (set_attr "shift" "2")
a2cd141b 2764 (set (attr "type") (if_then_else (match_operand 3 "const_int_operand" "")
d82e788e 2765 (const_string "logic_shift_imm")
2766 (const_string "logic_shift_reg")))]
6c4c2133 2767)
8a18b90c 2768
f7fbdd4a 2769(define_insn "*andsi_notsi_si_compare0"
bd5b4116 2770 [(set (reg:CC_NOOV CC_REGNUM)
e2348bcb 2771 (compare:CC_NOOV
2772 (and:SI (not:SI (match_operand:SI 2 "s_register_operand" "r"))
2773 (match_operand:SI 1 "s_register_operand" "r"))
2774 (const_int 0)))
9c08d1fa 2775 (set (match_operand:SI 0 "s_register_operand" "=r")
2776 (and:SI (not:SI (match_dup 2)) (match_dup 1)))]
25f905c2 2777 "TARGET_32BIT"
2778 "bic%.\\t%0, %1, %2"
d82e788e 2779 [(set_attr "conds" "set")
2780 (set_attr "type" "logics_shift_reg")]
0d66636f 2781)
9c08d1fa 2782
f7fbdd4a 2783(define_insn "*andsi_notsi_si_compare0_scratch"
bd5b4116 2784 [(set (reg:CC_NOOV CC_REGNUM)
e2348bcb 2785 (compare:CC_NOOV
2786 (and:SI (not:SI (match_operand:SI 2 "s_register_operand" "r"))
2787 (match_operand:SI 1 "s_register_operand" "r"))
2788 (const_int 0)))
9c08d1fa 2789 (clobber (match_scratch:SI 0 "=r"))]
25f905c2 2790 "TARGET_32BIT"
2791 "bic%.\\t%0, %1, %2"
d82e788e 2792 [(set_attr "conds" "set")
2793 (set_attr "type" "logics_shift_reg")]
0d66636f 2794)
9c08d1fa 2795
e2669ea7 2796(define_expand "iordi3"
2797 [(set (match_operand:DI 0 "s_register_operand" "")
2798 (ior:DI (match_operand:DI 1 "s_register_operand" "")
2799 (match_operand:DI 2 "neon_logic_op2" "")))]
2800 "TARGET_32BIT"
2801 ""
2802)
2803
74d6113f 2804(define_insn_and_split "*iordi3_insn"
2805 [(set (match_operand:DI 0 "s_register_operand" "=w,w ,&r,&r,&r,&r,?w,?w")
2806 (ior:DI (match_operand:DI 1 "s_register_operand" "%w,0 ,0 ,r ,0 ,r ,w ,0")
e0fe6977 2807 (match_operand:DI 2 "arm_iordi_operand_neon" "w ,Dl,r ,r ,Df,Df,w ,Dl")))]
74d6113f 2808 "TARGET_32BIT && !TARGET_IWMMXT"
2809 {
2810 switch (which_alternative)
2811 {
2812 case 0: /* fall through */
2813 case 6: return "vorr\t%P0, %P1, %P2";
2814 case 1: /* fall through */
2815 case 7: return neon_output_logic_immediate ("vorr", &operands[2],
2816 DImode, 0, VALID_NEON_QREG_MODE (DImode));
2817 case 2:
2818 case 3:
2819 case 4:
2820 case 5:
2821 return "#";
2822 default: gcc_unreachable ();
2823 }
2824 }
2825 "TARGET_32BIT && !TARGET_IWMMXT && reload_completed
2826 && !(IS_VFP_REGNUM (REGNO (operands[0])))"
2827 [(set (match_dup 3) (match_dup 4))
2828 (set (match_dup 5) (match_dup 6))]
2829 "
2830 {
2831 operands[3] = gen_lowpart (SImode, operands[0]);
2832 operands[5] = gen_highpart (SImode, operands[0]);
2833
2834 operands[4] = simplify_gen_binary (IOR, SImode,
2835 gen_lowpart (SImode, operands[1]),
2836 gen_lowpart (SImode, operands[2]));
2837 operands[6] = simplify_gen_binary (IOR, SImode,
2838 gen_highpart (SImode, operands[1]),
2839 gen_highpart_mode (SImode, DImode, operands[2]));
2840
2841 }"
32093010 2842 [(set_attr "type" "neon_logic,neon_logic,multiple,multiple,multiple,\
2843 multiple,neon_logic,neon_logic")
e0fe6977 2844 (set_attr "length" "*,*,8,8,8,8,*,*")
74d6113f 2845 (set_attr "arch" "neon_for_64bits,neon_for_64bits,*,*,*,*,avoid_neon_for_64bits,avoid_neon_for_64bits")]
cffb2a26 2846)
9c08d1fa 2847
f7fbdd4a 2848(define_insn "*iordi_zesidi_di"
9c08d1fa 2849 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2850 (ior:DI (zero_extend:DI
2851 (match_operand:SI 2 "s_register_operand" "r,r"))
e2348bcb 2852 (match_operand:DI 1 "s_register_operand" "0,?r")))]
25f905c2 2853 "TARGET_32BIT"
e2348bcb 2854 "@
97499065 2855 orr%?\\t%Q0, %Q1, %2
f6ebffac 2856 #"
0d66636f 2857 [(set_attr "length" "4,8")
d952d547 2858 (set_attr "predicable" "yes")
1b7da4ac 2859 (set_attr "predicable_short_it" "no")
2860 (set_attr "type" "logic_reg,multiple")]
cffb2a26 2861)
9c08d1fa 2862
f7fbdd4a 2863(define_insn "*iordi_sesidi_di"
9c08d1fa 2864 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2865 (ior:DI (sign_extend:DI
2866 (match_operand:SI 2 "s_register_operand" "r,r"))
e5fea38e 2867 (match_operand:DI 1 "s_register_operand" "0,r")))]
25f905c2 2868 "TARGET_32BIT"
f6ebffac 2869 "#"
0d66636f 2870 [(set_attr "length" "8")
1b7da4ac 2871 (set_attr "predicable" "yes")
2872 (set_attr "type" "multiple")]
cffb2a26 2873)
9c08d1fa 2874
87b22bf7 2875(define_expand "iorsi3"
cffb2a26 2876 [(set (match_operand:SI 0 "s_register_operand" "")
87b22bf7 2877 (ior:SI (match_operand:SI 1 "s_register_operand" "")
2878 (match_operand:SI 2 "reg_or_int_operand" "")))]
cffb2a26 2879 "TARGET_EITHER"
87b22bf7 2880 "
0438d37f 2881 if (CONST_INT_P (operands[2]))
87b22bf7 2882 {
25f905c2 2883 if (TARGET_32BIT)
cffb2a26 2884 {
96f57e36 2885 arm_split_constant (IOR, SImode, NULL_RTX,
2886 INTVAL (operands[2]), operands[0], operands[1],
e1ba4a27 2887 optimize && can_create_pseudo_p ());
cffb2a26 2888 DONE;
2889 }
25f905c2 2890 else /* TARGET_THUMB1 */
923ffadb 2891 {
2892 rtx tmp = force_reg (SImode, operands[2]);
2893 if (rtx_equal_p (operands[0], operands[1]))
2894 operands[2] = tmp;
2895 else
2896 {
2897 operands[2] = operands[1];
2898 operands[1] = tmp;
2899 }
2900 }
87b22bf7 2901 }
cffb2a26 2902 "
2903)
87b22bf7 2904
d5d4dc8d 2905(define_insn_and_split "*iorsi3_insn"
29e234a3 2906 [(set (match_operand:SI 0 "s_register_operand" "=r,l,r,r,r")
2907 (ior:SI (match_operand:SI 1 "s_register_operand" "%r,0,r,r,r")
2908 (match_operand:SI 2 "reg_or_int_operand" "I,l,K,r,?n")))]
d5d4dc8d 2909 "TARGET_32BIT"
87b22bf7 2910 "@
29e234a3 2911 orr%?\\t%0, %1, %2
87b22bf7 2912 orr%?\\t%0, %1, %2
d5d4dc8d 2913 orn%?\\t%0, %1, #%B2
65f68e55 2914 orr%?\\t%0, %1, %2
87b22bf7 2915 #"
d5d4dc8d 2916 "TARGET_32BIT
0438d37f 2917 && CONST_INT_P (operands[2])
d5d4dc8d 2918 && !(const_ok_for_arm (INTVAL (operands[2]))
2919 || (TARGET_THUMB2 && const_ok_for_arm (~INTVAL (operands[2]))))"
a0f94409 2920 [(clobber (const_int 0))]
d5d4dc8d 2921{
29e234a3 2922 arm_split_constant (IOR, SImode, curr_insn,
96f57e36 2923 INTVAL (operands[2]), operands[0], operands[1], 0);
a0f94409 2924 DONE;
d5d4dc8d 2925}
29e234a3 2926 [(set_attr "length" "4,4,4,4,16")
2927 (set_attr "arch" "32,t2,t2,32,32")
65f68e55 2928 (set_attr "predicable" "yes")
29e234a3 2929 (set_attr "predicable_short_it" "no,yes,no,no,no")
d82e788e 2930 (set_attr "type" "logic_imm,logic_reg,logic_imm,logic_reg,logic_reg")]
65f68e55 2931)
cffb2a26 2932
a0f94409 2933(define_peephole2
2934 [(match_scratch:SI 3 "r")
372575c7 2935 (set (match_operand:SI 0 "arm_general_register_operand" "")
2936 (ior:SI (match_operand:SI 1 "arm_general_register_operand" "")
87b22bf7 2937 (match_operand:SI 2 "const_int_operand" "")))]
90560cad 2938 "TARGET_ARM
a0f94409 2939 && !const_ok_for_arm (INTVAL (operands[2]))
2940 && const_ok_for_arm (~INTVAL (operands[2]))"
2941 [(set (match_dup 3) (match_dup 2))
2942 (set (match_dup 0) (ior:SI (match_dup 1) (match_dup 3)))]
2943 ""
215b30b3 2944)
a0f94409 2945
f7fbdd4a 2946(define_insn "*iorsi3_compare0"
bd5b4116 2947 [(set (reg:CC_NOOV CC_REGNUM)
65f68e55 2948 (compare:CC_NOOV (ior:SI (match_operand:SI 1 "s_register_operand" "%r,r")
2949 (match_operand:SI 2 "arm_rhs_operand" "I,r"))
9c08d1fa 2950 (const_int 0)))
65f68e55 2951 (set (match_operand:SI 0 "s_register_operand" "=r,r")
9c08d1fa 2952 (ior:SI (match_dup 1) (match_dup 2)))]
25f905c2 2953 "TARGET_32BIT"
2954 "orr%.\\t%0, %1, %2"
65f68e55 2955 [(set_attr "conds" "set")
d82e788e 2956 (set_attr "type" "logics_imm,logics_reg")]
cffb2a26 2957)
9c08d1fa 2958
f7fbdd4a 2959(define_insn "*iorsi3_compare0_scratch"
bd5b4116 2960 [(set (reg:CC_NOOV CC_REGNUM)
65f68e55 2961 (compare:CC_NOOV (ior:SI (match_operand:SI 1 "s_register_operand" "%r,r")
2962 (match_operand:SI 2 "arm_rhs_operand" "I,r"))
9c08d1fa 2963 (const_int 0)))
65f68e55 2964 (clobber (match_scratch:SI 0 "=r,r"))]
25f905c2 2965 "TARGET_32BIT"
2966 "orr%.\\t%0, %1, %2"
65f68e55 2967 [(set_attr "conds" "set")
d82e788e 2968 (set_attr "type" "logics_imm,logics_reg")]
0d66636f 2969)
9c08d1fa 2970
e2669ea7 2971(define_expand "xordi3"
2972 [(set (match_operand:DI 0 "s_register_operand" "")
2973 (xor:DI (match_operand:DI 1 "s_register_operand" "")
8ee7dc6f 2974 (match_operand:DI 2 "arm_xordi_operand" "")))]
e2669ea7 2975 "TARGET_32BIT"
2976 ""
2977)
2978
8ee7dc6f 2979(define_insn_and_split "*xordi3_insn"
2980 [(set (match_operand:DI 0 "s_register_operand" "=w,&r,&r,&r,&r,?w")
205c3b0a 2981 (xor:DI (match_operand:DI 1 "s_register_operand" "%w ,0,r ,0 ,r ,w")
8ee7dc6f 2982 (match_operand:DI 2 "arm_xordi_operand" "w ,r ,r ,Dg,Dg,w")))]
2983 "TARGET_32BIT && !TARGET_IWMMXT"
2984{
2985 switch (which_alternative)
2986 {
2987 case 1:
2988 case 2:
2989 case 3:
2990 case 4: /* fall through */
2991 return "#";
2992 case 0: /* fall through */
2993 case 5: return "veor\t%P0, %P1, %P2";
2994 default: gcc_unreachable ();
2995 }
2996}
2997 "TARGET_32BIT && !TARGET_IWMMXT && reload_completed
2998 && !(IS_VFP_REGNUM (REGNO (operands[0])))"
2999 [(set (match_dup 3) (match_dup 4))
3000 (set (match_dup 5) (match_dup 6))]
3001 "
3002 {
3003 operands[3] = gen_lowpart (SImode, operands[0]);
3004 operands[5] = gen_highpart (SImode, operands[0]);
3005
3006 operands[4] = simplify_gen_binary (XOR, SImode,
3007 gen_lowpart (SImode, operands[1]),
3008 gen_lowpart (SImode, operands[2]));
3009 operands[6] = simplify_gen_binary (XOR, SImode,
3010 gen_highpart (SImode, operands[1]),
3011 gen_highpart_mode (SImode, DImode, operands[2]));
3012
3013 }"
3014 [(set_attr "length" "*,8,8,8,8,*")
32093010 3015 (set_attr "type" "neon_logic,multiple,multiple,multiple,multiple,neon_logic")
8ee7dc6f 3016 (set_attr "arch" "neon_for_64bits,*,*,*,*,avoid_neon_for_64bits")]
cffb2a26 3017)
9c08d1fa 3018
f7fbdd4a 3019(define_insn "*xordi_zesidi_di"
9c08d1fa 3020 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
3021 (xor:DI (zero_extend:DI
3022 (match_operand:SI 2 "s_register_operand" "r,r"))
e2348bcb 3023 (match_operand:DI 1 "s_register_operand" "0,?r")))]
25f905c2 3024 "TARGET_32BIT"
e2348bcb 3025 "@
97499065 3026 eor%?\\t%Q0, %Q1, %2
f6ebffac 3027 #"
0d66636f 3028 [(set_attr "length" "4,8")
d952d547 3029 (set_attr "predicable" "yes")
1b7da4ac 3030 (set_attr "predicable_short_it" "no")
3031 (set_attr "type" "logic_reg")]
cffb2a26 3032)
9c08d1fa 3033
f7fbdd4a 3034(define_insn "*xordi_sesidi_di"
9c08d1fa 3035 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
3036 (xor:DI (sign_extend:DI
3037 (match_operand:SI 2 "s_register_operand" "r,r"))
e5fea38e 3038 (match_operand:DI 1 "s_register_operand" "0,r")))]
25f905c2 3039 "TARGET_32BIT"
f6ebffac 3040 "#"
0d66636f 3041 [(set_attr "length" "8")
1b7da4ac 3042 (set_attr "predicable" "yes")
3043 (set_attr "type" "multiple")]
cffb2a26 3044)
9c08d1fa 3045
cffb2a26 3046(define_expand "xorsi3"
3047 [(set (match_operand:SI 0 "s_register_operand" "")
3048 (xor:SI (match_operand:SI 1 "s_register_operand" "")
923ffadb 3049 (match_operand:SI 2 "reg_or_int_operand" "")))]
cffb2a26 3050 "TARGET_EITHER"
0438d37f 3051 "if (CONST_INT_P (operands[2]))
923ffadb 3052 {
3053 if (TARGET_32BIT)
3054 {
3055 arm_split_constant (XOR, SImode, NULL_RTX,
3056 INTVAL (operands[2]), operands[0], operands[1],
3057 optimize && can_create_pseudo_p ());
3058 DONE;
3059 }
3060 else /* TARGET_THUMB1 */
3061 {
3062 rtx tmp = force_reg (SImode, operands[2]);
3063 if (rtx_equal_p (operands[0], operands[1]))
3064 operands[2] = tmp;
3065 else
3066 {
3067 operands[2] = operands[1];
3068 operands[1] = tmp;
3069 }
3070 }
3071 }"
cffb2a26 3072)
3073
5dcb35d9 3074(define_insn_and_split "*arm_xorsi3"
29e234a3 3075 [(set (match_operand:SI 0 "s_register_operand" "=r,l,r,r")
3076 (xor:SI (match_operand:SI 1 "s_register_operand" "%r,0,r,r")
3077 (match_operand:SI 2 "reg_or_int_operand" "I,l,r,?n")))]
25f905c2 3078 "TARGET_32BIT"
5dcb35d9 3079 "@
29e234a3 3080 eor%?\\t%0, %1, %2
65f68e55 3081 eor%?\\t%0, %1, %2
5dcb35d9 3082 eor%?\\t%0, %1, %2
3083 #"
3084 "TARGET_32BIT
0438d37f 3085 && CONST_INT_P (operands[2])
5dcb35d9 3086 && !const_ok_for_arm (INTVAL (operands[2]))"
3087 [(clobber (const_int 0))]
3088{
3089 arm_split_constant (XOR, SImode, curr_insn,
3090 INTVAL (operands[2]), operands[0], operands[1], 0);
3091 DONE;
3092}
29e234a3 3093 [(set_attr "length" "4,4,4,16")
65f68e55 3094 (set_attr "predicable" "yes")
29e234a3 3095 (set_attr "predicable_short_it" "no,yes,no,no")
1b7da4ac 3096 (set_attr "type" "logic_imm,logic_reg,logic_reg,multiple")]
cffb2a26 3097)
3098
f7fbdd4a 3099(define_insn "*xorsi3_compare0"
bd5b4116 3100 [(set (reg:CC_NOOV CC_REGNUM)
65f68e55 3101 (compare:CC_NOOV (xor:SI (match_operand:SI 1 "s_register_operand" "r,r")
3102 (match_operand:SI 2 "arm_rhs_operand" "I,r"))
9c08d1fa 3103 (const_int 0)))
65f68e55 3104 (set (match_operand:SI 0 "s_register_operand" "=r,r")
9c08d1fa 3105 (xor:SI (match_dup 1) (match_dup 2)))]
25f905c2 3106 "TARGET_32BIT"
3107 "eor%.\\t%0, %1, %2"
65f68e55 3108 [(set_attr "conds" "set")
d82e788e 3109 (set_attr "type" "logics_imm,logics_reg")]
0d66636f 3110)
9c08d1fa 3111
f7fbdd4a 3112(define_insn "*xorsi3_compare0_scratch"
bd5b4116 3113 [(set (reg:CC_NOOV CC_REGNUM)
65f68e55 3114 (compare:CC_NOOV (xor:SI (match_operand:SI 0 "s_register_operand" "r,r")
3115 (match_operand:SI 1 "arm_rhs_operand" "I,r"))
9c08d1fa 3116 (const_int 0)))]
25f905c2 3117 "TARGET_32BIT"
40dbec34 3118 "teq%?\\t%0, %1"
65f68e55 3119 [(set_attr "conds" "set")
d82e788e 3120 (set_attr "type" "logics_imm,logics_reg")]
cffb2a26 3121)
9c08d1fa 3122
215b30b3 3123; By splitting (IOR (AND (NOT A) (NOT B)) C) as D = AND (IOR A B) (NOT C),
3124; (NOT D) we can sometimes merge the final NOT into one of the following
3125; insns.
9c08d1fa 3126
3127(define_split
a058e94a 3128 [(set (match_operand:SI 0 "s_register_operand" "")
3129 (ior:SI (and:SI (not:SI (match_operand:SI 1 "s_register_operand" ""))
3130 (not:SI (match_operand:SI 2 "arm_rhs_operand" "")))
3131 (match_operand:SI 3 "arm_rhs_operand" "")))
3132 (clobber (match_operand:SI 4 "s_register_operand" ""))]
25f905c2 3133 "TARGET_32BIT"
9c08d1fa 3134 [(set (match_dup 4) (and:SI (ior:SI (match_dup 1) (match_dup 2))
3135 (not:SI (match_dup 3))))
3136 (set (match_dup 0) (not:SI (match_dup 4)))]
3137 ""
3138)
3139
ba6a3b2f 3140(define_insn_and_split "*andsi_iorsi3_notsi"
9c08d1fa 3141 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r")
e5fea38e 3142 (and:SI (ior:SI (match_operand:SI 1 "s_register_operand" "%0,r,r")
9c08d1fa 3143 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI"))
3144 (not:SI (match_operand:SI 3 "arm_rhs_operand" "rI,rI,rI"))))]
25f905c2 3145 "TARGET_32BIT"
ba6a3b2f 3146 "#" ; "orr%?\\t%0, %1, %2\;bic%?\\t%0, %0, %3"
3147 "&& reload_completed"
3148 [(set (match_dup 0) (ior:SI (match_dup 1) (match_dup 2)))
3149 (set (match_dup 0) (and:SI (not:SI (match_dup 3)) (match_dup 0)))]
3150 ""
0d66636f 3151 [(set_attr "length" "8")
25f905c2 3152 (set_attr "ce_count" "2")
d952d547 3153 (set_attr "predicable" "yes")
1b7da4ac 3154 (set_attr "predicable_short_it" "no")
3155 (set_attr "type" "multiple")]
cffb2a26 3156)
9c08d1fa 3157
25f905c2 3158; ??? Are these four splitters still beneficial when the Thumb-2 bitfield
3159; insns are available?
d7863cfe 3160(define_split
3161 [(set (match_operand:SI 0 "s_register_operand" "")
3162 (match_operator:SI 1 "logical_binary_operator"
3163 [(zero_extract:SI (match_operand:SI 2 "s_register_operand" "")
3164 (match_operand:SI 3 "const_int_operand" "")
3165 (match_operand:SI 4 "const_int_operand" ""))
3166 (match_operator:SI 9 "logical_binary_operator"
3167 [(lshiftrt:SI (match_operand:SI 5 "s_register_operand" "")
3168 (match_operand:SI 6 "const_int_operand" ""))
3169 (match_operand:SI 7 "s_register_operand" "")])]))
3170 (clobber (match_operand:SI 8 "s_register_operand" ""))]
25f905c2 3171 "TARGET_32BIT
d7863cfe 3172 && GET_CODE (operands[1]) == GET_CODE (operands[9])
3173 && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
3174 [(set (match_dup 8)
3175 (match_op_dup 1
3176 [(ashift:SI (match_dup 2) (match_dup 4))
3177 (match_dup 5)]))
3178 (set (match_dup 0)
3179 (match_op_dup 1
3180 [(lshiftrt:SI (match_dup 8) (match_dup 6))
3181 (match_dup 7)]))]
3182 "
3183 operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
3184")
3185
3186(define_split
3187 [(set (match_operand:SI 0 "s_register_operand" "")
3188 (match_operator:SI 1 "logical_binary_operator"
3189 [(match_operator:SI 9 "logical_binary_operator"
3190 [(lshiftrt:SI (match_operand:SI 5 "s_register_operand" "")
3191 (match_operand:SI 6 "const_int_operand" ""))
3192 (match_operand:SI 7 "s_register_operand" "")])
3193 (zero_extract:SI (match_operand:SI 2 "s_register_operand" "")
3194 (match_operand:SI 3 "const_int_operand" "")
3195 (match_operand:SI 4 "const_int_operand" ""))]))
3196 (clobber (match_operand:SI 8 "s_register_operand" ""))]
25f905c2 3197 "TARGET_32BIT
d7863cfe 3198 && GET_CODE (operands[1]) == GET_CODE (operands[9])
3199 && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
3200 [(set (match_dup 8)
3201 (match_op_dup 1
3202 [(ashift:SI (match_dup 2) (match_dup 4))
3203 (match_dup 5)]))
3204 (set (match_dup 0)
3205 (match_op_dup 1
3206 [(lshiftrt:SI (match_dup 8) (match_dup 6))
3207 (match_dup 7)]))]
3208 "
3209 operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
3210")
3211
3212(define_split
3213 [(set (match_operand:SI 0 "s_register_operand" "")
3214 (match_operator:SI 1 "logical_binary_operator"
3215 [(sign_extract:SI (match_operand:SI 2 "s_register_operand" "")
3216 (match_operand:SI 3 "const_int_operand" "")
3217 (match_operand:SI 4 "const_int_operand" ""))
3218 (match_operator:SI 9 "logical_binary_operator"
3219 [(ashiftrt:SI (match_operand:SI 5 "s_register_operand" "")
3220 (match_operand:SI 6 "const_int_operand" ""))
3221 (match_operand:SI 7 "s_register_operand" "")])]))
3222 (clobber (match_operand:SI 8 "s_register_operand" ""))]
25f905c2 3223 "TARGET_32BIT
d7863cfe 3224 && GET_CODE (operands[1]) == GET_CODE (operands[9])
3225 && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
3226 [(set (match_dup 8)
3227 (match_op_dup 1
3228 [(ashift:SI (match_dup 2) (match_dup 4))
3229 (match_dup 5)]))
3230 (set (match_dup 0)
3231 (match_op_dup 1
3232 [(ashiftrt:SI (match_dup 8) (match_dup 6))
3233 (match_dup 7)]))]
3234 "
3235 operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
3236")
3237
3238(define_split
3239 [(set (match_operand:SI 0 "s_register_operand" "")
3240 (match_operator:SI 1 "logical_binary_operator"
3241 [(match_operator:SI 9 "logical_binary_operator"
3242 [(ashiftrt:SI (match_operand:SI 5 "s_register_operand" "")
3243 (match_operand:SI 6 "const_int_operand" ""))
3244 (match_operand:SI 7 "s_register_operand" "")])
3245 (sign_extract:SI (match_operand:SI 2 "s_register_operand" "")
3246 (match_operand:SI 3 "const_int_operand" "")
3247 (match_operand:SI 4 "const_int_operand" ""))]))
3248 (clobber (match_operand:SI 8 "s_register_operand" ""))]
25f905c2 3249 "TARGET_32BIT
d7863cfe 3250 && GET_CODE (operands[1]) == GET_CODE (operands[9])
3251 && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
3252 [(set (match_dup 8)
3253 (match_op_dup 1
3254 [(ashift:SI (match_dup 2) (match_dup 4))
3255 (match_dup 5)]))
3256 (set (match_dup 0)
3257 (match_op_dup 1
3258 [(ashiftrt:SI (match_dup 8) (match_dup 6))
3259 (match_dup 7)]))]
3260 "
3261 operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
3262")
9c08d1fa 3263\f
3264
3265;; Minimum and maximum insns
3266
8b9dc177 3267(define_expand "smaxsi3"
3268 [(parallel [
3269 (set (match_operand:SI 0 "s_register_operand" "")
3270 (smax:SI (match_operand:SI 1 "s_register_operand" "")
3271 (match_operand:SI 2 "arm_rhs_operand" "")))
3272 (clobber (reg:CC CC_REGNUM))])]
25f905c2 3273 "TARGET_32BIT"
8b9dc177 3274 "
8774928b 3275 if (operands[2] == const0_rtx || operands[2] == constm1_rtx)
8b9dc177 3276 {
3277 /* No need for a clobber of the condition code register here. */
3278 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
3279 gen_rtx_SMAX (SImode, operands[1],
3280 operands[2])));
3281 DONE;
3282 }
3283")
3284
3285(define_insn "*smax_0"
3286 [(set (match_operand:SI 0 "s_register_operand" "=r")
3287 (smax:SI (match_operand:SI 1 "s_register_operand" "r")
3288 (const_int 0)))]
25f905c2 3289 "TARGET_32BIT"
8b9dc177 3290 "bic%?\\t%0, %1, %1, asr #31"
d952d547 3291 [(set_attr "predicable" "yes")
1b7da4ac 3292 (set_attr "predicable_short_it" "no")
3293 (set_attr "type" "logic_shift_reg")]
8b9dc177 3294)
3295
8774928b 3296(define_insn "*smax_m1"
3297 [(set (match_operand:SI 0 "s_register_operand" "=r")
3298 (smax:SI (match_operand:SI 1 "s_register_operand" "r")
3299 (const_int -1)))]
25f905c2 3300 "TARGET_32BIT"
8774928b 3301 "orr%?\\t%0, %1, %1, asr #31"
d952d547 3302 [(set_attr "predicable" "yes")
1b7da4ac 3303 (set_attr "predicable_short_it" "no")
3304 (set_attr "type" "logic_shift_reg")]
8774928b 3305)
3306
3dc953f2 3307(define_insn_and_split "*arm_smax_insn"
8b9dc177 3308 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
3309 (smax:SI (match_operand:SI 1 "s_register_operand" "%0,?r")
3310 (match_operand:SI 2 "arm_rhs_operand" "rI,rI")))
bd5b4116 3311 (clobber (reg:CC CC_REGNUM))]
cffb2a26 3312 "TARGET_ARM"
3dc953f2 3313 "#"
3314 ; cmp\\t%1, %2\;movlt\\t%0, %2
3315 ; cmp\\t%1, %2\;movge\\t%0, %1\;movlt\\t%0, %2"
3316 "TARGET_ARM"
3317 [(set (reg:CC CC_REGNUM)
3318 (compare:CC (match_dup 1) (match_dup 2)))
3319 (set (match_dup 0)
3320 (if_then_else:SI (ge:SI (reg:CC CC_REGNUM) (const_int 0))
3321 (match_dup 1)
3322 (match_dup 2)))]
3323 ""
cffb2a26 3324 [(set_attr "conds" "clob")
1b7da4ac 3325 (set_attr "length" "8,12")
3326 (set_attr "type" "multiple")]
cffb2a26 3327)
9c08d1fa 3328
8b9dc177 3329(define_expand "sminsi3"
3330 [(parallel [
3331 (set (match_operand:SI 0 "s_register_operand" "")
3332 (smin:SI (match_operand:SI 1 "s_register_operand" "")
3333 (match_operand:SI 2 "arm_rhs_operand" "")))
3334 (clobber (reg:CC CC_REGNUM))])]
25f905c2 3335 "TARGET_32BIT"
8b9dc177 3336 "
3337 if (operands[2] == const0_rtx)
3338 {
3339 /* No need for a clobber of the condition code register here. */
3340 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
3341 gen_rtx_SMIN (SImode, operands[1],
3342 operands[2])));
3343 DONE;
3344 }
3345")
3346
3347(define_insn "*smin_0"
3348 [(set (match_operand:SI 0 "s_register_operand" "=r")
3349 (smin:SI (match_operand:SI 1 "s_register_operand" "r")
3350 (const_int 0)))]
25f905c2 3351 "TARGET_32BIT"
8b9dc177 3352 "and%?\\t%0, %1, %1, asr #31"
d952d547 3353 [(set_attr "predicable" "yes")
1b7da4ac 3354 (set_attr "predicable_short_it" "no")
3355 (set_attr "type" "logic_shift_reg")]
8b9dc177 3356)
3357
3dc953f2 3358(define_insn_and_split "*arm_smin_insn"
8b9dc177 3359 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
3360 (smin:SI (match_operand:SI 1 "s_register_operand" "%0,?r")
3361 (match_operand:SI 2 "arm_rhs_operand" "rI,rI")))
bd5b4116 3362 (clobber (reg:CC CC_REGNUM))]
cffb2a26 3363 "TARGET_ARM"
3dc953f2 3364 "#"
3365 ; cmp\\t%1, %2\;movge\\t%0, %2
3366 ; cmp\\t%1, %2\;movlt\\t%0, %1\;movge\\t%0, %2"
3367 "TARGET_ARM"
3368 [(set (reg:CC CC_REGNUM)
3369 (compare:CC (match_dup 1) (match_dup 2)))
3370 (set (match_dup 0)
3371 (if_then_else:SI (lt:SI (reg:CC CC_REGNUM) (const_int 0))
3372 (match_dup 1)
3373 (match_dup 2)))]
3374 ""
0d66636f 3375 [(set_attr "conds" "clob")
1b7da4ac 3376 (set_attr "length" "8,12")
3377 (set_attr "type" "multiple,multiple")]
0d66636f 3378)
9c08d1fa 3379
25f905c2 3380(define_expand "umaxsi3"
3381 [(parallel [
3382 (set (match_operand:SI 0 "s_register_operand" "")
3383 (umax:SI (match_operand:SI 1 "s_register_operand" "")
3384 (match_operand:SI 2 "arm_rhs_operand" "")))
3385 (clobber (reg:CC CC_REGNUM))])]
3386 "TARGET_32BIT"
3387 ""
3388)
3389
3dc953f2 3390(define_insn_and_split "*arm_umaxsi3"
9c08d1fa 3391 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
3392 (umax:SI (match_operand:SI 1 "s_register_operand" "0,r,?r")
3393 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
bd5b4116 3394 (clobber (reg:CC CC_REGNUM))]
cffb2a26 3395 "TARGET_ARM"
3dc953f2 3396 "#"
3397 ; cmp\\t%1, %2\;movcc\\t%0, %2
3398 ; cmp\\t%1, %2\;movcs\\t%0, %1
3399 ; cmp\\t%1, %2\;movcs\\t%0, %1\;movcc\\t%0, %2"
3400 "TARGET_ARM"
3401 [(set (reg:CC CC_REGNUM)
3402 (compare:CC (match_dup 1) (match_dup 2)))
3403 (set (match_dup 0)
3404 (if_then_else:SI (geu:SI (reg:CC CC_REGNUM) (const_int 0))
3405 (match_dup 1)
3406 (match_dup 2)))]
3407 ""
0d66636f 3408 [(set_attr "conds" "clob")
1b7da4ac 3409 (set_attr "length" "8,8,12")
3410 (set_attr "type" "store1")]
0d66636f 3411)
9c08d1fa 3412
25f905c2 3413(define_expand "uminsi3"
3414 [(parallel [
3415 (set (match_operand:SI 0 "s_register_operand" "")
3416 (umin:SI (match_operand:SI 1 "s_register_operand" "")
3417 (match_operand:SI 2 "arm_rhs_operand" "")))
3418 (clobber (reg:CC CC_REGNUM))])]
3419 "TARGET_32BIT"
3420 ""
3421)
3422
3dc953f2 3423(define_insn_and_split "*arm_uminsi3"
9c08d1fa 3424 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
3425 (umin:SI (match_operand:SI 1 "s_register_operand" "0,r,?r")
3426 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
bd5b4116 3427 (clobber (reg:CC CC_REGNUM))]
cffb2a26 3428 "TARGET_ARM"
3dc953f2 3429 "#"
3430 ; cmp\\t%1, %2\;movcs\\t%0, %2
3431 ; cmp\\t%1, %2\;movcc\\t%0, %1
3432 ; cmp\\t%1, %2\;movcc\\t%0, %1\;movcs\\t%0, %2"
3433 "TARGET_ARM"
3434 [(set (reg:CC CC_REGNUM)
3435 (compare:CC (match_dup 1) (match_dup 2)))
3436 (set (match_dup 0)
3437 (if_then_else:SI (ltu:SI (reg:CC CC_REGNUM) (const_int 0))
3438 (match_dup 1)
3439 (match_dup 2)))]
3440 ""
0d66636f 3441 [(set_attr "conds" "clob")
1b7da4ac 3442 (set_attr "length" "8,8,12")
3443 (set_attr "type" "store1")]
0d66636f 3444)
9c08d1fa 3445
8a18b90c 3446(define_insn "*store_minmaxsi"
9c08d1fa 3447 [(set (match_operand:SI 0 "memory_operand" "=m")
3448 (match_operator:SI 3 "minmax_operator"
3449 [(match_operand:SI 1 "s_register_operand" "r")
3450 (match_operand:SI 2 "s_register_operand" "r")]))
bd5b4116 3451 (clobber (reg:CC CC_REGNUM))]
5ce0ce9b 3452 "TARGET_32BIT && optimize_function_for_size_p (cfun)"
9c08d1fa 3453 "*
dc55b8a9 3454 operands[3] = gen_rtx_fmt_ee (minmax_code (operands[3]), SImode,
3455 operands[1], operands[2]);
e2348bcb 3456 output_asm_insn (\"cmp\\t%1, %2\", operands);
25f905c2 3457 if (TARGET_THUMB2)
3458 output_asm_insn (\"ite\t%d3\", operands);
e2348bcb 3459 output_asm_insn (\"str%d3\\t%1, %0\", operands);
3460 output_asm_insn (\"str%D3\\t%2, %0\", operands);
3461 return \"\";
0d66636f 3462 "
3463 [(set_attr "conds" "clob")
25f905c2 3464 (set (attr "length")
3465 (if_then_else (eq_attr "is_thumb" "yes")
3466 (const_int 14)
3467 (const_int 12)))
0d66636f 3468 (set_attr "type" "store1")]
3469)
9c08d1fa 3470
8a18b90c 3471; Reject the frame pointer in operand[1], since reloading this after
3472; it has been eliminated can cause carnage.
f7fbdd4a 3473(define_insn "*minmax_arithsi"
9c08d1fa 3474 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
3475 (match_operator:SI 4 "shiftable_operator"
3476 [(match_operator:SI 5 "minmax_operator"
3477 [(match_operand:SI 2 "s_register_operand" "r,r")
3478 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
3479 (match_operand:SI 1 "s_register_operand" "0,?r")]))
bd5b4116 3480 (clobber (reg:CC CC_REGNUM))]
7c36fe71 3481 "TARGET_32BIT && !arm_eliminable_register (operands[1]) && !arm_restrict_it"
9c08d1fa 3482 "*
0d66636f 3483 {
3484 enum rtx_code code = GET_CODE (operands[4]);
25f905c2 3485 bool need_else;
3486
3487 if (which_alternative != 0 || operands[3] != const0_rtx
ca0fc5a2 3488 || (code != PLUS && code != IOR && code != XOR))
25f905c2 3489 need_else = true;
3490 else
3491 need_else = false;
0d66636f 3492
dc55b8a9 3493 operands[5] = gen_rtx_fmt_ee (minmax_code (operands[5]), SImode,
3494 operands[2], operands[3]);
0d66636f 3495 output_asm_insn (\"cmp\\t%2, %3\", operands);
25f905c2 3496 if (TARGET_THUMB2)
3497 {
3498 if (need_else)
3499 output_asm_insn (\"ite\\t%d5\", operands);
3500 else
3501 output_asm_insn (\"it\\t%d5\", operands);
3502 }
0d66636f 3503 output_asm_insn (\"%i4%d5\\t%0, %1, %2\", operands);
25f905c2 3504 if (need_else)
0d66636f 3505 output_asm_insn (\"%i4%D5\\t%0, %1, %3\", operands);
3506 return \"\";
215b30b3 3507 }"
0d66636f 3508 [(set_attr "conds" "clob")
25f905c2 3509 (set (attr "length")
3510 (if_then_else (eq_attr "is_thumb" "yes")
3511 (const_int 14)
1b7da4ac 3512 (const_int 12)))
3513 (set_attr "type" "multiple")]
0d66636f 3514)
9c08d1fa 3515
4164bca1 3516; Reject the frame pointer in operand[1], since reloading this after
3517; it has been eliminated can cause carnage.
3518(define_insn_and_split "*minmax_arithsi_non_canon"
7c36fe71 3519 [(set (match_operand:SI 0 "s_register_operand" "=Ts,Ts")
4164bca1 3520 (minus:SI
7c36fe71 3521 (match_operand:SI 1 "s_register_operand" "0,?Ts")
4164bca1 3522 (match_operator:SI 4 "minmax_operator"
7c36fe71 3523 [(match_operand:SI 2 "s_register_operand" "Ts,Ts")
3524 (match_operand:SI 3 "arm_rhs_operand" "TsI,TsI")])))
4164bca1 3525 (clobber (reg:CC CC_REGNUM))]
7c36fe71 3526 "TARGET_32BIT && !arm_eliminable_register (operands[1])
3527 && !(arm_restrict_it && CONST_INT_P (operands[3]))"
4164bca1 3528 "#"
3529 "TARGET_32BIT && !arm_eliminable_register (operands[1]) && reload_completed"
3530 [(set (reg:CC CC_REGNUM)
3531 (compare:CC (match_dup 2) (match_dup 3)))
3532
3533 (cond_exec (match_op_dup 4 [(reg:CC CC_REGNUM) (const_int 0)])
3534 (set (match_dup 0)
3535 (minus:SI (match_dup 1)
3536 (match_dup 2))))
3537 (cond_exec (match_op_dup 5 [(reg:CC CC_REGNUM) (const_int 0)])
3538 (set (match_dup 0)
36ee0cde 3539 (match_dup 6)))]
4164bca1 3540 {
3541 enum machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
3542 operands[2], operands[3]);
3543 enum rtx_code rc = minmax_code (operands[4]);
3544 operands[4] = gen_rtx_fmt_ee (rc, VOIDmode,
3545 operands[2], operands[3]);
3546
3547 if (mode == CCFPmode || mode == CCFPEmode)
3548 rc = reverse_condition_maybe_unordered (rc);
3549 else
3550 rc = reverse_condition (rc);
3551 operands[5] = gen_rtx_fmt_ee (rc, SImode, operands[2], operands[3]);
36ee0cde 3552 if (CONST_INT_P (operands[3]))
3553 operands[6] = plus_constant (SImode, operands[1], -INTVAL (operands[3]));
3554 else
3555 operands[6] = gen_rtx_MINUS (SImode, operands[1], operands[3]);
4164bca1 3556 }
3557 [(set_attr "conds" "clob")
3558 (set (attr "length")
3559 (if_then_else (eq_attr "is_thumb" "yes")
3560 (const_int 14)
1b7da4ac 3561 (const_int 12)))
3562 (set_attr "type" "multiple")]
4164bca1 3563)
3564
b49e3742 3565(define_code_iterator SAT [smin smax])
3566(define_code_iterator SATrev [smin smax])
3567(define_code_attr SATlo [(smin "1") (smax "2")])
3568(define_code_attr SAThi [(smin "2") (smax "1")])
3569
3570(define_insn "*satsi_<SAT:code>"
3571 [(set (match_operand:SI 0 "s_register_operand" "=r")
3572 (SAT:SI (SATrev:SI (match_operand:SI 3 "s_register_operand" "r")
3573 (match_operand:SI 1 "const_int_operand" "i"))
3574 (match_operand:SI 2 "const_int_operand" "i")))]
3575 "TARGET_32BIT && arm_arch6 && <SAT:CODE> != <SATrev:CODE>
3576 && arm_sat_operator_match (operands[<SAT:SATlo>], operands[<SAT:SAThi>], NULL, NULL)"
3577{
3578 int mask;
3579 bool signed_sat;
3580 if (!arm_sat_operator_match (operands[<SAT:SATlo>], operands[<SAT:SAThi>],
3581 &mask, &signed_sat))
3582 gcc_unreachable ();
3583
3584 operands[1] = GEN_INT (mask);
3585 if (signed_sat)
3586 return "ssat%?\t%0, %1, %3";
3587 else
3588 return "usat%?\t%0, %1, %3";
3589}
7c36fe71 3590 [(set_attr "predicable" "yes")
1b7da4ac 3591 (set_attr "predicable_short_it" "no")
3592 (set_attr "type" "alus_imm")]
bebe9bbb 3593)
b49e3742 3594
3595(define_insn "*satsi_<SAT:code>_shift"
3596 [(set (match_operand:SI 0 "s_register_operand" "=r")
3597 (SAT:SI (SATrev:SI (match_operator:SI 3 "sat_shift_operator"
3598 [(match_operand:SI 4 "s_register_operand" "r")
3599 (match_operand:SI 5 "const_int_operand" "i")])
3600 (match_operand:SI 1 "const_int_operand" "i"))
3601 (match_operand:SI 2 "const_int_operand" "i")))]
3602 "TARGET_32BIT && arm_arch6 && <SAT:CODE> != <SATrev:CODE>
3603 && arm_sat_operator_match (operands[<SAT:SATlo>], operands[<SAT:SAThi>], NULL, NULL)"
3604{
3605 int mask;
3606 bool signed_sat;
3607 if (!arm_sat_operator_match (operands[<SAT:SATlo>], operands[<SAT:SAThi>],
3608 &mask, &signed_sat))
3609 gcc_unreachable ();
3610
3611 operands[1] = GEN_INT (mask);
3612 if (signed_sat)
3613 return "ssat%?\t%0, %1, %4%S3";
3614 else
3615 return "usat%?\t%0, %1, %4%S3";
3616}
3617 [(set_attr "predicable" "yes")
7c36fe71 3618 (set_attr "predicable_short_it" "no")
b49e3742 3619 (set_attr "shift" "3")
d82e788e 3620 (set_attr "type" "logic_shift_reg")])
b11cae9e 3621\f
3622;; Shift and rotation insns
3623
a2cd141b 3624(define_expand "ashldi3"
3625 [(set (match_operand:DI 0 "s_register_operand" "")
3626 (ashift:DI (match_operand:DI 1 "s_register_operand" "")
aa06c51c 3627 (match_operand:SI 2 "general_operand" "")))]
25f905c2 3628 "TARGET_32BIT"
a2cd141b 3629 "
aa06c51c 3630 if (TARGET_NEON)
3631 {
3632 /* Delay the decision whether to use NEON or core-regs until
3633 register allocation. */
3634 emit_insn (gen_ashldi3_neon (operands[0], operands[1], operands[2]));
3635 DONE;
3636 }
3637 else
3638 {
3639 /* Only the NEON case can handle in-memory shift counts. */
3640 if (!reg_or_int_operand (operands[2], SImode))
3641 operands[2] = force_reg (SImode, operands[2]);
3642 }
3643
b805622c 3644 if (!CONST_INT_P (operands[2]) && TARGET_REALLY_IWMMXT)
ffcc986d 3645 ; /* No special preparation statements; expand pattern as above. */
3646 else
a2cd141b 3647 {
ffcc986d 3648 rtx scratch1, scratch2;
3649
3650 if (CONST_INT_P (operands[2])
3651 && (HOST_WIDE_INT) INTVAL (operands[2]) == 1)
a2cd141b 3652 {
3653 emit_insn (gen_arm_ashldi3_1bit (operands[0], operands[1]));
3654 DONE;
3655 }
ffcc986d 3656
3657 /* Ideally we should use iwmmxt here if we could know that operands[1]
3658 ends up already living in an iwmmxt register. Otherwise it's
3659 cheaper to have the alternate code being generated than moving
3660 values to iwmmxt regs and back. */
3661
3662 /* If we're optimizing for size, we prefer the libgcc calls. */
3663 if (optimize_function_for_size_p (cfun))
3664 FAIL;
3665
3666 /* Expand operation using core-registers.
3667 'FAIL' would achieve the same thing, but this is a bit smarter. */
3668 scratch1 = gen_reg_rtx (SImode);
3669 scratch2 = gen_reg_rtx (SImode);
3670 arm_emit_coreregs_64bit_shift (ASHIFT, operands[0], operands[1],
3671 operands[2], scratch1, scratch2);
3672 DONE;
a2cd141b 3673 }
a2cd141b 3674 "
3675)
3676
2837e3fb 3677(define_insn "arm_ashldi3_1bit"
50ad1bf9 3678 [(set (match_operand:DI 0 "s_register_operand" "=r,&r")
e5fea38e 3679 (ashift:DI (match_operand:DI 1 "s_register_operand" "0,r")
a2cd141b 3680 (const_int 1)))
3681 (clobber (reg:CC CC_REGNUM))]
25f905c2 3682 "TARGET_32BIT"
2837e3fb 3683 "movs\\t%Q0, %Q1, asl #1\;adc\\t%R0, %R1, %R1"
a2cd141b 3684 [(set_attr "conds" "clob")
1b7da4ac 3685 (set_attr "length" "8")
3686 (set_attr "type" "multiple")]
a2cd141b 3687)
3688
87b22bf7 3689(define_expand "ashlsi3"
cffb2a26 3690 [(set (match_operand:SI 0 "s_register_operand" "")
87b22bf7 3691 (ashift:SI (match_operand:SI 1 "s_register_operand" "")
3692 (match_operand:SI 2 "arm_rhs_operand" "")))]
cffb2a26 3693 "TARGET_EITHER"
87b22bf7 3694 "
0438d37f 3695 if (CONST_INT_P (operands[2])
87b22bf7 3696 && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) > 31)
3697 {
3698 emit_insn (gen_movsi (operands[0], const0_rtx));
3699 DONE;
3700 }
cffb2a26 3701 "
3702)
3703
a2cd141b 3704(define_expand "ashrdi3"
3705 [(set (match_operand:DI 0 "s_register_operand" "")
3706 (ashiftrt:DI (match_operand:DI 1 "s_register_operand" "")
3707 (match_operand:SI 2 "reg_or_int_operand" "")))]
25f905c2 3708 "TARGET_32BIT"
a2cd141b 3709 "
aa06c51c 3710 if (TARGET_NEON)
3711 {
3712 /* Delay the decision whether to use NEON or core-regs until
3713 register allocation. */
3714 emit_insn (gen_ashrdi3_neon (operands[0], operands[1], operands[2]));
3715 DONE;
3716 }
3717
b805622c 3718 if (!CONST_INT_P (operands[2]) && TARGET_REALLY_IWMMXT)
ffcc986d 3719 ; /* No special preparation statements; expand pattern as above. */
3720 else
a2cd141b 3721 {
ffcc986d 3722 rtx scratch1, scratch2;
3723
3724 if (CONST_INT_P (operands[2])
3725 && (HOST_WIDE_INT) INTVAL (operands[2]) == 1)
a2cd141b 3726 {
3727 emit_insn (gen_arm_ashrdi3_1bit (operands[0], operands[1]));
3728 DONE;
3729 }
ffcc986d 3730
3731 /* Ideally we should use iwmmxt here if we could know that operands[1]
3732 ends up already living in an iwmmxt register. Otherwise it's
3733 cheaper to have the alternate code being generated than moving
3734 values to iwmmxt regs and back. */
3735
3736 /* If we're optimizing for size, we prefer the libgcc calls. */
3737 if (optimize_function_for_size_p (cfun))
3738 FAIL;
3739
3740 /* Expand operation using core-registers.
3741 'FAIL' would achieve the same thing, but this is a bit smarter. */
3742 scratch1 = gen_reg_rtx (SImode);
3743 scratch2 = gen_reg_rtx (SImode);
3744 arm_emit_coreregs_64bit_shift (ASHIFTRT, operands[0], operands[1],
3745 operands[2], scratch1, scratch2);
3746 DONE;
a2cd141b 3747 }
a2cd141b 3748 "
3749)
3750
2837e3fb 3751(define_insn "arm_ashrdi3_1bit"
50ad1bf9 3752 [(set (match_operand:DI 0 "s_register_operand" "=r,&r")
e5fea38e 3753 (ashiftrt:DI (match_operand:DI 1 "s_register_operand" "0,r")
a2cd141b 3754 (const_int 1)))
3755 (clobber (reg:CC CC_REGNUM))]
25f905c2 3756 "TARGET_32BIT"
2837e3fb 3757 "movs\\t%R0, %R1, asr #1\;mov\\t%Q0, %Q1, rrx"
a2cd141b 3758 [(set_attr "conds" "clob")
1b7da4ac 3759 (set_attr "length" "8")
3760 (set_attr "type" "multiple")]
a2cd141b 3761)
3762
87b22bf7 3763(define_expand "ashrsi3"
cffb2a26 3764 [(set (match_operand:SI 0 "s_register_operand" "")
87b22bf7 3765 (ashiftrt:SI (match_operand:SI 1 "s_register_operand" "")
3766 (match_operand:SI 2 "arm_rhs_operand" "")))]
cffb2a26 3767 "TARGET_EITHER"
87b22bf7 3768 "
0438d37f 3769 if (CONST_INT_P (operands[2])
87b22bf7 3770 && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) > 31)
3771 operands[2] = GEN_INT (31);
cffb2a26 3772 "
3773)
3774
a2cd141b 3775(define_expand "lshrdi3"
3776 [(set (match_operand:DI 0 "s_register_operand" "")
3777 (lshiftrt:DI (match_operand:DI 1 "s_register_operand" "")
3778 (match_operand:SI 2 "reg_or_int_operand" "")))]
25f905c2 3779 "TARGET_32BIT"
a2cd141b 3780 "
aa06c51c 3781 if (TARGET_NEON)
3782 {
3783 /* Delay the decision whether to use NEON or core-regs until
3784 register allocation. */
3785 emit_insn (gen_lshrdi3_neon (operands[0], operands[1], operands[2]));
3786 DONE;
3787 }
3788
b805622c 3789 if (!CONST_INT_P (operands[2]) && TARGET_REALLY_IWMMXT)
ffcc986d 3790 ; /* No special preparation statements; expand pattern as above. */
3791 else
a2cd141b 3792 {
ffcc986d 3793 rtx scratch1, scratch2;
3794
3795 if (CONST_INT_P (operands[2])
3796 && (HOST_WIDE_INT) INTVAL (operands[2]) == 1)
a2cd141b 3797 {
3798 emit_insn (gen_arm_lshrdi3_1bit (operands[0], operands[1]));
3799 DONE;
3800 }
ffcc986d 3801
3802 /* Ideally we should use iwmmxt here if we could know that operands[1]
3803 ends up already living in an iwmmxt register. Otherwise it's
3804 cheaper to have the alternate code being generated than moving
3805 values to iwmmxt regs and back. */
3806
3807 /* If we're optimizing for size, we prefer the libgcc calls. */
3808 if (optimize_function_for_size_p (cfun))
3809 FAIL;
3810
3811 /* Expand operation using core-registers.
3812 'FAIL' would achieve the same thing, but this is a bit smarter. */
3813 scratch1 = gen_reg_rtx (SImode);
3814 scratch2 = gen_reg_rtx (SImode);
3815 arm_emit_coreregs_64bit_shift (LSHIFTRT, operands[0], operands[1],
3816 operands[2], scratch1, scratch2);
3817 DONE;
a2cd141b 3818 }
a2cd141b 3819 "
3820)
3821
2837e3fb 3822(define_insn "arm_lshrdi3_1bit"
50ad1bf9 3823 [(set (match_operand:DI 0 "s_register_operand" "=r,&r")
e5fea38e 3824 (lshiftrt:DI (match_operand:DI 1 "s_register_operand" "0,r")
a2cd141b 3825 (const_int 1)))
3826 (clobber (reg:CC CC_REGNUM))]
25f905c2 3827 "TARGET_32BIT"
2837e3fb 3828 "movs\\t%R0, %R1, lsr #1\;mov\\t%Q0, %Q1, rrx"
a2cd141b 3829 [(set_attr "conds" "clob")
1b7da4ac 3830 (set_attr "length" "8")
3831 (set_attr "type" "multiple")]
a2cd141b 3832)
3833
87b22bf7 3834(define_expand "lshrsi3"
cffb2a26 3835 [(set (match_operand:SI 0 "s_register_operand" "")
87b22bf7 3836 (lshiftrt:SI (match_operand:SI 1 "s_register_operand" "")
3837 (match_operand:SI 2 "arm_rhs_operand" "")))]
cffb2a26 3838 "TARGET_EITHER"
87b22bf7 3839 "
0438d37f 3840 if (CONST_INT_P (operands[2])
87b22bf7 3841 && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) > 31)
3842 {
3843 emit_insn (gen_movsi (operands[0], const0_rtx));
3844 DONE;
3845 }
cffb2a26 3846 "
3847)
3848
87b22bf7 3849(define_expand "rotlsi3"
cffb2a26 3850 [(set (match_operand:SI 0 "s_register_operand" "")
87b22bf7 3851 (rotatert:SI (match_operand:SI 1 "s_register_operand" "")
3852 (match_operand:SI 2 "reg_or_int_operand" "")))]
25f905c2 3853 "TARGET_32BIT"
87b22bf7 3854 "
0438d37f 3855 if (CONST_INT_P (operands[2]))
87b22bf7 3856 operands[2] = GEN_INT ((32 - INTVAL (operands[2])) % 32);
3857 else
b11cae9e 3858 {
87b22bf7 3859 rtx reg = gen_reg_rtx (SImode);
3860 emit_insn (gen_subsi3 (reg, GEN_INT (32), operands[2]));
3861 operands[2] = reg;
b11cae9e 3862 }
cffb2a26 3863 "
3864)
9c08d1fa 3865
87b22bf7 3866(define_expand "rotrsi3"
cffb2a26 3867 [(set (match_operand:SI 0 "s_register_operand" "")
87b22bf7 3868 (rotatert:SI (match_operand:SI 1 "s_register_operand" "")
3869 (match_operand:SI 2 "arm_rhs_operand" "")))]
cffb2a26 3870 "TARGET_EITHER"
87b22bf7 3871 "
25f905c2 3872 if (TARGET_32BIT)
cffb2a26 3873 {
0438d37f 3874 if (CONST_INT_P (operands[2])
cffb2a26 3875 && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) > 31)
3876 operands[2] = GEN_INT (INTVAL (operands[2]) % 32);
3877 }
25f905c2 3878 else /* TARGET_THUMB1 */
cffb2a26 3879 {
0438d37f 3880 if (CONST_INT_P (operands [2]))
cffb2a26 3881 operands [2] = force_reg (SImode, operands[2]);
3882 }
3883 "
3884)
87b22bf7 3885
cffb2a26 3886(define_insn "*arm_shiftsi3"
88c29385 3887 [(set (match_operand:SI 0 "s_register_operand" "=l,l,r,r")
cffb2a26 3888 (match_operator:SI 3 "shift_operator"
88c29385 3889 [(match_operand:SI 1 "s_register_operand" "0,l,r,r")
3890 (match_operand:SI 2 "reg_or_int_operand" "l,M,M,r")]))]
25f905c2 3891 "TARGET_32BIT"
3892 "* return arm_output_shift(operands, 0);"
344495ea 3893 [(set_attr "predicable" "yes")
88c29385 3894 (set_attr "arch" "t2,t2,*,*")
3895 (set_attr "predicable_short_it" "yes,yes,no,no")
7c36fe71 3896 (set_attr "length" "4")
331beb1a 3897 (set_attr "shift" "1")
88c29385 3898 (set_attr "type" "alu_shift_reg,alu_shift_imm,alu_shift_imm,alu_shift_reg")]
6c4c2133 3899)
87b22bf7 3900
f7fbdd4a 3901(define_insn "*shiftsi3_compare0"
bd5b4116 3902 [(set (reg:CC_NOOV CC_REGNUM)
87b22bf7 3903 (compare:CC_NOOV (match_operator:SI 3 "shift_operator"
6b6abc9c 3904 [(match_operand:SI 1 "s_register_operand" "r,r")
3905 (match_operand:SI 2 "arm_rhs_operand" "M,r")])
9c08d1fa 3906 (const_int 0)))
6b6abc9c 3907 (set (match_operand:SI 0 "s_register_operand" "=r,r")
87b22bf7 3908 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))]
25f905c2 3909 "TARGET_32BIT"
3910 "* return arm_output_shift(operands, 1);"
344495ea 3911 [(set_attr "conds" "set")
331beb1a 3912 (set_attr "shift" "1")
d82e788e 3913 (set_attr "type" "alus_shift_imm,alus_shift_reg")]
0d66636f 3914)
9c08d1fa 3915
f7fbdd4a 3916(define_insn "*shiftsi3_compare0_scratch"
bd5b4116 3917 [(set (reg:CC_NOOV CC_REGNUM)
87b22bf7 3918 (compare:CC_NOOV (match_operator:SI 3 "shift_operator"
6b6abc9c 3919 [(match_operand:SI 1 "s_register_operand" "r,r")
3920 (match_operand:SI 2 "arm_rhs_operand" "M,r")])
9c08d1fa 3921 (const_int 0)))
6b6abc9c 3922 (clobber (match_scratch:SI 0 "=r,r"))]
25f905c2 3923 "TARGET_32BIT"
3924 "* return arm_output_shift(operands, 1);"
344495ea 3925 [(set_attr "conds" "set")
6b6abc9c 3926 (set_attr "shift" "1")
d82e788e 3927 (set_attr "type" "shift_imm,shift_reg")]
0d66636f 3928)
9c08d1fa 3929
d5d4dc8d 3930(define_insn "*not_shiftsi"
3931 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
87b22bf7 3932 (not:SI (match_operator:SI 3 "shift_operator"
d5d4dc8d 3933 [(match_operand:SI 1 "s_register_operand" "r,r")
3934 (match_operand:SI 2 "shift_amount_operand" "M,rM")])))]
3935 "TARGET_32BIT"
6c4c2133 3936 "mvn%?\\t%0, %1%S3"
344495ea 3937 [(set_attr "predicable" "yes")
d952d547 3938 (set_attr "predicable_short_it" "no")
331beb1a 3939 (set_attr "shift" "1")
d5d4dc8d 3940 (set_attr "arch" "32,a")
1aed5204 3941 (set_attr "type" "mvn_shift,mvn_shift_reg")])
9c08d1fa 3942
d5d4dc8d 3943(define_insn "*not_shiftsi_compare0"
bd5b4116 3944 [(set (reg:CC_NOOV CC_REGNUM)
d5d4dc8d 3945 (compare:CC_NOOV
3946 (not:SI (match_operator:SI 3 "shift_operator"
3947 [(match_operand:SI 1 "s_register_operand" "r,r")
3948 (match_operand:SI 2 "shift_amount_operand" "M,rM")]))
3949 (const_int 0)))
3950 (set (match_operand:SI 0 "s_register_operand" "=r,r")
87b22bf7 3951 (not:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)])))]
d5d4dc8d 3952 "TARGET_32BIT"
25f905c2 3953 "mvn%.\\t%0, %1%S3"
344495ea 3954 [(set_attr "conds" "set")
331beb1a 3955 (set_attr "shift" "1")
d5d4dc8d 3956 (set_attr "arch" "32,a")
1aed5204 3957 (set_attr "type" "mvn_shift,mvn_shift_reg")])
9c08d1fa 3958
d5d4dc8d 3959(define_insn "*not_shiftsi_compare0_scratch"
bd5b4116 3960 [(set (reg:CC_NOOV CC_REGNUM)
d5d4dc8d 3961 (compare:CC_NOOV
3962 (not:SI (match_operator:SI 3 "shift_operator"
3963 [(match_operand:SI 1 "s_register_operand" "r,r")
3964 (match_operand:SI 2 "shift_amount_operand" "M,rM")]))
3965 (const_int 0)))
3966 (clobber (match_scratch:SI 0 "=r,r"))]
3967 "TARGET_32BIT"
25f905c2 3968 "mvn%.\\t%0, %1%S3"
344495ea 3969 [(set_attr "conds" "set")
331beb1a 3970 (set_attr "shift" "1")
d5d4dc8d 3971 (set_attr "arch" "32,a")
1aed5204 3972 (set_attr "type" "mvn_shift,mvn_shift_reg")])
9c08d1fa 3973
cffb2a26 3974;; We don't really have extzv, but defining this using shifts helps
3975;; to reduce register pressure later on.
3976
3977(define_expand "extzv"
eb04cafb 3978 [(set (match_operand 0 "s_register_operand" "")
3979 (zero_extract (match_operand 1 "nonimmediate_operand" "")
3980 (match_operand 2 "const_int_operand" "")
3981 (match_operand 3 "const_int_operand" "")))]
8b054d5a 3982 "TARGET_THUMB1 || arm_arch_thumb2"
cffb2a26 3983 "
3984 {
3985 HOST_WIDE_INT lshift = 32 - INTVAL (operands[2]) - INTVAL (operands[3]);
3986 HOST_WIDE_INT rshift = 32 - INTVAL (operands[2]);
3987
8b054d5a 3988 if (arm_arch_thumb2)
3989 {
eb04cafb 3990 HOST_WIDE_INT width = INTVAL (operands[2]);
3991 HOST_WIDE_INT bitpos = INTVAL (operands[3]);
3992
3993 if (unaligned_access && MEM_P (operands[1])
3994 && (width == 16 || width == 32) && (bitpos % BITS_PER_UNIT) == 0)
3995 {
3996 rtx base_addr;
3997
3998 if (BYTES_BIG_ENDIAN)
3999 bitpos = GET_MODE_BITSIZE (GET_MODE (operands[0])) - width
4000 - bitpos;
4001
4002 if (width == 32)
4003 {
4004 base_addr = adjust_address (operands[1], SImode,
4005 bitpos / BITS_PER_UNIT);
4006 emit_insn (gen_unaligned_loadsi (operands[0], base_addr));
4007 }
4008 else
4009 {
4010 rtx dest = operands[0];
4011 rtx tmp = gen_reg_rtx (SImode);
4012
4013 /* We may get a paradoxical subreg here. Strip it off. */
4014 if (GET_CODE (dest) == SUBREG
4015 && GET_MODE (dest) == SImode
4016 && GET_MODE (SUBREG_REG (dest)) == HImode)
4017 dest = SUBREG_REG (dest);
4018
4019 if (GET_MODE_BITSIZE (GET_MODE (dest)) != width)
4020 FAIL;
4021
4022 base_addr = adjust_address (operands[1], HImode,
4023 bitpos / BITS_PER_UNIT);
4024 emit_insn (gen_unaligned_loadhiu (tmp, base_addr));
4025 emit_move_insn (gen_lowpart (SImode, dest), tmp);
4026 }
4027 DONE;
4028 }
4029 else if (s_register_operand (operands[1], GET_MODE (operands[1])))
4030 {
4031 emit_insn (gen_extzv_t2 (operands[0], operands[1], operands[2],
4032 operands[3]));
4033 DONE;
4034 }
4035 else
4036 FAIL;
8b054d5a 4037 }
eb04cafb 4038
4039 if (!s_register_operand (operands[1], GET_MODE (operands[1])))
4040 FAIL;
8b054d5a 4041
cffb2a26 4042 operands[3] = GEN_INT (rshift);
4043
4044 if (lshift == 0)
4045 {
4046 emit_insn (gen_lshrsi3 (operands[0], operands[1], operands[3]));
4047 DONE;
4048 }
4049
eb04cafb 4050 emit_insn (gen_extzv_t1 (operands[0], operands[1], GEN_INT (lshift),
4051 operands[3], gen_reg_rtx (SImode)));
4052 DONE;
215b30b3 4053 }"
cffb2a26 4054)
4055
eb04cafb 4056;; Helper for extzv, for the Thumb-1 register-shifts case.
4057
4058(define_expand "extzv_t1"
4059 [(set (match_operand:SI 4 "s_register_operand" "")
4060 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
4061 (match_operand:SI 2 "const_int_operand" "")))
4062 (set (match_operand:SI 0 "s_register_operand" "")
4063 (lshiftrt:SI (match_dup 4)
4064 (match_operand:SI 3 "const_int_operand" "")))]
4065 "TARGET_THUMB1"
4066 "")
4067
4068(define_expand "extv"
4069 [(set (match_operand 0 "s_register_operand" "")
4070 (sign_extract (match_operand 1 "nonimmediate_operand" "")
4071 (match_operand 2 "const_int_operand" "")
4072 (match_operand 3 "const_int_operand" "")))]
4073 "arm_arch_thumb2"
4074{
4075 HOST_WIDE_INT width = INTVAL (operands[2]);
4076 HOST_WIDE_INT bitpos = INTVAL (operands[3]);
4077
4078 if (unaligned_access && MEM_P (operands[1]) && (width == 16 || width == 32)
4079 && (bitpos % BITS_PER_UNIT) == 0)
4080 {
4081 rtx base_addr;
4082
4083 if (BYTES_BIG_ENDIAN)
4084 bitpos = GET_MODE_BITSIZE (GET_MODE (operands[0])) - width - bitpos;
4085
4086 if (width == 32)
4087 {
4088 base_addr = adjust_address (operands[1], SImode,
4089 bitpos / BITS_PER_UNIT);
4090 emit_insn (gen_unaligned_loadsi (operands[0], base_addr));
4091 }
4092 else
4093 {
4094 rtx dest = operands[0];
4095 rtx tmp = gen_reg_rtx (SImode);
4096
4097 /* We may get a paradoxical subreg here. Strip it off. */
4098 if (GET_CODE (dest) == SUBREG
4099 && GET_MODE (dest) == SImode
4100 && GET_MODE (SUBREG_REG (dest)) == HImode)
4101 dest = SUBREG_REG (dest);
4102
4103 if (GET_MODE_BITSIZE (GET_MODE (dest)) != width)
4104 FAIL;
4105
4106 base_addr = adjust_address (operands[1], HImode,
4107 bitpos / BITS_PER_UNIT);
4108 emit_insn (gen_unaligned_loadhis (tmp, base_addr));
4109 emit_move_insn (gen_lowpart (SImode, dest), tmp);
4110 }
4111
4112 DONE;
4113 }
4114 else if (!s_register_operand (operands[1], GET_MODE (operands[1])))
4115 FAIL;
4116 else if (GET_MODE (operands[0]) == SImode
4117 && GET_MODE (operands[1]) == SImode)
4118 {
4119 emit_insn (gen_extv_regsi (operands[0], operands[1], operands[2],
4120 operands[3]));
4121 DONE;
4122 }
4123
4124 FAIL;
4125})
4126
4127; Helper to expand register forms of extv with the proper modes.
4128
4129(define_expand "extv_regsi"
4130 [(set (match_operand:SI 0 "s_register_operand" "")
4131 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "")
4132 (match_operand 2 "const_int_operand" "")
4133 (match_operand 3 "const_int_operand" "")))]
4134 ""
4135{
4136})
4137
4138; ARMv6+ unaligned load/store instructions (used for packed structure accesses).
4139
4140(define_insn "unaligned_loadsi"
4141 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
4142 (unspec:SI [(match_operand:SI 1 "memory_operand" "Uw,m")]
4143 UNSPEC_UNALIGNED_LOAD))]
4144 "unaligned_access && TARGET_32BIT"
4145 "ldr%?\t%0, %1\t@ unaligned"
4146 [(set_attr "arch" "t2,any")
4147 (set_attr "length" "2,4")
4148 (set_attr "predicable" "yes")
d952d547 4149 (set_attr "predicable_short_it" "yes,no")
eb04cafb 4150 (set_attr "type" "load1")])
4151
4152(define_insn "unaligned_loadhis"
4153 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
4154 (sign_extend:SI
e3f4ccee 4155 (unspec:HI [(match_operand:HI 1 "memory_operand" "Uw,Uh")]
eb04cafb 4156 UNSPEC_UNALIGNED_LOAD)))]
4157 "unaligned_access && TARGET_32BIT"
4158 "ldr%(sh%)\t%0, %1\t@ unaligned"
4159 [(set_attr "arch" "t2,any")
4160 (set_attr "length" "2,4")
4161 (set_attr "predicable" "yes")
d952d547 4162 (set_attr "predicable_short_it" "yes,no")
eb04cafb 4163 (set_attr "type" "load_byte")])
4164
4165(define_insn "unaligned_loadhiu"
4166 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
4167 (zero_extend:SI
4168 (unspec:HI [(match_operand:HI 1 "memory_operand" "Uw,m")]
4169 UNSPEC_UNALIGNED_LOAD)))]
4170 "unaligned_access && TARGET_32BIT"
4171 "ldr%(h%)\t%0, %1\t@ unaligned"
4172 [(set_attr "arch" "t2,any")
4173 (set_attr "length" "2,4")
4174 (set_attr "predicable" "yes")
d952d547 4175 (set_attr "predicable_short_it" "yes,no")
eb04cafb 4176 (set_attr "type" "load_byte")])
4177
4178(define_insn "unaligned_storesi"
4179 [(set (match_operand:SI 0 "memory_operand" "=Uw,m")
4180 (unspec:SI [(match_operand:SI 1 "s_register_operand" "l,r")]
4181 UNSPEC_UNALIGNED_STORE))]
4182 "unaligned_access && TARGET_32BIT"
4183 "str%?\t%1, %0\t@ unaligned"
4184 [(set_attr "arch" "t2,any")
4185 (set_attr "length" "2,4")
4186 (set_attr "predicable" "yes")
d952d547 4187 (set_attr "predicable_short_it" "yes,no")
eb04cafb 4188 (set_attr "type" "store1")])
4189
4190(define_insn "unaligned_storehi"
4191 [(set (match_operand:HI 0 "memory_operand" "=Uw,m")
4192 (unspec:HI [(match_operand:HI 1 "s_register_operand" "l,r")]
4193 UNSPEC_UNALIGNED_STORE))]
4194 "unaligned_access && TARGET_32BIT"
4195 "str%(h%)\t%1, %0\t@ unaligned"
4196 [(set_attr "arch" "t2,any")
4197 (set_attr "length" "2,4")
4198 (set_attr "predicable" "yes")
d952d547 4199 (set_attr "predicable_short_it" "yes,no")
eb04cafb 4200 (set_attr "type" "store1")])
4201
ae51a965 4202;; Unaligned double-word load and store.
4203;; Split after reload into two unaligned single-word accesses.
4204;; It prevents lower_subreg from splitting some other aligned
4205;; double-word accesses too early. Used for internal memcpy.
4206
4207(define_insn_and_split "unaligned_loaddi"
4208 [(set (match_operand:DI 0 "s_register_operand" "=l,r")
4209 (unspec:DI [(match_operand:DI 1 "memory_operand" "o,o")]
4210 UNSPEC_UNALIGNED_LOAD))]
4211 "unaligned_access && TARGET_32BIT"
4212 "#"
4213 "&& reload_completed"
4214 [(set (match_dup 0) (unspec:SI [(match_dup 1)] UNSPEC_UNALIGNED_LOAD))
4215 (set (match_dup 2) (unspec:SI [(match_dup 3)] UNSPEC_UNALIGNED_LOAD))]
4216 {
4217 operands[2] = gen_highpart (SImode, operands[0]);
4218 operands[0] = gen_lowpart (SImode, operands[0]);
4219 operands[3] = gen_highpart (SImode, operands[1]);
4220 operands[1] = gen_lowpart (SImode, operands[1]);
4221
4222 /* If the first destination register overlaps with the base address,
4223 swap the order in which the loads are emitted. */
4224 if (reg_overlap_mentioned_p (operands[0], operands[1]))
4225 {
4226 rtx tmp = operands[1];
4227 operands[1] = operands[3];
4228 operands[3] = tmp;
4229 tmp = operands[0];
4230 operands[0] = operands[2];
4231 operands[2] = tmp;
4232 }
4233 }
4234 [(set_attr "arch" "t2,any")
4235 (set_attr "length" "4,8")
4236 (set_attr "predicable" "yes")
4237 (set_attr "type" "load2")])
4238
4239(define_insn_and_split "unaligned_storedi"
4240 [(set (match_operand:DI 0 "memory_operand" "=o,o")
4241 (unspec:DI [(match_operand:DI 1 "s_register_operand" "l,r")]
4242 UNSPEC_UNALIGNED_STORE))]
4243 "unaligned_access && TARGET_32BIT"
4244 "#"
4245 "&& reload_completed"
4246 [(set (match_dup 0) (unspec:SI [(match_dup 1)] UNSPEC_UNALIGNED_STORE))
4247 (set (match_dup 2) (unspec:SI [(match_dup 3)] UNSPEC_UNALIGNED_STORE))]
4248 {
4249 operands[2] = gen_highpart (SImode, operands[0]);
4250 operands[0] = gen_lowpart (SImode, operands[0]);
4251 operands[3] = gen_highpart (SImode, operands[1]);
4252 operands[1] = gen_lowpart (SImode, operands[1]);
4253 }
4254 [(set_attr "arch" "t2,any")
4255 (set_attr "length" "4,8")
4256 (set_attr "predicable" "yes")
4257 (set_attr "type" "store2")])
4258
4259
eb04cafb 4260(define_insn "*extv_reg"
8b054d5a 4261 [(set (match_operand:SI 0 "s_register_operand" "=r")
4262 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
809003b3 4263 (match_operand:SI 2 "const_int_M_operand" "M")
4264 (match_operand:SI 3 "const_int_M_operand" "M")))]
8b054d5a 4265 "arm_arch_thumb2"
4266 "sbfx%?\t%0, %1, %3, %2"
4267 [(set_attr "length" "4")
d952d547 4268 (set_attr "predicable" "yes")
d82e788e 4269 (set_attr "predicable_short_it" "no")
4270 (set_attr "type" "bfm")]
8b054d5a 4271)
4272
4273(define_insn "extzv_t2"
4274 [(set (match_operand:SI 0 "s_register_operand" "=r")
4275 (zero_extract:SI (match_operand:SI 1 "s_register_operand" "r")
809003b3 4276 (match_operand:SI 2 "const_int_M_operand" "M")
4277 (match_operand:SI 3 "const_int_M_operand" "M")))]
8b054d5a 4278 "arm_arch_thumb2"
4279 "ubfx%?\t%0, %1, %3, %2"
4280 [(set_attr "length" "4")
d952d547 4281 (set_attr "predicable" "yes")
d82e788e 4282 (set_attr "predicable_short_it" "no")
4283 (set_attr "type" "bfm")]
8b054d5a 4284)
4285
7d3cda8c 4286
4287;; Division instructions
4288(define_insn "divsi3"
4289 [(set (match_operand:SI 0 "s_register_operand" "=r")
4290 (div:SI (match_operand:SI 1 "s_register_operand" "r")
4291 (match_operand:SI 2 "s_register_operand" "r")))]
4292 "TARGET_IDIV"
4293 "sdiv%?\t%0, %1, %2"
4294 [(set_attr "predicable" "yes")
d952d547 4295 (set_attr "predicable_short_it" "no")
9da0ec36 4296 (set_attr "type" "sdiv")]
7d3cda8c 4297)
4298
4299(define_insn "udivsi3"
4300 [(set (match_operand:SI 0 "s_register_operand" "=r")
4301 (udiv:SI (match_operand:SI 1 "s_register_operand" "r")
4302 (match_operand:SI 2 "s_register_operand" "r")))]
4303 "TARGET_IDIV"
4304 "udiv%?\t%0, %1, %2"
4305 [(set_attr "predicable" "yes")
d952d547 4306 (set_attr "predicable_short_it" "no")
9da0ec36 4307 (set_attr "type" "udiv")]
7d3cda8c 4308)
4309
b11cae9e 4310\f
4311;; Unary arithmetic insns
4312
cffb2a26 4313(define_expand "negdi2"
4314 [(parallel
8135a42b 4315 [(set (match_operand:DI 0 "s_register_operand" "")
4316 (neg:DI (match_operand:DI 1 "s_register_operand" "")))
bd5b4116 4317 (clobber (reg:CC CC_REGNUM))])]
cffb2a26 4318 "TARGET_EITHER"
774d2fbb 4319 {
4320 if (TARGET_NEON)
4321 {
4322 emit_insn (gen_negdi2_neon (operands[0], operands[1]));
4323 DONE;
4324 }
4325 }
cffb2a26 4326)
4327
4328;; The constraints here are to prevent a *partial* overlap (where %Q0 == %R1).
e5fea38e 4329;; The first alternative allows the common case of a *full* overlap.
ba6a3b2f 4330(define_insn_and_split "*arm_negdi2"
458a8706 4331 [(set (match_operand:DI 0 "s_register_operand" "=r,&r")
e5fea38e 4332 (neg:DI (match_operand:DI 1 "s_register_operand" "0,r")))
bd5b4116 4333 (clobber (reg:CC CC_REGNUM))]
cffb2a26 4334 "TARGET_ARM"
ba6a3b2f 4335 "#" ; "rsbs\\t%Q0, %Q1, #0\;rsc\\t%R0, %R1, #0"
4336 "&& reload_completed"
4337 [(parallel [(set (reg:CC CC_REGNUM)
4338 (compare:CC (const_int 0) (match_dup 1)))
4339 (set (match_dup 0) (minus:SI (const_int 0) (match_dup 1)))])
4340 (set (match_dup 2) (minus:SI (minus:SI (const_int 0) (match_dup 3))
4341 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
4342 {
4343 operands[2] = gen_highpart (SImode, operands[0]);
4344 operands[0] = gen_lowpart (SImode, operands[0]);
4345 operands[3] = gen_highpart (SImode, operands[1]);
4346 operands[1] = gen_lowpart (SImode, operands[1]);
4347 }
cffb2a26 4348 [(set_attr "conds" "clob")
1b7da4ac 4349 (set_attr "length" "8")
4350 (set_attr "type" "multiple")]
cffb2a26 4351)
b11cae9e 4352
cffb2a26 4353(define_expand "negsi2"
4354 [(set (match_operand:SI 0 "s_register_operand" "")
4355 (neg:SI (match_operand:SI 1 "s_register_operand" "")))]
4356 "TARGET_EITHER"
b11cae9e 4357 ""
cffb2a26 4358)
4359
4360(define_insn "*arm_negsi2"
d952d547 4361 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
4362 (neg:SI (match_operand:SI 1 "s_register_operand" "l,r")))]
25f905c2 4363 "TARGET_32BIT"
cffb2a26 4364 "rsb%?\\t%0, %1, #0"
d952d547 4365 [(set_attr "predicable" "yes")
4366 (set_attr "predicable_short_it" "yes,no")
4367 (set_attr "arch" "t2,*")
1b7da4ac 4368 (set_attr "length" "4")
112eda6f 4369 (set_attr "type" "alu_sreg")]
cffb2a26 4370)
4371
604f3a0a 4372(define_expand "negsf2"
4373 [(set (match_operand:SF 0 "s_register_operand" "")
4374 (neg:SF (match_operand:SF 1 "s_register_operand" "")))]
994606f8 4375 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
604f3a0a 4376 ""
4377)
4378
4379(define_expand "negdf2"
4380 [(set (match_operand:DF 0 "s_register_operand" "")
4381 (neg:DF (match_operand:DF 1 "s_register_operand" "")))]
994606f8 4382 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
604f3a0a 4383 "")
4384
7eaf2be0 4385(define_insn_and_split "*zextendsidi_negsi"
4386 [(set (match_operand:DI 0 "s_register_operand" "=r")
4387 (zero_extend:DI (neg:SI (match_operand:SI 1 "s_register_operand" "r"))))]
4388 "TARGET_32BIT"
4389 "#"
4390 ""
4391 [(set (match_dup 2)
4392 (neg:SI (match_dup 1)))
4393 (set (match_dup 3)
4394 (const_int 0))]
4395 {
4396 operands[2] = gen_lowpart (SImode, operands[0]);
4397 operands[3] = gen_highpart (SImode, operands[0]);
4398 }
4399 [(set_attr "length" "8")
4400 (set_attr "type" "multiple")]
4401)
4402
83e2b922 4403;; Negate an extended 32-bit value.
4404(define_insn_and_split "*negdi_extendsidi"
61fa8ff2 4405 [(set (match_operand:DI 0 "s_register_operand" "=l,r")
4406 (neg:DI (sign_extend:DI
4407 (match_operand:SI 1 "s_register_operand" "l,r"))))
83e2b922 4408 (clobber (reg:CC CC_REGNUM))]
4409 "TARGET_32BIT"
61fa8ff2 4410 "#"
83e2b922 4411 "&& reload_completed"
4412 [(const_int 0)]
4413 {
61fa8ff2 4414 rtx low = gen_lowpart (SImode, operands[0]);
4415 rtx high = gen_highpart (SImode, operands[0]);
4416
4417 if (reg_overlap_mentioned_p (low, operands[1]))
4418 {
4419 /* Input overlaps the low word of the output. Use:
4420 asr Rhi, Rin, #31
4421 rsbs Rlo, Rin, #0
4422 rsc Rhi, Rhi, #0 (thumb2: sbc Rhi, Rhi, Rhi, lsl #1). */
4423 rtx cc_reg = gen_rtx_REG (CC_Cmode, CC_REGNUM);
4424
4425 emit_insn (gen_rtx_SET (VOIDmode, high,
4426 gen_rtx_ASHIFTRT (SImode, operands[1],
4427 GEN_INT (31))));
4428
4429 emit_insn (gen_subsi3_compare (low, const0_rtx, operands[1]));
4430 if (TARGET_ARM)
4431 emit_insn (gen_rtx_SET (VOIDmode, high,
4432 gen_rtx_MINUS (SImode,
4433 gen_rtx_MINUS (SImode,
4434 const0_rtx,
4435 high),
4436 gen_rtx_LTU (SImode,
4437 cc_reg,
4438 const0_rtx))));
4439 else
4440 {
4441 rtx two_x = gen_rtx_ASHIFT (SImode, high, GEN_INT (1));
4442 emit_insn (gen_rtx_SET (VOIDmode, high,
4443 gen_rtx_MINUS (SImode,
4444 gen_rtx_MINUS (SImode,
4445 high,
4446 two_x),
4447 gen_rtx_LTU (SImode,
4448 cc_reg,
4449 const0_rtx))));
4450 }
4451 }
4452 else
4453 {
4454 /* No overlap, or overlap on high word. Use:
4455 rsb Rlo, Rin, #0
4456 bic Rhi, Rlo, Rin
4457 asr Rhi, Rhi, #31
4458 Flags not needed for this sequence. */
4459 emit_insn (gen_rtx_SET (VOIDmode, low,
4460 gen_rtx_NEG (SImode, operands[1])));
4461 emit_insn (gen_rtx_SET (VOIDmode, high,
4462 gen_rtx_AND (SImode,
4463 gen_rtx_NOT (SImode, operands[1]),
4464 low)));
4465 emit_insn (gen_rtx_SET (VOIDmode, high,
4466 gen_rtx_ASHIFTRT (SImode, high,
4467 GEN_INT (31))));
4468 }
4469 DONE;
83e2b922 4470 }
61fa8ff2 4471 [(set_attr "length" "12")
4472 (set_attr "arch" "t2,*")
1b7da4ac 4473 (set_attr "type" "multiple")]
83e2b922 4474)
4475
4476(define_insn_and_split "*negdi_zero_extendsidi"
4477 [(set (match_operand:DI 0 "s_register_operand" "=r,&r")
4478 (neg:DI (zero_extend:DI (match_operand:SI 1 "s_register_operand" "0,r"))))
4479 (clobber (reg:CC CC_REGNUM))]
4480 "TARGET_32BIT"
4481 "#" ; "rsbs\\t%Q0, %1, #0\;sbc\\t%R0,%R0,%R0"
4482 ;; Don't care what register is input to sbc,
4483 ;; since we just just need to propagate the carry.
4484 "&& reload_completed"
4485 [(parallel [(set (reg:CC CC_REGNUM)
4486 (compare:CC (const_int 0) (match_dup 1)))
4487 (set (match_dup 0) (minus:SI (const_int 0) (match_dup 1)))])
4488 (set (match_dup 2) (minus:SI (minus:SI (match_dup 2) (match_dup 2))
4489 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
4490 {
4491 operands[2] = gen_highpart (SImode, operands[0]);
4492 operands[0] = gen_lowpart (SImode, operands[0]);
4493 }
4494 [(set_attr "conds" "clob")
1b7da4ac 4495 (set_attr "length" "8")
4496 (set_attr "type" "multiple")] ;; length in thumb is 4
83e2b922 4497)
4498
9c08d1fa 4499;; abssi2 doesn't really clobber the condition codes if a different register
4500;; is being set. To keep things simple, assume during rtl manipulations that
4501;; it does, but tell the final scan operator the truth. Similarly for
4502;; (neg (abs...))
4503
604f3a0a 4504(define_expand "abssi2"
4505 [(parallel
4506 [(set (match_operand:SI 0 "s_register_operand" "")
4507 (abs:SI (match_operand:SI 1 "s_register_operand" "")))
ba156559 4508 (clobber (match_dup 2))])]
4509 "TARGET_EITHER"
4510 "
25f905c2 4511 if (TARGET_THUMB1)
ba156559 4512 operands[2] = gen_rtx_SCRATCH (SImode);
4513 else
4514 operands[2] = gen_rtx_REG (CCmode, CC_REGNUM);
4515")
604f3a0a 4516
ba6a3b2f 4517(define_insn_and_split "*arm_abssi2"
ba156559 4518 [(set (match_operand:SI 0 "s_register_operand" "=r,&r")
9c08d1fa 4519 (abs:SI (match_operand:SI 1 "s_register_operand" "0,r")))
bd5b4116 4520 (clobber (reg:CC CC_REGNUM))]
cffb2a26 4521 "TARGET_ARM"
ba6a3b2f 4522 "#"
4523 "&& reload_completed"
4524 [(const_int 0)]
4525 {
4526 /* if (which_alternative == 0) */
4527 if (REGNO(operands[0]) == REGNO(operands[1]))
4528 {
4529 /* Emit the pattern:
4530 cmp\\t%0, #0\;rsblt\\t%0, %0, #0
4531 [(set (reg:CC CC_REGNUM)
4532 (compare:CC (match_dup 0) (const_int 0)))
4533 (cond_exec (lt:CC (reg:CC CC_REGNUM) (const_int 0))
4534 (set (match_dup 0) (minus:SI (const_int 0) (match_dup 1))))]
4535 */
4536 emit_insn (gen_rtx_SET (VOIDmode,
4537 gen_rtx_REG (CCmode, CC_REGNUM),
4538 gen_rtx_COMPARE (CCmode, operands[0], const0_rtx)));
4539 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
4540 (gen_rtx_LT (SImode,
4541 gen_rtx_REG (CCmode, CC_REGNUM),
4542 const0_rtx)),
4543 (gen_rtx_SET (VOIDmode,
4544 operands[0],
4545 (gen_rtx_MINUS (SImode,
4546 const0_rtx,
4547 operands[1]))))));
4548 DONE;
4549 }
4550 else
4551 {
4552 /* Emit the pattern:
4553 alt1: eor%?\\t%0, %1, %1, asr #31\;sub%?\\t%0, %0, %1, asr #31
4554 [(set (match_dup 0)
4555 (xor:SI (match_dup 1)
4556 (ashiftrt:SI (match_dup 1) (const_int 31))))
4557 (set (match_dup 0)
4558 (minus:SI (match_dup 0)
4559 (ashiftrt:SI (match_dup 1) (const_int 31))))]
4560 */
4561 emit_insn (gen_rtx_SET (VOIDmode,
4562 operands[0],
4563 gen_rtx_XOR (SImode,
4564 gen_rtx_ASHIFTRT (SImode,
4565 operands[1],
4566 GEN_INT (31)),
4567 operands[1])));
4568 emit_insn (gen_rtx_SET (VOIDmode,
4569 operands[0],
4570 gen_rtx_MINUS (SImode,
4571 operands[0],
4572 gen_rtx_ASHIFTRT (SImode,
4573 operands[1],
4574 GEN_INT (31)))));
4575 DONE;
4576 }
4577 }
cffb2a26 4578 [(set_attr "conds" "clob,*")
331beb1a 4579 (set_attr "shift" "1")
2ad08b65 4580 (set_attr "predicable" "no, yes")
1b7da4ac 4581 (set_attr "length" "8")
4582 (set_attr "type" "multiple")]
cffb2a26 4583)
9c08d1fa 4584
ba6a3b2f 4585(define_insn_and_split "*arm_neg_abssi2"
9c08d1fa 4586 [(set (match_operand:SI 0 "s_register_operand" "=r,&r")
4587 (neg:SI (abs:SI (match_operand:SI 1 "s_register_operand" "0,r"))))
bd5b4116 4588 (clobber (reg:CC CC_REGNUM))]
cffb2a26 4589 "TARGET_ARM"
ba6a3b2f 4590 "#"
4591 "&& reload_completed"
4592 [(const_int 0)]
4593 {
4594 /* if (which_alternative == 0) */
4595 if (REGNO (operands[0]) == REGNO (operands[1]))
4596 {
4597 /* Emit the pattern:
4598 cmp\\t%0, #0\;rsbgt\\t%0, %0, #0
4599 */
4600 emit_insn (gen_rtx_SET (VOIDmode,
4601 gen_rtx_REG (CCmode, CC_REGNUM),
4602 gen_rtx_COMPARE (CCmode, operands[0], const0_rtx)));
4603 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
4604 gen_rtx_GT (SImode,
4605 gen_rtx_REG (CCmode, CC_REGNUM),
4606 const0_rtx),
4607 gen_rtx_SET (VOIDmode,
4608 operands[0],
4609 (gen_rtx_MINUS (SImode,
4610 const0_rtx,
4611 operands[1])))));
4612 }
4613 else
4614 {
4615 /* Emit the pattern:
4616 eor%?\\t%0, %1, %1, asr #31\;rsb%?\\t%0, %0, %1, asr #31
4617 */
4618 emit_insn (gen_rtx_SET (VOIDmode,
4619 operands[0],
4620 gen_rtx_XOR (SImode,
4621 gen_rtx_ASHIFTRT (SImode,
4622 operands[1],
4623 GEN_INT (31)),
4624 operands[1])));
4625 emit_insn (gen_rtx_SET (VOIDmode,
4626 operands[0],
4627 gen_rtx_MINUS (SImode,
4628 gen_rtx_ASHIFTRT (SImode,
4629 operands[1],
4630 GEN_INT (31)),
4631 operands[0])));
4632 }
4633 DONE;
4634 }
cffb2a26 4635 [(set_attr "conds" "clob,*")
331beb1a 4636 (set_attr "shift" "1")
2ad08b65 4637 (set_attr "predicable" "no, yes")
1b7da4ac 4638 (set_attr "length" "8")
4639 (set_attr "type" "multiple")]
cffb2a26 4640)
b11cae9e 4641
604f3a0a 4642(define_expand "abssf2"
4643 [(set (match_operand:SF 0 "s_register_operand" "")
4644 (abs:SF (match_operand:SF 1 "s_register_operand" "")))]
25f905c2 4645 "TARGET_32BIT && TARGET_HARD_FLOAT"
604f3a0a 4646 "")
4647
604f3a0a 4648(define_expand "absdf2"
4649 [(set (match_operand:DF 0 "s_register_operand" "")
4650 (abs:DF (match_operand:DF 1 "s_register_operand" "")))]
a50d7267 4651 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
604f3a0a 4652 "")
4653
7db9af5d 4654(define_expand "sqrtsf2"
4655 [(set (match_operand:SF 0 "s_register_operand" "")
4656 (sqrt:SF (match_operand:SF 1 "s_register_operand" "")))]
994606f8 4657 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
7db9af5d 4658 "")
9c08d1fa 4659
7db9af5d 4660(define_expand "sqrtdf2"
4661 [(set (match_operand:DF 0 "s_register_operand" "")
4662 (sqrt:DF (match_operand:DF 1 "s_register_operand" "")))]
994606f8 4663 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
7db9af5d 4664 "")
9c08d1fa 4665
a0f94409 4666(define_insn_and_split "one_cmpldi2"
10efb95f 4667 [(set (match_operand:DI 0 "s_register_operand" "=w,&r,&r,?w")
4668 (not:DI (match_operand:DI 1 "s_register_operand" " w, 0, r, w")))]
25f905c2 4669 "TARGET_32BIT"
10efb95f 4670 "@
4671 vmvn\t%P0, %P1
4672 #
4673 #
4674 vmvn\t%P0, %P1"
4675 "TARGET_32BIT && reload_completed
4676 && arm_general_register_operand (operands[0], DImode)"
a0f94409 4677 [(set (match_dup 0) (not:SI (match_dup 1)))
4678 (set (match_dup 2) (not:SI (match_dup 3)))]
4679 "
4680 {
4681 operands[2] = gen_highpart (SImode, operands[0]);
4682 operands[0] = gen_lowpart (SImode, operands[0]);
4683 operands[3] = gen_highpart (SImode, operands[1]);
4684 operands[1] = gen_lowpart (SImode, operands[1]);
4685 }"
10efb95f 4686 [(set_attr "length" "*,8,8,*")
4687 (set_attr "predicable" "no,yes,yes,no")
32093010 4688 (set_attr "type" "neon_move,multiple,multiple,neon_move")
b6779ddc 4689 (set_attr "arch" "neon_for_64bits,*,*,avoid_neon_for_64bits")]
cffb2a26 4690)
b11cae9e 4691
cffb2a26 4692(define_expand "one_cmplsi2"
4693 [(set (match_operand:SI 0 "s_register_operand" "")
4694 (not:SI (match_operand:SI 1 "s_register_operand" "")))]
4695 "TARGET_EITHER"
b11cae9e 4696 ""
cffb2a26 4697)
4698
4699(define_insn "*arm_one_cmplsi2"
d952d547 4700 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
4701 (not:SI (match_operand:SI 1 "s_register_operand" "l,r")))]
25f905c2 4702 "TARGET_32BIT"
cffb2a26 4703 "mvn%?\\t%0, %1"
d2a518d1 4704 [(set_attr "predicable" "yes")
d952d547 4705 (set_attr "predicable_short_it" "yes,no")
4706 (set_attr "arch" "t2,*")
4707 (set_attr "length" "4")
1aed5204 4708 (set_attr "type" "mvn_reg")]
cffb2a26 4709)
4710
f7fbdd4a 4711(define_insn "*notsi_compare0"
bd5b4116 4712 [(set (reg:CC_NOOV CC_REGNUM)
9c08d1fa 4713 (compare:CC_NOOV (not:SI (match_operand:SI 1 "s_register_operand" "r"))
4714 (const_int 0)))
4715 (set (match_operand:SI 0 "s_register_operand" "=r")
4716 (not:SI (match_dup 1)))]
25f905c2 4717 "TARGET_32BIT"
4718 "mvn%.\\t%0, %1"
d2a518d1 4719 [(set_attr "conds" "set")
1aed5204 4720 (set_attr "type" "mvn_reg")]
cffb2a26 4721)
9c08d1fa 4722
f7fbdd4a 4723(define_insn "*notsi_compare0_scratch"
bd5b4116 4724 [(set (reg:CC_NOOV CC_REGNUM)
9c08d1fa 4725 (compare:CC_NOOV (not:SI (match_operand:SI 1 "s_register_operand" "r"))
4726 (const_int 0)))
4727 (clobber (match_scratch:SI 0 "=r"))]
25f905c2 4728 "TARGET_32BIT"
4729 "mvn%.\\t%0, %1"
d2a518d1 4730 [(set_attr "conds" "set")
1aed5204 4731 (set_attr "type" "mvn_reg")]
cffb2a26 4732)
b11cae9e 4733\f
4734;; Fixed <--> Floating conversion insns
4735
9b8516be 4736(define_expand "floatsihf2"
4737 [(set (match_operand:HF 0 "general_operand" "")
4738 (float:HF (match_operand:SI 1 "general_operand" "")))]
4739 "TARGET_EITHER"
4740 "
4741 {
4742 rtx op1 = gen_reg_rtx (SFmode);
4743 expand_float (op1, operands[1], 0);
4744 op1 = convert_to_mode (HFmode, op1, 0);
4745 emit_move_insn (operands[0], op1);
4746 DONE;
4747 }"
4748)
4749
4750(define_expand "floatdihf2"
4751 [(set (match_operand:HF 0 "general_operand" "")
4752 (float:HF (match_operand:DI 1 "general_operand" "")))]
4753 "TARGET_EITHER"
4754 "
4755 {
4756 rtx op1 = gen_reg_rtx (SFmode);
4757 expand_float (op1, operands[1], 0);
4758 op1 = convert_to_mode (HFmode, op1, 0);
4759 emit_move_insn (operands[0], op1);
4760 DONE;
4761 }"
4762)
4763
604f3a0a 4764(define_expand "floatsisf2"
4765 [(set (match_operand:SF 0 "s_register_operand" "")
4766 (float:SF (match_operand:SI 1 "s_register_operand" "")))]
25f905c2 4767 "TARGET_32BIT && TARGET_HARD_FLOAT"
604f3a0a 4768 "
604f3a0a 4769")
4770
604f3a0a 4771(define_expand "floatsidf2"
4772 [(set (match_operand:DF 0 "s_register_operand" "")
4773 (float:DF (match_operand:SI 1 "s_register_operand" "")))]
a50d7267 4774 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
604f3a0a 4775 "
604f3a0a 4776")
4777
9b8516be 4778(define_expand "fix_trunchfsi2"
4779 [(set (match_operand:SI 0 "general_operand" "")
4780 (fix:SI (fix:HF (match_operand:HF 1 "general_operand" ""))))]
4781 "TARGET_EITHER"
4782 "
4783 {
4784 rtx op1 = convert_to_mode (SFmode, operands[1], 0);
4785 expand_fix (operands[0], op1, 0);
4786 DONE;
4787 }"
4788)
4789
4790(define_expand "fix_trunchfdi2"
4791 [(set (match_operand:DI 0 "general_operand" "")
4792 (fix:DI (fix:HF (match_operand:HF 1 "general_operand" ""))))]
4793 "TARGET_EITHER"
4794 "
4795 {
4796 rtx op1 = convert_to_mode (SFmode, operands[1], 0);
4797 expand_fix (operands[0], op1, 0);
4798 DONE;
4799 }"
4800)
4801
604f3a0a 4802(define_expand "fix_truncsfsi2"
4803 [(set (match_operand:SI 0 "s_register_operand" "")
a33d5c9c 4804 (fix:SI (fix:SF (match_operand:SF 1 "s_register_operand" ""))))]
25f905c2 4805 "TARGET_32BIT && TARGET_HARD_FLOAT"
604f3a0a 4806 "
604f3a0a 4807")
4808
604f3a0a 4809(define_expand "fix_truncdfsi2"
4810 [(set (match_operand:SI 0 "s_register_operand" "")
a33d5c9c 4811 (fix:SI (fix:DF (match_operand:DF 1 "s_register_operand" ""))))]
a50d7267 4812 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
604f3a0a 4813 "
604f3a0a 4814")
4815
f544c6d2 4816;; Truncation insns
b11cae9e 4817
604f3a0a 4818(define_expand "truncdfsf2"
4819 [(set (match_operand:SF 0 "s_register_operand" "")
4820 (float_truncate:SF
4821 (match_operand:DF 1 "s_register_operand" "")))]
a50d7267 4822 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
604f3a0a 4823 ""
4824)
9b8516be 4825
4826/* DFmode -> HFmode conversions have to go through SFmode. */
4827(define_expand "truncdfhf2"
4828 [(set (match_operand:HF 0 "general_operand" "")
4829 (float_truncate:HF
4830 (match_operand:DF 1 "general_operand" "")))]
4831 "TARGET_EITHER"
4832 "
4833 {
4834 rtx op1;
4835 op1 = convert_to_mode (SFmode, operands[1], 0);
4836 op1 = convert_to_mode (HFmode, op1, 0);
4837 emit_move_insn (operands[0], op1);
4838 DONE;
4839 }"
4840)
b11cae9e 4841\f
9c08d1fa 4842;; Zero and sign extension instructions.
b11cae9e 4843
848e66ac 4844(define_insn "zero_extend<mode>di2"
6aa689e8 4845 [(set (match_operand:DI 0 "s_register_operand" "=w,r,?r,w")
6d97728e 4846 (zero_extend:DI (match_operand:QHSI 1 "<qhs_zextenddi_op>"
4847 "<qhs_zextenddi_cstr>")))]
848e66ac 4848 "TARGET_32BIT <qhs_zextenddi_cond>"
4849 "#"
6aa689e8 4850 [(set_attr "length" "8,4,8,8")
b6779ddc 4851 (set_attr "arch" "neon_for_64bits,*,*,avoid_neon_for_64bits")
848e66ac 4852 (set_attr "ce_count" "2")
efbb5e19 4853 (set_attr "predicable" "yes")
4854 (set_attr "type" "multiple,mov_reg,multiple,multiple")]
25f905c2 4855)
4856
848e66ac 4857(define_insn "extend<mode>di2"
6aa689e8 4858 [(set (match_operand:DI 0 "s_register_operand" "=w,r,?r,?r,w")
63d204a8 4859 (sign_extend:DI (match_operand:QHSI 1 "<qhs_extenddi_op>"
4860 "<qhs_extenddi_cstr>")))]
848e66ac 4861 "TARGET_32BIT <qhs_sextenddi_cond>"
4862 "#"
6aa689e8 4863 [(set_attr "length" "8,4,8,8,8")
848e66ac 4864 (set_attr "ce_count" "2")
4865 (set_attr "shift" "1")
8012d2c2 4866 (set_attr "predicable" "yes")
1b7da4ac 4867 (set_attr "arch" "neon_for_64bits,*,a,t,avoid_neon_for_64bits")
4868 (set_attr "type" "multiple,mov_reg,multiple,multiple,multiple")]
0d66636f 4869)
9c08d1fa 4870
848e66ac 4871;; Splits for all extensions to DImode
4872(define_split
4873 [(set (match_operand:DI 0 "s_register_operand" "")
4874 (zero_extend:DI (match_operand 1 "nonimmediate_operand" "")))]
6aa689e8 4875 "TARGET_32BIT && reload_completed && !IS_VFP_REGNUM (REGNO (operands[0]))"
848e66ac 4876 [(set (match_dup 0) (match_dup 1))]
4877{
848e66ac 4878 rtx lo_part = gen_lowpart (SImode, operands[0]);
4879 enum machine_mode src_mode = GET_MODE (operands[1]);
4880
4881 if (REG_P (operands[0])
4882 && !reg_overlap_mentioned_p (operands[0], operands[1]))
4883 emit_clobber (operands[0]);
4884 if (!REG_P (lo_part) || src_mode != SImode
4885 || !rtx_equal_p (lo_part, operands[1]))
4886 {
4887 if (src_mode == SImode)
4888 emit_move_insn (lo_part, operands[1]);
4889 else
4890 emit_insn (gen_rtx_SET (VOIDmode, lo_part,
4891 gen_rtx_ZERO_EXTEND (SImode, operands[1])));
4892 operands[1] = lo_part;
4893 }
4894 operands[0] = gen_highpart (SImode, operands[0]);
4895 operands[1] = const0_rtx;
4896})
9c08d1fa 4897
848e66ac 4898(define_split
25f905c2 4899 [(set (match_operand:DI 0 "s_register_operand" "")
848e66ac 4900 (sign_extend:DI (match_operand 1 "nonimmediate_operand" "")))]
6aa689e8 4901 "TARGET_32BIT && reload_completed && !IS_VFP_REGNUM (REGNO (operands[0]))"
848e66ac 4902 [(set (match_dup 0) (ashiftrt:SI (match_dup 1) (const_int 31)))]
4903{
4904 rtx lo_part = gen_lowpart (SImode, operands[0]);
4905 enum machine_mode src_mode = GET_MODE (operands[1]);
25f905c2 4906
848e66ac 4907 if (REG_P (operands[0])
4908 && !reg_overlap_mentioned_p (operands[0], operands[1]))
4909 emit_clobber (operands[0]);
4910
4911 if (!REG_P (lo_part) || src_mode != SImode
4912 || !rtx_equal_p (lo_part, operands[1]))
4913 {
4914 if (src_mode == SImode)
4915 emit_move_insn (lo_part, operands[1]);
4916 else
4917 emit_insn (gen_rtx_SET (VOIDmode, lo_part,
4918 gen_rtx_SIGN_EXTEND (SImode, operands[1])));
4919 operands[1] = lo_part;
4920 }
4921 operands[0] = gen_highpart (SImode, operands[0]);
4922})
9c08d1fa 4923
4924(define_expand "zero_extendhisi2"
ef51b8e1 4925 [(set (match_operand:SI 0 "s_register_operand" "")
4926 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
cffb2a26 4927 "TARGET_EITHER"
ef51b8e1 4928{
4929 if (TARGET_ARM && !arm_arch4 && MEM_P (operands[1]))
f7fbdd4a 4930 {
ef51b8e1 4931 emit_insn (gen_movhi_bytes (operands[0], operands[1]));
4932 DONE;
25f7a26e 4933 }
ef51b8e1 4934 if (!arm_arch6 && !MEM_P (operands[1]))
4935 {
4936 rtx t = gen_lowpart (SImode, operands[1]);
4937 rtx tmp = gen_reg_rtx (SImode);
4938 emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (16)));
4939 emit_insn (gen_lshrsi3 (operands[0], tmp, GEN_INT (16)));
4940 DONE;
4941 }
4942})
9c08d1fa 4943
ef51b8e1 4944(define_split
b146458f 4945 [(set (match_operand:SI 0 "s_register_operand" "")
4946 (zero_extend:SI (match_operand:HI 1 "s_register_operand" "")))]
ef51b8e1 4947 "!TARGET_THUMB2 && !arm_arch6"
4948 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
4949 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 16)))]
4950{
4951 operands[2] = gen_lowpart (SImode, operands[1]);
4952})
4953
cffb2a26 4954(define_insn "*arm_zero_extendhisi2"
ef51b8e1 4955 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4956 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
a2cd141b 4957 "TARGET_ARM && arm_arch4 && !arm_arch6"
ef51b8e1 4958 "@
4959 #
4960 ldr%(h%)\\t%0, %1"
d82e788e 4961 [(set_attr "type" "alu_shift_reg,load_byte")
848e66ac 4962 (set_attr "predicable" "yes")]
cffb2a26 4963)
f7fbdd4a 4964
a2cd141b 4965(define_insn "*arm_zero_extendhisi2_v6"
4966 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
e3f4ccee 4967 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,Uh")))]
a2cd141b 4968 "TARGET_ARM && arm_arch6"
4969 "@
4970 uxth%?\\t%0, %1
25f905c2 4971 ldr%(h%)\\t%0, %1"
65f68e55 4972 [(set_attr "predicable" "yes")
6b6abc9c 4973 (set_attr "type" "extend,load_byte")]
a2cd141b 4974)
4975
4976(define_insn "*arm_zero_extendhisi2addsi"
4977 [(set (match_operand:SI 0 "s_register_operand" "=r")
4978 (plus:SI (zero_extend:SI (match_operand:HI 1 "s_register_operand" "r"))
4979 (match_operand:SI 2 "s_register_operand" "r")))]
25f905c2 4980 "TARGET_INT_SIMD"
a2cd141b 4981 "uxtah%?\\t%0, %2, %1"
d82e788e 4982 [(set_attr "type" "alu_shift_reg")
d952d547 4983 (set_attr "predicable" "yes")
4984 (set_attr "predicable_short_it" "no")]
a2cd141b 4985)
4986
87b22bf7 4987(define_expand "zero_extendqisi2"
cffb2a26 4988 [(set (match_operand:SI 0 "s_register_operand" "")
4989 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))]
4990 "TARGET_EITHER"
ef51b8e1 4991{
0438d37f 4992 if (TARGET_ARM && !arm_arch6 && !MEM_P (operands[1]))
87b22bf7 4993 {
ef51b8e1 4994 emit_insn (gen_andsi3 (operands[0],
4995 gen_lowpart (SImode, operands[1]),
4996 GEN_INT (255)));
4997 DONE;
4998 }
4999 if (!arm_arch6 && !MEM_P (operands[1]))
5000 {
5001 rtx t = gen_lowpart (SImode, operands[1]);
5002 rtx tmp = gen_reg_rtx (SImode);
5003 emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (24)));
5004 emit_insn (gen_lshrsi3 (operands[0], tmp, GEN_INT (24)));
5005 DONE;
5006 }
5007})
cffb2a26 5008
ef51b8e1 5009(define_split
b146458f 5010 [(set (match_operand:SI 0 "s_register_operand" "")
5011 (zero_extend:SI (match_operand:QI 1 "s_register_operand" "")))]
ef51b8e1 5012 "!arm_arch6"
5013 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 24)))
5014 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 24)))]
5015{
5016 operands[2] = simplify_gen_subreg (SImode, operands[1], QImode, 0);
5017 if (TARGET_ARM)
5018 {
5019 emit_insn (gen_andsi3 (operands[0], operands[2], GEN_INT (255)));
87b22bf7 5020 DONE;
5021 }
ef51b8e1 5022})
9c08d1fa 5023
cffb2a26 5024(define_insn "*arm_zero_extendqisi2"
ef51b8e1 5025 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5026 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
a2cd141b 5027 "TARGET_ARM && !arm_arch6"
ef51b8e1 5028 "@
5029 #
5030 ldr%(b%)\\t%0, %1\\t%@ zero_extendqisi2"
5031 [(set_attr "length" "8,4")
d82e788e 5032 (set_attr "type" "alu_shift_reg,load_byte")
848e66ac 5033 (set_attr "predicable" "yes")]
cffb2a26 5034)
87b22bf7 5035
a2cd141b 5036(define_insn "*arm_zero_extendqisi2_v6"
5037 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
e3f4ccee 5038 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "r,Uh")))]
a2cd141b 5039 "TARGET_ARM && arm_arch6"
5040 "@
25f905c2 5041 uxtb%(%)\\t%0, %1
5042 ldr%(b%)\\t%0, %1\\t%@ zero_extendqisi2"
6b6abc9c 5043 [(set_attr "type" "extend,load_byte")
848e66ac 5044 (set_attr "predicable" "yes")]
a2cd141b 5045)
5046
5047(define_insn "*arm_zero_extendqisi2addsi"
5048 [(set (match_operand:SI 0 "s_register_operand" "=r")
5049 (plus:SI (zero_extend:SI (match_operand:QI 1 "s_register_operand" "r"))
5050 (match_operand:SI 2 "s_register_operand" "r")))]
25f905c2 5051 "TARGET_INT_SIMD"
a2cd141b 5052 "uxtab%?\\t%0, %2, %1"
5053 [(set_attr "predicable" "yes")
d952d547 5054 (set_attr "predicable_short_it" "no")
d82e788e 5055 (set_attr "type" "alu_shift_reg")]
a2cd141b 5056)
5057
87b22bf7 5058(define_split
5059 [(set (match_operand:SI 0 "s_register_operand" "")
5060 (zero_extend:SI (subreg:QI (match_operand:SI 1 "" "") 0)))
5061 (clobber (match_operand:SI 2 "s_register_operand" ""))]
0438d37f 5062 "TARGET_32BIT && (!MEM_P (operands[1])) && ! BYTES_BIG_ENDIAN"
87b22bf7 5063 [(set (match_dup 2) (match_dup 1))
5064 (set (match_dup 0) (and:SI (match_dup 2) (const_int 255)))]
cffb2a26 5065 ""
5066)
9c08d1fa 5067
8a4d25d6 5068(define_split
5069 [(set (match_operand:SI 0 "s_register_operand" "")
5070 (zero_extend:SI (subreg:QI (match_operand:SI 1 "" "") 3)))
5071 (clobber (match_operand:SI 2 "s_register_operand" ""))]
0438d37f 5072 "TARGET_32BIT && (!MEM_P (operands[1])) && BYTES_BIG_ENDIAN"
8a4d25d6 5073 [(set (match_dup 2) (match_dup 1))
5074 (set (match_dup 0) (and:SI (match_dup 2) (const_int 255)))]
5075 ""
5076)
5077
1c274529 5078
5079(define_split
5080 [(set (match_operand:SI 0 "s_register_operand" "")
5081 (ior_xor:SI (and:SI (ashift:SI
5082 (match_operand:SI 1 "s_register_operand" "")
5083 (match_operand:SI 2 "const_int_operand" ""))
5084 (match_operand:SI 3 "const_int_operand" ""))
5085 (zero_extend:SI
5086 (match_operator 5 "subreg_lowpart_operator"
5087 [(match_operand:SI 4 "s_register_operand" "")]))))]
5088 "TARGET_32BIT
63787642 5089 && ((unsigned HOST_WIDE_INT) INTVAL (operands[3])
1c274529 5090 == (GET_MODE_MASK (GET_MODE (operands[5]))
5091 & (GET_MODE_MASK (GET_MODE (operands[5]))
5092 << (INTVAL (operands[2])))))"
5093 [(set (match_dup 0) (ior_xor:SI (ashift:SI (match_dup 1) (match_dup 2))
5094 (match_dup 4)))
5095 (set (match_dup 0) (zero_extend:SI (match_dup 5)))]
5096 "operands[5] = gen_lowpart (GET_MODE (operands[5]), operands[0]);"
5097)
5098
f7fbdd4a 5099(define_insn "*compareqi_eq0"
bd5b4116 5100 [(set (reg:CC_Z CC_REGNUM)
206ee9a2 5101 (compare:CC_Z (match_operand:QI 0 "s_register_operand" "r")
87b22bf7 5102 (const_int 0)))]
25f905c2 5103 "TARGET_32BIT"
596e5e8f 5104 "tst%?\\t%0, #255"
5105 [(set_attr "conds" "set")
d952d547 5106 (set_attr "predicable" "yes")
1b7da4ac 5107 (set_attr "predicable_short_it" "no")
5108 (set_attr "type" "logic_imm")]
cffb2a26 5109)
b11cae9e 5110
b11cae9e 5111(define_expand "extendhisi2"
ef51b8e1 5112 [(set (match_operand:SI 0 "s_register_operand" "")
5113 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
cffb2a26 5114 "TARGET_EITHER"
ef51b8e1 5115{
5116 if (TARGET_THUMB1)
5117 {
5118 emit_insn (gen_thumb1_extendhisi2 (operands[0], operands[1]));
5119 DONE;
5120 }
5121 if (MEM_P (operands[1]) && TARGET_ARM && !arm_arch4)
5122 {
5123 emit_insn (gen_extendhisi2_mem (operands[0], operands[1]));
5124 DONE;
5125 }
ed29c566 5126
ef51b8e1 5127 if (!arm_arch6 && !MEM_P (operands[1]))
5128 {
5129 rtx t = gen_lowpart (SImode, operands[1]);
5130 rtx tmp = gen_reg_rtx (SImode);
5131 emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (16)));
5132 emit_insn (gen_ashrsi3 (operands[0], tmp, GEN_INT (16)));
5133 DONE;
5134 }
5135})
cffb2a26 5136
ef51b8e1 5137(define_split
5138 [(parallel
5139 [(set (match_operand:SI 0 "register_operand" "")
5140 (sign_extend:SI (match_operand:HI 1 "register_operand" "")))
5141 (clobber (match_scratch:SI 2 ""))])]
5142 "!arm_arch6"
5143 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
5144 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 16)))]
5145{
5146 operands[2] = simplify_gen_subreg (SImode, operands[1], HImode, 0);
5147})
25f7a26e 5148
25f905c2 5149;; This pattern will only be used when ldsh is not available
25f7a26e 5150(define_expand "extendhisi2_mem"
eab14235 5151 [(set (match_dup 2) (zero_extend:SI (match_operand:HI 1 "" "")))
25f7a26e 5152 (set (match_dup 3)
eab14235 5153 (zero_extend:SI (match_dup 7)))
25f7a26e 5154 (set (match_dup 6) (ashift:SI (match_dup 4) (const_int 24)))
5155 (set (match_operand:SI 0 "" "")
5156 (ior:SI (ashiftrt:SI (match_dup 6) (const_int 16)) (match_dup 5)))]
cffb2a26 5157 "TARGET_ARM"
25f7a26e 5158 "
215b30b3 5159 {
5160 rtx mem1, mem2;
5161 rtx addr = copy_to_mode_reg (SImode, XEXP (operands[1], 0));
5162
788fcce0 5163 mem1 = change_address (operands[1], QImode, addr);
29c05e22 5164 mem2 = change_address (operands[1], QImode,
5165 plus_constant (Pmode, addr, 1));
215b30b3 5166 operands[0] = gen_lowpart (SImode, operands[0]);
5167 operands[1] = mem1;
5168 operands[2] = gen_reg_rtx (SImode);
5169 operands[3] = gen_reg_rtx (SImode);
5170 operands[6] = gen_reg_rtx (SImode);
5171 operands[7] = mem2;
25f7a26e 5172
215b30b3 5173 if (BYTES_BIG_ENDIAN)
5174 {
5175 operands[4] = operands[2];
5176 operands[5] = operands[3];
5177 }
5178 else
5179 {
5180 operands[4] = operands[3];
5181 operands[5] = operands[2];
5182 }
5183 }"
5184)
b11cae9e 5185
ef51b8e1 5186(define_split
5187 [(set (match_operand:SI 0 "register_operand" "")
5188 (sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
5189 "!arm_arch6"
5190 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
5191 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 16)))]
5192{
5193 operands[2] = simplify_gen_subreg (SImode, operands[1], HImode, 0);
5194})
5195
a2cd141b 5196(define_insn "*arm_extendhisi2"
ef51b8e1 5197 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
e3f4ccee 5198 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,Uh")))]
a2cd141b 5199 "TARGET_ARM && arm_arch4 && !arm_arch6"
ef51b8e1 5200 "@
5201 #
5202 ldr%(sh%)\\t%0, %1"
5203 [(set_attr "length" "8,4")
d82e788e 5204 (set_attr "type" "alu_shift_reg,load_byte")
e3f4ccee 5205 (set_attr "predicable" "yes")]
cffb2a26 5206)
f7fbdd4a 5207
25f905c2 5208;; ??? Check Thumb-2 pool range
a2cd141b 5209(define_insn "*arm_extendhisi2_v6"
5210 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
e3f4ccee 5211 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,Uh")))]
25f905c2 5212 "TARGET_32BIT && arm_arch6"
a2cd141b 5213 "@
5214 sxth%?\\t%0, %1
25f905c2 5215 ldr%(sh%)\\t%0, %1"
6b6abc9c 5216 [(set_attr "type" "extend,load_byte")
a2cd141b 5217 (set_attr "predicable" "yes")
e3f4ccee 5218 (set_attr "predicable_short_it" "no")]
a2cd141b 5219)
5220
5221(define_insn "*arm_extendhisi2addsi"
5222 [(set (match_operand:SI 0 "s_register_operand" "=r")
5223 (plus:SI (sign_extend:SI (match_operand:HI 1 "s_register_operand" "r"))
5224 (match_operand:SI 2 "s_register_operand" "r")))]
25f905c2 5225 "TARGET_INT_SIMD"
a2cd141b 5226 "sxtah%?\\t%0, %2, %1"
1b7da4ac 5227 [(set_attr "type" "alu_shift_reg")]
a2cd141b 5228)
5229
c8f69309 5230(define_expand "extendqihi2"
5231 [(set (match_dup 2)
bed7d9a5 5232 (ashift:SI (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "")
c8f69309 5233 (const_int 24)))
9c08d1fa 5234 (set (match_operand:HI 0 "s_register_operand" "")
c8f69309 5235 (ashiftrt:SI (match_dup 2)
5236 (const_int 24)))]
cffb2a26 5237 "TARGET_ARM"
c8f69309 5238 "
215b30b3 5239 {
0438d37f 5240 if (arm_arch4 && MEM_P (operands[1]))
215b30b3 5241 {
5242 emit_insn (gen_rtx_SET (VOIDmode,
5243 operands[0],
5244 gen_rtx_SIGN_EXTEND (HImode, operands[1])));
5245 DONE;
5246 }
5247 if (!s_register_operand (operands[1], QImode))
5248 operands[1] = copy_to_mode_reg (QImode, operands[1]);
5249 operands[0] = gen_lowpart (SImode, operands[0]);
5250 operands[1] = gen_lowpart (SImode, operands[1]);
5251 operands[2] = gen_reg_rtx (SImode);
5252 }"
5253)
f7fbdd4a 5254
25f905c2 5255(define_insn "*arm_extendqihi_insn"
b4e8a300 5256 [(set (match_operand:HI 0 "s_register_operand" "=r")
bed7d9a5 5257 (sign_extend:HI (match_operand:QI 1 "arm_extendqisi_mem_op" "Uq")))]
cffb2a26 5258 "TARGET_ARM && arm_arch4"
25f905c2 5259 "ldr%(sb%)\\t%0, %1"
a2cd141b 5260 [(set_attr "type" "load_byte")
e3f4ccee 5261 (set_attr "predicable" "yes")]
cffb2a26 5262)
3fc2009e 5263
b11cae9e 5264(define_expand "extendqisi2"
ef51b8e1 5265 [(set (match_operand:SI 0 "s_register_operand" "")
5266 (sign_extend:SI (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "")))]
cffb2a26 5267 "TARGET_EITHER"
ef51b8e1 5268{
5269 if (!arm_arch4 && MEM_P (operands[1]))
5270 operands[1] = copy_to_mode_reg (QImode, operands[1]);
a2cd141b 5271
ef51b8e1 5272 if (!arm_arch6 && !MEM_P (operands[1]))
5273 {
5274 rtx t = gen_lowpart (SImode, operands[1]);
5275 rtx tmp = gen_reg_rtx (SImode);
5276 emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (24)));
5277 emit_insn (gen_ashrsi3 (operands[0], tmp, GEN_INT (24)));
5278 DONE;
5279 }
5280})
a2cd141b 5281
ef51b8e1 5282(define_split
5283 [(set (match_operand:SI 0 "register_operand" "")
5284 (sign_extend:SI (match_operand:QI 1 "register_operand" "")))]
5285 "!arm_arch6"
5286 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 24)))
5287 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 24)))]
5288{
5289 operands[2] = simplify_gen_subreg (SImode, operands[1], QImode, 0);
5290})
f7fbdd4a 5291
a2cd141b 5292(define_insn "*arm_extendqisi"
ef51b8e1 5293 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5294 (sign_extend:SI (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "r,Uq")))]
a2cd141b 5295 "TARGET_ARM && arm_arch4 && !arm_arch6"
ef51b8e1 5296 "@
5297 #
5298 ldr%(sb%)\\t%0, %1"
5299 [(set_attr "length" "8,4")
d82e788e 5300 (set_attr "type" "alu_shift_reg,load_byte")
e3f4ccee 5301 (set_attr "predicable" "yes")]
cffb2a26 5302)
3fc2009e 5303
a2cd141b 5304(define_insn "*arm_extendqisi_v6"
5305 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
bed7d9a5 5306 (sign_extend:SI
5307 (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "r,Uq")))]
a2cd141b 5308 "TARGET_ARM && arm_arch6"
b4e8a300 5309 "@
5310 sxtb%?\\t%0, %1
25f905c2 5311 ldr%(sb%)\\t%0, %1"
6b6abc9c 5312 [(set_attr "type" "extend,load_byte")
e3f4ccee 5313 (set_attr "predicable" "yes")]
a2cd141b 5314)
5315
5316(define_insn "*arm_extendqisi2addsi"
5317 [(set (match_operand:SI 0 "s_register_operand" "=r")
5318 (plus:SI (sign_extend:SI (match_operand:QI 1 "s_register_operand" "r"))
5319 (match_operand:SI 2 "s_register_operand" "r")))]
25f905c2 5320 "TARGET_INT_SIMD"
a2cd141b 5321 "sxtab%?\\t%0, %2, %1"
d82e788e 5322 [(set_attr "type" "alu_shift_reg")
d952d547 5323 (set_attr "predicable" "yes")
5324 (set_attr "predicable_short_it" "no")]
a2cd141b 5325)
5326
caedf871 5327(define_expand "extendsfdf2"
5328 [(set (match_operand:DF 0 "s_register_operand" "")
5329 (float_extend:DF (match_operand:SF 1 "s_register_operand" "")))]
a50d7267 5330 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
caedf871 5331 ""
5332)
9b8516be 5333
5334/* HFmode -> DFmode conversions have to go through SFmode. */
5335(define_expand "extendhfdf2"
5336 [(set (match_operand:DF 0 "general_operand" "")
5337 (float_extend:DF (match_operand:HF 1 "general_operand" "")))]
5338 "TARGET_EITHER"
5339 "
5340 {
5341 rtx op1;
5342 op1 = convert_to_mode (SFmode, operands[1], 0);
5343 op1 = convert_to_mode (DFmode, op1, 0);
5344 emit_insn (gen_movdf (operands[0], op1));
5345 DONE;
5346 }"
5347)
b11cae9e 5348\f
5349;; Move insns (including loads and stores)
5350
5351;; XXX Just some ideas about movti.
9c08d1fa 5352;; I don't think these are a good idea on the arm, there just aren't enough
5353;; registers
b11cae9e 5354;;(define_expand "loadti"
9c08d1fa 5355;; [(set (match_operand:TI 0 "s_register_operand" "")
b11cae9e 5356;; (mem:TI (match_operand:SI 1 "address_operand" "")))]
5357;; "" "")
5358
5359;;(define_expand "storeti"
5360;; [(set (mem:TI (match_operand:TI 0 "address_operand" ""))
9c08d1fa 5361;; (match_operand:TI 1 "s_register_operand" ""))]
b11cae9e 5362;; "" "")
5363
5364;;(define_expand "movti"
5365;; [(set (match_operand:TI 0 "general_operand" "")
5366;; (match_operand:TI 1 "general_operand" ""))]
5367;; ""
5368;; "
5369;;{
5370;; rtx insn;
5371;;
0438d37f 5372;; if (MEM_P (operands[0]) && MEM_P (operands[1]))
b11cae9e 5373;; operands[1] = copy_to_reg (operands[1]);
0438d37f 5374;; if (MEM_P (operands[0]))
b11cae9e 5375;; insn = gen_storeti (XEXP (operands[0], 0), operands[1]);
0438d37f 5376;; else if (MEM_P (operands[1]))
b11cae9e 5377;; insn = gen_loadti (operands[0], XEXP (operands[1], 0));
5378;; else
5379;; FAIL;
5380;;
5381;; emit_insn (insn);
5382;; DONE;
5383;;}")
5384
a2f10574 5385;; Recognize garbage generated above.
b11cae9e 5386
5387;;(define_insn ""
5388;; [(set (match_operand:TI 0 "general_operand" "=r,r,r,<,>,m")
5389;; (match_operand:TI 1 "general_operand" "<,>,m,r,r,r"))]
5390;; ""
5391;; "*
5392;; {
5393;; register mem = (which_alternative < 3);
0d66636f 5394;; register const char *template;
b11cae9e 5395;;
5396;; operands[mem] = XEXP (operands[mem], 0);
5397;; switch (which_alternative)
5398;; {
5399;; case 0: template = \"ldmdb\\t%1!, %M0\"; break;
5400;; case 1: template = \"ldmia\\t%1!, %M0\"; break;
5401;; case 2: template = \"ldmia\\t%1, %M0\"; break;
5402;; case 3: template = \"stmdb\\t%0!, %M1\"; break;
5403;; case 4: template = \"stmia\\t%0!, %M1\"; break;
5404;; case 5: template = \"stmia\\t%0, %M1\"; break;
5405;; }
e2348bcb 5406;; output_asm_insn (template, operands);
5407;; return \"\";
b11cae9e 5408;; }")
5409
cffb2a26 5410(define_expand "movdi"
5411 [(set (match_operand:DI 0 "general_operand" "")
5412 (match_operand:DI 1 "general_operand" ""))]
5413 "TARGET_EITHER"
5414 "
e1ba4a27 5415 if (can_create_pseudo_p ())
cffb2a26 5416 {
0438d37f 5417 if (!REG_P (operands[0]))
b2778788 5418 operands[1] = force_reg (DImode, operands[1]);
cffb2a26 5419 }
5420 "
5421)
b11cae9e 5422
cffb2a26 5423(define_insn "*arm_movdi"
353cf59a 5424 [(set (match_operand:DI 0 "nonimmediate_di_operand" "=r, r, r, q, m")
5425 (match_operand:DI 1 "di_operand" "rDa,Db,Dc,mi,q"))]
cde1623a 5426 "TARGET_32BIT
b805622c 5427 && !(TARGET_HARD_FLOAT && TARGET_VFP)
b2778788 5428 && !TARGET_IWMMXT
5429 && ( register_operand (operands[0], DImode)
5430 || register_operand (operands[1], DImode))"
b11cae9e 5431 "*
d51f92df 5432 switch (which_alternative)
5433 {
5434 case 0:
5435 case 1:
5436 case 2:
5437 return \"#\";
5438 default:
26ff80c0 5439 return output_move_double (operands, true, NULL);
d51f92df 5440 }
cffb2a26 5441 "
359a6e9f 5442 [(set_attr "length" "8,12,16,8,8")
1b7da4ac 5443 (set_attr "type" "multiple,multiple,multiple,load2,store2")
cde1623a 5444 (set_attr "arm_pool_range" "*,*,*,1020,*")
8848d797 5445 (set_attr "arm_neg_pool_range" "*,*,*,1004,*")
42e1de19 5446 (set_attr "thumb2_pool_range" "*,*,*,4094,*")
cde1623a 5447 (set_attr "thumb2_neg_pool_range" "*,*,*,0,*")]
cffb2a26 5448)
5449
d51f92df 5450(define_split
5451 [(set (match_operand:ANY64 0 "arm_general_register_operand" "")
e6dd3afa 5452 (match_operand:ANY64 1 "immediate_operand" ""))]
25f905c2 5453 "TARGET_32BIT
d51f92df 5454 && reload_completed
5455 && (arm_const_double_inline_cost (operands[1])
861033d5 5456 <= arm_max_const_double_inline_cost ())"
d51f92df 5457 [(const_int 0)]
5458 "
5459 arm_split_constant (SET, SImode, curr_insn,
5460 INTVAL (gen_lowpart (SImode, operands[1])),
5461 gen_lowpart (SImode, operands[0]), NULL_RTX, 0);
5462 arm_split_constant (SET, SImode, curr_insn,
5463 INTVAL (gen_highpart_mode (SImode,
5464 GET_MODE (operands[0]),
5465 operands[1])),
5466 gen_highpart (SImode, operands[0]), NULL_RTX, 0);
5467 DONE;
5468 "
5469)
5470
e5ba9289 5471; If optimizing for size, or if we have load delay slots, then
5472; we want to split the constant into two separate operations.
5473; In both cases this may split a trivial part into a single data op
5474; leaving a single complex constant to load. We can also get longer
5475; offsets in a LDR which means we get better chances of sharing the pool
5476; entries. Finally, we can normally do a better job of scheduling
5477; LDR instructions than we can with LDM.
5478; This pattern will only match if the one above did not.
5479(define_split
5480 [(set (match_operand:ANY64 0 "arm_general_register_operand" "")
5481 (match_operand:ANY64 1 "const_double_operand" ""))]
5482 "TARGET_ARM && reload_completed
5483 && arm_const_double_by_parts (operands[1])"
5484 [(set (match_dup 0) (match_dup 1))
5485 (set (match_dup 2) (match_dup 3))]
5486 "
5487 operands[2] = gen_highpart (SImode, operands[0]);
5488 operands[3] = gen_highpart_mode (SImode, GET_MODE (operands[0]),
5489 operands[1]);
5490 operands[0] = gen_lowpart (SImode, operands[0]);
5491 operands[1] = gen_lowpart (SImode, operands[1]);
5492 "
5493)
5494
d51f92df 5495(define_split
5496 [(set (match_operand:ANY64 0 "arm_general_register_operand" "")
5497 (match_operand:ANY64 1 "arm_general_register_operand" ""))]
5498 "TARGET_EITHER && reload_completed"
5499 [(set (match_dup 0) (match_dup 1))
5500 (set (match_dup 2) (match_dup 3))]
5501 "
5502 operands[2] = gen_highpart (SImode, operands[0]);
5503 operands[3] = gen_highpart (SImode, operands[1]);
5504 operands[0] = gen_lowpart (SImode, operands[0]);
5505 operands[1] = gen_lowpart (SImode, operands[1]);
5506
5507 /* Handle a partial overlap. */
5508 if (rtx_equal_p (operands[0], operands[3]))
5509 {
5510 rtx tmp0 = operands[0];
5511 rtx tmp1 = operands[1];
5512
5513 operands[0] = operands[2];
5514 operands[1] = operands[3];
5515 operands[2] = tmp0;
5516 operands[3] = tmp1;
5517 }
5518 "
5519)
5520
a8a3b539 5521;; We can't actually do base+index doubleword loads if the index and
5522;; destination overlap. Split here so that we at least have chance to
5523;; schedule.
5524(define_split
5525 [(set (match_operand:DI 0 "s_register_operand" "")
5526 (mem:DI (plus:SI (match_operand:SI 1 "s_register_operand" "")
5527 (match_operand:SI 2 "s_register_operand" ""))))]
5528 "TARGET_LDRD
5529 && reg_overlap_mentioned_p (operands[0], operands[1])
5530 && reg_overlap_mentioned_p (operands[0], operands[2])"
5531 [(set (match_dup 4)
5532 (plus:SI (match_dup 1)
5533 (match_dup 2)))
5534 (set (match_dup 0)
5535 (mem:DI (match_dup 4)))]
5536 "
5537 operands[4] = gen_rtx_REG (SImode, REGNO(operands[0]));
5538 "
5539)
5540
9c08d1fa 5541(define_expand "movsi"
5542 [(set (match_operand:SI 0 "general_operand" "")
5543 (match_operand:SI 1 "general_operand" ""))]
cffb2a26 5544 "TARGET_EITHER"
9c08d1fa 5545 "
befb0bac 5546 {
e348ff3e 5547 rtx base, offset, tmp;
5548
25f905c2 5549 if (TARGET_32BIT)
9c08d1fa 5550 {
674a8f0b 5551 /* Everything except mem = const or mem = mem can be done easily. */
0438d37f 5552 if (MEM_P (operands[0]))
cffb2a26 5553 operands[1] = force_reg (SImode, operands[1]);
a2cd141b 5554 if (arm_general_register_operand (operands[0], SImode)
0438d37f 5555 && CONST_INT_P (operands[1])
cffb2a26 5556 && !(const_ok_for_arm (INTVAL (operands[1]))
5557 || const_ok_for_arm (~INTVAL (operands[1]))))
5558 {
96f57e36 5559 arm_split_constant (SET, SImode, NULL_RTX,
5560 INTVAL (operands[1]), operands[0], NULL_RTX,
e1ba4a27 5561 optimize && can_create_pseudo_p ());
cffb2a26 5562 DONE;
5563 }
5564 }
25f905c2 5565 else /* TARGET_THUMB1... */
cffb2a26 5566 {
e1ba4a27 5567 if (can_create_pseudo_p ())
cffb2a26 5568 {
0438d37f 5569 if (!REG_P (operands[0]))
cffb2a26 5570 operands[1] = force_reg (SImode, operands[1]);
5571 }
9c08d1fa 5572 }
f655717d 5573
e348ff3e 5574 if (ARM_OFFSETS_MUST_BE_WITHIN_SECTIONS_P)
5575 {
5576 split_const (operands[1], &base, &offset);
5577 if (GET_CODE (base) == SYMBOL_REF
5578 && !offset_within_block_p (base, INTVAL (offset)))
5579 {
b308ddcf 5580 tmp = can_create_pseudo_p () ? gen_reg_rtx (SImode) : operands[0];
e348ff3e 5581 emit_move_insn (tmp, base);
5582 emit_insn (gen_addsi3 (operands[0], tmp, offset));
5583 DONE;
5584 }
5585 }
5586
f655717d 5587 /* Recognize the case where operand[1] is a reference to thread-local
5588 data and load its address to a register. */
5589 if (arm_tls_referenced_p (operands[1]))
5590 {
5591 rtx tmp = operands[1];
5592 rtx addend = NULL;
5593
5594 if (GET_CODE (tmp) == CONST && GET_CODE (XEXP (tmp, 0)) == PLUS)
5595 {
5596 addend = XEXP (XEXP (tmp, 0), 1);
5597 tmp = XEXP (XEXP (tmp, 0), 0);
5598 }
5599
5600 gcc_assert (GET_CODE (tmp) == SYMBOL_REF);
5601 gcc_assert (SYMBOL_REF_TLS_MODEL (tmp) != 0);
5602
e1ba4a27 5603 tmp = legitimize_tls_address (tmp,
5604 !can_create_pseudo_p () ? operands[0] : 0);
f655717d 5605 if (addend)
5606 {
5607 tmp = gen_rtx_PLUS (SImode, tmp, addend);
5608 tmp = force_operand (tmp, operands[0]);
5609 }
5610 operands[1] = tmp;
5611 }
5612 else if (flag_pic
5613 && (CONSTANT_P (operands[1])
5614 || symbol_mentioned_p (operands[1])
5615 || label_mentioned_p (operands[1])))
5616 operands[1] = legitimize_pic_address (operands[1], SImode,
e1ba4a27 5617 (!can_create_pseudo_p ()
5618 ? operands[0]
5619 : 0));
befb0bac 5620 }
215b30b3 5621 "
5622)
9c08d1fa 5623
d0e6a121 5624;; The ARM LO_SUM and HIGH are backwards - HIGH sets the low bits, and
5625;; LO_SUM adds in the high bits. Fortunately these are opaque operations
5626;; so this does not matter.
5627(define_insn "*arm_movt"
5628 [(set (match_operand:SI 0 "nonimmediate_operand" "=r")
5629 (lo_sum:SI (match_operand:SI 1 "nonimmediate_operand" "0")
5630 (match_operand:SI 2 "general_operand" "i")))]
c9b2ce40 5631 "arm_arch_thumb2"
d0e6a121 5632 "movt%?\t%0, #:upper16:%c2"
5633 [(set_attr "predicable" "yes")
d952d547 5634 (set_attr "predicable_short_it" "no")
1b7da4ac 5635 (set_attr "length" "4")
5636 (set_attr "type" "mov_imm")]
d0e6a121 5637)
5638
cffb2a26 5639(define_insn "*arm_movsi_insn"
aaa37ad6 5640 [(set (match_operand:SI 0 "nonimmediate_operand" "=rk,r,r,r,rk,m")
110eae03 5641 (match_operand:SI 1 "general_operand" "rk, I,K,j,mi,rk"))]
755eb2b4 5642 "TARGET_ARM && ! TARGET_IWMMXT
a2cd141b 5643 && !(TARGET_HARD_FLOAT && TARGET_VFP)
cffb2a26 5644 && ( register_operand (operands[0], SImode)
5645 || register_operand (operands[1], SImode))"
f7fbdd4a 5646 "@
aaa37ad6 5647 mov%?\\t%0, %1
f7fbdd4a 5648 mov%?\\t%0, %1
5649 mvn%?\\t%0, #%B1
25f905c2 5650 movw%?\\t%0, %1
f7fbdd4a 5651 ldr%?\\t%0, %1
5652 str%?\\t%1, %0"
1aed5204 5653 [(set_attr "type" "mov_reg,mov_imm,mvn_imm,mov_imm,load1,store1")
0d66636f 5654 (set_attr "predicable" "yes")
aaa37ad6 5655 (set_attr "pool_range" "*,*,*,*,4096,*")
5656 (set_attr "neg_pool_range" "*,*,*,*,4084,*")]
cffb2a26 5657)
87b22bf7 5658
5659(define_split
a2cd141b 5660 [(set (match_operand:SI 0 "arm_general_register_operand" "")
87b22bf7 5661 (match_operand:SI 1 "const_int_operand" ""))]
25f905c2 5662 "TARGET_32BIT
215b30b3 5663 && (!(const_ok_for_arm (INTVAL (operands[1]))
5664 || const_ok_for_arm (~INTVAL (operands[1]))))"
87b22bf7 5665 [(clobber (const_int 0))]
5666 "
96f57e36 5667 arm_split_constant (SET, SImode, NULL_RTX,
5668 INTVAL (operands[1]), operands[0], NULL_RTX, 0);
87b22bf7 5669 DONE;
215b30b3 5670 "
5671)
9c08d1fa 5672
861033d5 5673;; A normal way to do (symbol + offset) requires three instructions at least
5674;; (depends on how big the offset is) as below:
5675;; movw r0, #:lower16:g
5676;; movw r0, #:upper16:g
5677;; adds r0, #4
5678;;
5679;; A better way would be:
5680;; movw r0, #:lower16:g+4
5681;; movw r0, #:upper16:g+4
5682;;
5683;; The limitation of this way is that the length of offset should be a 16-bit
5684;; signed value, because current assembler only supports REL type relocation for
5685;; such case. If the more powerful RELA type is supported in future, we should
5686;; update this pattern to go with better way.
5687(define_split
5688 [(set (match_operand:SI 0 "arm_general_register_operand" "")
5689 (const:SI (plus:SI (match_operand:SI 1 "general_operand" "")
5690 (match_operand:SI 2 "const_int_operand" ""))))]
5691 "TARGET_THUMB2
5692 && arm_disable_literal_pool
5693 && reload_completed
5694 && GET_CODE (operands[1]) == SYMBOL_REF"
5695 [(clobber (const_int 0))]
5696 "
5697 int offset = INTVAL (operands[2]);
5698
5699 if (offset < -0x8000 || offset > 0x7fff)
5700 {
5701 arm_emit_movpair (operands[0], operands[1]);
5702 emit_insn (gen_rtx_SET (SImode, operands[0],
5703 gen_rtx_PLUS (SImode, operands[0], operands[2])));
5704 }
5705 else
5706 {
5707 rtx op = gen_rtx_CONST (SImode,
5708 gen_rtx_PLUS (SImode, operands[1], operands[2]));
5709 arm_emit_movpair (operands[0], op);
5710 }
5711 "
5712)
5713
b8d5d078 5714;; Split symbol_refs at the later stage (after cprop), instead of generating
5715;; movt/movw pair directly at expand. Otherwise corresponding high_sum
5716;; and lo_sum would be merged back into memory load at cprop. However,
5717;; if the default is to prefer movt/movw rather than a load from the constant
5718;; pool, the performance is better.
5719(define_split
5720 [(set (match_operand:SI 0 "arm_general_register_operand" "")
5721 (match_operand:SI 1 "general_operand" ""))]
5722 "TARGET_32BIT
5723 && TARGET_USE_MOVT && GET_CODE (operands[1]) == SYMBOL_REF
5724 && !flag_pic && !target_word_relocations
5725 && !arm_tls_referenced_p (operands[1])"
5726 [(clobber (const_int 0))]
5727{
5728 arm_emit_movpair (operands[0], operands[1]);
5729 DONE;
5730})
5731
bc360af8 5732;; When generating pic, we need to load the symbol offset into a register.
5733;; So that the optimizer does not confuse this with a normal symbol load
5734;; we use an unspec. The offset will be loaded from a constant pool entry,
5735;; since that is the only type of relocation we can use.
cffb2a26 5736
bc360af8 5737;; Wrap calculation of the whole PIC address in a single pattern for the
5738;; benefit of optimizers, particularly, PRE and HOIST. Calculation of
5739;; a PIC address involves two loads from memory, so we want to CSE it
5740;; as often as possible.
5741;; This pattern will be split into one of the pic_load_addr_* patterns
5742;; and a move after GCSE optimizations.
5743;;
5744;; Note: Update arm.c: legitimize_pic_address() when changing this pattern.
5745(define_expand "calculate_pic_address"
94f8caca 5746 [(set (match_operand:SI 0 "register_operand" "")
5747 (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "")
5748 (unspec:SI [(match_operand:SI 2 "" "")]
5749 UNSPEC_PIC_SYM))))]
5750 "flag_pic"
5751)
5752
5753;; Split calculate_pic_address into pic_load_addr_* and a move.
5754(define_split
5755 [(set (match_operand:SI 0 "register_operand" "")
5756 (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "")
5757 (unspec:SI [(match_operand:SI 2 "" "")]
5758 UNSPEC_PIC_SYM))))]
5759 "flag_pic"
5760 [(set (match_dup 3) (unspec:SI [(match_dup 2)] UNSPEC_PIC_SYM))
5761 (set (match_dup 0) (mem:SI (plus:SI (match_dup 1) (match_dup 3))))]
5762 "operands[3] = can_create_pseudo_p () ? gen_reg_rtx (SImode) : operands[0];"
5763)
5764
350ccca5 5765;; operand1 is the memory address to go into
5766;; pic_load_addr_32bit.
5767;; operand2 is the PIC label to be emitted
5768;; from pic_add_dot_plus_eight.
5769;; We do this to allow hoisting of the entire insn.
5770(define_insn_and_split "pic_load_addr_unified"
5771 [(set (match_operand:SI 0 "s_register_operand" "=r,r,l")
5772 (unspec:SI [(match_operand:SI 1 "" "mX,mX,mX")
5773 (match_operand:SI 2 "" "")]
5774 UNSPEC_PIC_UNIFIED))]
5775 "flag_pic"
5776 "#"
5777 "&& reload_completed"
5778 [(set (match_dup 0) (unspec:SI [(match_dup 1)] UNSPEC_PIC_SYM))
5779 (set (match_dup 0) (unspec:SI [(match_dup 0) (match_dup 3)
5780 (match_dup 2)] UNSPEC_PIC_BASE))]
5781 "operands[3] = TARGET_THUMB ? GEN_INT (4) : GEN_INT (8);"
5782 [(set_attr "type" "load1,load1,load1")
42e1de19 5783 (set_attr "pool_range" "4096,4094,1022")
350ccca5 5784 (set_attr "neg_pool_range" "4084,0,0")
5785 (set_attr "arch" "a,t2,t1")
5786 (set_attr "length" "8,6,4")]
5787)
5788
67336bcf 5789;; The rather odd constraints on the following are to force reload to leave
5790;; the insn alone, and to force the minipool generation pass to then move
5791;; the GOT symbol to memory.
849170fd 5792
b3cd5f55 5793(define_insn "pic_load_addr_32bit"
849170fd 5794 [(set (match_operand:SI 0 "s_register_operand" "=r")
e1159bbe 5795 (unspec:SI [(match_operand:SI 1 "" "mX")] UNSPEC_PIC_SYM))]
b3cd5f55 5796 "TARGET_32BIT && flag_pic"
67336bcf 5797 "ldr%?\\t%0, %1"
a2cd141b 5798 [(set_attr "type" "load1")
42e1de19 5799 (set (attr "pool_range")
5800 (if_then_else (eq_attr "is_thumb" "no")
5801 (const_int 4096)
5802 (const_int 4094)))
b3cd5f55 5803 (set (attr "neg_pool_range")
5804 (if_then_else (eq_attr "is_thumb" "no")
5805 (const_int 4084)
5806 (const_int 0)))]
8c4d8060 5807)
5808
25f905c2 5809(define_insn "pic_load_addr_thumb1"
8c4d8060 5810 [(set (match_operand:SI 0 "s_register_operand" "=l")
e1159bbe 5811 (unspec:SI [(match_operand:SI 1 "" "mX")] UNSPEC_PIC_SYM))]
25f905c2 5812 "TARGET_THUMB1 && flag_pic"
8c4d8060 5813 "ldr\\t%0, %1"
a2cd141b 5814 [(set_attr "type" "load1")
42e1de19 5815 (set (attr "pool_range") (const_int 1018))]
cffb2a26 5816)
849170fd 5817
cffb2a26 5818(define_insn "pic_add_dot_plus_four"
15d5d060 5819 [(set (match_operand:SI 0 "register_operand" "=r")
c0c1fba5 5820 (unspec:SI [(match_operand:SI 1 "register_operand" "0")
5821 (const_int 4)
beef0fb5 5822 (match_operand 2 "" "")]
5823 UNSPEC_PIC_BASE))]
b3cd5f55 5824 "TARGET_THUMB"
cffb2a26 5825 "*
6cdcb15c 5826 (*targetm.asm_out.internal_label) (asm_out_file, \"LPIC\",
5827 INTVAL (operands[2]));
cffb2a26 5828 return \"add\\t%0, %|pc\";
5829 "
1b7da4ac 5830 [(set_attr "length" "2")
112eda6f 5831 (set_attr "type" "alu_sreg")]
cffb2a26 5832)
849170fd 5833
5834(define_insn "pic_add_dot_plus_eight"
15d5d060 5835 [(set (match_operand:SI 0 "register_operand" "=r")
c0c1fba5 5836 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
5837 (const_int 8)
beef0fb5 5838 (match_operand 2 "" "")]
5839 UNSPEC_PIC_BASE))]
f655717d 5840 "TARGET_ARM"
c4034607 5841 "*
6cdcb15c 5842 (*targetm.asm_out.internal_label) (asm_out_file, \"LPIC\",
5843 INTVAL (operands[2]));
15d5d060 5844 return \"add%?\\t%0, %|pc, %1\";
cffb2a26 5845 "
1b7da4ac 5846 [(set_attr "predicable" "yes")
112eda6f 5847 (set_attr "type" "alu_sreg")]
cffb2a26 5848)
849170fd 5849
f655717d 5850(define_insn "tls_load_dot_plus_eight"
cc071db6 5851 [(set (match_operand:SI 0 "register_operand" "=r")
c0c1fba5 5852 (mem:SI (unspec:SI [(match_operand:SI 1 "register_operand" "r")
5853 (const_int 8)
beef0fb5 5854 (match_operand 2 "" "")]
5855 UNSPEC_PIC_BASE)))]
f655717d 5856 "TARGET_ARM"
5857 "*
6cdcb15c 5858 (*targetm.asm_out.internal_label) (asm_out_file, \"LPIC\",
5859 INTVAL (operands[2]));
f655717d 5860 return \"ldr%?\\t%0, [%|pc, %1]\t\t@ tls_load_dot_plus_eight\";
5861 "
1b7da4ac 5862 [(set_attr "predicable" "yes")
5863 (set_attr "type" "load1")]
f655717d 5864)
5865
5866;; PIC references to local variables can generate pic_add_dot_plus_eight
5867;; followed by a load. These sequences can be crunched down to
5868;; tls_load_dot_plus_eight by a peephole.
5869
5870(define_peephole2
c0c1fba5 5871 [(set (match_operand:SI 0 "register_operand" "")
5872 (unspec:SI [(match_operand:SI 3 "register_operand" "")
5873 (const_int 8)
5874 (match_operand 1 "" "")]
5875 UNSPEC_PIC_BASE))
2d05dfad 5876 (set (match_operand:SI 2 "arm_general_register_operand" "")
5877 (mem:SI (match_dup 0)))]
f655717d 5878 "TARGET_ARM && peep2_reg_dead_p (2, operands[0])"
c0c1fba5 5879 [(set (match_dup 2)
5880 (mem:SI (unspec:SI [(match_dup 3)
5881 (const_int 8)
5882 (match_dup 1)]
5883 UNSPEC_PIC_BASE)))]
f655717d 5884 ""
5885)
5886
bac7fc85 5887(define_insn "pic_offset_arm"
5888 [(set (match_operand:SI 0 "register_operand" "=r")
5889 (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
5890 (unspec:SI [(match_operand:SI 2 "" "X")]
5891 UNSPEC_PIC_OFFSET))))]
5892 "TARGET_VXWORKS_RTP && TARGET_ARM && flag_pic"
5893 "ldr%?\\t%0, [%1,%2]"
5894 [(set_attr "type" "load1")]
5895)
5896
95373f08 5897(define_expand "builtin_setjmp_receiver"
5898 [(label_ref (match_operand 0 "" ""))]
5899 "flag_pic"
5900 "
5901{
b935b306 5902 /* r3 is clobbered by set/longjmp, so we can use it as a scratch
5903 register. */
2cb7d577 5904 if (arm_pic_register != INVALID_REGNUM)
5905 arm_load_pic_register (1UL << 3);
95373f08 5906 DONE;
5907}")
5908
9c08d1fa 5909;; If copying one reg to another we can set the condition codes according to
5910;; its value. Such a move is common after a return from subroutine and the
5911;; result is being tested against zero.
5912
f7fbdd4a 5913(define_insn "*movsi_compare0"
bd5b4116 5914 [(set (reg:CC CC_REGNUM)
cffb2a26 5915 (compare:CC (match_operand:SI 1 "s_register_operand" "0,r")
5916 (const_int 0)))
5917 (set (match_operand:SI 0 "s_register_operand" "=r,r")
5918 (match_dup 1))]
25f905c2 5919 "TARGET_32BIT"
e2348bcb 5920 "@
40dbec34 5921 cmp%?\\t%0, #0
25f905c2 5922 sub%.\\t%0, %1, #0"
65f68e55 5923 [(set_attr "conds" "set")
d82e788e 5924 (set_attr "type" "alus_imm,alus_imm")]
cffb2a26 5925)
b11cae9e 5926
b11cae9e 5927;; Subroutine to store a half word from a register into memory.
5928;; Operand 0 is the source register (HImode)
c8f69309 5929;; Operand 1 is the destination address in a register (SImode)
b11cae9e 5930
9c08d1fa 5931;; In both this routine and the next, we must be careful not to spill
01cc3b75 5932;; a memory address of reg+large_const into a separate PLUS insn, since this
9c08d1fa 5933;; can generate unrecognizable rtl.
5934
b11cae9e 5935(define_expand "storehi"
c8f69309 5936 [;; store the low byte
f082f1c4 5937 (set (match_operand 1 "" "") (match_dup 3))
b11cae9e 5938 ;; extract the high byte
c8f69309 5939 (set (match_dup 2)
5940 (ashiftrt:SI (match_operand 0 "" "") (const_int 8)))
b11cae9e 5941 ;; store the high byte
787f8210 5942 (set (match_dup 4) (match_dup 5))]
cffb2a26 5943 "TARGET_ARM"
b11cae9e 5944 "
215b30b3 5945 {
537ffcfc 5946 rtx op1 = operands[1];
5947 rtx addr = XEXP (op1, 0);
215b30b3 5948 enum rtx_code code = GET_CODE (addr);
5949
0438d37f 5950 if ((code == PLUS && !CONST_INT_P (XEXP (addr, 1)))
215b30b3 5951 || code == MINUS)
537ffcfc 5952 op1 = replace_equiv_address (operands[1], force_reg (SImode, addr));
215b30b3 5953
537ffcfc 5954 operands[4] = adjust_address (op1, QImode, 1);
e513d163 5955 operands[1] = adjust_address (operands[1], QImode, 0);
215b30b3 5956 operands[3] = gen_lowpart (QImode, operands[0]);
5957 operands[0] = gen_lowpart (SImode, operands[0]);
787f8210 5958 operands[2] = gen_reg_rtx (SImode);
5959 operands[5] = gen_lowpart (QImode, operands[2]);
215b30b3 5960 }"
5961)
b11cae9e 5962
c7597b5d 5963(define_expand "storehi_bigend"
f082f1c4 5964 [(set (match_dup 4) (match_dup 3))
c7597b5d 5965 (set (match_dup 2)
5966 (ashiftrt:SI (match_operand 0 "" "") (const_int 8)))
787f8210 5967 (set (match_operand 1 "" "") (match_dup 5))]
cffb2a26 5968 "TARGET_ARM"
b11cae9e 5969 "
215b30b3 5970 {
537ffcfc 5971 rtx op1 = operands[1];
5972 rtx addr = XEXP (op1, 0);
215b30b3 5973 enum rtx_code code = GET_CODE (addr);
5974
0438d37f 5975 if ((code == PLUS && !CONST_INT_P (XEXP (addr, 1)))
215b30b3 5976 || code == MINUS)
537ffcfc 5977 op1 = replace_equiv_address (op1, force_reg (SImode, addr));
215b30b3 5978
537ffcfc 5979 operands[4] = adjust_address (op1, QImode, 1);
e513d163 5980 operands[1] = adjust_address (operands[1], QImode, 0);
215b30b3 5981 operands[3] = gen_lowpart (QImode, operands[0]);
5982 operands[0] = gen_lowpart (SImode, operands[0]);
5983 operands[2] = gen_reg_rtx (SImode);
787f8210 5984 operands[5] = gen_lowpart (QImode, operands[2]);
215b30b3 5985 }"
5986)
c7597b5d 5987
5988;; Subroutine to store a half word integer constant into memory.
5989(define_expand "storeinthi"
f082f1c4 5990 [(set (match_operand 0 "" "")
787f8210 5991 (match_operand 1 "" ""))
9e8503e6 5992 (set (match_dup 3) (match_dup 2))]
cffb2a26 5993 "TARGET_ARM"
c7597b5d 5994 "
215b30b3 5995 {
5996 HOST_WIDE_INT value = INTVAL (operands[1]);
5997 rtx addr = XEXP (operands[0], 0);
537ffcfc 5998 rtx op0 = operands[0];
215b30b3 5999 enum rtx_code code = GET_CODE (addr);
c7597b5d 6000
0438d37f 6001 if ((code == PLUS && !CONST_INT_P (XEXP (addr, 1)))
215b30b3 6002 || code == MINUS)
537ffcfc 6003 op0 = replace_equiv_address (op0, force_reg (SImode, addr));
c7597b5d 6004
215b30b3 6005 operands[1] = gen_reg_rtx (SImode);
6006 if (BYTES_BIG_ENDIAN)
6007 {
6008 emit_insn (gen_movsi (operands[1], GEN_INT ((value >> 8) & 255)));
6009 if ((value & 255) == ((value >> 8) & 255))
6010 operands[2] = operands[1];
6011 else
6012 {
6013 operands[2] = gen_reg_rtx (SImode);
6014 emit_insn (gen_movsi (operands[2], GEN_INT (value & 255)));
6015 }
6016 }
6017 else
6018 {
6019 emit_insn (gen_movsi (operands[1], GEN_INT (value & 255)));
6020 if ((value & 255) == ((value >> 8) & 255))
6021 operands[2] = operands[1];
6022 else
6023 {
6024 operands[2] = gen_reg_rtx (SImode);
6025 emit_insn (gen_movsi (operands[2], GEN_INT ((value >> 8) & 255)));
6026 }
6027 }
c7597b5d 6028
537ffcfc 6029 operands[3] = adjust_address (op0, QImode, 1);
e513d163 6030 operands[0] = adjust_address (operands[0], QImode, 0);
9e8503e6 6031 operands[2] = gen_lowpart (QImode, operands[2]);
787f8210 6032 operands[1] = gen_lowpart (QImode, operands[1]);
215b30b3 6033 }"
6034)
b11cae9e 6035
f7fbdd4a 6036(define_expand "storehi_single_op"
6037 [(set (match_operand:HI 0 "memory_operand" "")
6038 (match_operand:HI 1 "general_operand" ""))]
25f905c2 6039 "TARGET_32BIT && arm_arch4"
f7fbdd4a 6040 "
215b30b3 6041 if (!s_register_operand (operands[1], HImode))
f7fbdd4a 6042 operands[1] = copy_to_mode_reg (HImode, operands[1]);
215b30b3 6043 "
6044)
f7fbdd4a 6045
b11cae9e 6046(define_expand "movhi"
6047 [(set (match_operand:HI 0 "general_operand" "")
c8f69309 6048 (match_operand:HI 1 "general_operand" ""))]
cffb2a26 6049 "TARGET_EITHER"
b11cae9e 6050 "
cffb2a26 6051 if (TARGET_ARM)
b11cae9e 6052 {
e1ba4a27 6053 if (can_create_pseudo_p ())
cffb2a26 6054 {
0438d37f 6055 if (MEM_P (operands[0]))
b11cae9e 6056 {
cffb2a26 6057 if (arm_arch4)
6058 {
6059 emit_insn (gen_storehi_single_op (operands[0], operands[1]));
6060 DONE;
6061 }
0438d37f 6062 if (CONST_INT_P (operands[1]))
cffb2a26 6063 emit_insn (gen_storeinthi (operands[0], operands[1]));
c7597b5d 6064 else
cffb2a26 6065 {
0438d37f 6066 if (MEM_P (operands[1]))
cffb2a26 6067 operands[1] = force_reg (HImode, operands[1]);
6068 if (BYTES_BIG_ENDIAN)
6069 emit_insn (gen_storehi_bigend (operands[1], operands[0]));
6070 else
6071 emit_insn (gen_storehi (operands[1], operands[0]));
6072 }
6073 DONE;
b11cae9e 6074 }
cffb2a26 6075 /* Sign extend a constant, and keep it in an SImode reg. */
0438d37f 6076 else if (CONST_INT_P (operands[1]))
9c08d1fa 6077 {
cffb2a26 6078 rtx reg = gen_reg_rtx (SImode);
6079 HOST_WIDE_INT val = INTVAL (operands[1]) & 0xffff;
6080
6081 /* If the constant is already valid, leave it alone. */
215b30b3 6082 if (!const_ok_for_arm (val))
cffb2a26 6083 {
6084 /* If setting all the top bits will make the constant
6085 loadable in a single instruction, then set them.
6086 Otherwise, sign extend the number. */
6087
215b30b3 6088 if (const_ok_for_arm (~(val | ~0xffff)))
cffb2a26 6089 val |= ~0xffff;
6090 else if (val & 0x8000)
6091 val |= ~0xffff;
6092 }
6093
6094 emit_insn (gen_movsi (reg, GEN_INT (val)));
9e8503e6 6095 operands[1] = gen_lowpart (HImode, reg);
9c08d1fa 6096 }
e1ba4a27 6097 else if (arm_arch4 && optimize && can_create_pseudo_p ()
0438d37f 6098 && MEM_P (operands[1]))
0045890a 6099 {
6100 rtx reg = gen_reg_rtx (SImode);
6101
6102 emit_insn (gen_zero_extendhisi2 (reg, operands[1]));
6103 operands[1] = gen_lowpart (HImode, reg);
6104 }
215b30b3 6105 else if (!arm_arch4)
f7fbdd4a 6106 {
0438d37f 6107 if (MEM_P (operands[1]))
cffb2a26 6108 {
c1a66faf 6109 rtx base;
6110 rtx offset = const0_rtx;
6111 rtx reg = gen_reg_rtx (SImode);
6112
0438d37f 6113 if ((REG_P (base = XEXP (operands[1], 0))
c1a66faf 6114 || (GET_CODE (base) == PLUS
0438d37f 6115 && (CONST_INT_P (offset = XEXP (base, 1)))
c1a66faf 6116 && ((INTVAL(offset) & 1) != 1)
0438d37f 6117 && REG_P (base = XEXP (base, 0))))
c1a66faf 6118 && REGNO_POINTER_ALIGN (REGNO (base)) >= 32)
206ee9a2 6119 {
8deb3959 6120 rtx new_rtx;
c1a66faf 6121
8deb3959 6122 new_rtx = widen_memory_access (operands[1], SImode,
6123 ((INTVAL (offset) & ~3)
6124 - INTVAL (offset)));
6125 emit_insn (gen_movsi (reg, new_rtx));
c1a66faf 6126 if (((INTVAL (offset) & 2) != 0)
6127 ^ (BYTES_BIG_ENDIAN ? 1 : 0))
6128 {
6129 rtx reg2 = gen_reg_rtx (SImode);
6130
6131 emit_insn (gen_lshrsi3 (reg2, reg, GEN_INT (16)));
6132 reg = reg2;
6133 }
206ee9a2 6134 }
c1a66faf 6135 else
6136 emit_insn (gen_movhi_bytes (reg, operands[1]));
6137
6138 operands[1] = gen_lowpart (HImode, reg);
cffb2a26 6139 }
6140 }
6141 }
674a8f0b 6142 /* Handle loading a large integer during reload. */
0438d37f 6143 else if (CONST_INT_P (operands[1])
215b30b3 6144 && !const_ok_for_arm (INTVAL (operands[1]))
6145 && !const_ok_for_arm (~INTVAL (operands[1])))
cffb2a26 6146 {
6147 /* Writing a constant to memory needs a scratch, which should
6148 be handled with SECONDARY_RELOADs. */
0438d37f 6149 gcc_assert (REG_P (operands[0]));
cffb2a26 6150
6151 operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
6152 emit_insn (gen_movsi (operands[0], operands[1]));
6153 DONE;
6154 }
6155 }
25f905c2 6156 else if (TARGET_THUMB2)
6157 {
6158 /* Thumb-2 can do everything except mem=mem and mem=const easily. */
e1ba4a27 6159 if (can_create_pseudo_p ())
25f905c2 6160 {
0438d37f 6161 if (!REG_P (operands[0]))
25f905c2 6162 operands[1] = force_reg (HImode, operands[1]);
6163 /* Zero extend a constant, and keep it in an SImode reg. */
0438d37f 6164 else if (CONST_INT_P (operands[1]))
25f905c2 6165 {
6166 rtx reg = gen_reg_rtx (SImode);
6167 HOST_WIDE_INT val = INTVAL (operands[1]) & 0xffff;
6168
6169 emit_insn (gen_movsi (reg, GEN_INT (val)));
6170 operands[1] = gen_lowpart (HImode, reg);
6171 }
6172 }
6173 }
6174 else /* TARGET_THUMB1 */
cffb2a26 6175 {
e1ba4a27 6176 if (can_create_pseudo_p ())
cffb2a26 6177 {
0438d37f 6178 if (CONST_INT_P (operands[1]))
6cffc037 6179 {
6180 rtx reg = gen_reg_rtx (SImode);
6181
6182 emit_insn (gen_movsi (reg, operands[1]));
6183 operands[1] = gen_lowpart (HImode, reg);
6184 }
cffb2a26 6185
6186 /* ??? We shouldn't really get invalid addresses here, but this can
215b30b3 6187 happen if we are passed a SP (never OK for HImode/QImode) or
bc409cb4 6188 virtual register (also rejected as illegitimate for HImode/QImode)
6189 relative address. */
cffb2a26 6190 /* ??? This should perhaps be fixed elsewhere, for instance, in
6191 fixup_stack_1, by checking for other kinds of invalid addresses,
6192 e.g. a bare reference to a virtual register. This may confuse the
6193 alpha though, which must handle this case differently. */
0438d37f 6194 if (MEM_P (operands[0])
215b30b3 6195 && !memory_address_p (GET_MODE (operands[0]),
6196 XEXP (operands[0], 0)))
537ffcfc 6197 operands[0]
6198 = replace_equiv_address (operands[0],
6199 copy_to_reg (XEXP (operands[0], 0)));
cffb2a26 6200
0438d37f 6201 if (MEM_P (operands[1])
215b30b3 6202 && !memory_address_p (GET_MODE (operands[1]),
6203 XEXP (operands[1], 0)))
537ffcfc 6204 operands[1]
6205 = replace_equiv_address (operands[1],
6206 copy_to_reg (XEXP (operands[1], 0)));
6cffc037 6207
0438d37f 6208 if (MEM_P (operands[1]) && optimize > 0)
6cffc037 6209 {
6210 rtx reg = gen_reg_rtx (SImode);
6211
6212 emit_insn (gen_zero_extendhisi2 (reg, operands[1]));
6213 operands[1] = gen_lowpart (HImode, reg);
6214 }
6215
0438d37f 6216 if (MEM_P (operands[0]))
6cffc037 6217 operands[1] = force_reg (HImode, operands[1]);
cffb2a26 6218 }
0438d37f 6219 else if (CONST_INT_P (operands[1])
234f6557 6220 && !satisfies_constraint_I (operands[1]))
cffb2a26 6221 {
6cffc037 6222 /* Handle loading a large integer during reload. */
6223
cffb2a26 6224 /* Writing a constant to memory needs a scratch, which should
6225 be handled with SECONDARY_RELOADs. */
0438d37f 6226 gcc_assert (REG_P (operands[0]));
cffb2a26 6227
1a83b3ff 6228 operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
cffb2a26 6229 emit_insn (gen_movsi (operands[0], operands[1]));
6230 DONE;
6231 }
b11cae9e 6232 }
cffb2a26 6233 "
6234)
6235
25f7a26e 6236(define_expand "movhi_bytes"
eab14235 6237 [(set (match_dup 2) (zero_extend:SI (match_operand:HI 1 "" "")))
25f7a26e 6238 (set (match_dup 3)
eab14235 6239 (zero_extend:SI (match_dup 6)))
25f7a26e 6240 (set (match_operand:SI 0 "" "")
6241 (ior:SI (ashift:SI (match_dup 4) (const_int 8)) (match_dup 5)))]
cffb2a26 6242 "TARGET_ARM"
25f7a26e 6243 "
215b30b3 6244 {
6245 rtx mem1, mem2;
6246 rtx addr = copy_to_mode_reg (SImode, XEXP (operands[1], 0));
6247
788fcce0 6248 mem1 = change_address (operands[1], QImode, addr);
29c05e22 6249 mem2 = change_address (operands[1], QImode,
6250 plus_constant (Pmode, addr, 1));
215b30b3 6251 operands[0] = gen_lowpart (SImode, operands[0]);
6252 operands[1] = mem1;
6253 operands[2] = gen_reg_rtx (SImode);
6254 operands[3] = gen_reg_rtx (SImode);
6255 operands[6] = mem2;
25f7a26e 6256
215b30b3 6257 if (BYTES_BIG_ENDIAN)
6258 {
6259 operands[4] = operands[2];
6260 operands[5] = operands[3];
6261 }
6262 else
6263 {
6264 operands[4] = operands[3];
6265 operands[5] = operands[2];
6266 }
6267 }"
6268)
25f7a26e 6269
c7597b5d 6270(define_expand "movhi_bigend"
6271 [(set (match_dup 2)
6272 (rotate:SI (subreg:SI (match_operand:HI 1 "memory_operand" "") 0)
6273 (const_int 16)))
6274 (set (match_dup 3)
6275 (ashiftrt:SI (match_dup 2) (const_int 16)))
6276 (set (match_operand:HI 0 "s_register_operand" "")
787f8210 6277 (match_dup 4))]
cffb2a26 6278 "TARGET_ARM"
c7597b5d 6279 "
6280 operands[2] = gen_reg_rtx (SImode);
6281 operands[3] = gen_reg_rtx (SImode);
787f8210 6282 operands[4] = gen_lowpart (HImode, operands[3]);
215b30b3 6283 "
6284)
b11cae9e 6285
a2f10574 6286;; Pattern to recognize insn generated default case above
f7fbdd4a 6287(define_insn "*movhi_insn_arch4"
cde1623a 6288 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,m,r")
5fd254ed 6289 (match_operand:HI 1 "general_operand" "rIk,K,r,mi"))]
cffb2a26 6290 "TARGET_ARM
6291 && arm_arch4
85e02ccb 6292 && (register_operand (operands[0], HImode)
6293 || register_operand (operands[1], HImode))"
f7fbdd4a 6294 "@
6295 mov%?\\t%0, %1\\t%@ movhi
6296 mvn%?\\t%0, #%B1\\t%@ movhi
25f905c2 6297 str%(h%)\\t%1, %0\\t%@ movhi
6298 ldr%(h%)\\t%0, %1\\t%@ movhi"
65f68e55 6299 [(set_attr "predicable" "yes")
cffb2a26 6300 (set_attr "pool_range" "*,*,*,256")
65f68e55 6301 (set_attr "neg_pool_range" "*,*,*,244")
6302 (set_attr_alternative "type"
6303 [(if_then_else (match_operand 1 "const_int_operand" "")
1aed5204 6304 (const_string "mov_imm" )
6305 (const_string "mov_reg"))
6306 (const_string "mvn_imm")
65f68e55 6307 (const_string "store1")
6308 (const_string "load1")])]
cffb2a26 6309)
f7fbdd4a 6310
f7fbdd4a 6311(define_insn "*movhi_bytes"
65f68e55 6312 [(set (match_operand:HI 0 "s_register_operand" "=r,r,r")
5fd254ed 6313 (match_operand:HI 1 "arm_rhs_operand" "I,rk,K"))]
c1a66faf 6314 "TARGET_ARM"
25f7a26e 6315 "@
65f68e55 6316 mov%?\\t%0, %1\\t%@ movhi
25f7a26e 6317 mov%?\\t%0, %1\\t%@ movhi
0d66636f 6318 mvn%?\\t%0, #%B1\\t%@ movhi"
d2a518d1 6319 [(set_attr "predicable" "yes")
1aed5204 6320 (set_attr "type" "mov_imm,mov_reg,mvn_imm")]
0d66636f 6321)
cffb2a26 6322
bc5c7e08 6323;; We use a DImode scratch because we may occasionally need an additional
6324;; temporary if the address isn't offsettable -- push_reload doesn't seem
6325;; to take any notice of the "o" constraints on reload_memory_operand operand.
d3373b54 6326(define_expand "reload_outhi"
cffb2a26 6327 [(parallel [(match_operand:HI 0 "arm_reload_memory_operand" "=o")
215b30b3 6328 (match_operand:HI 1 "s_register_operand" "r")
6329 (match_operand:DI 2 "s_register_operand" "=&l")])]
cffb2a26 6330 "TARGET_EITHER"
6331 "if (TARGET_ARM)
6332 arm_reload_out_hi (operands);
6333 else
6334 thumb_reload_out_hi (operands);
d3373b54 6335 DONE;
cffb2a26 6336 "
6337)
d3373b54 6338
25f7a26e 6339(define_expand "reload_inhi"
6340 [(parallel [(match_operand:HI 0 "s_register_operand" "=r")
cffb2a26 6341 (match_operand:HI 1 "arm_reload_memory_operand" "o")
bc5c7e08 6342 (match_operand:DI 2 "s_register_operand" "=&r")])]
c1a66faf 6343 "TARGET_EITHER"
25f7a26e 6344 "
cffb2a26 6345 if (TARGET_ARM)
6346 arm_reload_in_hi (operands);
6347 else
6348 thumb_reload_out_hi (operands);
25f7a26e 6349 DONE;
6350")
6351
9c08d1fa 6352(define_expand "movqi"
6353 [(set (match_operand:QI 0 "general_operand" "")
6354 (match_operand:QI 1 "general_operand" ""))]
cffb2a26 6355 "TARGET_EITHER"
9c08d1fa 6356 "
6cffc037 6357 /* Everything except mem = const or mem = mem can be done easily */
0045890a 6358
e1ba4a27 6359 if (can_create_pseudo_p ())
cffb2a26 6360 {
0438d37f 6361 if (CONST_INT_P (operands[1]))
6cffc037 6362 {
6363 rtx reg = gen_reg_rtx (SImode);
6364
03770691 6365 /* For thumb we want an unsigned immediate, then we are more likely
6366 to be able to use a movs insn. */
6367 if (TARGET_THUMB)
6368 operands[1] = GEN_INT (INTVAL (operands[1]) & 255);
6369
6cffc037 6370 emit_insn (gen_movsi (reg, operands[1]));
6371 operands[1] = gen_lowpart (QImode, reg);
6372 }
cffb2a26 6373
6cffc037 6374 if (TARGET_THUMB)
6375 {
cffb2a26 6376 /* ??? We shouldn't really get invalid addresses here, but this can
215b30b3 6377 happen if we are passed a SP (never OK for HImode/QImode) or
bc409cb4 6378 virtual register (also rejected as illegitimate for HImode/QImode)
6379 relative address. */
cffb2a26 6380 /* ??? This should perhaps be fixed elsewhere, for instance, in
6381 fixup_stack_1, by checking for other kinds of invalid addresses,
6382 e.g. a bare reference to a virtual register. This may confuse the
6383 alpha though, which must handle this case differently. */
0438d37f 6384 if (MEM_P (operands[0])
215b30b3 6385 && !memory_address_p (GET_MODE (operands[0]),
cffb2a26 6386 XEXP (operands[0], 0)))
537ffcfc 6387 operands[0]
6388 = replace_equiv_address (operands[0],
6389 copy_to_reg (XEXP (operands[0], 0)));
0438d37f 6390 if (MEM_P (operands[1])
215b30b3 6391 && !memory_address_p (GET_MODE (operands[1]),
cffb2a26 6392 XEXP (operands[1], 0)))
537ffcfc 6393 operands[1]
6394 = replace_equiv_address (operands[1],
6395 copy_to_reg (XEXP (operands[1], 0)));
6cffc037 6396 }
6397
0438d37f 6398 if (MEM_P (operands[1]) && optimize > 0)
6cffc037 6399 {
6400 rtx reg = gen_reg_rtx (SImode);
6401
6402 emit_insn (gen_zero_extendqisi2 (reg, operands[1]));
6403 operands[1] = gen_lowpart (QImode, reg);
6404 }
6405
0438d37f 6406 if (MEM_P (operands[0]))
6cffc037 6407 operands[1] = force_reg (QImode, operands[1]);
6408 }
6409 else if (TARGET_THUMB
0438d37f 6410 && CONST_INT_P (operands[1])
234f6557 6411 && !satisfies_constraint_I (operands[1]))
6cffc037 6412 {
674a8f0b 6413 /* Handle loading a large integer during reload. */
cffb2a26 6414
6cffc037 6415 /* Writing a constant to memory needs a scratch, which should
6416 be handled with SECONDARY_RELOADs. */
0438d37f 6417 gcc_assert (REG_P (operands[0]));
6cffc037 6418
6419 operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
6420 emit_insn (gen_movsi (operands[0], operands[1]));
6421 DONE;
cffb2a26 6422 }
6423 "
6424)
b11cae9e 6425
cffb2a26 6426(define_insn "*arm_movqi_insn"
fd711051 6427 [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,r,l,r,l,Uu,r,m")
5fd254ed 6428 (match_operand:QI 1 "general_operand" "rk,rk,I,Py,K,Uu,l,m,r"))]
25f905c2 6429 "TARGET_32BIT
cffb2a26 6430 && ( register_operand (operands[0], QImode)
6431 || register_operand (operands[1], QImode))"
5565501b 6432 "@
fd711051 6433 mov%?\\t%0, %1
6434 mov%?\\t%0, %1
65f68e55 6435 mov%?\\t%0, %1
5565501b 6436 mov%?\\t%0, %1
6437 mvn%?\\t%0, #%B1
25f905c2 6438 ldr%(b%)\\t%0, %1
a54e3e7b 6439 str%(b%)\\t%1, %0
6440 ldr%(b%)\\t%0, %1
25f905c2 6441 str%(b%)\\t%1, %0"
1aed5204 6442 [(set_attr "type" "mov_reg,mov_reg,mov_imm,mov_imm,mvn_imm,load1,store1,load1,store1")
a54e3e7b 6443 (set_attr "predicable" "yes")
fd711051 6444 (set_attr "predicable_short_it" "yes,yes,yes,no,no,no,no,no,no")
6445 (set_attr "arch" "t2,any,any,t2,any,t2,t2,any,any")
6446 (set_attr "length" "2,4,4,2,4,2,2,4,4")]
cffb2a26 6447)
6448
9b8516be 6449;; HFmode moves
6450(define_expand "movhf"
6451 [(set (match_operand:HF 0 "general_operand" "")
6452 (match_operand:HF 1 "general_operand" ""))]
6453 "TARGET_EITHER"
6454 "
6455 if (TARGET_32BIT)
6456 {
0438d37f 6457 if (MEM_P (operands[0]))
9b8516be 6458 operands[1] = force_reg (HFmode, operands[1]);
6459 }
6460 else /* TARGET_THUMB1 */
6461 {
6462 if (can_create_pseudo_p ())
6463 {
0438d37f 6464 if (!REG_P (operands[0]))
9b8516be 6465 operands[1] = force_reg (HFmode, operands[1]);
6466 }
6467 }
6468 "
6469)
6470
6471(define_insn "*arm32_movhf"
6472 [(set (match_operand:HF 0 "nonimmediate_operand" "=r,m,r,r")
6473 (match_operand:HF 1 "general_operand" " m,r,r,F"))]
7c36fe71 6474 "TARGET_32BIT && !(TARGET_HARD_FLOAT && TARGET_FP16) && !arm_restrict_it
9b8516be 6475 && ( s_register_operand (operands[0], HFmode)
6476 || s_register_operand (operands[1], HFmode))"
6477 "*
6478 switch (which_alternative)
6479 {
6480 case 0: /* ARM register from memory */
6481 return \"ldr%(h%)\\t%0, %1\\t%@ __fp16\";
6482 case 1: /* memory from ARM register */
6483 return \"str%(h%)\\t%1, %0\\t%@ __fp16\";
6484 case 2: /* ARM register from ARM register */
6485 return \"mov%?\\t%0, %1\\t%@ __fp16\";
6486 case 3: /* ARM register from constant */
6487 {
6488 REAL_VALUE_TYPE r;
6489 long bits;
6490 rtx ops[4];
6491
6492 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
6493 bits = real_to_target (NULL, &r, HFmode);
6494 ops[0] = operands[0];
6495 ops[1] = GEN_INT (bits);
6496 ops[2] = GEN_INT (bits & 0xff00);
6497 ops[3] = GEN_INT (bits & 0x00ff);
6498
6499 if (arm_arch_thumb2)
6500 output_asm_insn (\"movw%?\\t%0, %1\", ops);
6501 else
6502 output_asm_insn (\"mov%?\\t%0, %2\;orr%?\\t%0, %0, %3\", ops);
6503 return \"\";
6504 }
6505 default:
6506 gcc_unreachable ();
6507 }
6508 "
6509 [(set_attr "conds" "unconditional")
ad4fc3c0 6510 (set_attr "type" "load1,store1,mov_reg,multiple")
9b8516be 6511 (set_attr "length" "4,4,4,8")
d2a518d1 6512 (set_attr "predicable" "yes")]
9b8516be 6513)
6514
87b22bf7 6515(define_expand "movsf"
6516 [(set (match_operand:SF 0 "general_operand" "")
6517 (match_operand:SF 1 "general_operand" ""))]
cffb2a26 6518 "TARGET_EITHER"
87b22bf7 6519 "
25f905c2 6520 if (TARGET_32BIT)
cffb2a26 6521 {
0438d37f 6522 if (MEM_P (operands[0]))
cffb2a26 6523 operands[1] = force_reg (SFmode, operands[1]);
6524 }
25f905c2 6525 else /* TARGET_THUMB1 */
cffb2a26 6526 {
e1ba4a27 6527 if (can_create_pseudo_p ())
cffb2a26 6528 {
0438d37f 6529 if (!REG_P (operands[0]))
cffb2a26 6530 operands[1] = force_reg (SFmode, operands[1]);
6531 }
6532 }
6533 "
6534)
6535
03d440a6 6536;; Transform a floating-point move of a constant into a core register into
6537;; an SImode operation.
cffb2a26 6538(define_split
03d440a6 6539 [(set (match_operand:SF 0 "arm_general_register_operand" "")
cffb2a26 6540 (match_operand:SF 1 "immediate_operand" ""))]
339034d0 6541 "TARGET_EITHER
cffb2a26 6542 && reload_completed
0438d37f 6543 && CONST_DOUBLE_P (operands[1])"
cffb2a26 6544 [(set (match_dup 2) (match_dup 3))]
6545 "
6546 operands[2] = gen_lowpart (SImode, operands[0]);
6547 operands[3] = gen_lowpart (SImode, operands[1]);
6548 if (operands[2] == 0 || operands[3] == 0)
6549 FAIL;
215b30b3 6550 "
6551)
87b22bf7 6552
cffb2a26 6553(define_insn "*arm_movsf_soft_insn"
6554 [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,m")
6555 (match_operand:SF 1 "general_operand" "r,mE,r"))]
cde1623a 6556 "TARGET_32BIT
cffb2a26 6557 && TARGET_SOFT_FLOAT
0438d37f 6558 && (!MEM_P (operands[0])
215b30b3 6559 || register_operand (operands[1], SFmode))"
9a1112d7 6560 "@
6561 mov%?\\t%0, %1
6562 ldr%?\\t%0, %1\\t%@ float
6563 str%?\\t%1, %0\\t%@ float"
cde1623a 6564 [(set_attr "predicable" "yes")
7c36fe71 6565 (set_attr "predicable_short_it" "no")
1aed5204 6566 (set_attr "type" "mov_reg,load1,store1")
42e1de19 6567 (set_attr "arm_pool_range" "*,4096,*")
6568 (set_attr "thumb2_pool_range" "*,4094,*")
cde1623a 6569 (set_attr "arm_neg_pool_range" "*,4084,*")
6570 (set_attr "thumb2_neg_pool_range" "*,0,*")]
cffb2a26 6571)
6572
9c08d1fa 6573(define_expand "movdf"
87b22bf7 6574 [(set (match_operand:DF 0 "general_operand" "")
6575 (match_operand:DF 1 "general_operand" ""))]
cffb2a26 6576 "TARGET_EITHER"
9c08d1fa 6577 "
25f905c2 6578 if (TARGET_32BIT)
cffb2a26 6579 {
0438d37f 6580 if (MEM_P (operands[0]))
cffb2a26 6581 operands[1] = force_reg (DFmode, operands[1]);
6582 }
6583 else /* TARGET_THUMB */
6584 {
e1ba4a27 6585 if (can_create_pseudo_p ())
cffb2a26 6586 {
0438d37f 6587 if (!REG_P (operands[0]))
cffb2a26 6588 operands[1] = force_reg (DFmode, operands[1]);
6589 }
6590 }
6591 "
6592)
b11cae9e 6593
9c08d1fa 6594;; Reloading a df mode value stored in integer regs to memory can require a
6595;; scratch reg.
6596(define_expand "reload_outdf"
cffb2a26 6597 [(match_operand:DF 0 "arm_reload_memory_operand" "=o")
87b22bf7 6598 (match_operand:DF 1 "s_register_operand" "r")
6599 (match_operand:SI 2 "s_register_operand" "=&r")]
06adefdc 6600 "TARGET_THUMB2"
87b22bf7 6601 "
215b30b3 6602 {
6603 enum rtx_code code = GET_CODE (XEXP (operands[0], 0));
f7fbdd4a 6604
215b30b3 6605 if (code == REG)
6606 operands[2] = XEXP (operands[0], 0);
6607 else if (code == POST_INC || code == PRE_DEC)
6608 {
6609 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
6610 operands[1] = gen_rtx_SUBREG (DImode, operands[1], 0);
6611 emit_insn (gen_movdi (operands[0], operands[1]));
6612 DONE;
6613 }
6614 else if (code == PRE_INC)
6615 {
6616 rtx reg = XEXP (XEXP (operands[0], 0), 0);
f7fbdd4a 6617
215b30b3 6618 emit_insn (gen_addsi3 (reg, reg, GEN_INT (8)));
6619 operands[2] = reg;
6620 }
6621 else if (code == POST_DEC)
6622 operands[2] = XEXP (XEXP (operands[0], 0), 0);
6623 else
6624 emit_insn (gen_addsi3 (operands[2], XEXP (XEXP (operands[0], 0), 0),
6625 XEXP (XEXP (operands[0], 0), 1)));
f7fbdd4a 6626
788fcce0 6627 emit_insn (gen_rtx_SET (VOIDmode,
6628 replace_equiv_address (operands[0], operands[2]),
215b30b3 6629 operands[1]));
f7fbdd4a 6630
215b30b3 6631 if (code == POST_DEC)
6632 emit_insn (gen_addsi3 (operands[2], operands[2], GEN_INT (-8)));
6633
6634 DONE;
6635 }"
6636)
9c08d1fa 6637
9a1112d7 6638(define_insn "*movdf_soft_insn"
353cf59a 6639 [(set (match_operand:DF 0 "nonimmediate_soft_df_operand" "=r,r,r,q,m")
6640 (match_operand:DF 1 "soft_df_operand" "rDa,Db,Dc,mF,q"))]
cde1623a 6641 "TARGET_32BIT && TARGET_SOFT_FLOAT
b2778788 6642 && ( register_operand (operands[0], DFmode)
6643 || register_operand (operands[1], DFmode))"
d51f92df 6644 "*
6645 switch (which_alternative)
6646 {
6647 case 0:
6648 case 1:
6649 case 2:
6650 return \"#\";
6651 default:
26ff80c0 6652 return output_move_double (operands, true, NULL);
d51f92df 6653 }
6654 "
359a6e9f 6655 [(set_attr "length" "8,12,16,8,8")
1b7da4ac 6656 (set_attr "type" "multiple,multiple,multiple,load2,store2")
42e1de19 6657 (set_attr "arm_pool_range" "*,*,*,1020,*")
6658 (set_attr "thumb2_pool_range" "*,*,*,1018,*")
8848d797 6659 (set_attr "arm_neg_pool_range" "*,*,*,1004,*")
cde1623a 6660 (set_attr "thumb2_neg_pool_range" "*,*,*,0,*")]
cffb2a26 6661)
b11cae9e 6662\f
b11cae9e 6663
9c08d1fa 6664;; load- and store-multiple insns
6665;; The arm can load/store any set of registers, provided that they are in
320ea44d 6666;; ascending order, but these expanders assume a contiguous set.
b11cae9e 6667
9c08d1fa 6668(define_expand "load_multiple"
6669 [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
6670 (match_operand:SI 1 "" ""))
6671 (use (match_operand:SI 2 "" ""))])]
25f905c2 6672 "TARGET_32BIT"
9580c25f 6673{
6674 HOST_WIDE_INT offset = 0;
6675
bd5b4116 6676 /* Support only fixed point registers. */
0438d37f 6677 if (!CONST_INT_P (operands[2])
9c08d1fa 6678 || INTVAL (operands[2]) > 14
6679 || INTVAL (operands[2]) < 2
0438d37f 6680 || !MEM_P (operands[1])
6681 || !REG_P (operands[0])
bd5b4116 6682 || REGNO (operands[0]) > (LAST_ARM_REGNUM - 1)
6683 || REGNO (operands[0]) + INTVAL (operands[2]) > LAST_ARM_REGNUM)
9c08d1fa 6684 FAIL;
6685
6686 operands[3]
320ea44d 6687 = arm_gen_load_multiple (arm_regs_in_sequence + REGNO (operands[0]),
6688 INTVAL (operands[2]),
f082f1c4 6689 force_reg (SImode, XEXP (operands[1], 0)),
320ea44d 6690 FALSE, operands[1], &offset);
9580c25f 6691})
b11cae9e 6692
9c08d1fa 6693(define_expand "store_multiple"
6694 [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
6695 (match_operand:SI 1 "" ""))
6696 (use (match_operand:SI 2 "" ""))])]
25f905c2 6697 "TARGET_32BIT"
9580c25f 6698{
6699 HOST_WIDE_INT offset = 0;
6700
674a8f0b 6701 /* Support only fixed point registers. */
0438d37f 6702 if (!CONST_INT_P (operands[2])
9c08d1fa 6703 || INTVAL (operands[2]) > 14
6704 || INTVAL (operands[2]) < 2
0438d37f 6705 || !REG_P (operands[1])
6706 || !MEM_P (operands[0])
bd5b4116 6707 || REGNO (operands[1]) > (LAST_ARM_REGNUM - 1)
6708 || REGNO (operands[1]) + INTVAL (operands[2]) > LAST_ARM_REGNUM)
9c08d1fa 6709 FAIL;
6710
6711 operands[3]
320ea44d 6712 = arm_gen_store_multiple (arm_regs_in_sequence + REGNO (operands[1]),
6713 INTVAL (operands[2]),
f082f1c4 6714 force_reg (SImode, XEXP (operands[0], 0)),
320ea44d 6715 FALSE, operands[0], &offset);
9580c25f 6716})
b11cae9e 6717
9c08d1fa 6718
6719;; Move a block of memory if it is word aligned and MORE than 2 words long.
6720;; We could let this apply for blocks of less than this, but it clobbers so
6721;; many registers that there is then probably a better way.
6722
008c057d 6723(define_expand "movmemqi"
34191dd1 6724 [(match_operand:BLK 0 "general_operand" "")
6725 (match_operand:BLK 1 "general_operand" "")
6726 (match_operand:SI 2 "const_int_operand" "")
6727 (match_operand:SI 3 "const_int_operand" "")]
ae51a965 6728 ""
9c08d1fa 6729 "
25f905c2 6730 if (TARGET_32BIT)
cffb2a26 6731 {
ae51a965 6732 if (TARGET_LDRD && current_tune->prefer_ldrd_strd
6733 && !optimize_function_for_size_p (cfun))
6734 {
6735 if (gen_movmem_ldrd_strd (operands))
6736 DONE;
6737 FAIL;
6738 }
6739
008c057d 6740 if (arm_gen_movmemqi (operands))
cffb2a26 6741 DONE;
6742 FAIL;
6743 }
25f905c2 6744 else /* TARGET_THUMB1 */
cffb2a26 6745 {
6746 if ( INTVAL (operands[3]) != 4
6747 || INTVAL (operands[2]) > 48)
6748 FAIL;
6749
008c057d 6750 thumb_expand_movmemqi (operands);
cffb2a26 6751 DONE;
6752 }
6753 "
6754)
9c08d1fa 6755\f
b11cae9e 6756
341940e8 6757;; Compare & branch insns
8d232dc7 6758;; The range calculations are based as follows:
341940e8 6759;; For forward branches, the address calculation returns the address of
6760;; the next instruction. This is 2 beyond the branch instruction.
6761;; For backward branches, the address calculation returns the address of
6762;; the first instruction in this pattern (cmp). This is 2 before the branch
6763;; instruction for the shortest sequence, and 4 before the branch instruction
6764;; if we have to jump around an unconditional branch.
6765;; To the basic branch range the PC offset must be added (this is +4).
6766;; So for forward branches we have
6767;; (pos_range - pos_base_offs + pc_offs) = (pos_range - 2 + 4).
6768;; And for backward branches we have
6769;; (neg_range - neg_base_offs + pc_offs) = (neg_range - (-2 or -4) + 4).
6770;;
6771;; For a 'b' pos_range = 2046, neg_range = -2048 giving (-2040->2048).
6772;; For a 'b<cond>' pos_range = 254, neg_range = -256 giving (-250 ->256).
cffb2a26 6773
aeac46d4 6774(define_expand "cbranchsi4"
6775 [(set (pc) (if_then_else
aa06947a 6776 (match_operator 0 "expandable_comparison_operator"
aeac46d4 6777 [(match_operand:SI 1 "s_register_operand" "")
6778 (match_operand:SI 2 "nonmemory_operand" "")])
6779 (label_ref (match_operand 3 "" ""))
6780 (pc)))]
f9aa4160 6781 "TARGET_EITHER"
aeac46d4 6782 "
74f4459c 6783 if (!TARGET_THUMB1)
6784 {
f9aa4160 6785 if (!arm_validize_comparison (&operands[0], &operands[1], &operands[2]))
6786 FAIL;
74f4459c 6787 emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
6788 operands[3]));
6789 DONE;
6790 }
25f905c2 6791 if (thumb1_cmpneg_operand (operands[2], SImode))
aeac46d4 6792 {
6793 emit_jump_insn (gen_cbranchsi4_scratch (NULL, operands[1], operands[2],
6794 operands[3], operands[0]));
6795 DONE;
6796 }
25f905c2 6797 if (!thumb1_cmp_operand (operands[2], SImode))
aeac46d4 6798 operands[2] = force_reg (SImode, operands[2]);
6799 ")
6800
74f4459c 6801(define_expand "cbranchsf4"
6802 [(set (pc) (if_then_else
aa06947a 6803 (match_operator 0 "expandable_comparison_operator"
74f4459c 6804 [(match_operand:SF 1 "s_register_operand" "")
6805 (match_operand:SF 2 "arm_float_compare_operand" "")])
6806 (label_ref (match_operand 3 "" ""))
6807 (pc)))]
6808 "TARGET_32BIT && TARGET_HARD_FLOAT"
6809 "emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
6810 operands[3])); DONE;"
6811)
6812
6813(define_expand "cbranchdf4"
6814 [(set (pc) (if_then_else
aa06947a 6815 (match_operator 0 "expandable_comparison_operator"
74f4459c 6816 [(match_operand:DF 1 "s_register_operand" "")
6817 (match_operand:DF 2 "arm_float_compare_operand" "")])
6818 (label_ref (match_operand 3 "" ""))
6819 (pc)))]
a50d7267 6820 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
74f4459c 6821 "emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
6822 operands[3])); DONE;"
6823)
6824
74f4459c 6825(define_expand "cbranchdi4"
6826 [(set (pc) (if_then_else
aa06947a 6827 (match_operator 0 "expandable_comparison_operator"
b8eae306 6828 [(match_operand:DI 1 "s_register_operand" "")
a8045a4f 6829 (match_operand:DI 2 "cmpdi_operand" "")])
74f4459c 6830 (label_ref (match_operand 3 "" ""))
6831 (pc)))]
a8045a4f 6832 "TARGET_32BIT"
6833 "{
0438d37f 6834 if (!arm_validize_comparison (&operands[0], &operands[1], &operands[2]))
f9aa4160 6835 FAIL;
6836 emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
a8045a4f 6837 operands[3]));
6838 DONE;
6839 }"
74f4459c 6840)
6841
9c08d1fa 6842;; Comparison and test insns
6843
cffb2a26 6844(define_insn "*arm_cmpsi_insn"
bd5b4116 6845 [(set (reg:CC CC_REGNUM)
f9f234ec 6846 (compare:CC (match_operand:SI 0 "s_register_operand" "l,r,r,r,r")
6847 (match_operand:SI 1 "arm_add_operand" "Py,r,r,I,L")))]
25f905c2 6848 "TARGET_32BIT"
5565501b 6849 "@
a6864a24 6850 cmp%?\\t%0, %1
6851 cmp%?\\t%0, %1
aea4c774 6852 cmp%?\\t%0, %1
f9f234ec 6853 cmp%?\\t%0, %1
aea4c774 6854 cmn%?\\t%0, #%n1"
a6864a24 6855 [(set_attr "conds" "set")
f9f234ec 6856 (set_attr "arch" "t2,t2,any,any,any")
6857 (set_attr "length" "2,2,4,4,4")
65f68e55 6858 (set_attr "predicable" "yes")
f9f234ec 6859 (set_attr "predicable_short_it" "yes,yes,yes,no,no")
112eda6f 6860 (set_attr "type" "alus_imm,alus_sreg,alus_sreg,alus_imm,alus_imm")]
cffb2a26 6861)
b11cae9e 6862
d5d4dc8d 6863(define_insn "*cmpsi_shiftsi"
bd5b4116 6864 [(set (reg:CC CC_REGNUM)
d82e788e 6865 (compare:CC (match_operand:SI 0 "s_register_operand" "r,r,r")
cffb2a26 6866 (match_operator:SI 3 "shift_operator"
d82e788e 6867 [(match_operand:SI 1 "s_register_operand" "r,r,r")
6868 (match_operand:SI 2 "shift_amount_operand" "M,r,M")])))]
d5d4dc8d 6869 "TARGET_32BIT"
f9f234ec 6870 "cmp\\t%0, %1%S3"
344495ea 6871 [(set_attr "conds" "set")
331beb1a 6872 (set_attr "shift" "1")
d82e788e 6873 (set_attr "arch" "32,a,a")
6874 (set_attr "type" "alus_shift_imm,alu_shift_reg,alus_shift_imm")])
b11cae9e 6875
d5d4dc8d 6876(define_insn "*cmpsi_shiftsi_swp"
bd5b4116 6877 [(set (reg:CC_SWP CC_REGNUM)
aea4c774 6878 (compare:CC_SWP (match_operator:SI 3 "shift_operator"
d82e788e 6879 [(match_operand:SI 1 "s_register_operand" "r,r,r")
6880 (match_operand:SI 2 "shift_amount_operand" "M,r,M")])
6881 (match_operand:SI 0 "s_register_operand" "r,r,r")))]
d5d4dc8d 6882 "TARGET_32BIT"
aea4c774 6883 "cmp%?\\t%0, %1%S3"
344495ea 6884 [(set_attr "conds" "set")
331beb1a 6885 (set_attr "shift" "1")
d82e788e 6886 (set_attr "arch" "32,a,a")
6887 (set_attr "type" "alus_shift_imm,alu_shift_reg,alus_shift_imm")])
b11cae9e 6888
25f905c2 6889(define_insn "*arm_cmpsi_negshiftsi_si"
aed179ae 6890 [(set (reg:CC_Z CC_REGNUM)
6891 (compare:CC_Z
6892 (neg:SI (match_operator:SI 1 "shift_operator"
6893 [(match_operand:SI 2 "s_register_operand" "r")
6894 (match_operand:SI 3 "reg_or_int_operand" "rM")]))
6895 (match_operand:SI 0 "s_register_operand" "r")))]
cffb2a26 6896 "TARGET_ARM"
aed179ae 6897 "cmn%?\\t%0, %2%S1"
344495ea 6898 [(set_attr "conds" "set")
aed179ae 6899 (set (attr "type") (if_then_else (match_operand 3 "const_int_operand" "")
d82e788e 6900 (const_string "alus_shift_imm")
6901 (const_string "alus_shift_reg")))
596e5e8f 6902 (set_attr "predicable" "yes")]
0d66636f 6903)
b11cae9e 6904
a8045a4f 6905;; DImode comparisons. The generic code generates branches that
6906;; if-conversion can not reduce to a conditional compare, so we do
6907;; that directly.
6908
ba6a3b2f 6909(define_insn_and_split "*arm_cmpdi_insn"
a8045a4f 6910 [(set (reg:CC_NCV CC_REGNUM)
6911 (compare:CC_NCV (match_operand:DI 0 "s_register_operand" "r")
6912 (match_operand:DI 1 "arm_di_operand" "rDi")))
6913 (clobber (match_scratch:SI 2 "=r"))]
b805622c 6914 "TARGET_32BIT"
ba6a3b2f 6915 "#" ; "cmp\\t%Q0, %Q1\;sbcs\\t%2, %R0, %R1"
6916 "&& reload_completed"
6917 [(set (reg:CC CC_REGNUM)
6918 (compare:CC (match_dup 0) (match_dup 1)))
6919 (parallel [(set (reg:CC CC_REGNUM)
6920 (compare:CC (match_dup 3) (match_dup 4)))
6921 (set (match_dup 2)
6922 (minus:SI (match_dup 5)
6923 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))])]
6924 {
6925 operands[3] = gen_highpart (SImode, operands[0]);
6926 operands[0] = gen_lowpart (SImode, operands[0]);
6927 if (CONST_INT_P (operands[1]))
6928 {
6929 operands[4] = GEN_INT (~INTVAL (gen_highpart_mode (SImode,
6930 DImode,
6931 operands[1])));
6932 operands[5] = gen_rtx_PLUS (SImode, operands[3], operands[4]);
6933 }
6934 else
6935 {
6936 operands[4] = gen_highpart (SImode, operands[1]);
6937 operands[5] = gen_rtx_MINUS (SImode, operands[3], operands[4]);
6938 }
6939 operands[1] = gen_lowpart (SImode, operands[1]);
6940 operands[2] = gen_lowpart (SImode, operands[2]);
6941 }
a8045a4f 6942 [(set_attr "conds" "set")
1b7da4ac 6943 (set_attr "length" "8")
6944 (set_attr "type" "multiple")]
a8045a4f 6945)
6946
ba6a3b2f 6947(define_insn_and_split "*arm_cmpdi_unsigned"
a8045a4f 6948 [(set (reg:CC_CZ CC_REGNUM)
1a86364b 6949 (compare:CC_CZ (match_operand:DI 0 "s_register_operand" "l,r,r,r")
6950 (match_operand:DI 1 "arm_di_operand" "Py,r,Di,rDi")))]
7c36fe71 6951
48a98053 6952 "TARGET_32BIT"
ba6a3b2f 6953 "#" ; "cmp\\t%R0, %R1\;it eq\;cmpeq\\t%Q0, %Q1"
6954 "&& reload_completed"
6955 [(set (reg:CC CC_REGNUM)
6956 (compare:CC (match_dup 2) (match_dup 3)))
6957 (cond_exec (eq:SI (reg:CC CC_REGNUM) (const_int 0))
6958 (set (reg:CC CC_REGNUM)
6959 (compare:CC (match_dup 0) (match_dup 1))))]
6960 {
6961 operands[2] = gen_highpart (SImode, operands[0]);
6962 operands[0] = gen_lowpart (SImode, operands[0]);
6963 if (CONST_INT_P (operands[1]))
6964 operands[3] = gen_highpart_mode (SImode, DImode, operands[1]);
6965 else
6966 operands[3] = gen_highpart (SImode, operands[1]);
6967 operands[1] = gen_lowpart (SImode, operands[1]);
6968 }
a8045a4f 6969 [(set_attr "conds" "set")
1a86364b 6970 (set_attr "enabled_for_depr_it" "yes,yes,no,*")
6971 (set_attr "arch" "t2,t2,t2,a")
6972 (set_attr "length" "6,6,10,8")
1b7da4ac 6973 (set_attr "type" "multiple")]
a8045a4f 6974)
6975
6976(define_insn "*arm_cmpdi_zero"
6977 [(set (reg:CC_Z CC_REGNUM)
6978 (compare:CC_Z (match_operand:DI 0 "s_register_operand" "r")
6979 (const_int 0)))
6980 (clobber (match_scratch:SI 1 "=r"))]
6981 "TARGET_32BIT"
6982 "orr%.\\t%1, %Q0, %R0"
1b7da4ac 6983 [(set_attr "conds" "set")
6984 (set_attr "type" "logics_reg")]
a8045a4f 6985)
6986
9c08d1fa 6987; This insn allows redundant compares to be removed by cse, nothing should
6988; ever appear in the output file since (set (reg x) (reg x)) is a no-op that
6989; is deleted later on. The match_dup will match the mode here, so that
6990; mode changes of the condition codes aren't lost by this even though we don't
6991; specify what they are.
6992
8a18b90c 6993(define_insn "*deleted_compare"
9c08d1fa 6994 [(set (match_operand 0 "cc_register" "") (match_dup 0))]
25f905c2 6995 "TARGET_32BIT"
40dbec34 6996 "\\t%@ deleted compare"
cffb2a26 6997 [(set_attr "conds" "set")
1b7da4ac 6998 (set_attr "length" "0")
6999 (set_attr "type" "no_insn")]
cffb2a26 7000)
9c08d1fa 7001
7002\f
7003;; Conditional branch insns
7004
74f4459c 7005(define_expand "cbranch_cc"
9c08d1fa 7006 [(set (pc)
74f4459c 7007 (if_then_else (match_operator 0 "" [(match_operand 1 "" "")
7008 (match_operand 2 "" "")])
7009 (label_ref (match_operand 3 "" ""))
9c08d1fa 7010 (pc)))]
25f905c2 7011 "TARGET_32BIT"
74f4459c 7012 "operands[1] = arm_gen_compare_reg (GET_CODE (operands[0]),
e1b93706 7013 operands[1], operands[2], NULL_RTX);
74f4459c 7014 operands[2] = const0_rtx;"
8fa3ba89 7015)
7016
7017;;
7018;; Patterns to match conditional branch insns.
7019;;
7020
ffcc986d 7021(define_insn "arm_cond_branch"
9c08d1fa 7022 [(set (pc)
8fa3ba89 7023 (if_then_else (match_operator 1 "arm_comparison_operator"
8a18b90c 7024 [(match_operand 2 "cc_register" "") (const_int 0)])
9c08d1fa 7025 (label_ref (match_operand 0 "" ""))
7026 (pc)))]
25f905c2 7027 "TARGET_32BIT"
d75350ce 7028 "*
9c08d1fa 7029 if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
cffb2a26 7030 {
7031 arm_ccfsm_state += 2;
7032 return \"\";
7033 }
e2348bcb 7034 return \"b%d1\\t%l0\";
cffb2a26 7035 "
a2cd141b 7036 [(set_attr "conds" "use")
a6864a24 7037 (set_attr "type" "branch")
7038 (set (attr "length")
7039 (if_then_else
0bf497f5 7040 (and (match_test "TARGET_THUMB2")
a6864a24 7041 (and (ge (minus (match_dup 0) (pc)) (const_int -250))
7042 (le (minus (match_dup 0) (pc)) (const_int 256))))
7043 (const_int 2)
7044 (const_int 4)))]
cffb2a26 7045)
d75350ce 7046
cffb2a26 7047(define_insn "*arm_cond_branch_reversed"
9c08d1fa 7048 [(set (pc)
8fa3ba89 7049 (if_then_else (match_operator 1 "arm_comparison_operator"
8a18b90c 7050 [(match_operand 2 "cc_register" "") (const_int 0)])
9c08d1fa 7051 (pc)
7052 (label_ref (match_operand 0 "" ""))))]
25f905c2 7053 "TARGET_32BIT"
d75350ce 7054 "*
9c08d1fa 7055 if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
cffb2a26 7056 {
7057 arm_ccfsm_state += 2;
7058 return \"\";
7059 }
e2348bcb 7060 return \"b%D1\\t%l0\";
cffb2a26 7061 "
a2cd141b 7062 [(set_attr "conds" "use")
a6864a24 7063 (set_attr "type" "branch")
7064 (set (attr "length")
7065 (if_then_else
0bf497f5 7066 (and (match_test "TARGET_THUMB2")
a6864a24 7067 (and (ge (minus (match_dup 0) (pc)) (const_int -250))
7068 (le (minus (match_dup 0) (pc)) (const_int 256))))
7069 (const_int 2)
7070 (const_int 4)))]
cffb2a26 7071)
7072
b11cae9e 7073\f
9c08d1fa 7074
7075; scc insns
7076
74f4459c 7077(define_expand "cstore_cc"
7db9af5d 7078 [(set (match_operand:SI 0 "s_register_operand" "")
74f4459c 7079 (match_operator:SI 1 "" [(match_operand 2 "" "")
7080 (match_operand 3 "" "")]))]
25f905c2 7081 "TARGET_32BIT"
74f4459c 7082 "operands[2] = arm_gen_compare_reg (GET_CODE (operands[1]),
e1b93706 7083 operands[2], operands[3], NULL_RTX);
74f4459c 7084 operands[3] = const0_rtx;"
8fa3ba89 7085)
7086
a3b84066 7087(define_insn_and_split "*mov_scc"
9c08d1fa 7088 [(set (match_operand:SI 0 "s_register_operand" "=r")
8fa3ba89 7089 (match_operator:SI 1 "arm_comparison_operator"
8a18b90c 7090 [(match_operand 2 "cc_register" "") (const_int 0)]))]
cffb2a26 7091 "TARGET_ARM"
a3b84066 7092 "#" ; "mov%D1\\t%0, #0\;mov%d1\\t%0, #1"
7093 "TARGET_ARM"
7094 [(set (match_dup 0)
7095 (if_then_else:SI (match_dup 1)
7096 (const_int 1)
7097 (const_int 0)))]
7098 ""
cffb2a26 7099 [(set_attr "conds" "use")
1b7da4ac 7100 (set_attr "length" "8")
7101 (set_attr "type" "multiple")]
cffb2a26 7102)
9c08d1fa 7103
a3b84066 7104(define_insn_and_split "*mov_negscc"
9c08d1fa 7105 [(set (match_operand:SI 0 "s_register_operand" "=r")
8fa3ba89 7106 (neg:SI (match_operator:SI 1 "arm_comparison_operator"
8a18b90c 7107 [(match_operand 2 "cc_register" "") (const_int 0)])))]
cffb2a26 7108 "TARGET_ARM"
a3b84066 7109 "#" ; "mov%D1\\t%0, #0\;mvn%d1\\t%0, #0"
7110 "TARGET_ARM"
7111 [(set (match_dup 0)
7112 (if_then_else:SI (match_dup 1)
7113 (match_dup 3)
7114 (const_int 0)))]
7115 {
7116 operands[3] = GEN_INT (~0);
7117 }
cffb2a26 7118 [(set_attr "conds" "use")
1b7da4ac 7119 (set_attr "length" "8")
7120 (set_attr "type" "multiple")]
cffb2a26 7121)
9c08d1fa 7122
a3b84066 7123(define_insn_and_split "*mov_notscc"
9c08d1fa 7124 [(set (match_operand:SI 0 "s_register_operand" "=r")
8fa3ba89 7125 (not:SI (match_operator:SI 1 "arm_comparison_operator"
8a18b90c 7126 [(match_operand 2 "cc_register" "") (const_int 0)])))]
cffb2a26 7127 "TARGET_ARM"
a3b84066 7128 "#" ; "mvn%D1\\t%0, #0\;mvn%d1\\t%0, #1"
7129 "TARGET_ARM"
7130 [(set (match_dup 0)
7131 (if_then_else:SI (match_dup 1)
7132 (match_dup 3)
7133 (match_dup 4)))]
7134 {
7135 operands[3] = GEN_INT (~1);
7136 operands[4] = GEN_INT (~0);
7137 }
cffb2a26 7138 [(set_attr "conds" "use")
1b7da4ac 7139 (set_attr "length" "8")
7140 (set_attr "type" "multiple")]
cffb2a26 7141)
9c08d1fa 7142
595d88b5 7143(define_expand "cstoresi4"
7144 [(set (match_operand:SI 0 "s_register_operand" "")
aa06947a 7145 (match_operator:SI 1 "expandable_comparison_operator"
595d88b5 7146 [(match_operand:SI 2 "s_register_operand" "")
7147 (match_operand:SI 3 "reg_or_int_operand" "")]))]
74f4459c 7148 "TARGET_32BIT || TARGET_THUMB1"
595d88b5 7149 "{
7150 rtx op3, scratch, scratch2;
7151
74f4459c 7152 if (!TARGET_THUMB1)
7153 {
7154 if (!arm_add_operand (operands[3], SImode))
7155 operands[3] = force_reg (SImode, operands[3]);
7156 emit_insn (gen_cstore_cc (operands[0], operands[1],
7157 operands[2], operands[3]));
7158 DONE;
7159 }
7160
595d88b5 7161 if (operands[3] == const0_rtx)
7162 {
7163 switch (GET_CODE (operands[1]))
7164 {
7165 case EQ:
25f905c2 7166 emit_insn (gen_cstoresi_eq0_thumb1 (operands[0], operands[2]));
595d88b5 7167 break;
7168
7169 case NE:
25f905c2 7170 emit_insn (gen_cstoresi_ne0_thumb1 (operands[0], operands[2]));
595d88b5 7171 break;
7172
7173 case LE:
7174 scratch = expand_binop (SImode, add_optab, operands[2], constm1_rtx,
7175 NULL_RTX, 0, OPTAB_WIDEN);
7176 scratch = expand_binop (SImode, ior_optab, operands[2], scratch,
7177 NULL_RTX, 0, OPTAB_WIDEN);
7178 expand_binop (SImode, lshr_optab, scratch, GEN_INT (31),
7179 operands[0], 1, OPTAB_WIDEN);
7180 break;
7181
7182 case GE:
7183 scratch = expand_unop (SImode, one_cmpl_optab, operands[2],
7184 NULL_RTX, 1);
7185 expand_binop (SImode, lshr_optab, scratch, GEN_INT (31),
7186 NULL_RTX, 1, OPTAB_WIDEN);
7187 break;
7188
7189 case GT:
7190 scratch = expand_binop (SImode, ashr_optab, operands[2],
7191 GEN_INT (31), NULL_RTX, 0, OPTAB_WIDEN);
7192 scratch = expand_binop (SImode, sub_optab, scratch, operands[2],
7193 NULL_RTX, 0, OPTAB_WIDEN);
7194 expand_binop (SImode, lshr_optab, scratch, GEN_INT (31), operands[0],
7195 0, OPTAB_WIDEN);
7196 break;
7197
7198 /* LT is handled by generic code. No need for unsigned with 0. */
7199 default:
7200 FAIL;
7201 }
7202 DONE;
7203 }
7204
7205 switch (GET_CODE (operands[1]))
7206 {
7207 case EQ:
7208 scratch = expand_binop (SImode, sub_optab, operands[2], operands[3],
7209 NULL_RTX, 0, OPTAB_WIDEN);
25f905c2 7210 emit_insn (gen_cstoresi_eq0_thumb1 (operands[0], scratch));
595d88b5 7211 break;
7212
7213 case NE:
7214 scratch = expand_binop (SImode, sub_optab, operands[2], operands[3],
7215 NULL_RTX, 0, OPTAB_WIDEN);
25f905c2 7216 emit_insn (gen_cstoresi_ne0_thumb1 (operands[0], scratch));
595d88b5 7217 break;
7218
7219 case LE:
7220 op3 = force_reg (SImode, operands[3]);
7221
7222 scratch = expand_binop (SImode, lshr_optab, operands[2], GEN_INT (31),
7223 NULL_RTX, 1, OPTAB_WIDEN);
7224 scratch2 = expand_binop (SImode, ashr_optab, op3, GEN_INT (31),
7225 NULL_RTX, 0, OPTAB_WIDEN);
25f905c2 7226 emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch2,
595d88b5 7227 op3, operands[2]));
7228 break;
7229
7230 case GE:
7231 op3 = operands[3];
25f905c2 7232 if (!thumb1_cmp_operand (op3, SImode))
595d88b5 7233 op3 = force_reg (SImode, op3);
7234 scratch = expand_binop (SImode, ashr_optab, operands[2], GEN_INT (31),
7235 NULL_RTX, 0, OPTAB_WIDEN);
7236 scratch2 = expand_binop (SImode, lshr_optab, op3, GEN_INT (31),
7237 NULL_RTX, 1, OPTAB_WIDEN);
25f905c2 7238 emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch2,
595d88b5 7239 operands[2], op3));
7240 break;
7241
7242 case LEU:
7243 op3 = force_reg (SImode, operands[3]);
7244 scratch = force_reg (SImode, const0_rtx);
25f905c2 7245 emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch,
595d88b5 7246 op3, operands[2]));
7247 break;
7248
7249 case GEU:
7250 op3 = operands[3];
25f905c2 7251 if (!thumb1_cmp_operand (op3, SImode))
595d88b5 7252 op3 = force_reg (SImode, op3);
7253 scratch = force_reg (SImode, const0_rtx);
25f905c2 7254 emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch,
595d88b5 7255 operands[2], op3));
7256 break;
7257
7258 case LTU:
7259 op3 = operands[3];
25f905c2 7260 if (!thumb1_cmp_operand (op3, SImode))
595d88b5 7261 op3 = force_reg (SImode, op3);
7262 scratch = gen_reg_rtx (SImode);
408b7ae5 7263 emit_insn (gen_cstoresi_ltu_thumb1 (operands[0], operands[2], op3));
595d88b5 7264 break;
7265
7266 case GTU:
7267 op3 = force_reg (SImode, operands[3]);
7268 scratch = gen_reg_rtx (SImode);
408b7ae5 7269 emit_insn (gen_cstoresi_ltu_thumb1 (operands[0], op3, operands[2]));
595d88b5 7270 break;
7271
7272 /* No good sequences for GT, LT. */
7273 default:
7274 FAIL;
7275 }
7276 DONE;
7277}")
7278
74f4459c 7279(define_expand "cstoresf4"
7280 [(set (match_operand:SI 0 "s_register_operand" "")
aa06947a 7281 (match_operator:SI 1 "expandable_comparison_operator"
74f4459c 7282 [(match_operand:SF 2 "s_register_operand" "")
7283 (match_operand:SF 3 "arm_float_compare_operand" "")]))]
7284 "TARGET_32BIT && TARGET_HARD_FLOAT"
7285 "emit_insn (gen_cstore_cc (operands[0], operands[1],
7286 operands[2], operands[3])); DONE;"
7287)
7288
7289(define_expand "cstoredf4"
7290 [(set (match_operand:SI 0 "s_register_operand" "")
aa06947a 7291 (match_operator:SI 1 "expandable_comparison_operator"
74f4459c 7292 [(match_operand:DF 2 "s_register_operand" "")
7293 (match_operand:DF 3 "arm_float_compare_operand" "")]))]
d63ed457 7294 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
74f4459c 7295 "emit_insn (gen_cstore_cc (operands[0], operands[1],
7296 operands[2], operands[3])); DONE;"
7297)
7298
74f4459c 7299(define_expand "cstoredi4"
7300 [(set (match_operand:SI 0 "s_register_operand" "")
aa06947a 7301 (match_operator:SI 1 "expandable_comparison_operator"
b8eae306 7302 [(match_operand:DI 2 "s_register_operand" "")
a8045a4f 7303 (match_operand:DI 3 "cmpdi_operand" "")]))]
7304 "TARGET_32BIT"
7305 "{
f9aa4160 7306 if (!arm_validize_comparison (&operands[1],
7307 &operands[2],
7308 &operands[3]))
7309 FAIL;
7310 emit_insn (gen_cstore_cc (operands[0], operands[1], operands[2],
a8045a4f 7311 operands[3]));
7312 DONE;
7313 }"
74f4459c 7314)
7315
9c08d1fa 7316\f
39b5e676 7317;; Conditional move insns
7318
7319(define_expand "movsicc"
8a18b90c 7320 [(set (match_operand:SI 0 "s_register_operand" "")
aa06947a 7321 (if_then_else:SI (match_operand 1 "expandable_comparison_operator" "")
aea4c774 7322 (match_operand:SI 2 "arm_not_operand" "")
8a18b90c 7323 (match_operand:SI 3 "arm_not_operand" "")))]
25f905c2 7324 "TARGET_32BIT"
39b5e676 7325 "
215b30b3 7326 {
f9aa4160 7327 enum rtx_code code;
278b301d 7328 rtx ccreg;
7329
f9aa4160 7330 if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0),
7331 &XEXP (operands[1], 1)))
278b301d 7332 FAIL;
f9aa4160 7333
7334 code = GET_CODE (operands[1]);
74f4459c 7335 ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
e1b93706 7336 XEXP (operands[1], 1), NULL_RTX);
29bb088d 7337 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
215b30b3 7338 }"
7339)
39b5e676 7340
7341(define_expand "movsfcc"
8a18b90c 7342 [(set (match_operand:SF 0 "s_register_operand" "")
4df97ffc 7343 (if_then_else:SF (match_operand 1 "arm_cond_move_operator" "")
8a18b90c 7344 (match_operand:SF 2 "s_register_operand" "")
d86c91f6 7345 (match_operand:SF 3 "s_register_operand" "")))]
19f6bf8d 7346 "TARGET_32BIT && TARGET_HARD_FLOAT"
39b5e676 7347 "
215b30b3 7348 {
7349 enum rtx_code code = GET_CODE (operands[1]);
7350 rtx ccreg;
f082f1c4 7351
f9aa4160 7352 if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0),
7353 &XEXP (operands[1], 1)))
7354 FAIL;
39b5e676 7355
f9aa4160 7356 code = GET_CODE (operands[1]);
74f4459c 7357 ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
e1b93706 7358 XEXP (operands[1], 1), NULL_RTX);
29bb088d 7359 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
215b30b3 7360 }"
7361)
39b5e676 7362
7363(define_expand "movdfcc"
8a18b90c 7364 [(set (match_operand:DF 0 "s_register_operand" "")
4df97ffc 7365 (if_then_else:DF (match_operand 1 "arm_cond_move_operator" "")
8a18b90c 7366 (match_operand:DF 2 "s_register_operand" "")
d86c91f6 7367 (match_operand:DF 3 "s_register_operand" "")))]
994606f8 7368 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
39b5e676 7369 "
215b30b3 7370 {
7371 enum rtx_code code = GET_CODE (operands[1]);
278b301d 7372 rtx ccreg;
39b5e676 7373
f9aa4160 7374 if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0),
7375 &XEXP (operands[1], 1)))
7376 FAIL;
7377 code = GET_CODE (operands[1]);
74f4459c 7378 ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
e1b93706 7379 XEXP (operands[1], 1), NULL_RTX);
29bb088d 7380 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
215b30b3 7381 }"
7382)
39b5e676 7383
91cb50d2 7384(define_insn "*cmov<mode>"
7385 [(set (match_operand:SDF 0 "s_register_operand" "=<F_constraint>")
7386 (if_then_else:SDF (match_operator 1 "arm_vsel_comparison_operator"
7387 [(match_operand 2 "cc_register" "") (const_int 0)])
7388 (match_operand:SDF 3 "s_register_operand"
7389 "<F_constraint>")
7390 (match_operand:SDF 4 "s_register_operand"
7391 "<F_constraint>")))]
7392 "TARGET_HARD_FLOAT && TARGET_FPU_ARMV8 <vfp_double_cond>"
7393 "*
7394 {
7395 enum arm_cond_code code = maybe_get_arm_condition_code (operands[1]);
7396 switch (code)
7397 {
7398 case ARM_GE:
7399 case ARM_GT:
7400 case ARM_EQ:
7401 case ARM_VS:
7402 return \"vsel%d1.<V_if_elem>\\t%<V_reg>0, %<V_reg>3, %<V_reg>4\";
7403 case ARM_LT:
7404 case ARM_LE:
7405 case ARM_NE:
7406 case ARM_VC:
7407 return \"vsel%D1.<V_if_elem>\\t%<V_reg>0, %<V_reg>4, %<V_reg>3\";
7408 default:
7409 gcc_unreachable ();
7410 }
7411 return \"\";
7412 }"
7413 [(set_attr "conds" "use")
6664d308 7414 (set_attr "type" "fcsel")]
91cb50d2 7415)
7416
190efb17 7417(define_insn_and_split "*movsicc_insn"
f082f1c4 7418 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r,r,r,r,r")
8a18b90c 7419 (if_then_else:SI
8fa3ba89 7420 (match_operator 3 "arm_comparison_operator"
8a18b90c 7421 [(match_operand 4 "cc_register" "") (const_int 0)])
f082f1c4 7422 (match_operand:SI 1 "arm_not_operand" "0,0,rI,K,rI,rI,K,K")
7423 (match_operand:SI 2 "arm_not_operand" "rI,K,0,0,rI,K,rI,K")))]
cffb2a26 7424 "TARGET_ARM"
39b5e676 7425 "@
8a18b90c 7426 mov%D3\\t%0, %2
7427 mvn%D3\\t%0, #%B2
f082f1c4 7428 mov%d3\\t%0, %1
7429 mvn%d3\\t%0, #%B1
190efb17 7430 #
7431 #
7432 #
7433 #"
7434 ; alt4: mov%d3\\t%0, %1\;mov%D3\\t%0, %2
7435 ; alt5: mov%d3\\t%0, %1\;mvn%D3\\t%0, #%B2
7436 ; alt6: mvn%d3\\t%0, #%B1\;mov%D3\\t%0, %2
7437 ; alt7: mvn%d3\\t%0, #%B1\;mvn%D3\\t%0, #%B2"
7438 "&& reload_completed"
7439 [(const_int 0)]
7440 {
7441 enum rtx_code rev_code;
7442 enum machine_mode mode;
7443 rtx rev_cond;
7444
7445 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
7446 operands[3],
7447 gen_rtx_SET (VOIDmode,
7448 operands[0],
7449 operands[1])));
7450
7451 rev_code = GET_CODE (operands[3]);
7452 mode = GET_MODE (operands[4]);
7453 if (mode == CCFPmode || mode == CCFPEmode)
7454 rev_code = reverse_condition_maybe_unordered (rev_code);
7455 else
7456 rev_code = reverse_condition (rev_code);
7457
7458 rev_cond = gen_rtx_fmt_ee (rev_code,
7459 VOIDmode,
7460 operands[4],
7461 const0_rtx);
7462 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
7463 rev_cond,
7464 gen_rtx_SET (VOIDmode,
7465 operands[0],
7466 operands[2])));
7467 DONE;
7468 }
f082f1c4 7469 [(set_attr "length" "4,4,4,4,8,8,8,8")
d2a518d1 7470 (set_attr "conds" "use")
65f68e55 7471 (set_attr_alternative "type"
7472 [(if_then_else (match_operand 2 "const_int_operand" "")
1aed5204 7473 (const_string "mov_imm")
7474 (const_string "mov_reg"))
7475 (const_string "mvn_imm")
65f68e55 7476 (if_then_else (match_operand 1 "const_int_operand" "")
1aed5204 7477 (const_string "mov_imm")
7478 (const_string "mov_reg"))
7479 (const_string "mvn_imm")
7480 (const_string "mov_reg")
7481 (const_string "mov_reg")
7482 (const_string "mov_reg")
7483 (const_string "mov_reg")])]
215b30b3 7484)
39b5e676 7485
39b5e676 7486(define_insn "*movsfcc_soft_insn"
f082f1c4 7487 [(set (match_operand:SF 0 "s_register_operand" "=r,r")
8fa3ba89 7488 (if_then_else:SF (match_operator 3 "arm_comparison_operator"
8a18b90c 7489 [(match_operand 4 "cc_register" "") (const_int 0)])
f082f1c4 7490 (match_operand:SF 1 "s_register_operand" "0,r")
7491 (match_operand:SF 2 "s_register_operand" "r,0")))]
cffb2a26 7492 "TARGET_ARM && TARGET_SOFT_FLOAT"
f082f1c4 7493 "@
7494 mov%D3\\t%0, %2
7495 mov%d3\\t%0, %1"
d2a518d1 7496 [(set_attr "conds" "use")
1aed5204 7497 (set_attr "type" "mov_reg")]
8fa3ba89 7498)
39b5e676 7499
39b5e676 7500\f
9c08d1fa 7501;; Jump and linkage insns
7502
cffb2a26 7503(define_expand "jump"
9c08d1fa 7504 [(set (pc)
7505 (label_ref (match_operand 0 "" "")))]
cffb2a26 7506 "TARGET_EITHER"
9c08d1fa 7507 ""
cffb2a26 7508)
7509
7510(define_insn "*arm_jump"
7511 [(set (pc)
7512 (label_ref (match_operand 0 "" "")))]
25f905c2 7513 "TARGET_32BIT"
9c08d1fa 7514 "*
0d66636f 7515 {
7516 if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
7517 {
7518 arm_ccfsm_state += 2;
7519 return \"\";
7520 }
7521 return \"b%?\\t%l0\";
7522 }
7523 "
a6864a24 7524 [(set_attr "predicable" "yes")
7525 (set (attr "length")
7526 (if_then_else
0bf497f5 7527 (and (match_test "TARGET_THUMB2")
a6864a24 7528 (and (ge (minus (match_dup 0) (pc)) (const_int -2044))
7529 (le (minus (match_dup 0) (pc)) (const_int 2048))))
7530 (const_int 2)
1b7da4ac 7531 (const_int 4)))
7532 (set_attr "type" "branch")]
0d66636f 7533)
9c08d1fa 7534
d3373b54 7535(define_expand "call"
7536 [(parallel [(call (match_operand 0 "memory_operand" "")
7537 (match_operand 1 "general_operand" ""))
cffb2a26 7538 (use (match_operand 2 "" ""))
bd5b4116 7539 (clobber (reg:SI LR_REGNUM))])]
cffb2a26 7540 "TARGET_EITHER"
6c4c2133 7541 "
7542 {
bac7fc85 7543 rtx callee, pat;
bbe777ea 7544
bbe777ea 7545 /* In an untyped call, we can get NULL for operand 2. */
7546 if (operands[2] == NULL_RTX)
7547 operands[2] = const0_rtx;
7548
de55252a 7549 /* Decide if we should generate indirect calls by loading the
85c36fd1 7550 32-bit address of the callee into a register before performing the
de55252a 7551 branch and link. */
7552 callee = XEXP (operands[0], 0);
7553 if (GET_CODE (callee) == SYMBOL_REF
7554 ? arm_is_long_call_p (SYMBOL_REF_DECL (callee))
7555 : !REG_P (callee))
bbe777ea 7556 XEXP (operands[0], 0) = force_reg (Pmode, callee);
bac7fc85 7557
7558 pat = gen_call_internal (operands[0], operands[1], operands[2]);
ca373797 7559 arm_emit_call_insn (pat, XEXP (operands[0], 0), false);
bac7fc85 7560 DONE;
6c4c2133 7561 }"
7562)
d3373b54 7563
bac7fc85 7564(define_expand "call_internal"
7565 [(parallel [(call (match_operand 0 "memory_operand" "")
7566 (match_operand 1 "general_operand" ""))
7567 (use (match_operand 2 "" ""))
7568 (clobber (reg:SI LR_REGNUM))])])
7569
f1039640 7570(define_insn "*call_reg_armv5"
d3373b54 7571 [(call (mem:SI (match_operand:SI 0 "s_register_operand" "r"))
cffb2a26 7572 (match_operand 1 "" ""))
7573 (use (match_operand 2 "" ""))
bd5b4116 7574 (clobber (reg:SI LR_REGNUM))]
33ae7c4b 7575 "TARGET_ARM && arm_arch5 && !SIBLING_CALL_P (insn)"
f1039640 7576 "blx%?\\t%0"
7577 [(set_attr "type" "call")]
7578)
7579
7580(define_insn "*call_reg_arm"
7581 [(call (mem:SI (match_operand:SI 0 "s_register_operand" "r"))
7582 (match_operand 1 "" ""))
7583 (use (match_operand 2 "" ""))
7584 (clobber (reg:SI LR_REGNUM))]
33ae7c4b 7585 "TARGET_ARM && !arm_arch5 && !SIBLING_CALL_P (insn)"
9c08d1fa 7586 "*
5565501b 7587 return output_call (operands);
cffb2a26 7588 "
7589 ;; length is worst case, normally it is only two
7590 [(set_attr "length" "12")
7591 (set_attr "type" "call")]
7592)
9c08d1fa 7593
89504fc1 7594
7595;; Note: not used for armv5+ because the sequence used (ldr pc, ...) is not
7596;; considered a function call by the branch predictor of some cores (PR40887).
7597;; Falls back to blx rN (*call_reg_armv5).
7598
f7fbdd4a 7599(define_insn "*call_mem"
a3c63a9d 7600 [(call (mem:SI (match_operand:SI 0 "call_memory_operand" "m"))
cffb2a26 7601 (match_operand 1 "" ""))
7602 (use (match_operand 2 "" ""))
bd5b4116 7603 (clobber (reg:SI LR_REGNUM))]
33ae7c4b 7604 "TARGET_ARM && !arm_arch5 && !SIBLING_CALL_P (insn)"
9c08d1fa 7605 "*
5565501b 7606 return output_call_mem (operands);
cffb2a26 7607 "
7608 [(set_attr "length" "12")
7609 (set_attr "type" "call")]
7610)
7611
d3373b54 7612(define_expand "call_value"
e0698af7 7613 [(parallel [(set (match_operand 0 "" "")
7614 (call (match_operand 1 "memory_operand" "")
7615 (match_operand 2 "general_operand" "")))
cffb2a26 7616 (use (match_operand 3 "" ""))
bd5b4116 7617 (clobber (reg:SI LR_REGNUM))])]
cffb2a26 7618 "TARGET_EITHER"
6c4c2133 7619 "
7620 {
bac7fc85 7621 rtx pat, callee;
bbe777ea 7622
7623 /* In an untyped call, we can get NULL for operand 2. */
7624 if (operands[3] == 0)
7625 operands[3] = const0_rtx;
7626
de55252a 7627 /* Decide if we should generate indirect calls by loading the
7628 32-bit address of the callee into a register before performing the
7629 branch and link. */
7630 callee = XEXP (operands[1], 0);
7631 if (GET_CODE (callee) == SYMBOL_REF
7632 ? arm_is_long_call_p (SYMBOL_REF_DECL (callee))
7633 : !REG_P (callee))
78fe751b 7634 XEXP (operands[1], 0) = force_reg (Pmode, callee);
bac7fc85 7635
7636 pat = gen_call_value_internal (operands[0], operands[1],
7637 operands[2], operands[3]);
ca373797 7638 arm_emit_call_insn (pat, XEXP (operands[1], 0), false);
bac7fc85 7639 DONE;
6c4c2133 7640 }"
7641)
d3373b54 7642
bac7fc85 7643(define_expand "call_value_internal"
7644 [(parallel [(set (match_operand 0 "" "")
7645 (call (match_operand 1 "memory_operand" "")
7646 (match_operand 2 "general_operand" "")))
7647 (use (match_operand 3 "" ""))
7648 (clobber (reg:SI LR_REGNUM))])])
7649
f1039640 7650(define_insn "*call_value_reg_armv5"
27ed6835 7651 [(set (match_operand 0 "" "")
755eb2b4 7652 (call (mem:SI (match_operand:SI 1 "s_register_operand" "r"))
cffb2a26 7653 (match_operand 2 "" "")))
bbe777ea 7654 (use (match_operand 3 "" ""))
bd5b4116 7655 (clobber (reg:SI LR_REGNUM))]
33ae7c4b 7656 "TARGET_ARM && arm_arch5 && !SIBLING_CALL_P (insn)"
f1039640 7657 "blx%?\\t%1"
7658 [(set_attr "type" "call")]
7659)
7660
7661(define_insn "*call_value_reg_arm"
7662 [(set (match_operand 0 "" "")
7663 (call (mem:SI (match_operand:SI 1 "s_register_operand" "r"))
7664 (match_operand 2 "" "")))
7665 (use (match_operand 3 "" ""))
7666 (clobber (reg:SI LR_REGNUM))]
33ae7c4b 7667 "TARGET_ARM && !arm_arch5 && !SIBLING_CALL_P (insn)"
9c08d1fa 7668 "*
215b30b3 7669 return output_call (&operands[1]);
cffb2a26 7670 "
7671 [(set_attr "length" "12")
7672 (set_attr "type" "call")]
7673)
9c08d1fa 7674
89504fc1 7675;; Note: see *call_mem
7676
f7fbdd4a 7677(define_insn "*call_value_mem"
27ed6835 7678 [(set (match_operand 0 "" "")
a3c63a9d 7679 (call (mem:SI (match_operand:SI 1 "call_memory_operand" "m"))
cffb2a26 7680 (match_operand 2 "" "")))
bbe777ea 7681 (use (match_operand 3 "" ""))
bd5b4116 7682 (clobber (reg:SI LR_REGNUM))]
33ae7c4b 7683 "TARGET_ARM && !arm_arch5 && (!CONSTANT_ADDRESS_P (XEXP (operands[1], 0)))
7684 && !SIBLING_CALL_P (insn)"
9c08d1fa 7685 "*
215b30b3 7686 return output_call_mem (&operands[1]);
cffb2a26 7687 "
7688 [(set_attr "length" "12")
7689 (set_attr "type" "call")]
7690)
9c08d1fa 7691
7692;; Allow calls to SYMBOL_REFs specially as they are not valid general addresses
7693;; The 'a' causes the operand to be treated as an address, i.e. no '#' output.
7694
f7fbdd4a 7695(define_insn "*call_symbol"
27ed6835 7696 [(call (mem:SI (match_operand:SI 0 "" ""))
cffb2a26 7697 (match_operand 1 "" ""))
bbe777ea 7698 (use (match_operand 2 "" ""))
bd5b4116 7699 (clobber (reg:SI LR_REGNUM))]
d68c2c10 7700 "TARGET_32BIT
33ae7c4b 7701 && !SIBLING_CALL_P (insn)
cffb2a26 7702 && (GET_CODE (operands[0]) == SYMBOL_REF)
de55252a 7703 && !arm_is_long_call_p (SYMBOL_REF_DECL (operands[0]))"
6ebaa29d 7704 "*
7705 {
55c1e470 7706 return NEED_PLT_RELOC ? \"bl%?\\t%a0(PLT)\" : \"bl%?\\t%a0\";
6ebaa29d 7707 }"
cffb2a26 7708 [(set_attr "type" "call")]
7709)
9c08d1fa 7710
f7fbdd4a 7711(define_insn "*call_value_symbol"
ccd90aaa 7712 [(set (match_operand 0 "" "")
27ed6835 7713 (call (mem:SI (match_operand:SI 1 "" ""))
dd6d7504 7714 (match_operand:SI 2 "" "")))
bbe777ea 7715 (use (match_operand 3 "" ""))
bd5b4116 7716 (clobber (reg:SI LR_REGNUM))]
d68c2c10 7717 "TARGET_32BIT
33ae7c4b 7718 && !SIBLING_CALL_P (insn)
cffb2a26 7719 && (GET_CODE (operands[1]) == SYMBOL_REF)
de55252a 7720 && !arm_is_long_call_p (SYMBOL_REF_DECL (operands[1]))"
6ebaa29d 7721 "*
7722 {
55c1e470 7723 return NEED_PLT_RELOC ? \"bl%?\\t%a1(PLT)\" : \"bl%?\\t%a1\";
6ebaa29d 7724 }"
cffb2a26 7725 [(set_attr "type" "call")]
7726)
7727
ca373797 7728(define_expand "sibcall_internal"
7729 [(parallel [(call (match_operand 0 "memory_operand" "")
7730 (match_operand 1 "general_operand" ""))
7731 (return)
7732 (use (match_operand 2 "" ""))])])
7733
1c494086 7734;; We may also be able to do sibcalls for Thumb, but it's much harder...
7735(define_expand "sibcall"
7736 [(parallel [(call (match_operand 0 "memory_operand" "")
7737 (match_operand 1 "general_operand" ""))
2ba80634 7738 (return)
7739 (use (match_operand 2 "" ""))])]
d68c2c10 7740 "TARGET_32BIT"
1c494086 7741 "
7742 {
ca373797 7743 rtx pat;
7744
3112c3f7 7745 if ((!REG_P (XEXP (operands[0], 0))
7746 && GET_CODE (XEXP (operands[0], 0)) != SYMBOL_REF)
7747 || (GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
7748 && arm_is_long_call_p (SYMBOL_REF_DECL (XEXP (operands[0], 0)))))
33ae7c4b 7749 XEXP (operands[0], 0) = force_reg (SImode, XEXP (operands[0], 0));
7750
1c494086 7751 if (operands[2] == NULL_RTX)
7752 operands[2] = const0_rtx;
ca373797 7753
7754 pat = gen_sibcall_internal (operands[0], operands[1], operands[2]);
7755 arm_emit_call_insn (pat, operands[0], true);
7756 DONE;
1c494086 7757 }"
7758)
7759
ca373797 7760(define_expand "sibcall_value_internal"
7761 [(parallel [(set (match_operand 0 "" "")
7762 (call (match_operand 1 "memory_operand" "")
7763 (match_operand 2 "general_operand" "")))
7764 (return)
7765 (use (match_operand 3 "" ""))])])
7766
1c494086 7767(define_expand "sibcall_value"
ccd90aaa 7768 [(parallel [(set (match_operand 0 "" "")
1c494086 7769 (call (match_operand 1 "memory_operand" "")
7770 (match_operand 2 "general_operand" "")))
2ba80634 7771 (return)
7772 (use (match_operand 3 "" ""))])]
d68c2c10 7773 "TARGET_32BIT"
1c494086 7774 "
7775 {
ca373797 7776 rtx pat;
7777
3112c3f7 7778 if ((!REG_P (XEXP (operands[1], 0))
7779 && GET_CODE (XEXP (operands[1], 0)) != SYMBOL_REF)
7780 || (GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
7781 && arm_is_long_call_p (SYMBOL_REF_DECL (XEXP (operands[1], 0)))))
33ae7c4b 7782 XEXP (operands[1], 0) = force_reg (SImode, XEXP (operands[1], 0));
7783
1c494086 7784 if (operands[3] == NULL_RTX)
7785 operands[3] = const0_rtx;
ca373797 7786
7787 pat = gen_sibcall_value_internal (operands[0], operands[1],
7788 operands[2], operands[3]);
7789 arm_emit_call_insn (pat, operands[1], true);
7790 DONE;
1c494086 7791 }"
7792)
7793
7794(define_insn "*sibcall_insn"
84ce8e5c 7795 [(call (mem:SI (match_operand:SI 0 "call_insn_operand" "Cs, US"))
1c494086 7796 (match_operand 1 "" ""))
2ba80634 7797 (return)
7798 (use (match_operand 2 "" ""))]
33ae7c4b 7799 "TARGET_32BIT && SIBLING_CALL_P (insn)"
1c494086 7800 "*
33ae7c4b 7801 if (which_alternative == 1)
7802 return NEED_PLT_RELOC ? \"b%?\\t%a0(PLT)\" : \"b%?\\t%a0\";
7803 else
7804 {
7805 if (arm_arch5 || arm_arch4t)
947d113e 7806 return \"bx%?\\t%0\\t%@ indirect register sibling call\";
33ae7c4b 7807 else
7808 return \"mov%?\\t%|pc, %0\\t%@ indirect register sibling call\";
7809 }
1c494086 7810 "
7811 [(set_attr "type" "call")]
7812)
7813
7814(define_insn "*sibcall_value_insn"
84ce8e5c 7815 [(set (match_operand 0 "" "")
7816 (call (mem:SI (match_operand:SI 1 "call_insn_operand" "Cs,US"))
1c494086 7817 (match_operand 2 "" "")))
2ba80634 7818 (return)
7819 (use (match_operand 3 "" ""))]
33ae7c4b 7820 "TARGET_32BIT && SIBLING_CALL_P (insn)"
1c494086 7821 "*
33ae7c4b 7822 if (which_alternative == 1)
7823 return NEED_PLT_RELOC ? \"b%?\\t%a1(PLT)\" : \"b%?\\t%a1\";
7824 else
7825 {
7826 if (arm_arch5 || arm_arch4t)
84ce8e5c 7827 return \"bx%?\\t%1\";
33ae7c4b 7828 else
7829 return \"mov%?\\t%|pc, %1\\t@ indirect sibling call \";
7830 }
1c494086 7831 "
7832 [(set_attr "type" "call")]
7833)
7834
0686440e 7835(define_expand "<return_str>return"
7836 [(returns)]
8cba51a5 7837 "(TARGET_ARM || (TARGET_THUMB2
7838 && ARM_FUNC_TYPE (arm_current_func_type ()) == ARM_FT_NORMAL
7839 && !IS_STACKALIGN (arm_current_func_type ())))
0686440e 7840 <return_cond_false>"
8cba51a5 7841 "
7842 {
7843 if (TARGET_THUMB2)
7844 {
0686440e 7845 thumb2_expand_return (<return_simple_p>);
8cba51a5 7846 DONE;
7847 }
7848 }
7849 "
7850)
d68c2c10 7851
9c08d1fa 7852;; Often the return insn will be the same as loading from memory, so set attr
d68c2c10 7853(define_insn "*arm_return"
9c08d1fa 7854 [(return)]
cffb2a26 7855 "TARGET_ARM && USE_RETURN_INSN (FALSE)"
9c08d1fa 7856 "*
9c08d1fa 7857 {
cffb2a26 7858 if (arm_ccfsm_state == 2)
7859 {
7860 arm_ccfsm_state += 2;
7861 return \"\";
7862 }
e2549f81 7863 return output_return_instruction (const_true_rtx, true, false, false);
cffb2a26 7864 }"
a2cd141b 7865 [(set_attr "type" "load1")
755eb2b4 7866 (set_attr "length" "12")
0d66636f 7867 (set_attr "predicable" "yes")]
cffb2a26 7868)
9c08d1fa 7869
0686440e 7870(define_insn "*cond_<return_str>return"
9c08d1fa 7871 [(set (pc)
8fa3ba89 7872 (if_then_else (match_operator 0 "arm_comparison_operator"
8a18b90c 7873 [(match_operand 1 "cc_register" "") (const_int 0)])
0686440e 7874 (returns)
9c08d1fa 7875 (pc)))]
0686440e 7876 "TARGET_ARM <return_cond_true>"
9c08d1fa 7877 "*
8fa3ba89 7878 {
7879 if (arm_ccfsm_state == 2)
7880 {
7881 arm_ccfsm_state += 2;
7882 return \"\";
7883 }
0686440e 7884 return output_return_instruction (operands[0], true, false,
7885 <return_simple_p>);
8fa3ba89 7886 }"
7887 [(set_attr "conds" "use")
755eb2b4 7888 (set_attr "length" "12")
a2cd141b 7889 (set_attr "type" "load1")]
8fa3ba89 7890)
9c08d1fa 7891
0686440e 7892(define_insn "*cond_<return_str>return_inverted"
9c08d1fa 7893 [(set (pc)
8fa3ba89 7894 (if_then_else (match_operator 0 "arm_comparison_operator"
8a18b90c 7895 [(match_operand 1 "cc_register" "") (const_int 0)])
9c08d1fa 7896 (pc)
0686440e 7897 (returns)))]
7898 "TARGET_ARM <return_cond_true>"
9c08d1fa 7899 "*
8fa3ba89 7900 {
7901 if (arm_ccfsm_state == 2)
7902 {
7903 arm_ccfsm_state += 2;
7904 return \"\";
7905 }
0686440e 7906 return output_return_instruction (operands[0], true, true,
7907 <return_simple_p>);
8fa3ba89 7908 }"
7909 [(set_attr "conds" "use")
37a1317b 7910 (set_attr "length" "12")
a2cd141b 7911 (set_attr "type" "load1")]
8fa3ba89 7912)
9c08d1fa 7913
e2549f81 7914(define_insn "*arm_simple_return"
7915 [(simple_return)]
7916 "TARGET_ARM"
7917 "*
7918 {
7919 if (arm_ccfsm_state == 2)
7920 {
7921 arm_ccfsm_state += 2;
7922 return \"\";
7923 }
7924 return output_return_instruction (const_true_rtx, true, false, true);
7925 }"
7926 [(set_attr "type" "branch")
7927 (set_attr "length" "4")
7928 (set_attr "predicable" "yes")]
7929)
7930
68121397 7931;; Generate a sequence of instructions to determine if the processor is
7932;; in 26-bit or 32-bit mode, and return the appropriate return address
7933;; mask.
7934
7935(define_expand "return_addr_mask"
7936 [(set (match_dup 1)
7937 (compare:CC_NOOV (unspec [(const_int 0)] UNSPEC_CHECK_ARCH)
7938 (const_int 0)))
7939 (set (match_operand:SI 0 "s_register_operand" "")
7940 (if_then_else:SI (eq (match_dup 1) (const_int 0))
7941 (const_int -1)
7942 (const_int 67108860)))] ; 0x03fffffc
7943 "TARGET_ARM"
7944 "
62eddbd4 7945 operands[1] = gen_rtx_REG (CC_NOOVmode, CC_REGNUM);
68121397 7946 ")
7947
7948(define_insn "*check_arch2"
7949 [(set (match_operand:CC_NOOV 0 "cc_register" "")
7950 (compare:CC_NOOV (unspec [(const_int 0)] UNSPEC_CHECK_ARCH)
7951 (const_int 0)))]
7952 "TARGET_ARM"
7953 "teq\\t%|r0, %|r0\;teq\\t%|pc, %|pc"
7954 [(set_attr "length" "8")
1b7da4ac 7955 (set_attr "conds" "set")
7956 (set_attr "type" "multiple")]
68121397 7957)
7958
9c08d1fa 7959;; Call subroutine returning any type.
7960
7961(define_expand "untyped_call"
7962 [(parallel [(call (match_operand 0 "" "")
7963 (const_int 0))
7964 (match_operand 1 "" "")
7965 (match_operand 2 "" "")])]
ccd90aaa 7966 "TARGET_EITHER"
9c08d1fa 7967 "
215b30b3 7968 {
7969 int i;
ccd90aaa 7970 rtx par = gen_rtx_PARALLEL (VOIDmode,
7971 rtvec_alloc (XVECLEN (operands[2], 0)));
7972 rtx addr = gen_reg_rtx (Pmode);
7973 rtx mem;
7974 int size = 0;
9c08d1fa 7975
ccd90aaa 7976 emit_move_insn (addr, XEXP (operands[1], 0));
7977 mem = change_address (operands[1], BLKmode, addr);
9c08d1fa 7978
215b30b3 7979 for (i = 0; i < XVECLEN (operands[2], 0); i++)
7980 {
ccd90aaa 7981 rtx src = SET_SRC (XVECEXP (operands[2], 0, i));
9c08d1fa 7982
ccd90aaa 7983 /* Default code only uses r0 as a return value, but we could
7984 be using anything up to 4 registers. */
7985 if (REGNO (src) == R0_REGNUM)
7986 src = gen_rtx_REG (TImode, R0_REGNUM);
7987
7988 XVECEXP (par, 0, i) = gen_rtx_EXPR_LIST (VOIDmode, src,
7989 GEN_INT (size));
7990 size += GET_MODE_SIZE (GET_MODE (src));
7991 }
7992
7993 emit_call_insn (GEN_CALL_VALUE (par, operands[0], const0_rtx, NULL,
7994 const0_rtx));
7995
7996 size = 0;
7997
7998 for (i = 0; i < XVECLEN (par, 0); i++)
7999 {
8000 HOST_WIDE_INT offset = 0;
8001 rtx reg = XEXP (XVECEXP (par, 0, i), 0);
8002
8003 if (size != 0)
29c05e22 8004 emit_move_insn (addr, plus_constant (Pmode, addr, size));
ccd90aaa 8005
8006 mem = change_address (mem, GET_MODE (reg), NULL);
8007 if (REGNO (reg) == R0_REGNUM)
8008 {
8009 /* On thumb we have to use a write-back instruction. */
320ea44d 8010 emit_insn (arm_gen_store_multiple (arm_regs_in_sequence, 4, addr,
8011 TARGET_THUMB ? TRUE : FALSE, mem, &offset));
ccd90aaa 8012 size = TARGET_ARM ? 16 : 0;
8013 }
8014 else
8015 {
8016 emit_move_insn (mem, reg);
8017 size = GET_MODE_SIZE (GET_MODE (reg));
8018 }
215b30b3 8019 }
9c08d1fa 8020
215b30b3 8021 /* The optimizer does not know that the call sets the function value
8022 registers we stored in the result block. We avoid problems by
8023 claiming that all hard registers are used and clobbered at this
8024 point. */
8025 emit_insn (gen_blockage ());
8026
8027 DONE;
8028 }"
8029)
9c08d1fa 8030
ccd90aaa 8031(define_expand "untyped_return"
8032 [(match_operand:BLK 0 "memory_operand" "")
8033 (match_operand 1 "" "")]
8034 "TARGET_EITHER"
8035 "
8036 {
8037 int i;
8038 rtx addr = gen_reg_rtx (Pmode);
8039 rtx mem;
8040 int size = 0;
8041
8042 emit_move_insn (addr, XEXP (operands[0], 0));
8043 mem = change_address (operands[0], BLKmode, addr);
8044
8045 for (i = 0; i < XVECLEN (operands[1], 0); i++)
8046 {
8047 HOST_WIDE_INT offset = 0;
8048 rtx reg = SET_DEST (XVECEXP (operands[1], 0, i));
8049
8050 if (size != 0)
29c05e22 8051 emit_move_insn (addr, plus_constant (Pmode, addr, size));
ccd90aaa 8052
8053 mem = change_address (mem, GET_MODE (reg), NULL);
8054 if (REGNO (reg) == R0_REGNUM)
8055 {
8056 /* On thumb we have to use a write-back instruction. */
320ea44d 8057 emit_insn (arm_gen_load_multiple (arm_regs_in_sequence, 4, addr,
8058 TARGET_THUMB ? TRUE : FALSE, mem, &offset));
ccd90aaa 8059 size = TARGET_ARM ? 16 : 0;
8060 }
8061 else
8062 {
8063 emit_move_insn (reg, mem);
8064 size = GET_MODE_SIZE (GET_MODE (reg));
8065 }
8066 }
8067
8068 /* Emit USE insns before the return. */
8069 for (i = 0; i < XVECLEN (operands[1], 0); i++)
18b42941 8070 emit_use (SET_DEST (XVECEXP (operands[1], 0, i)));
ccd90aaa 8071
8072 /* Construct the return. */
8073 expand_naked_return ();
8074
8075 DONE;
8076 }"
8077)
8078
9c08d1fa 8079;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
8080;; all of memory. This blocks insns from being moved across this point.
8081
8082(define_insn "blockage"
e1159bbe 8083 [(unspec_volatile [(const_int 0)] VUNSPEC_BLOCKAGE)]
cffb2a26 8084 "TARGET_EITHER"
9c08d1fa 8085 ""
cffb2a26 8086 [(set_attr "length" "0")
8087 (set_attr "type" "block")]
8088)
9c08d1fa 8089
f7fbdd4a 8090(define_expand "casesi"
8091 [(match_operand:SI 0 "s_register_operand" "") ; index to jump on
aea4c774 8092 (match_operand:SI 1 "const_int_operand" "") ; lower bound
8093 (match_operand:SI 2 "const_int_operand" "") ; total range
f7fbdd4a 8094 (match_operand:SI 3 "" "") ; table label
8095 (match_operand:SI 4 "" "")] ; Out of range label
e6ac8414 8096 "TARGET_32BIT || optimize_size || flag_pic"
f7fbdd4a 8097 "
215b30b3 8098 {
e6ac8414 8099 enum insn_code code;
215b30b3 8100 if (operands[1] != const0_rtx)
8101 {
e6ac8414 8102 rtx reg = gen_reg_rtx (SImode);
f7fbdd4a 8103
215b30b3 8104 emit_insn (gen_addsi3 (reg, operands[0],
d022fa24 8105 gen_int_mode (-INTVAL (operands[1]),
8106 SImode)));
215b30b3 8107 operands[0] = reg;
8108 }
9c08d1fa 8109
25f905c2 8110 if (TARGET_ARM)
e6ac8414 8111 code = CODE_FOR_arm_casesi_internal;
3db2019b 8112 else if (TARGET_THUMB1)
e6ac8414 8113 code = CODE_FOR_thumb1_casesi_internal_pic;
25f905c2 8114 else if (flag_pic)
e6ac8414 8115 code = CODE_FOR_thumb2_casesi_internal_pic;
25f905c2 8116 else
e6ac8414 8117 code = CODE_FOR_thumb2_casesi_internal;
8118
8119 if (!insn_data[(int) code].operand[1].predicate(operands[2], SImode))
8120 operands[2] = force_reg (SImode, operands[2]);
8121
8122 emit_jump_insn (GEN_FCN ((int) code) (operands[0], operands[2],
8123 operands[3], operands[4]));
215b30b3 8124 DONE;
8125 }"
8126)
f7fbdd4a 8127
f082f1c4 8128;; The USE in this pattern is needed to tell flow analysis that this is
8129;; a CASESI insn. It has no other purpose.
25f905c2 8130(define_insn "arm_casesi_internal"
f082f1c4 8131 [(parallel [(set (pc)
8132 (if_then_else
8133 (leu (match_operand:SI 0 "s_register_operand" "r")
8134 (match_operand:SI 1 "arm_rhs_operand" "rI"))
8135 (mem:SI (plus:SI (mult:SI (match_dup 0) (const_int 4))
8136 (label_ref (match_operand 2 "" ""))))
8137 (label_ref (match_operand 3 "" ""))))
bd5b4116 8138 (clobber (reg:CC CC_REGNUM))
f082f1c4 8139 (use (label_ref (match_dup 2)))])]
cffb2a26 8140 "TARGET_ARM"
f7fbdd4a 8141 "*
0d66636f 8142 if (flag_pic)
8143 return \"cmp\\t%0, %1\;addls\\t%|pc, %|pc, %0, asl #2\;b\\t%l3\";
8144 return \"cmp\\t%0, %1\;ldrls\\t%|pc, [%|pc, %0, asl #2]\;b\\t%l3\";
8145 "
8146 [(set_attr "conds" "clob")
1b7da4ac 8147 (set_attr "length" "12")
8148 (set_attr "type" "multiple")]
0d66636f 8149)
9c08d1fa 8150
cffb2a26 8151(define_expand "indirect_jump"
9c08d1fa 8152 [(set (pc)
cffb2a26 8153 (match_operand:SI 0 "s_register_operand" ""))]
8154 "TARGET_EITHER"
25f905c2 8155 "
8156 /* Thumb-2 doesn't have mov pc, reg. Explicitly set the low bit of the
8157 address and use bx. */
8158 if (TARGET_THUMB2)
8159 {
8160 rtx tmp;
8161 tmp = gen_reg_rtx (SImode);
8162 emit_insn (gen_iorsi3 (tmp, operands[0], GEN_INT(1)));
8163 operands[0] = tmp;
8164 }
8165 "
cffb2a26 8166)
8167
f1039640 8168;; NB Never uses BX.
cffb2a26 8169(define_insn "*arm_indirect_jump"
8170 [(set (pc)
8171 (match_operand:SI 0 "s_register_operand" "r"))]
8172 "TARGET_ARM"
8173 "mov%?\\t%|pc, %0\\t%@ indirect register jump"
1b7da4ac 8174 [(set_attr "predicable" "yes")
8175 (set_attr "type" "branch")]
cffb2a26 8176)
9c08d1fa 8177
f7fbdd4a 8178(define_insn "*load_indirect_jump"
9c08d1fa 8179 [(set (pc)
8180 (match_operand:SI 0 "memory_operand" "m"))]
cffb2a26 8181 "TARGET_ARM"
8182 "ldr%?\\t%|pc, %0\\t%@ indirect memory jump"
a2cd141b 8183 [(set_attr "type" "load1")
61a2d04c 8184 (set_attr "pool_range" "4096")
8185 (set_attr "neg_pool_range" "4084")
0d66636f 8186 (set_attr "predicable" "yes")]
cffb2a26 8187)
8188
9c08d1fa 8189\f
8190;; Misc insns
8191
8192(define_insn "nop"
8193 [(const_int 0)]
cffb2a26 8194 "TARGET_EITHER"
8195 "*
25f905c2 8196 if (TARGET_UNIFIED_ASM)
8197 return \"nop\";
cffb2a26 8198 if (TARGET_ARM)
8199 return \"mov%?\\t%|r0, %|r0\\t%@ nop\";
8200 return \"mov\\tr8, r8\";
8201 "
8202 [(set (attr "length")
8203 (if_then_else (eq_attr "is_thumb" "yes")
8204 (const_int 2)
1b7da4ac 8205 (const_int 4)))
8206 (set_attr "type" "mov_reg")]
cffb2a26 8207)
8208
ad9d4399 8209(define_insn "trap"
8210 [(trap_if (const_int 1) (const_int 0))]
8211 ""
8212 "*
8213 if (TARGET_ARM)
8214 return \".inst\\t0xe7f000f0\";
8215 else
8216 return \".inst\\t0xdeff\";
8217 "
8218 [(set (attr "length")
8219 (if_then_else (eq_attr "is_thumb" "yes")
8220 (const_int 2)
8221 (const_int 4)))
8222 (set_attr "type" "trap")
8223 (set_attr "conds" "unconditional")]
8224)
8225
9c08d1fa 8226\f
8227;; Patterns to allow combination of arithmetic, cond code and shifts
8228
0abea32c 8229(define_insn "*<arith_shift_insn>_multsi"
8230 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8231 (shiftable_ops:SI
8232 (mult:SI (match_operand:SI 2 "s_register_operand" "r,r")
8233 (match_operand:SI 3 "power_of_two_operand" ""))
8234 (match_operand:SI 1 "s_register_operand" "rk,<t2_binop0>")))]
d5d4dc8d 8235 "TARGET_32BIT"
0abea32c 8236 "<arith_shift_insn>%?\\t%0, %1, %2, lsl %b3"
8237 [(set_attr "predicable" "yes")
8238 (set_attr "predicable_short_it" "no")
8239 (set_attr "shift" "4")
8240 (set_attr "arch" "a,t2")
8241 (set_attr "type" "alu_shift_imm")])
8242
8243(define_insn "*<arith_shift_insn>_shiftsi"
8244 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
8245 (shiftable_ops:SI
8246 (match_operator:SI 2 "shift_nomul_operator"
8247 [(match_operand:SI 3 "s_register_operand" "r,r,r")
8248 (match_operand:SI 4 "shift_amount_operand" "M,M,r")])
8249 (match_operand:SI 1 "s_register_operand" "rk,<t2_binop0>,rk")))]
8250 "TARGET_32BIT && GET_CODE (operands[3]) != MULT"
8251 "<arith_shift_insn>%?\\t%0, %1, %3%S2"
344495ea 8252 [(set_attr "predicable" "yes")
74ef923b 8253 (set_attr "predicable_short_it" "no")
331beb1a 8254 (set_attr "shift" "4")
0abea32c 8255 (set_attr "arch" "a,t2,a")
8256 (set_attr "type" "alu_shift_imm,alu_shift_imm,alu_shift_reg")])
9c08d1fa 8257
d7863cfe 8258(define_split
8259 [(set (match_operand:SI 0 "s_register_operand" "")
8260 (match_operator:SI 1 "shiftable_operator"
8261 [(match_operator:SI 2 "shiftable_operator"
8262 [(match_operator:SI 3 "shift_operator"
8263 [(match_operand:SI 4 "s_register_operand" "")
8264 (match_operand:SI 5 "reg_or_int_operand" "")])
8265 (match_operand:SI 6 "s_register_operand" "")])
8266 (match_operand:SI 7 "arm_rhs_operand" "")]))
8267 (clobber (match_operand:SI 8 "s_register_operand" ""))]
d5d4dc8d 8268 "TARGET_32BIT"
d7863cfe 8269 [(set (match_dup 8)
8270 (match_op_dup 2 [(match_op_dup 3 [(match_dup 4) (match_dup 5)])
8271 (match_dup 6)]))
8272 (set (match_dup 0)
8273 (match_op_dup 1 [(match_dup 8) (match_dup 7)]))]
8274 "")
8275
f7fbdd4a 8276(define_insn "*arith_shiftsi_compare0"
bd5b4116 8277 [(set (reg:CC_NOOV CC_REGNUM)
d5d4dc8d 8278 (compare:CC_NOOV
8279 (match_operator:SI 1 "shiftable_operator"
8280 [(match_operator:SI 3 "shift_operator"
8281 [(match_operand:SI 4 "s_register_operand" "r,r")
8282 (match_operand:SI 5 "shift_amount_operand" "M,r")])
8283 (match_operand:SI 2 "s_register_operand" "r,r")])
8284 (const_int 0)))
8285 (set (match_operand:SI 0 "s_register_operand" "=r,r")
9c08d1fa 8286 (match_op_dup 1 [(match_op_dup 3 [(match_dup 4) (match_dup 5)])
8287 (match_dup 2)]))]
d5d4dc8d 8288 "TARGET_32BIT"
25f905c2 8289 "%i1%.\\t%0, %2, %4%S3"
344495ea 8290 [(set_attr "conds" "set")
331beb1a 8291 (set_attr "shift" "4")
d5d4dc8d 8292 (set_attr "arch" "32,a")
d82e788e 8293 (set_attr "type" "alus_shift_imm,alus_shift_reg")])
9c08d1fa 8294
f7fbdd4a 8295(define_insn "*arith_shiftsi_compare0_scratch"
bd5b4116 8296 [(set (reg:CC_NOOV CC_REGNUM)
d5d4dc8d 8297 (compare:CC_NOOV
8298 (match_operator:SI 1 "shiftable_operator"
8299 [(match_operator:SI 3 "shift_operator"
8300 [(match_operand:SI 4 "s_register_operand" "r,r")
8301 (match_operand:SI 5 "shift_amount_operand" "M,r")])
8302 (match_operand:SI 2 "s_register_operand" "r,r")])
8303 (const_int 0)))
8304 (clobber (match_scratch:SI 0 "=r,r"))]
8305 "TARGET_32BIT"
25f905c2 8306 "%i1%.\\t%0, %2, %4%S3"
344495ea 8307 [(set_attr "conds" "set")
331beb1a 8308 (set_attr "shift" "4")
d5d4dc8d 8309 (set_attr "arch" "32,a")
d82e788e 8310 (set_attr "type" "alus_shift_imm,alus_shift_reg")])
9c08d1fa 8311
f7fbdd4a 8312(define_insn "*sub_shiftsi"
d5d4dc8d 8313 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8314 (minus:SI (match_operand:SI 1 "s_register_operand" "r,r")
9c08d1fa 8315 (match_operator:SI 2 "shift_operator"
d5d4dc8d 8316 [(match_operand:SI 3 "s_register_operand" "r,r")
8317 (match_operand:SI 4 "shift_amount_operand" "M,r")])))]
8318 "TARGET_32BIT"
6c4c2133 8319 "sub%?\\t%0, %1, %3%S2"
344495ea 8320 [(set_attr "predicable" "yes")
331beb1a 8321 (set_attr "shift" "3")
d5d4dc8d 8322 (set_attr "arch" "32,a")
d82e788e 8323 (set_attr "type" "alus_shift_imm,alus_shift_reg")])
9c08d1fa 8324
f7fbdd4a 8325(define_insn "*sub_shiftsi_compare0"
bd5b4116 8326 [(set (reg:CC_NOOV CC_REGNUM)
40dbec34 8327 (compare:CC_NOOV
d82e788e 8328 (minus:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
40dbec34 8329 (match_operator:SI 2 "shift_operator"
d82e788e 8330 [(match_operand:SI 3 "s_register_operand" "r,r,r")
8331 (match_operand:SI 4 "shift_amount_operand" "M,r,M")]))
40dbec34 8332 (const_int 0)))
d82e788e 8333 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
d5d4dc8d 8334 (minus:SI (match_dup 1)
8335 (match_op_dup 2 [(match_dup 3) (match_dup 4)])))]
8336 "TARGET_32BIT"
25f905c2 8337 "sub%.\\t%0, %1, %3%S2"
344495ea 8338 [(set_attr "conds" "set")
a2cd141b 8339 (set_attr "shift" "3")
d82e788e 8340 (set_attr "arch" "32,a,a")
8341 (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")])
9c08d1fa 8342
f7fbdd4a 8343(define_insn "*sub_shiftsi_compare0_scratch"
bd5b4116 8344 [(set (reg:CC_NOOV CC_REGNUM)
40dbec34 8345 (compare:CC_NOOV
d82e788e 8346 (minus:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
40dbec34 8347 (match_operator:SI 2 "shift_operator"
d82e788e 8348 [(match_operand:SI 3 "s_register_operand" "r,r,r")
8349 (match_operand:SI 4 "shift_amount_operand" "M,r,M")]))
40dbec34 8350 (const_int 0)))
d82e788e 8351 (clobber (match_scratch:SI 0 "=r,r,r"))]
d5d4dc8d 8352 "TARGET_32BIT"
25f905c2 8353 "sub%.\\t%0, %1, %3%S2"
344495ea 8354 [(set_attr "conds" "set")
a2cd141b 8355 (set_attr "shift" "3")
d82e788e 8356 (set_attr "arch" "32,a,a")
8357 (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")])
9c08d1fa 8358\f
8359
190efb17 8360(define_insn_and_split "*and_scc"
9c08d1fa 8361 [(set (match_operand:SI 0 "s_register_operand" "=r")
8fa3ba89 8362 (and:SI (match_operator:SI 1 "arm_comparison_operator"
190efb17 8363 [(match_operand 2 "cc_register" "") (const_int 0)])
8364 (match_operand:SI 3 "s_register_operand" "r")))]
cffb2a26 8365 "TARGET_ARM"
190efb17 8366 "#" ; "mov%D1\\t%0, #0\;and%d1\\t%0, %3, #1"
8367 "&& reload_completed"
8368 [(cond_exec (match_dup 5) (set (match_dup 0) (const_int 0)))
8369 (cond_exec (match_dup 4) (set (match_dup 0)
8370 (and:SI (match_dup 3) (const_int 1))))]
8371 {
8372 enum machine_mode mode = GET_MODE (operands[2]);
8373 enum rtx_code rc = GET_CODE (operands[1]);
8374
8375 /* Note that operands[4] is the same as operands[1],
8376 but with VOIDmode as the result. */
8377 operands[4] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
8378 if (mode == CCFPmode || mode == CCFPEmode)
8379 rc = reverse_condition_maybe_unordered (rc);
8380 else
8381 rc = reverse_condition (rc);
8382 operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
8383 }
8fa3ba89 8384 [(set_attr "conds" "use")
1b7da4ac 8385 (set_attr "type" "multiple")
8fa3ba89 8386 (set_attr "length" "8")]
8387)
9c08d1fa 8388
190efb17 8389(define_insn_and_split "*ior_scc"
9c08d1fa 8390 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
190efb17 8391 (ior:SI (match_operator:SI 1 "arm_comparison_operator"
8392 [(match_operand 2 "cc_register" "") (const_int 0)])
8393 (match_operand:SI 3 "s_register_operand" "0,?r")))]
cffb2a26 8394 "TARGET_ARM"
e2348bcb 8395 "@
190efb17 8396 orr%d1\\t%0, %3, #1
8397 #"
8398 "&& reload_completed
8399 && REGNO (operands [0]) != REGNO (operands[3])"
8400 ;; && which_alternative == 1
8401 ; mov%D1\\t%0, %3\;orr%d1\\t%0, %3, #1
8402 [(cond_exec (match_dup 5) (set (match_dup 0) (match_dup 3)))
8403 (cond_exec (match_dup 4) (set (match_dup 0)
8404 (ior:SI (match_dup 3) (const_int 1))))]
8405 {
8406 enum machine_mode mode = GET_MODE (operands[2]);
8407 enum rtx_code rc = GET_CODE (operands[1]);
8408
8409 /* Note that operands[4] is the same as operands[1],
8410 but with VOIDmode as the result. */
8411 operands[4] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
8412 if (mode == CCFPmode || mode == CCFPEmode)
8413 rc = reverse_condition_maybe_unordered (rc);
8414 else
8415 rc = reverse_condition (rc);
8416 operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
8417 }
8fa3ba89 8418 [(set_attr "conds" "use")
1b7da4ac 8419 (set_attr "length" "4,8")
8420 (set_attr "type" "logic_imm,multiple")]
8fa3ba89 8421)
9c08d1fa 8422
2df9477b 8423; A series of splitters for the compare_scc pattern below. Note that
8424; order is important.
8425(define_split
8426 [(set (match_operand:SI 0 "s_register_operand" "")
8427 (lt:SI (match_operand:SI 1 "s_register_operand" "")
8428 (const_int 0)))
8429 (clobber (reg:CC CC_REGNUM))]
8430 "TARGET_32BIT && reload_completed"
8431 [(set (match_dup 0) (lshiftrt:SI (match_dup 1) (const_int 31)))])
8432
8433(define_split
8434 [(set (match_operand:SI 0 "s_register_operand" "")
8435 (ge:SI (match_operand:SI 1 "s_register_operand" "")
8436 (const_int 0)))
8437 (clobber (reg:CC CC_REGNUM))]
8438 "TARGET_32BIT && reload_completed"
8439 [(set (match_dup 0) (not:SI (match_dup 1)))
8440 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 31)))])
8441
98562479 8442(define_split
8443 [(set (match_operand:SI 0 "s_register_operand" "")
8444 (eq:SI (match_operand:SI 1 "s_register_operand" "")
8445 (const_int 0)))
8446 (clobber (reg:CC CC_REGNUM))]
8447 "arm_arch5 && TARGET_32BIT"
8448 [(set (match_dup 0) (clz:SI (match_dup 1)))
8449 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 5)))]
8450)
8451
2df9477b 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 "TARGET_32BIT && reload_completed"
8458 [(parallel
080c0b9a 8459 [(set (reg:CC CC_REGNUM)
8460 (compare:CC (const_int 1) (match_dup 1)))
2df9477b 8461 (set (match_dup 0)
8462 (minus:SI (const_int 1) (match_dup 1)))])
080c0b9a 8463 (cond_exec (ltu:CC (reg:CC CC_REGNUM) (const_int 0))
2df9477b 8464 (set (match_dup 0) (const_int 0)))])
8465
8466(define_split
8467 [(set (match_operand:SI 0 "s_register_operand" "")
8468 (ne:SI (match_operand:SI 1 "s_register_operand" "")
8469 (match_operand:SI 2 "const_int_operand" "")))
8470 (clobber (reg:CC CC_REGNUM))]
8471 "TARGET_32BIT && reload_completed"
8472 [(parallel
8473 [(set (reg:CC CC_REGNUM)
8474 (compare:CC (match_dup 1) (match_dup 2)))
8475 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 3)))])
8476 (cond_exec (ne:CC (reg:CC CC_REGNUM) (const_int 0))
8477 (set (match_dup 0) (const_int 1)))]
8478{
8479 operands[3] = GEN_INT (-INTVAL (operands[2]));
8480})
8481
8482(define_split
8483 [(set (match_operand:SI 0 "s_register_operand" "")
8484 (ne:SI (match_operand:SI 1 "s_register_operand" "")
8485 (match_operand:SI 2 "arm_add_operand" "")))
8486 (clobber (reg:CC CC_REGNUM))]
8487 "TARGET_32BIT && reload_completed"
8488 [(parallel
8489 [(set (reg:CC_NOOV CC_REGNUM)
8490 (compare:CC_NOOV (minus:SI (match_dup 1) (match_dup 2))
8491 (const_int 0)))
8492 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
8493 (cond_exec (ne:CC_NOOV (reg:CC_NOOV CC_REGNUM) (const_int 0))
8494 (set (match_dup 0) (const_int 1)))])
8495
8496(define_insn_and_split "*compare_scc"
fd711051 8497 [(set (match_operand:SI 0 "s_register_operand" "=Ts,Ts")
8fa3ba89 8498 (match_operator:SI 1 "arm_comparison_operator"
5565501b 8499 [(match_operand:SI 2 "s_register_operand" "r,r")
8500 (match_operand:SI 3 "arm_add_operand" "rI,L")]))
bd5b4116 8501 (clobber (reg:CC CC_REGNUM))]
2df9477b 8502 "TARGET_32BIT"
8503 "#"
8504 "&& reload_completed"
8505 [(set (reg:CC CC_REGNUM) (compare:CC (match_dup 2) (match_dup 3)))
8506 (cond_exec (match_dup 4) (set (match_dup 0) (const_int 0)))
8507 (cond_exec (match_dup 5) (set (match_dup 0) (const_int 1)))]
8508{
8509 rtx tmp1;
8510 enum machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
8511 operands[2], operands[3]);
8512 enum rtx_code rc = GET_CODE (operands[1]);
e2348bcb 8513
2df9477b 8514 tmp1 = gen_rtx_REG (mode, CC_REGNUM);
080c0b9a 8515
2df9477b 8516 operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, tmp1, const0_rtx);
8517 if (mode == CCFPmode || mode == CCFPEmode)
8518 rc = reverse_condition_maybe_unordered (rc);
8519 else
8520 rc = reverse_condition (rc);
8521 operands[4] = gen_rtx_fmt_ee (rc, VOIDmode, tmp1, const0_rtx);
1b7da4ac 8522}
8523 [(set_attr "type" "multiple")]
8524)
9c08d1fa 8525
080c0b9a 8526;; Attempt to improve the sequence generated by the compare_scc splitters
8527;; not to use conditional execution.
98562479 8528
8529;; Rd = (eq (reg1) (const_int0)) // ARMv5
8530;; clz Rd, reg1
8531;; lsr Rd, Rd, #5
080c0b9a 8532(define_peephole2
8533 [(set (reg:CC CC_REGNUM)
8534 (compare:CC (match_operand:SI 1 "register_operand" "")
98562479 8535 (const_int 0)))
8536 (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
8537 (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
8538 (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
8539 (set (match_dup 0) (const_int 1)))]
8540 "arm_arch5 && TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)"
8541 [(set (match_dup 0) (clz:SI (match_dup 1)))
8542 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 5)))]
8543)
8544
8545;; Rd = (eq (reg1) (const_int0)) // !ARMv5
8546;; negs Rd, reg1
8547;; adc Rd, Rd, reg1
8548(define_peephole2
8549 [(set (reg:CC CC_REGNUM)
8550 (compare:CC (match_operand:SI 1 "register_operand" "")
8551 (const_int 0)))
080c0b9a 8552 (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
8553 (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
8554 (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
8555 (set (match_dup 0) (const_int 1)))
98562479 8556 (match_scratch:SI 2 "r")]
8557 "TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)"
922b6913 8558 [(parallel
8559 [(set (reg:CC CC_REGNUM)
98562479 8560 (compare:CC (const_int 0) (match_dup 1)))
8561 (set (match_dup 2) (minus:SI (const_int 0) (match_dup 1)))])
8562 (set (match_dup 0)
8563 (plus:SI (plus:SI (match_dup 1) (match_dup 2))
8564 (geu:SI (reg:CC CC_REGNUM) (const_int 0))))]
8565)
8566
31991287 8567;; Rd = (eq (reg1) (reg2/imm)) // ARMv5 and optimising for speed.
98562479 8568;; sub Rd, Reg1, reg2
8569;; clz Rd, Rd
8570;; lsr Rd, Rd, #5
8571(define_peephole2
8572 [(set (reg:CC CC_REGNUM)
8573 (compare:CC (match_operand:SI 1 "register_operand" "")
8574 (match_operand:SI 2 "arm_rhs_operand" "")))
8575 (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
8576 (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
8577 (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
8578 (set (match_dup 0) (const_int 1)))]
31991287 8579 "arm_arch5 && TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)
8580 && !(TARGET_THUMB2 && optimize_insn_for_size_p ())"
98562479 8581 [(set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))
8582 (set (match_dup 0) (clz:SI (match_dup 0)))
8583 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 5)))]
8584)
8585
8586
31991287 8587;; Rd = (eq (reg1) (reg2)) // ! ARMv5 or optimising for size.
98562479 8588;; sub T1, Reg1, reg2
8589;; negs Rd, T1
8590;; adc Rd, Rd, T1
8591(define_peephole2
8592 [(set (reg:CC CC_REGNUM)
8593 (compare:CC (match_operand:SI 1 "register_operand" "")
8594 (match_operand:SI 2 "arm_rhs_operand" "")))
8595 (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
8596 (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
8597 (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
8598 (set (match_dup 0) (const_int 1)))
8599 (match_scratch:SI 3 "r")]
8600 "TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)"
31991287 8601 [(set (match_dup 3) (match_dup 4))
080c0b9a 8602 (parallel
8603 [(set (reg:CC CC_REGNUM)
8604 (compare:CC (const_int 0) (match_dup 3)))
8605 (set (match_dup 0) (minus:SI (const_int 0) (match_dup 3)))])
98562479 8606 (set (match_dup 0)
8607 (plus:SI (plus:SI (match_dup 0) (match_dup 3))
8608 (geu:SI (reg:CC CC_REGNUM) (const_int 0))))]
31991287 8609 "
8610 if (CONST_INT_P (operands[2]))
8611 operands[4] = plus_constant (SImode, operands[1], -INTVAL (operands[2]));
8612 else
8613 operands[4] = gen_rtx_MINUS (SImode, operands[1], operands[2]);
8614 ")
080c0b9a 8615
f7fbdd4a 8616(define_insn "*cond_move"
9c08d1fa 8617 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
aea4c774 8618 (if_then_else:SI (match_operator 3 "equality_operator"
8fa3ba89 8619 [(match_operator 4 "arm_comparison_operator"
8a18b90c 8620 [(match_operand 5 "cc_register" "") (const_int 0)])
aea4c774 8621 (const_int 0)])
8622 (match_operand:SI 1 "arm_rhs_operand" "0,rI,?rI")
8623 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))]
cffb2a26 8624 "TARGET_ARM"
9c08d1fa 8625 "*
8fa3ba89 8626 if (GET_CODE (operands[3]) == NE)
8627 {
8628 if (which_alternative != 1)
8629 output_asm_insn (\"mov%D4\\t%0, %2\", operands);
8630 if (which_alternative != 0)
8631 output_asm_insn (\"mov%d4\\t%0, %1\", operands);
8632 return \"\";
8633 }
8634 if (which_alternative != 0)
8635 output_asm_insn (\"mov%D4\\t%0, %1\", operands);
8636 if (which_alternative != 1)
8637 output_asm_insn (\"mov%d4\\t%0, %2\", operands);
8638 return \"\";
8639 "
8640 [(set_attr "conds" "use")
1b7da4ac 8641 (set_attr "type" "mov_reg,mov_reg,multiple")
8fa3ba89 8642 (set_attr "length" "4,4,8")]
8643)
9c08d1fa 8644
f7fbdd4a 8645(define_insn "*cond_arith"
9c08d1fa 8646 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8647 (match_operator:SI 5 "shiftable_operator"
8fa3ba89 8648 [(match_operator:SI 4 "arm_comparison_operator"
9c08d1fa 8649 [(match_operand:SI 2 "s_register_operand" "r,r")
8650 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
8651 (match_operand:SI 1 "s_register_operand" "0,?r")]))
bd5b4116 8652 (clobber (reg:CC CC_REGNUM))]
cffb2a26 8653 "TARGET_ARM"
9c08d1fa 8654 "*
8fa3ba89 8655 if (GET_CODE (operands[4]) == LT && operands[3] == const0_rtx)
8656 return \"%i5\\t%0, %1, %2, lsr #31\";
40dbec34 8657
8fa3ba89 8658 output_asm_insn (\"cmp\\t%2, %3\", operands);
8659 if (GET_CODE (operands[5]) == AND)
8660 output_asm_insn (\"mov%D4\\t%0, #0\", operands);
8661 else if (GET_CODE (operands[5]) == MINUS)
8662 output_asm_insn (\"rsb%D4\\t%0, %1, #0\", operands);
8663 else if (which_alternative != 0)
8664 output_asm_insn (\"mov%D4\\t%0, %1\", operands);
8665 return \"%i5%d4\\t%0, %1, #1\";
8666 "
8667 [(set_attr "conds" "clob")
1b7da4ac 8668 (set_attr "length" "12")
8669 (set_attr "type" "multiple")]
8fa3ba89 8670)
9c08d1fa 8671
f7fbdd4a 8672(define_insn "*cond_sub"
9c08d1fa 8673 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8674 (minus:SI (match_operand:SI 1 "s_register_operand" "0,?r")
8fa3ba89 8675 (match_operator:SI 4 "arm_comparison_operator"
9c08d1fa 8676 [(match_operand:SI 2 "s_register_operand" "r,r")
8677 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))
bd5b4116 8678 (clobber (reg:CC CC_REGNUM))]
cffb2a26 8679 "TARGET_ARM"
9c08d1fa 8680 "*
8fa3ba89 8681 output_asm_insn (\"cmp\\t%2, %3\", operands);
8682 if (which_alternative != 0)
8683 output_asm_insn (\"mov%D4\\t%0, %1\", operands);
8684 return \"sub%d4\\t%0, %1, #1\";
8685 "
8686 [(set_attr "conds" "clob")
1b7da4ac 8687 (set_attr "length" "8,12")
8688 (set_attr "type" "multiple")]
8fa3ba89 8689)
9c08d1fa 8690
aea4c774 8691(define_insn "*cmp_ite0"
cffb2a26 8692 [(set (match_operand 6 "dominant_cc_register" "")
aea4c774 8693 (compare
8694 (if_then_else:SI
8fa3ba89 8695 (match_operator 4 "arm_comparison_operator"
2ff91fec 8696 [(match_operand:SI 0 "s_register_operand"
8697 "l,l,l,r,r,r,r,r,r")
8698 (match_operand:SI 1 "arm_add_operand"
8699 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
8fa3ba89 8700 (match_operator:SI 5 "arm_comparison_operator"
2ff91fec 8701 [(match_operand:SI 2 "s_register_operand"
8702 "l,r,r,l,l,r,r,r,r")
8703 (match_operand:SI 3 "arm_add_operand"
8704 "lPy,rI,L,lPy,lPy,rI,rI,L,L")])
aea4c774 8705 (const_int 0))
8706 (const_int 0)))]
2ff91fec 8707 "TARGET_32BIT"
9c08d1fa 8708 "*
aea4c774 8709 {
2ff91fec 8710 static const char * const cmp1[NUM_OF_COND_CMP][2] =
8711 {
8712 {\"cmp%d5\\t%0, %1\",
8713 \"cmp%d4\\t%2, %3\"},
8714 {\"cmn%d5\\t%0, #%n1\",
8715 \"cmp%d4\\t%2, %3\"},
8716 {\"cmp%d5\\t%0, %1\",
8717 \"cmn%d4\\t%2, #%n3\"},
8718 {\"cmn%d5\\t%0, #%n1\",
8719 \"cmn%d4\\t%2, #%n3\"}
8720 };
8721 static const char * const cmp2[NUM_OF_COND_CMP][2] =
8722 {
8723 {\"cmp\\t%2, %3\",
8724 \"cmp\\t%0, %1\"},
8725 {\"cmp\\t%2, %3\",
8726 \"cmn\\t%0, #%n1\"},
8727 {\"cmn\\t%2, #%n3\",
8728 \"cmp\\t%0, %1\"},
8729 {\"cmn\\t%2, #%n3\",
8730 \"cmn\\t%0, #%n1\"}
8731 };
8732 static const char * const ite[2] =
8fa3ba89 8733 {
2ff91fec 8734 \"it\\t%d5\",
8735 \"it\\t%d4\"
8fa3ba89 8736 };
2ff91fec 8737 static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
8738 CMP_CMP, CMN_CMP, CMP_CMP,
8739 CMN_CMP, CMP_CMN, CMN_CMN};
8fa3ba89 8740 int swap =
8741 comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4]));
8742
2ff91fec 8743 output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
8744 if (TARGET_THUMB2) {
8745 output_asm_insn (ite[swap], operands);
8746 }
8747 output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
8748 return \"\";
8fa3ba89 8749 }"
8750 [(set_attr "conds" "set")
2ff91fec 8751 (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
1b7da4ac 8752 (set_attr "type" "multiple")
2ff91fec 8753 (set_attr_alternative "length"
8754 [(const_int 6)
8755 (const_int 8)
8756 (const_int 8)
8757 (const_int 8)
8758 (const_int 8)
8759 (if_then_else (eq_attr "is_thumb" "no")
8760 (const_int 8)
8761 (const_int 10))
8762 (if_then_else (eq_attr "is_thumb" "no")
8763 (const_int 8)
8764 (const_int 10))
8765 (if_then_else (eq_attr "is_thumb" "no")
8766 (const_int 8)
8767 (const_int 10))
8768 (if_then_else (eq_attr "is_thumb" "no")
8769 (const_int 8)
8770 (const_int 10))])]
8fa3ba89 8771)
9c08d1fa 8772
aea4c774 8773(define_insn "*cmp_ite1"
cffb2a26 8774 [(set (match_operand 6 "dominant_cc_register" "")
aea4c774 8775 (compare
8776 (if_then_else:SI
8fa3ba89 8777 (match_operator 4 "arm_comparison_operator"
2ff91fec 8778 [(match_operand:SI 0 "s_register_operand"
8779 "l,l,l,r,r,r,r,r,r")
8780 (match_operand:SI 1 "arm_add_operand"
8781 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
8fa3ba89 8782 (match_operator:SI 5 "arm_comparison_operator"
2ff91fec 8783 [(match_operand:SI 2 "s_register_operand"
8784 "l,r,r,l,l,r,r,r,r")
8785 (match_operand:SI 3 "arm_add_operand"
8786 "lPy,rI,L,lPy,lPy,rI,rI,L,L")])
aea4c774 8787 (const_int 1))
8788 (const_int 0)))]
2ff91fec 8789 "TARGET_32BIT"
9c08d1fa 8790 "*
9c08d1fa 8791 {
2ff91fec 8792 static const char * const cmp1[NUM_OF_COND_CMP][2] =
8793 {
8794 {\"cmp\\t%0, %1\",
8795 \"cmp\\t%2, %3\"},
8796 {\"cmn\\t%0, #%n1\",
8797 \"cmp\\t%2, %3\"},
8798 {\"cmp\\t%0, %1\",
8799 \"cmn\\t%2, #%n3\"},
8800 {\"cmn\\t%0, #%n1\",
8801 \"cmn\\t%2, #%n3\"}
8802 };
8803 static const char * const cmp2[NUM_OF_COND_CMP][2] =
215b30b3 8804 {
2ff91fec 8805 {\"cmp%d4\\t%2, %3\",
8806 \"cmp%D5\\t%0, %1\"},
8807 {\"cmp%d4\\t%2, %3\",
8808 \"cmn%D5\\t%0, #%n1\"},
8809 {\"cmn%d4\\t%2, #%n3\",
8810 \"cmp%D5\\t%0, %1\"},
8811 {\"cmn%d4\\t%2, #%n3\",
8812 \"cmn%D5\\t%0, #%n1\"}
215b30b3 8813 };
2ff91fec 8814 static const char * const ite[2] =
8815 {
8816 \"it\\t%d4\",
8817 \"it\\t%D5\"
8818 };
8819 static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
8820 CMP_CMP, CMN_CMP, CMP_CMP,
8821 CMN_CMP, CMP_CMN, CMN_CMN};
215b30b3 8822 int swap =
8823 comparison_dominates_p (GET_CODE (operands[5]),
8824 reverse_condition (GET_CODE (operands[4])));
8825
2ff91fec 8826 output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
8827 if (TARGET_THUMB2) {
8828 output_asm_insn (ite[swap], operands);
8829 }
8830 output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
8831 return \"\";
215b30b3 8832 }"
8fa3ba89 8833 [(set_attr "conds" "set")
2ff91fec 8834 (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
8835 (set_attr_alternative "length"
8836 [(const_int 6)
8837 (const_int 8)
8838 (const_int 8)
8839 (const_int 8)
8840 (const_int 8)
8841 (if_then_else (eq_attr "is_thumb" "no")
8842 (const_int 8)
8843 (const_int 10))
8844 (if_then_else (eq_attr "is_thumb" "no")
8845 (const_int 8)
8846 (const_int 10))
8847 (if_then_else (eq_attr "is_thumb" "no")
8848 (const_int 8)
8849 (const_int 10))
8850 (if_then_else (eq_attr "is_thumb" "no")
8851 (const_int 8)
1b7da4ac 8852 (const_int 10))])
8853 (set_attr "type" "multiple")]
8fa3ba89 8854)
9c08d1fa 8855
f6c53574 8856(define_insn "*cmp_and"
8857 [(set (match_operand 6 "dominant_cc_register" "")
8858 (compare
8859 (and:SI
8860 (match_operator 4 "arm_comparison_operator"
2ff91fec 8861 [(match_operand:SI 0 "s_register_operand"
8862 "l,l,l,r,r,r,r,r,r")
8863 (match_operand:SI 1 "arm_add_operand"
8864 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
f6c53574 8865 (match_operator:SI 5 "arm_comparison_operator"
2ff91fec 8866 [(match_operand:SI 2 "s_register_operand"
8867 "l,r,r,l,l,r,r,r,r")
8868 (match_operand:SI 3 "arm_add_operand"
8869 "lPy,rI,L,lPy,lPy,rI,rI,L,L")]))
f6c53574 8870 (const_int 0)))]
2ff91fec 8871 "TARGET_32BIT"
f6c53574 8872 "*
8873 {
2ff91fec 8874 static const char *const cmp1[NUM_OF_COND_CMP][2] =
f6c53574 8875 {
2ff91fec 8876 {\"cmp%d5\\t%0, %1\",
8877 \"cmp%d4\\t%2, %3\"},
8878 {\"cmn%d5\\t%0, #%n1\",
8879 \"cmp%d4\\t%2, %3\"},
8880 {\"cmp%d5\\t%0, %1\",
8881 \"cmn%d4\\t%2, #%n3\"},
8882 {\"cmn%d5\\t%0, #%n1\",
8883 \"cmn%d4\\t%2, #%n3\"}
f6c53574 8884 };
2ff91fec 8885 static const char *const cmp2[NUM_OF_COND_CMP][2] =
8886 {
8887 {\"cmp\\t%2, %3\",
8888 \"cmp\\t%0, %1\"},
8889 {\"cmp\\t%2, %3\",
8890 \"cmn\\t%0, #%n1\"},
8891 {\"cmn\\t%2, #%n3\",
8892 \"cmp\\t%0, %1\"},
8893 {\"cmn\\t%2, #%n3\",
8894 \"cmn\\t%0, #%n1\"}
8895 };
8896 static const char *const ite[2] =
8897 {
8898 \"it\\t%d5\",
8899 \"it\\t%d4\"
8900 };
8901 static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
8902 CMP_CMP, CMN_CMP, CMP_CMP,
8903 CMN_CMP, CMP_CMN, CMN_CMN};
f6c53574 8904 int swap =
8905 comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4]));
8906
2ff91fec 8907 output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
8908 if (TARGET_THUMB2) {
8909 output_asm_insn (ite[swap], operands);
8910 }
8911 output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
8912 return \"\";
f6c53574 8913 }"
8914 [(set_attr "conds" "set")
8915 (set_attr "predicable" "no")
2ff91fec 8916 (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
8917 (set_attr_alternative "length"
8918 [(const_int 6)
8919 (const_int 8)
8920 (const_int 8)
8921 (const_int 8)
8922 (const_int 8)
8923 (if_then_else (eq_attr "is_thumb" "no")
8924 (const_int 8)
8925 (const_int 10))
8926 (if_then_else (eq_attr "is_thumb" "no")
8927 (const_int 8)
8928 (const_int 10))
8929 (if_then_else (eq_attr "is_thumb" "no")
8930 (const_int 8)
8931 (const_int 10))
8932 (if_then_else (eq_attr "is_thumb" "no")
8933 (const_int 8)
1b7da4ac 8934 (const_int 10))])
8935 (set_attr "type" "multiple")]
f6c53574 8936)
8937
8938(define_insn "*cmp_ior"
8939 [(set (match_operand 6 "dominant_cc_register" "")
8940 (compare
8941 (ior:SI
8942 (match_operator 4 "arm_comparison_operator"
2ff91fec 8943 [(match_operand:SI 0 "s_register_operand"
8944 "l,l,l,r,r,r,r,r,r")
8945 (match_operand:SI 1 "arm_add_operand"
8946 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
f6c53574 8947 (match_operator:SI 5 "arm_comparison_operator"
2ff91fec 8948 [(match_operand:SI 2 "s_register_operand"
8949 "l,r,r,l,l,r,r,r,r")
8950 (match_operand:SI 3 "arm_add_operand"
8951 "lPy,rI,L,lPy,lPy,rI,rI,L,L")]))
f6c53574 8952 (const_int 0)))]
2ff91fec 8953 "TARGET_32BIT"
f6c53574 8954 "*
f6c53574 8955 {
2ff91fec 8956 static const char *const cmp1[NUM_OF_COND_CMP][2] =
8957 {
8958 {\"cmp\\t%0, %1\",
8959 \"cmp\\t%2, %3\"},
8960 {\"cmn\\t%0, #%n1\",
8961 \"cmp\\t%2, %3\"},
8962 {\"cmp\\t%0, %1\",
8963 \"cmn\\t%2, #%n3\"},
8964 {\"cmn\\t%0, #%n1\",
8965 \"cmn\\t%2, #%n3\"}
8966 };
8967 static const char *const cmp2[NUM_OF_COND_CMP][2] =
8968 {
8969 {\"cmp%D4\\t%2, %3\",
8970 \"cmp%D5\\t%0, %1\"},
8971 {\"cmp%D4\\t%2, %3\",
8972 \"cmn%D5\\t%0, #%n1\"},
8973 {\"cmn%D4\\t%2, #%n3\",
8974 \"cmp%D5\\t%0, %1\"},
8975 {\"cmn%D4\\t%2, #%n3\",
8976 \"cmn%D5\\t%0, #%n1\"}
8977 };
8978 static const char *const ite[2] =
8979 {
8980 \"it\\t%D4\",
8981 \"it\\t%D5\"
8982 };
8983 static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
8984 CMP_CMP, CMN_CMP, CMP_CMP,
8985 CMN_CMP, CMP_CMN, CMN_CMN};
8986 int swap =
8987 comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4]));
8988
8989 output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
8990 if (TARGET_THUMB2) {
8991 output_asm_insn (ite[swap], operands);
8992 }
8993 output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
8994 return \"\";
8995 }
8996 "
f6c53574 8997 [(set_attr "conds" "set")
2ff91fec 8998 (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
8999 (set_attr_alternative "length"
9000 [(const_int 6)
9001 (const_int 8)
9002 (const_int 8)
9003 (const_int 8)
9004 (const_int 8)
9005 (if_then_else (eq_attr "is_thumb" "no")
9006 (const_int 8)
9007 (const_int 10))
9008 (if_then_else (eq_attr "is_thumb" "no")
9009 (const_int 8)
9010 (const_int 10))
9011 (if_then_else (eq_attr "is_thumb" "no")
9012 (const_int 8)
9013 (const_int 10))
9014 (if_then_else (eq_attr "is_thumb" "no")
9015 (const_int 8)
1b7da4ac 9016 (const_int 10))])
9017 (set_attr "type" "multiple")]
f6c53574 9018)
9019
3c5afce6 9020(define_insn_and_split "*ior_scc_scc"
fd711051 9021 [(set (match_operand:SI 0 "s_register_operand" "=Ts")
3c5afce6 9022 (ior:SI (match_operator:SI 3 "arm_comparison_operator"
9023 [(match_operand:SI 1 "s_register_operand" "r")
9024 (match_operand:SI 2 "arm_add_operand" "rIL")])
9025 (match_operator:SI 6 "arm_comparison_operator"
9026 [(match_operand:SI 4 "s_register_operand" "r")
9027 (match_operand:SI 5 "arm_add_operand" "rIL")])))
9028 (clobber (reg:CC CC_REGNUM))]
2ff91fec 9029 "TARGET_32BIT
3c5afce6 9030 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_OR_Y)
9031 != CCmode)"
9032 "#"
2ff91fec 9033 "TARGET_32BIT && reload_completed"
3c5afce6 9034 [(set (match_dup 7)
9035 (compare
9036 (ior:SI
9037 (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9038 (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9039 (const_int 0)))
9040 (set (match_dup 0) (ne:SI (match_dup 7) (const_int 0)))]
9041 "operands[7]
9042 = gen_rtx_REG (arm_select_dominance_cc_mode (operands[3], operands[6],
9043 DOM_CC_X_OR_Y),
601f584c 9044 CC_REGNUM);"
9045 [(set_attr "conds" "clob")
1b7da4ac 9046 (set_attr "length" "16")
9047 (set_attr "type" "multiple")]
9048)
601f584c 9049
9050; If the above pattern is followed by a CMP insn, then the compare is
9051; redundant, since we can rework the conditional instruction that follows.
9052(define_insn_and_split "*ior_scc_scc_cmp"
9053 [(set (match_operand 0 "dominant_cc_register" "")
9054 (compare (ior:SI (match_operator:SI 3 "arm_comparison_operator"
9055 [(match_operand:SI 1 "s_register_operand" "r")
9056 (match_operand:SI 2 "arm_add_operand" "rIL")])
9057 (match_operator:SI 6 "arm_comparison_operator"
9058 [(match_operand:SI 4 "s_register_operand" "r")
9059 (match_operand:SI 5 "arm_add_operand" "rIL")]))
9060 (const_int 0)))
fd711051 9061 (set (match_operand:SI 7 "s_register_operand" "=Ts")
601f584c 9062 (ior:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9063 (match_op_dup 6 [(match_dup 4) (match_dup 5)])))]
2ff91fec 9064 "TARGET_32BIT"
601f584c 9065 "#"
2ff91fec 9066 "TARGET_32BIT && reload_completed"
601f584c 9067 [(set (match_dup 0)
9068 (compare
9069 (ior:SI
9070 (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9071 (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9072 (const_int 0)))
9073 (set (match_dup 7) (ne:SI (match_dup 0) (const_int 0)))]
9074 ""
9075 [(set_attr "conds" "set")
1b7da4ac 9076 (set_attr "length" "16")
9077 (set_attr "type" "multiple")]
9078)
3c5afce6 9079
9080(define_insn_and_split "*and_scc_scc"
fd711051 9081 [(set (match_operand:SI 0 "s_register_operand" "=Ts")
3c5afce6 9082 (and:SI (match_operator:SI 3 "arm_comparison_operator"
9083 [(match_operand:SI 1 "s_register_operand" "r")
9084 (match_operand:SI 2 "arm_add_operand" "rIL")])
9085 (match_operator:SI 6 "arm_comparison_operator"
9086 [(match_operand:SI 4 "s_register_operand" "r")
9087 (match_operand:SI 5 "arm_add_operand" "rIL")])))
9088 (clobber (reg:CC CC_REGNUM))]
2ff91fec 9089 "TARGET_32BIT
3c5afce6 9090 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y)
9091 != CCmode)"
9092 "#"
2ff91fec 9093 "TARGET_32BIT && reload_completed
601f584c 9094 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y)
9095 != CCmode)"
3c5afce6 9096 [(set (match_dup 7)
9097 (compare
9098 (and:SI
9099 (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9100 (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9101 (const_int 0)))
9102 (set (match_dup 0) (ne:SI (match_dup 7) (const_int 0)))]
9103 "operands[7]
9104 = gen_rtx_REG (arm_select_dominance_cc_mode (operands[3], operands[6],
9105 DOM_CC_X_AND_Y),
601f584c 9106 CC_REGNUM);"
9107 [(set_attr "conds" "clob")
1b7da4ac 9108 (set_attr "length" "16")
9109 (set_attr "type" "multiple")]
9110)
601f584c 9111
9112; If the above pattern is followed by a CMP insn, then the compare is
9113; redundant, since we can rework the conditional instruction that follows.
9114(define_insn_and_split "*and_scc_scc_cmp"
9115 [(set (match_operand 0 "dominant_cc_register" "")
9116 (compare (and:SI (match_operator:SI 3 "arm_comparison_operator"
9117 [(match_operand:SI 1 "s_register_operand" "r")
9118 (match_operand:SI 2 "arm_add_operand" "rIL")])
9119 (match_operator:SI 6 "arm_comparison_operator"
9120 [(match_operand:SI 4 "s_register_operand" "r")
9121 (match_operand:SI 5 "arm_add_operand" "rIL")]))
9122 (const_int 0)))
fd711051 9123 (set (match_operand:SI 7 "s_register_operand" "=Ts")
601f584c 9124 (and:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9125 (match_op_dup 6 [(match_dup 4) (match_dup 5)])))]
2ff91fec 9126 "TARGET_32BIT"
601f584c 9127 "#"
2ff91fec 9128 "TARGET_32BIT && reload_completed"
601f584c 9129 [(set (match_dup 0)
9130 (compare
9131 (and:SI
9132 (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9133 (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9134 (const_int 0)))
9135 (set (match_dup 7) (ne:SI (match_dup 0) (const_int 0)))]
9136 ""
9137 [(set_attr "conds" "set")
1b7da4ac 9138 (set_attr "length" "16")
9139 (set_attr "type" "multiple")]
9140)
601f584c 9141
9142;; If there is no dominance in the comparison, then we can still save an
9143;; instruction in the AND case, since we can know that the second compare
9144;; need only zero the value if false (if true, then the value is already
9145;; correct).
9146(define_insn_and_split "*and_scc_scc_nodom"
fd711051 9147 [(set (match_operand:SI 0 "s_register_operand" "=&Ts,&Ts,&Ts")
601f584c 9148 (and:SI (match_operator:SI 3 "arm_comparison_operator"
9149 [(match_operand:SI 1 "s_register_operand" "r,r,0")
9150 (match_operand:SI 2 "arm_add_operand" "rIL,0,rIL")])
9151 (match_operator:SI 6 "arm_comparison_operator"
9152 [(match_operand:SI 4 "s_register_operand" "r,r,r")
9153 (match_operand:SI 5 "arm_add_operand" "rIL,rIL,rIL")])))
9154 (clobber (reg:CC CC_REGNUM))]
2ff91fec 9155 "TARGET_32BIT
601f584c 9156 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y)
9157 == CCmode)"
9158 "#"
2ff91fec 9159 "TARGET_32BIT && reload_completed"
601f584c 9160 [(parallel [(set (match_dup 0)
9161 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
9162 (clobber (reg:CC CC_REGNUM))])
9163 (set (match_dup 7) (match_op_dup 8 [(match_dup 4) (match_dup 5)]))
9164 (set (match_dup 0)
9165 (if_then_else:SI (match_op_dup 6 [(match_dup 7) (const_int 0)])
9166 (match_dup 0)
9167 (const_int 0)))]
9168 "operands[7] = gen_rtx_REG (SELECT_CC_MODE (GET_CODE (operands[6]),
9169 operands[4], operands[5]),
9170 CC_REGNUM);
9171 operands[8] = gen_rtx_COMPARE (GET_MODE (operands[7]), operands[4],
9172 operands[5]);"
9173 [(set_attr "conds" "clob")
1b7da4ac 9174 (set_attr "length" "20")
9175 (set_attr "type" "multiple")]
9176)
3c5afce6 9177
3a0bdee0 9178(define_split
9179 [(set (reg:CC_NOOV CC_REGNUM)
9180 (compare:CC_NOOV (ior:SI
9181 (and:SI (match_operand:SI 0 "s_register_operand" "")
9182 (const_int 1))
b0694be0 9183 (match_operator:SI 1 "arm_comparison_operator"
3a0bdee0 9184 [(match_operand:SI 2 "s_register_operand" "")
9185 (match_operand:SI 3 "arm_add_operand" "")]))
9186 (const_int 0)))
9187 (clobber (match_operand:SI 4 "s_register_operand" ""))]
9188 "TARGET_ARM"
9189 [(set (match_dup 4)
9190 (ior:SI (match_op_dup 1 [(match_dup 2) (match_dup 3)])
9191 (match_dup 0)))
9192 (set (reg:CC_NOOV CC_REGNUM)
9193 (compare:CC_NOOV (and:SI (match_dup 4) (const_int 1))
9194 (const_int 0)))]
9195 "")
9196
9197(define_split
9198 [(set (reg:CC_NOOV CC_REGNUM)
9199 (compare:CC_NOOV (ior:SI
b0694be0 9200 (match_operator:SI 1 "arm_comparison_operator"
3a0bdee0 9201 [(match_operand:SI 2 "s_register_operand" "")
9202 (match_operand:SI 3 "arm_add_operand" "")])
9203 (and:SI (match_operand:SI 0 "s_register_operand" "")
9204 (const_int 1)))
9205 (const_int 0)))
9206 (clobber (match_operand:SI 4 "s_register_operand" ""))]
9207 "TARGET_ARM"
9208 [(set (match_dup 4)
9209 (ior:SI (match_op_dup 1 [(match_dup 2) (match_dup 3)])
9210 (match_dup 0)))
9211 (set (reg:CC_NOOV CC_REGNUM)
9212 (compare:CC_NOOV (and:SI (match_dup 4) (const_int 1))
9213 (const_int 0)))]
9214 "")
25f905c2 9215;; ??? The conditional patterns above need checking for Thumb-2 usefulness
3a0bdee0 9216
190efb17 9217(define_insn_and_split "*negscc"
9c08d1fa 9218 [(set (match_operand:SI 0 "s_register_operand" "=r")
8fa3ba89 9219 (neg:SI (match_operator 3 "arm_comparison_operator"
9c08d1fa 9220 [(match_operand:SI 1 "s_register_operand" "r")
9221 (match_operand:SI 2 "arm_rhs_operand" "rI")])))
bd5b4116 9222 (clobber (reg:CC CC_REGNUM))]
cffb2a26 9223 "TARGET_ARM"
190efb17 9224 "#"
9225 "&& reload_completed"
9226 [(const_int 0)]
9227 {
9228 rtx cc_reg = gen_rtx_REG (CCmode, CC_REGNUM);
e2348bcb 9229
190efb17 9230 if (GET_CODE (operands[3]) == LT && operands[2] == const0_rtx)
9231 {
9232 /* Emit mov\\t%0, %1, asr #31 */
9233 emit_insn (gen_rtx_SET (VOIDmode,
9234 operands[0],
9235 gen_rtx_ASHIFTRT (SImode,
9236 operands[1],
9237 GEN_INT (31))));
9238 DONE;
9239 }
9240 else if (GET_CODE (operands[3]) == NE)
9241 {
9242 /* Emit subs\\t%0, %1, %2\;mvnne\\t%0, #0 */
9243 if (CONST_INT_P (operands[2]))
9244 emit_insn (gen_cmpsi2_addneg (operands[0], operands[1], operands[2],
9245 GEN_INT (- INTVAL (operands[2]))));
9246 else
9247 emit_insn (gen_subsi3_compare (operands[0], operands[1], operands[2]));
9248
9249 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
9250 gen_rtx_NE (SImode,
9251 cc_reg,
9252 const0_rtx),
9253 gen_rtx_SET (SImode,
9254 operands[0],
9255 GEN_INT (~0))));
9256 DONE;
9257 }
9258 else
9259 {
9260 /* Emit: cmp\\t%1, %2\;mov%D3\\t%0, #0\;mvn%d3\\t%0, #0 */
9261 emit_insn (gen_rtx_SET (VOIDmode,
9262 cc_reg,
9263 gen_rtx_COMPARE (CCmode, operands[1], operands[2])));
9264 enum rtx_code rc = GET_CODE (operands[3]);
9265
9266 rc = reverse_condition (rc);
9267 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
9268 gen_rtx_fmt_ee (rc,
9269 VOIDmode,
9270 cc_reg,
9271 const0_rtx),
9272 gen_rtx_SET (VOIDmode, operands[0], const0_rtx)));
9273 rc = GET_CODE (operands[3]);
9274 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
9275 gen_rtx_fmt_ee (rc,
9276 VOIDmode,
9277 cc_reg,
9278 const0_rtx),
9279 gen_rtx_SET (VOIDmode,
9280 operands[0],
9281 GEN_INT (~0))));
9282 DONE;
9283 }
9284 FAIL;
9285 }
8fa3ba89 9286 [(set_attr "conds" "clob")
1b7da4ac 9287 (set_attr "length" "12")
9288 (set_attr "type" "multiple")]
8fa3ba89 9289)
9c08d1fa 9290
90404b57 9291(define_insn_and_split "movcond_addsi"
9292 [(set (match_operand:SI 0 "s_register_operand" "=r,l,r")
9293 (if_then_else:SI
9294 (match_operator 5 "comparison_operator"
9295 [(plus:SI (match_operand:SI 3 "s_register_operand" "r,r,r")
9296 (match_operand:SI 4 "arm_add_operand" "rIL,rIL,rIL"))
9297 (const_int 0)])
9298 (match_operand:SI 1 "arm_rhs_operand" "rI,rPy,r")
9299 (match_operand:SI 2 "arm_rhs_operand" "rI,rPy,r")))
9300 (clobber (reg:CC CC_REGNUM))]
9301 "TARGET_32BIT"
9302 "#"
9303 "&& reload_completed"
9304 [(set (reg:CC_NOOV CC_REGNUM)
9305 (compare:CC_NOOV
9306 (plus:SI (match_dup 3)
9307 (match_dup 4))
9308 (const_int 0)))
9309 (set (match_dup 0) (match_dup 1))
9310 (cond_exec (match_dup 6)
9311 (set (match_dup 0) (match_dup 2)))]
9312 "
9313 {
9314 enum machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[5]),
9315 operands[3], operands[4]);
9316 enum rtx_code rc = GET_CODE (operands[5]);
9317
9318 operands[6] = gen_rtx_REG (mode, CC_REGNUM);
9319 gcc_assert (!(mode == CCFPmode || mode == CCFPEmode));
9320 rc = reverse_condition (rc);
9321
9322 operands[6] = gen_rtx_fmt_ee (rc, VOIDmode, operands[6], const0_rtx);
9323 }
9324 "
9325 [(set_attr "conds" "clob")
1b7da4ac 9326 (set_attr "enabled_for_depr_it" "no,yes,yes")
9327 (set_attr "type" "multiple")]
90404b57 9328)
9329
9c08d1fa 9330(define_insn "movcond"
9331 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
5565501b 9332 (if_then_else:SI
8fa3ba89 9333 (match_operator 5 "arm_comparison_operator"
5565501b 9334 [(match_operand:SI 3 "s_register_operand" "r,r,r")
9335 (match_operand:SI 4 "arm_add_operand" "rIL,rIL,rIL")])
9336 (match_operand:SI 1 "arm_rhs_operand" "0,rI,?rI")
9337 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
bd5b4116 9338 (clobber (reg:CC CC_REGNUM))]
cffb2a26 9339 "TARGET_ARM"
9c08d1fa 9340 "*
9341 if (GET_CODE (operands[5]) == LT
9342 && (operands[4] == const0_rtx))
9343 {
0438d37f 9344 if (which_alternative != 1 && REG_P (operands[1]))
9c08d1fa 9345 {
9c08d1fa 9346 if (operands[2] == const0_rtx)
e2348bcb 9347 return \"and\\t%0, %1, %3, asr #31\";
9348 return \"ands\\t%0, %1, %3, asr #32\;movcc\\t%0, %2\";
9c08d1fa 9349 }
0438d37f 9350 else if (which_alternative != 0 && REG_P (operands[2]))
9c08d1fa 9351 {
9c08d1fa 9352 if (operands[1] == const0_rtx)
e2348bcb 9353 return \"bic\\t%0, %2, %3, asr #31\";
9354 return \"bics\\t%0, %2, %3, asr #32\;movcs\\t%0, %1\";
9c08d1fa 9355 }
9356 /* The only case that falls through to here is when both ops 1 & 2
674a8f0b 9357 are constants. */
9c08d1fa 9358 }
e2348bcb 9359
9c08d1fa 9360 if (GET_CODE (operands[5]) == GE
9361 && (operands[4] == const0_rtx))
9362 {
0438d37f 9363 if (which_alternative != 1 && REG_P (operands[1]))
9c08d1fa 9364 {
9c08d1fa 9365 if (operands[2] == const0_rtx)
e2348bcb 9366 return \"bic\\t%0, %1, %3, asr #31\";
9367 return \"bics\\t%0, %1, %3, asr #32\;movcs\\t%0, %2\";
9c08d1fa 9368 }
0438d37f 9369 else if (which_alternative != 0 && REG_P (operands[2]))
9c08d1fa 9370 {
9c08d1fa 9371 if (operands[1] == const0_rtx)
e2348bcb 9372 return \"and\\t%0, %2, %3, asr #31\";
9373 return \"ands\\t%0, %2, %3, asr #32\;movcc\\t%0, %1\";
9c08d1fa 9374 }
9375 /* The only case that falls through to here is when both ops 1 & 2
674a8f0b 9376 are constants. */
9c08d1fa 9377 }
0438d37f 9378 if (CONST_INT_P (operands[4])
9c08d1fa 9379 && !const_ok_for_arm (INTVAL (operands[4])))
e2348bcb 9380 output_asm_insn (\"cmn\\t%3, #%n4\", operands);
9c08d1fa 9381 else
e2348bcb 9382 output_asm_insn (\"cmp\\t%3, %4\", operands);
9c08d1fa 9383 if (which_alternative != 0)
e2348bcb 9384 output_asm_insn (\"mov%d5\\t%0, %1\", operands);
9c08d1fa 9385 if (which_alternative != 1)
e2348bcb 9386 output_asm_insn (\"mov%D5\\t%0, %2\", operands);
9c08d1fa 9387 return \"\";
215b30b3 9388 "
8fa3ba89 9389 [(set_attr "conds" "clob")
1b7da4ac 9390 (set_attr "length" "8,8,12")
9391 (set_attr "type" "multiple")]
8fa3ba89 9392)
9c08d1fa 9393
25f905c2 9394;; ??? The patterns below need checking for Thumb-2 usefulness.
9395
8a18b90c 9396(define_insn "*ifcompare_plus_move"
9397 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8fa3ba89 9398 (if_then_else:SI (match_operator 6 "arm_comparison_operator"
8a18b90c 9399 [(match_operand:SI 4 "s_register_operand" "r,r")
9400 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
9401 (plus:SI
9402 (match_operand:SI 2 "s_register_operand" "r,r")
9403 (match_operand:SI 3 "arm_add_operand" "rIL,rIL"))
129a2fe4 9404 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))
bd5b4116 9405 (clobber (reg:CC CC_REGNUM))]
cffb2a26 9406 "TARGET_ARM"
8a18b90c 9407 "#"
8fa3ba89 9408 [(set_attr "conds" "clob")
1b7da4ac 9409 (set_attr "length" "8,12")
9410 (set_attr "type" "multiple")]
8fa3ba89 9411)
8a18b90c 9412
9413(define_insn "*if_plus_move"
129a2fe4 9414 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r")
8a18b90c 9415 (if_then_else:SI
8fa3ba89 9416 (match_operator 4 "arm_comparison_operator"
8a18b90c 9417 [(match_operand 5 "cc_register" "") (const_int 0)])
9418 (plus:SI
129a2fe4 9419 (match_operand:SI 2 "s_register_operand" "r,r,r,r")
9420 (match_operand:SI 3 "arm_add_operand" "rI,L,rI,L"))
9421 (match_operand:SI 1 "arm_rhs_operand" "0,0,?rI,?rI")))]
cffb2a26 9422 "TARGET_ARM"
8a18b90c 9423 "@
9424 add%d4\\t%0, %2, %3
9425 sub%d4\\t%0, %2, #%n3
9426 add%d4\\t%0, %2, %3\;mov%D4\\t%0, %1
129a2fe4 9427 sub%d4\\t%0, %2, #%n3\;mov%D4\\t%0, %1"
8fa3ba89 9428 [(set_attr "conds" "use")
9429 (set_attr "length" "4,4,8,8")
65f68e55 9430 (set_attr_alternative "type"
9431 [(if_then_else (match_operand 3 "const_int_operand" "")
d82e788e 9432 (const_string "alu_imm" )
112eda6f 9433 (const_string "alu_sreg"))
d82e788e 9434 (const_string "alu_imm")
112eda6f 9435 (const_string "alu_sreg")
9436 (const_string "alu_sreg")])]
8fa3ba89 9437)
8a18b90c 9438
9439(define_insn "*ifcompare_move_plus"
5565501b 9440 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8fa3ba89 9441 (if_then_else:SI (match_operator 6 "arm_comparison_operator"
8a18b90c 9442 [(match_operand:SI 4 "s_register_operand" "r,r")
9443 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
129a2fe4 9444 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
8a18b90c 9445 (plus:SI
9446 (match_operand:SI 2 "s_register_operand" "r,r")
9447 (match_operand:SI 3 "arm_add_operand" "rIL,rIL"))))
bd5b4116 9448 (clobber (reg:CC CC_REGNUM))]
cffb2a26 9449 "TARGET_ARM"
8a18b90c 9450 "#"
8fa3ba89 9451 [(set_attr "conds" "clob")
1b7da4ac 9452 (set_attr "length" "8,12")
9453 (set_attr "type" "multiple")]
8fa3ba89 9454)
8a18b90c 9455
9456(define_insn "*if_move_plus"
129a2fe4 9457 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r")
8a18b90c 9458 (if_then_else:SI
8fa3ba89 9459 (match_operator 4 "arm_comparison_operator"
8a18b90c 9460 [(match_operand 5 "cc_register" "") (const_int 0)])
129a2fe4 9461 (match_operand:SI 1 "arm_rhs_operand" "0,0,?rI,?rI")
8a18b90c 9462 (plus:SI
129a2fe4 9463 (match_operand:SI 2 "s_register_operand" "r,r,r,r")
9464 (match_operand:SI 3 "arm_add_operand" "rI,L,rI,L"))))]
cffb2a26 9465 "TARGET_ARM"
8a18b90c 9466 "@
9467 add%D4\\t%0, %2, %3
9468 sub%D4\\t%0, %2, #%n3
9469 add%D4\\t%0, %2, %3\;mov%d4\\t%0, %1
129a2fe4 9470 sub%D4\\t%0, %2, #%n3\;mov%d4\\t%0, %1"
8fa3ba89 9471 [(set_attr "conds" "use")
9472 (set_attr "length" "4,4,8,8")
112eda6f 9473 (set_attr "type" "alu_sreg,alu_imm,multiple,multiple")]
8fa3ba89 9474)
8a18b90c 9475
9476(define_insn "*ifcompare_arith_arith"
9477 [(set (match_operand:SI 0 "s_register_operand" "=r")
8fa3ba89 9478 (if_then_else:SI (match_operator 9 "arm_comparison_operator"
8a18b90c 9479 [(match_operand:SI 5 "s_register_operand" "r")
9480 (match_operand:SI 6 "arm_add_operand" "rIL")])
9c08d1fa 9481 (match_operator:SI 8 "shiftable_operator"
8a18b90c 9482 [(match_operand:SI 1 "s_register_operand" "r")
9483 (match_operand:SI 2 "arm_rhs_operand" "rI")])
9c08d1fa 9484 (match_operator:SI 7 "shiftable_operator"
8a18b90c 9485 [(match_operand:SI 3 "s_register_operand" "r")
9486 (match_operand:SI 4 "arm_rhs_operand" "rI")])))
bd5b4116 9487 (clobber (reg:CC CC_REGNUM))]
cffb2a26 9488 "TARGET_ARM"
8a18b90c 9489 "#"
8fa3ba89 9490 [(set_attr "conds" "clob")
1b7da4ac 9491 (set_attr "length" "12")
9492 (set_attr "type" "multiple")]
8fa3ba89 9493)
9c08d1fa 9494
8a18b90c 9495(define_insn "*if_arith_arith"
9496 [(set (match_operand:SI 0 "s_register_operand" "=r")
8fa3ba89 9497 (if_then_else:SI (match_operator 5 "arm_comparison_operator"
8a18b90c 9498 [(match_operand 8 "cc_register" "") (const_int 0)])
9499 (match_operator:SI 6 "shiftable_operator"
9500 [(match_operand:SI 1 "s_register_operand" "r")
9501 (match_operand:SI 2 "arm_rhs_operand" "rI")])
9502 (match_operator:SI 7 "shiftable_operator"
9503 [(match_operand:SI 3 "s_register_operand" "r")
9504 (match_operand:SI 4 "arm_rhs_operand" "rI")])))]
cffb2a26 9505 "TARGET_ARM"
8a18b90c 9506 "%I6%d5\\t%0, %1, %2\;%I7%D5\\t%0, %3, %4"
8fa3ba89 9507 [(set_attr "conds" "use")
1b7da4ac 9508 (set_attr "length" "8")
9509 (set_attr "type" "multiple")]
8fa3ba89 9510)
8a18b90c 9511
f7fbdd4a 9512(define_insn "*ifcompare_arith_move"
9c08d1fa 9513 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8fa3ba89 9514 (if_then_else:SI (match_operator 6 "arm_comparison_operator"
9c08d1fa 9515 [(match_operand:SI 2 "s_register_operand" "r,r")
5565501b 9516 (match_operand:SI 3 "arm_add_operand" "rIL,rIL")])
9c08d1fa 9517 (match_operator:SI 7 "shiftable_operator"
9518 [(match_operand:SI 4 "s_register_operand" "r,r")
9519 (match_operand:SI 5 "arm_rhs_operand" "rI,rI")])
129a2fe4 9520 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))
bd5b4116 9521 (clobber (reg:CC CC_REGNUM))]
cffb2a26 9522 "TARGET_ARM"
9c08d1fa 9523 "*
9c08d1fa 9524 /* If we have an operation where (op x 0) is the identity operation and
01cc3b75 9525 the conditional operator is LT or GE and we are comparing against zero and
674a8f0b 9526 everything is in registers then we can do this in two instructions. */
9c08d1fa 9527 if (operands[3] == const0_rtx
9528 && GET_CODE (operands[7]) != AND
0438d37f 9529 && REG_P (operands[5])
9530 && REG_P (operands[1])
9c08d1fa 9531 && REGNO (operands[1]) == REGNO (operands[4])
9532 && REGNO (operands[4]) != REGNO (operands[0]))
9533 {
9534 if (GET_CODE (operands[6]) == LT)
40dbec34 9535 return \"and\\t%0, %5, %2, asr #31\;%I7\\t%0, %4, %0\";
9c08d1fa 9536 else if (GET_CODE (operands[6]) == GE)
40dbec34 9537 return \"bic\\t%0, %5, %2, asr #31\;%I7\\t%0, %4, %0\";
9c08d1fa 9538 }
0438d37f 9539 if (CONST_INT_P (operands[3])
9c08d1fa 9540 && !const_ok_for_arm (INTVAL (operands[3])))
e2348bcb 9541 output_asm_insn (\"cmn\\t%2, #%n3\", operands);
9c08d1fa 9542 else
e2348bcb 9543 output_asm_insn (\"cmp\\t%2, %3\", operands);
40dbec34 9544 output_asm_insn (\"%I7%d6\\t%0, %4, %5\", operands);
9c08d1fa 9545 if (which_alternative != 0)
129a2fe4 9546 return \"mov%D6\\t%0, %1\";
9c08d1fa 9547 return \"\";
215b30b3 9548 "
8fa3ba89 9549 [(set_attr "conds" "clob")
1b7da4ac 9550 (set_attr "length" "8,12")
9551 (set_attr "type" "multiple")]
8fa3ba89 9552)
9c08d1fa 9553
8a18b90c 9554(define_insn "*if_arith_move"
129a2fe4 9555 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8fa3ba89 9556 (if_then_else:SI (match_operator 4 "arm_comparison_operator"
8a18b90c 9557 [(match_operand 6 "cc_register" "") (const_int 0)])
9558 (match_operator:SI 5 "shiftable_operator"
129a2fe4 9559 [(match_operand:SI 2 "s_register_operand" "r,r")
9560 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
9561 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))]
cffb2a26 9562 "TARGET_ARM"
8a18b90c 9563 "@
9564 %I5%d4\\t%0, %2, %3
129a2fe4 9565 %I5%d4\\t%0, %2, %3\;mov%D4\\t%0, %1"
8fa3ba89 9566 [(set_attr "conds" "use")
9567 (set_attr "length" "4,8")
1b7da4ac 9568 (set_attr "type" "alu_shift_reg,multiple")]
8fa3ba89 9569)
8a18b90c 9570
f7fbdd4a 9571(define_insn "*ifcompare_move_arith"
9c08d1fa 9572 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8fa3ba89 9573 (if_then_else:SI (match_operator 6 "arm_comparison_operator"
9c08d1fa 9574 [(match_operand:SI 4 "s_register_operand" "r,r")
5565501b 9575 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
129a2fe4 9576 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
9c08d1fa 9577 (match_operator:SI 7 "shiftable_operator"
9578 [(match_operand:SI 2 "s_register_operand" "r,r")
9579 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))
bd5b4116 9580 (clobber (reg:CC CC_REGNUM))]
cffb2a26 9581 "TARGET_ARM"
9c08d1fa 9582 "*
9c08d1fa 9583 /* If we have an operation where (op x 0) is the identity operation and
01cc3b75 9584 the conditional operator is LT or GE and we are comparing against zero and
9c08d1fa 9585 everything is in registers then we can do this in two instructions */
9586 if (operands[5] == const0_rtx
9587 && GET_CODE (operands[7]) != AND
0438d37f 9588 && REG_P (operands[3])
9589 && REG_P (operands[1])
9c08d1fa 9590 && REGNO (operands[1]) == REGNO (operands[2])
9591 && REGNO (operands[2]) != REGNO (operands[0]))
9592 {
9593 if (GET_CODE (operands[6]) == GE)
40dbec34 9594 return \"and\\t%0, %3, %4, asr #31\;%I7\\t%0, %2, %0\";
9c08d1fa 9595 else if (GET_CODE (operands[6]) == LT)
40dbec34 9596 return \"bic\\t%0, %3, %4, asr #31\;%I7\\t%0, %2, %0\";
9c08d1fa 9597 }
40dbec34 9598
0438d37f 9599 if (CONST_INT_P (operands[5])
9c08d1fa 9600 && !const_ok_for_arm (INTVAL (operands[5])))
e2348bcb 9601 output_asm_insn (\"cmn\\t%4, #%n5\", operands);
9c08d1fa 9602 else
e2348bcb 9603 output_asm_insn (\"cmp\\t%4, %5\", operands);
40dbec34 9604
9c08d1fa 9605 if (which_alternative != 0)
129a2fe4 9606 output_asm_insn (\"mov%d6\\t%0, %1\", operands);
40dbec34 9607 return \"%I7%D6\\t%0, %2, %3\";
215b30b3 9608 "
8fa3ba89 9609 [(set_attr "conds" "clob")
1b7da4ac 9610 (set_attr "length" "8,12")
9611 (set_attr "type" "multiple")]
8fa3ba89 9612)
9c08d1fa 9613
8a18b90c 9614(define_insn "*if_move_arith"
129a2fe4 9615 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8a18b90c 9616 (if_then_else:SI
8fa3ba89 9617 (match_operator 4 "arm_comparison_operator"
8a18b90c 9618 [(match_operand 6 "cc_register" "") (const_int 0)])
129a2fe4 9619 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
8a18b90c 9620 (match_operator:SI 5 "shiftable_operator"
129a2fe4 9621 [(match_operand:SI 2 "s_register_operand" "r,r")
9622 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))]
cffb2a26 9623 "TARGET_ARM"
8a18b90c 9624 "@
9625 %I5%D4\\t%0, %2, %3
129a2fe4 9626 %I5%D4\\t%0, %2, %3\;mov%d4\\t%0, %1"
8fa3ba89 9627 [(set_attr "conds" "use")
9628 (set_attr "length" "4,8")
1b7da4ac 9629 (set_attr "type" "alu_shift_reg,multiple")]
8fa3ba89 9630)
8a18b90c 9631
9632(define_insn "*ifcompare_move_not"
9c08d1fa 9633 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8a18b90c 9634 (if_then_else:SI
8fa3ba89 9635 (match_operator 5 "arm_comparison_operator"
8a18b90c 9636 [(match_operand:SI 3 "s_register_operand" "r,r")
9637 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
9638 (match_operand:SI 1 "arm_not_operand" "0,?rIK")
9639 (not:SI
9640 (match_operand:SI 2 "s_register_operand" "r,r"))))
bd5b4116 9641 (clobber (reg:CC CC_REGNUM))]
cffb2a26 9642 "TARGET_ARM"
8a18b90c 9643 "#"
8fa3ba89 9644 [(set_attr "conds" "clob")
1b7da4ac 9645 (set_attr "length" "8,12")
9646 (set_attr "type" "multiple")]
8fa3ba89 9647)
9c08d1fa 9648
8a18b90c 9649(define_insn "*if_move_not"
9650 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9651 (if_then_else:SI
8fa3ba89 9652 (match_operator 4 "arm_comparison_operator"
8a18b90c 9653 [(match_operand 3 "cc_register" "") (const_int 0)])
9654 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")
9655 (not:SI (match_operand:SI 2 "s_register_operand" "r,r,r"))))]
cffb2a26 9656 "TARGET_ARM"
8a18b90c 9657 "@
9658 mvn%D4\\t%0, %2
9659 mov%d4\\t%0, %1\;mvn%D4\\t%0, %2
9660 mvn%d4\\t%0, #%B1\;mvn%D4\\t%0, %2"
8fa3ba89 9661 [(set_attr "conds" "use")
1aed5204 9662 (set_attr "type" "mvn_reg")
1b7da4ac 9663 (set_attr "length" "4,8,8")
9664 (set_attr "type" "mvn_reg,multiple,multiple")]
8fa3ba89 9665)
8a18b90c 9666
9667(define_insn "*ifcompare_not_move"
9c08d1fa 9668 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8a18b90c 9669 (if_then_else:SI
8fa3ba89 9670 (match_operator 5 "arm_comparison_operator"
8a18b90c 9671 [(match_operand:SI 3 "s_register_operand" "r,r")
9672 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
9673 (not:SI
9674 (match_operand:SI 2 "s_register_operand" "r,r"))
9675 (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
bd5b4116 9676 (clobber (reg:CC CC_REGNUM))]
cffb2a26 9677 "TARGET_ARM"
8a18b90c 9678 "#"
8fa3ba89 9679 [(set_attr "conds" "clob")
1b7da4ac 9680 (set_attr "length" "8,12")
9681 (set_attr "type" "multiple")]
8fa3ba89 9682)
9c08d1fa 9683
8a18b90c 9684(define_insn "*if_not_move"
9685 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9686 (if_then_else:SI
8fa3ba89 9687 (match_operator 4 "arm_comparison_operator"
8a18b90c 9688 [(match_operand 3 "cc_register" "") (const_int 0)])
9689 (not:SI (match_operand:SI 2 "s_register_operand" "r,r,r"))
9690 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")))]
cffb2a26 9691 "TARGET_ARM"
8a18b90c 9692 "@
9693 mvn%d4\\t%0, %2
9694 mov%D4\\t%0, %1\;mvn%d4\\t%0, %2
9695 mvn%D4\\t%0, #%B1\;mvn%d4\\t%0, %2"
8fa3ba89 9696 [(set_attr "conds" "use")
1b7da4ac 9697 (set_attr "type" "mvn_reg,multiple,multiple")
8fa3ba89 9698 (set_attr "length" "4,8,8")]
9699)
8a18b90c 9700
9701(define_insn "*ifcompare_shift_move"
9c08d1fa 9702 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8a18b90c 9703 (if_then_else:SI
8fa3ba89 9704 (match_operator 6 "arm_comparison_operator"
8a18b90c 9705 [(match_operand:SI 4 "s_register_operand" "r,r")
9706 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
9707 (match_operator:SI 7 "shift_operator"
9708 [(match_operand:SI 2 "s_register_operand" "r,r")
9709 (match_operand:SI 3 "arm_rhs_operand" "rM,rM")])
9710 (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
bd5b4116 9711 (clobber (reg:CC CC_REGNUM))]
cffb2a26 9712 "TARGET_ARM"
9c08d1fa 9713 "#"
8fa3ba89 9714 [(set_attr "conds" "clob")
1b7da4ac 9715 (set_attr "length" "8,12")
9716 (set_attr "type" "multiple")]
8fa3ba89 9717)
9c08d1fa 9718
8a18b90c 9719(define_insn "*if_shift_move"
9720 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9721 (if_then_else:SI
8fa3ba89 9722 (match_operator 5 "arm_comparison_operator"
8a18b90c 9723 [(match_operand 6 "cc_register" "") (const_int 0)])
9724 (match_operator:SI 4 "shift_operator"
9725 [(match_operand:SI 2 "s_register_operand" "r,r,r")
9726 (match_operand:SI 3 "arm_rhs_operand" "rM,rM,rM")])
9727 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")))]
cffb2a26 9728 "TARGET_ARM"
5565501b 9729 "@
8a18b90c 9730 mov%d5\\t%0, %2%S4
9731 mov%D5\\t%0, %1\;mov%d5\\t%0, %2%S4
9732 mvn%D5\\t%0, #%B1\;mov%d5\\t%0, %2%S4"
8fa3ba89 9733 [(set_attr "conds" "use")
331beb1a 9734 (set_attr "shift" "2")
a2cd141b 9735 (set_attr "length" "4,8,8")
1b7da4ac 9736 (set_attr "type" "mov_shift_reg,multiple,multiple")]
8fa3ba89 9737)
5565501b 9738
8a18b90c 9739(define_insn "*ifcompare_move_shift"
9740 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5565501b 9741 (if_then_else:SI
8fa3ba89 9742 (match_operator 6 "arm_comparison_operator"
8a18b90c 9743 [(match_operand:SI 4 "s_register_operand" "r,r")
9744 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
9745 (match_operand:SI 1 "arm_not_operand" "0,?rIK")
5565501b 9746 (match_operator:SI 7 "shift_operator"
8a18b90c 9747 [(match_operand:SI 2 "s_register_operand" "r,r")
9748 (match_operand:SI 3 "arm_rhs_operand" "rM,rM")])))
bd5b4116 9749 (clobber (reg:CC CC_REGNUM))]
cffb2a26 9750 "TARGET_ARM"
8a18b90c 9751 "#"
8fa3ba89 9752 [(set_attr "conds" "clob")
1b7da4ac 9753 (set_attr "length" "8,12")
9754 (set_attr "type" "multiple")]
8fa3ba89 9755)
5565501b 9756
8a18b90c 9757(define_insn "*if_move_shift"
9758 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
5565501b 9759 (if_then_else:SI
8fa3ba89 9760 (match_operator 5 "arm_comparison_operator"
8a18b90c 9761 [(match_operand 6 "cc_register" "") (const_int 0)])
9762 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")
9763 (match_operator:SI 4 "shift_operator"
9764 [(match_operand:SI 2 "s_register_operand" "r,r,r")
9765 (match_operand:SI 3 "arm_rhs_operand" "rM,rM,rM")])))]
cffb2a26 9766 "TARGET_ARM"
5565501b 9767 "@
8a18b90c 9768 mov%D5\\t%0, %2%S4
9769 mov%d5\\t%0, %1\;mov%D5\\t%0, %2%S4
9770 mvn%d5\\t%0, #%B1\;mov%D5\\t%0, %2%S4"
8fa3ba89 9771 [(set_attr "conds" "use")
331beb1a 9772 (set_attr "shift" "2")
a2cd141b 9773 (set_attr "length" "4,8,8")
1b7da4ac 9774 (set_attr "type" "mov_shift_reg,multiple,multiple")]
8fa3ba89 9775)
9c08d1fa 9776
f7fbdd4a 9777(define_insn "*ifcompare_shift_shift"
8a18b90c 9778 [(set (match_operand:SI 0 "s_register_operand" "=r")
5565501b 9779 (if_then_else:SI
8fa3ba89 9780 (match_operator 7 "arm_comparison_operator"
8a18b90c 9781 [(match_operand:SI 5 "s_register_operand" "r")
9782 (match_operand:SI 6 "arm_add_operand" "rIL")])
5565501b 9783 (match_operator:SI 8 "shift_operator"
8a18b90c 9784 [(match_operand:SI 1 "s_register_operand" "r")
9785 (match_operand:SI 2 "arm_rhs_operand" "rM")])
5565501b 9786 (match_operator:SI 9 "shift_operator"
8a18b90c 9787 [(match_operand:SI 3 "s_register_operand" "r")
9788 (match_operand:SI 4 "arm_rhs_operand" "rM")])))
bd5b4116 9789 (clobber (reg:CC CC_REGNUM))]
cffb2a26 9790 "TARGET_ARM"
8a18b90c 9791 "#"
8fa3ba89 9792 [(set_attr "conds" "clob")
1b7da4ac 9793 (set_attr "length" "12")
9794 (set_attr "type" "multiple")]
8fa3ba89 9795)
9c08d1fa 9796
8a18b90c 9797(define_insn "*if_shift_shift"
9798 [(set (match_operand:SI 0 "s_register_operand" "=r")
9799 (if_then_else:SI
8fa3ba89 9800 (match_operator 5 "arm_comparison_operator"
8a18b90c 9801 [(match_operand 8 "cc_register" "") (const_int 0)])
9802 (match_operator:SI 6 "shift_operator"
9803 [(match_operand:SI 1 "s_register_operand" "r")
9804 (match_operand:SI 2 "arm_rhs_operand" "rM")])
9805 (match_operator:SI 7 "shift_operator"
9806 [(match_operand:SI 3 "s_register_operand" "r")
9807 (match_operand:SI 4 "arm_rhs_operand" "rM")])))]
cffb2a26 9808 "TARGET_ARM"
8a18b90c 9809 "mov%d5\\t%0, %1%S6\;mov%D5\\t%0, %3%S7"
8fa3ba89 9810 [(set_attr "conds" "use")
331beb1a 9811 (set_attr "shift" "1")
a2cd141b 9812 (set_attr "length" "8")
9813 (set (attr "type") (if_then_else
9814 (and (match_operand 2 "const_int_operand" "")
9815 (match_operand 4 "const_int_operand" ""))
1aed5204 9816 (const_string "mov_shift")
9817 (const_string "mov_shift_reg")))]
8fa3ba89 9818)
8a18b90c 9819
f7fbdd4a 9820(define_insn "*ifcompare_not_arith"
8a18b90c 9821 [(set (match_operand:SI 0 "s_register_operand" "=r")
5565501b 9822 (if_then_else:SI
8fa3ba89 9823 (match_operator 6 "arm_comparison_operator"
8a18b90c 9824 [(match_operand:SI 4 "s_register_operand" "r")
9825 (match_operand:SI 5 "arm_add_operand" "rIL")])
9826 (not:SI (match_operand:SI 1 "s_register_operand" "r"))
5565501b 9827 (match_operator:SI 7 "shiftable_operator"
8a18b90c 9828 [(match_operand:SI 2 "s_register_operand" "r")
9829 (match_operand:SI 3 "arm_rhs_operand" "rI")])))
bd5b4116 9830 (clobber (reg:CC CC_REGNUM))]
cffb2a26 9831 "TARGET_ARM"
8a18b90c 9832 "#"
8fa3ba89 9833 [(set_attr "conds" "clob")
1b7da4ac 9834 (set_attr "length" "12")
9835 (set_attr "type" "multiple")]
8fa3ba89 9836)
9c08d1fa 9837
8a18b90c 9838(define_insn "*if_not_arith"
9839 [(set (match_operand:SI 0 "s_register_operand" "=r")
9840 (if_then_else:SI
8fa3ba89 9841 (match_operator 5 "arm_comparison_operator"
8a18b90c 9842 [(match_operand 4 "cc_register" "") (const_int 0)])
9843 (not:SI (match_operand:SI 1 "s_register_operand" "r"))
9844 (match_operator:SI 6 "shiftable_operator"
9845 [(match_operand:SI 2 "s_register_operand" "r")
9846 (match_operand:SI 3 "arm_rhs_operand" "rI")])))]
cffb2a26 9847 "TARGET_ARM"
8a18b90c 9848 "mvn%d5\\t%0, %1\;%I6%D5\\t%0, %2, %3"
8fa3ba89 9849 [(set_attr "conds" "use")
1aed5204 9850 (set_attr "type" "mvn_reg")
8fa3ba89 9851 (set_attr "length" "8")]
9852)
8a18b90c 9853
9854(define_insn "*ifcompare_arith_not"
9855 [(set (match_operand:SI 0 "s_register_operand" "=r")
5565501b 9856 (if_then_else:SI
8fa3ba89 9857 (match_operator 6 "arm_comparison_operator"
8a18b90c 9858 [(match_operand:SI 4 "s_register_operand" "r")
9859 (match_operand:SI 5 "arm_add_operand" "rIL")])
5565501b 9860 (match_operator:SI 7 "shiftable_operator"
8a18b90c 9861 [(match_operand:SI 2 "s_register_operand" "r")
9862 (match_operand:SI 3 "arm_rhs_operand" "rI")])
9863 (not:SI (match_operand:SI 1 "s_register_operand" "r"))))
bd5b4116 9864 (clobber (reg:CC CC_REGNUM))]
cffb2a26 9865 "TARGET_ARM"
8a18b90c 9866 "#"
8fa3ba89 9867 [(set_attr "conds" "clob")
1b7da4ac 9868 (set_attr "length" "12")
9869 (set_attr "type" "multiple")]
8fa3ba89 9870)
9c08d1fa 9871
8a18b90c 9872(define_insn "*if_arith_not"
9873 [(set (match_operand:SI 0 "s_register_operand" "=r")
9874 (if_then_else:SI
8fa3ba89 9875 (match_operator 5 "arm_comparison_operator"
8a18b90c 9876 [(match_operand 4 "cc_register" "") (const_int 0)])
9877 (match_operator:SI 6 "shiftable_operator"
9878 [(match_operand:SI 2 "s_register_operand" "r")
9879 (match_operand:SI 3 "arm_rhs_operand" "rI")])
9880 (not:SI (match_operand:SI 1 "s_register_operand" "r"))))]
cffb2a26 9881 "TARGET_ARM"
8a18b90c 9882 "mvn%D5\\t%0, %1\;%I6%d5\\t%0, %2, %3"
8fa3ba89 9883 [(set_attr "conds" "use")
1b7da4ac 9884 (set_attr "type" "multiple")
8fa3ba89 9885 (set_attr "length" "8")]
9886)
8a18b90c 9887
f7fbdd4a 9888(define_insn "*ifcompare_neg_move"
8a18b90c 9889 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5565501b 9890 (if_then_else:SI
8fa3ba89 9891 (match_operator 5 "arm_comparison_operator"
8a18b90c 9892 [(match_operand:SI 3 "s_register_operand" "r,r")
9893 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
9894 (neg:SI (match_operand:SI 2 "s_register_operand" "r,r"))
9895 (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
bd5b4116 9896 (clobber (reg:CC CC_REGNUM))]
cffb2a26 9897 "TARGET_ARM"
8a18b90c 9898 "#"
8fa3ba89 9899 [(set_attr "conds" "clob")
1b7da4ac 9900 (set_attr "length" "8,12")
9901 (set_attr "type" "multiple")]
8fa3ba89 9902)
8a18b90c 9903
9904(define_insn "*if_neg_move"
9905 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9906 (if_then_else:SI
8fa3ba89 9907 (match_operator 4 "arm_comparison_operator"
8a18b90c 9908 [(match_operand 3 "cc_register" "") (const_int 0)])
9909 (neg:SI (match_operand:SI 2 "s_register_operand" "r,r,r"))
9910 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")))]
cffb2a26 9911 "TARGET_ARM"
8a18b90c 9912 "@
9913 rsb%d4\\t%0, %2, #0
9914 mov%D4\\t%0, %1\;rsb%d4\\t%0, %2, #0
9915 mvn%D4\\t%0, #%B1\;rsb%d4\\t%0, %2, #0"
8fa3ba89 9916 [(set_attr "conds" "use")
1b7da4ac 9917 (set_attr "length" "4,8,8")
9918 (set_attr "type" "logic_shift_imm,multiple,multiple")]
8fa3ba89 9919)
9c08d1fa 9920
f7fbdd4a 9921(define_insn "*ifcompare_move_neg"
8a18b90c 9922 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5565501b 9923 (if_then_else:SI
8fa3ba89 9924 (match_operator 5 "arm_comparison_operator"
8a18b90c 9925 [(match_operand:SI 3 "s_register_operand" "r,r")
9926 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
9927 (match_operand:SI 1 "arm_not_operand" "0,?rIK")
9928 (neg:SI (match_operand:SI 2 "s_register_operand" "r,r"))))
bd5b4116 9929 (clobber (reg:CC CC_REGNUM))]
cffb2a26 9930 "TARGET_ARM"
8a18b90c 9931 "#"
8fa3ba89 9932 [(set_attr "conds" "clob")
1b7da4ac 9933 (set_attr "length" "8,12")
9934 (set_attr "type" "multiple")]
8fa3ba89 9935)
8a18b90c 9936
9937(define_insn "*if_move_neg"
9938 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9939 (if_then_else:SI
8fa3ba89 9940 (match_operator 4 "arm_comparison_operator"
8a18b90c 9941 [(match_operand 3 "cc_register" "") (const_int 0)])
9942 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")
9943 (neg:SI (match_operand:SI 2 "s_register_operand" "r,r,r"))))]
cffb2a26 9944 "TARGET_ARM"
8a18b90c 9945 "@
9946 rsb%D4\\t%0, %2, #0
9947 mov%d4\\t%0, %1\;rsb%D4\\t%0, %2, #0
9948 mvn%d4\\t%0, #%B1\;rsb%D4\\t%0, %2, #0"
0d66636f 9949 [(set_attr "conds" "use")
1b7da4ac 9950 (set_attr "length" "4,8,8")
9951 (set_attr "type" "logic_shift_imm,multiple,multiple")]
0d66636f 9952)
9c08d1fa 9953
f7fbdd4a 9954(define_insn "*arith_adjacentmem"
9c08d1fa 9955 [(set (match_operand:SI 0 "s_register_operand" "=r")
9956 (match_operator:SI 1 "shiftable_operator"
9957 [(match_operand:SI 2 "memory_operand" "m")
9958 (match_operand:SI 3 "memory_operand" "m")]))
9959 (clobber (match_scratch:SI 4 "=r"))]
cffb2a26 9960 "TARGET_ARM && adjacent_mem_locations (operands[2], operands[3])"
9c08d1fa 9961 "*
215b30b3 9962 {
9963 rtx ldm[3];
9964 rtx arith[4];
94dee231 9965 rtx base_reg;
9966 HOST_WIDE_INT val1 = 0, val2 = 0;
9c08d1fa 9967
215b30b3 9968 if (REGNO (operands[0]) > REGNO (operands[4]))
9969 {
9970 ldm[1] = operands[4];
9971 ldm[2] = operands[0];
9972 }
9973 else
9974 {
9975 ldm[1] = operands[0];
9976 ldm[2] = operands[4];
9977 }
94dee231 9978
9979 base_reg = XEXP (operands[2], 0);
9980
9981 if (!REG_P (base_reg))
9982 {
9983 val1 = INTVAL (XEXP (base_reg, 1));
9984 base_reg = XEXP (base_reg, 0);
9985 }
9986
9987 if (!REG_P (XEXP (operands[3], 0)))
215b30b3 9988 val2 = INTVAL (XEXP (XEXP (operands[3], 0), 1));
94dee231 9989
215b30b3 9990 arith[0] = operands[0];
9991 arith[3] = operands[1];
94dee231 9992
215b30b3 9993 if (val1 < val2)
9994 {
9995 arith[1] = ldm[1];
9996 arith[2] = ldm[2];
9997 }
9998 else
9999 {
10000 arith[1] = ldm[2];
10001 arith[2] = ldm[1];
10002 }
94dee231 10003
10004 ldm[0] = base_reg;
10005 if (val1 !=0 && val2 != 0)
215b30b3 10006 {
cdb1295a 10007 rtx ops[3];
10008
94dee231 10009 if (val1 == 4 || val2 == 4)
10010 /* Other val must be 8, since we know they are adjacent and neither
10011 is zero. */
25f905c2 10012 output_asm_insn (\"ldm%(ib%)\\t%0, {%1, %2}\", ldm);
cdb1295a 10013 else if (const_ok_for_arm (val1) || const_ok_for_arm (-val1))
94dee231 10014 {
94dee231 10015 ldm[0] = ops[0] = operands[4];
10016 ops[1] = base_reg;
10017 ops[2] = GEN_INT (val1);
10018 output_add_immediate (ops);
10019 if (val1 < val2)
25f905c2 10020 output_asm_insn (\"ldm%(ia%)\\t%0, {%1, %2}\", ldm);
94dee231 10021 else
25f905c2 10022 output_asm_insn (\"ldm%(da%)\\t%0, {%1, %2}\", ldm);
94dee231 10023 }
cdb1295a 10024 else
10025 {
10026 /* Offset is out of range for a single add, so use two ldr. */
10027 ops[0] = ldm[1];
10028 ops[1] = base_reg;
10029 ops[2] = GEN_INT (val1);
10030 output_asm_insn (\"ldr%?\\t%0, [%1, %2]\", ops);
10031 ops[0] = ldm[2];
10032 ops[2] = GEN_INT (val2);
10033 output_asm_insn (\"ldr%?\\t%0, [%1, %2]\", ops);
10034 }
215b30b3 10035 }
94dee231 10036 else if (val1 != 0)
215b30b3 10037 {
215b30b3 10038 if (val1 < val2)
25f905c2 10039 output_asm_insn (\"ldm%(da%)\\t%0, {%1, %2}\", ldm);
215b30b3 10040 else
25f905c2 10041 output_asm_insn (\"ldm%(ia%)\\t%0, {%1, %2}\", ldm);
215b30b3 10042 }
10043 else
10044 {
215b30b3 10045 if (val1 < val2)
25f905c2 10046 output_asm_insn (\"ldm%(ia%)\\t%0, {%1, %2}\", ldm);
215b30b3 10047 else
25f905c2 10048 output_asm_insn (\"ldm%(da%)\\t%0, {%1, %2}\", ldm);
215b30b3 10049 }
10050 output_asm_insn (\"%I3%?\\t%0, %1, %2\", arith);
10051 return \"\";
10052 }"
10053 [(set_attr "length" "12")
10054 (set_attr "predicable" "yes")
a2cd141b 10055 (set_attr "type" "load1")]
215b30b3 10056)
9c08d1fa 10057
9c08d1fa 10058; This pattern is never tried by combine, so do it as a peephole
10059
a0f94409 10060(define_peephole2
372575c7 10061 [(set (match_operand:SI 0 "arm_general_register_operand" "")
10062 (match_operand:SI 1 "arm_general_register_operand" ""))
bd5b4116 10063 (set (reg:CC CC_REGNUM)
aea4c774 10064 (compare:CC (match_dup 1) (const_int 0)))]
372575c7 10065 "TARGET_ARM"
a0f94409 10066 [(parallel [(set (reg:CC CC_REGNUM) (compare:CC (match_dup 1) (const_int 0)))
10067 (set (match_dup 0) (match_dup 1))])]
10068 ""
0d66636f 10069)
9c08d1fa 10070
9c08d1fa 10071(define_split
10072 [(set (match_operand:SI 0 "s_register_operand" "")
10073 (and:SI (ge:SI (match_operand:SI 1 "s_register_operand" "")
10074 (const_int 0))
8fa3ba89 10075 (neg:SI (match_operator:SI 2 "arm_comparison_operator"
9c08d1fa 10076 [(match_operand:SI 3 "s_register_operand" "")
10077 (match_operand:SI 4 "arm_rhs_operand" "")]))))
10078 (clobber (match_operand:SI 5 "s_register_operand" ""))]
cffb2a26 10079 "TARGET_ARM"
9c08d1fa 10080 [(set (match_dup 5) (not:SI (ashiftrt:SI (match_dup 1) (const_int 31))))
10081 (set (match_dup 0) (and:SI (match_op_dup 2 [(match_dup 3) (match_dup 4)])
10082 (match_dup 5)))]
215b30b3 10083 ""
10084)
9c08d1fa 10085
aea4c774 10086;; This split can be used because CC_Z mode implies that the following
10087;; branch will be an equality, or an unsigned inequality, so the sign
10088;; extension is not needed.
9c08d1fa 10089
aea4c774 10090(define_split
bd5b4116 10091 [(set (reg:CC_Z CC_REGNUM)
aea4c774 10092 (compare:CC_Z
10093 (ashift:SI (subreg:SI (match_operand:QI 0 "memory_operand" "") 0)
9c08d1fa 10094 (const_int 24))
aea4c774 10095 (match_operand 1 "const_int_operand" "")))
10096 (clobber (match_scratch:SI 2 ""))]
cffb2a26 10097 "TARGET_ARM
10098 && (((unsigned HOST_WIDE_INT) INTVAL (operands[1]))
10099 == (((unsigned HOST_WIDE_INT) INTVAL (operands[1])) >> 24) << 24)"
aea4c774 10100 [(set (match_dup 2) (zero_extend:SI (match_dup 0)))
bd5b4116 10101 (set (reg:CC CC_REGNUM) (compare:CC (match_dup 2) (match_dup 1)))]
aea4c774 10102 "
9c08d1fa 10103 operands[1] = GEN_INT (((unsigned long) INTVAL (operands[1])) >> 24);
215b30b3 10104 "
10105)
25f905c2 10106;; ??? Check the patterns above for Thumb-2 usefulness
9c08d1fa 10107
87b22bf7 10108(define_expand "prologue"
10109 [(clobber (const_int 0))]
cffb2a26 10110 "TARGET_EITHER"
25f905c2 10111 "if (TARGET_32BIT)
cffb2a26 10112 arm_expand_prologue ();
10113 else
25f905c2 10114 thumb1_expand_prologue ();
87b22bf7 10115 DONE;
cffb2a26 10116 "
10117)
87b22bf7 10118
56d27660 10119(define_expand "epilogue"
4c44712e 10120 [(clobber (const_int 0))]
cffb2a26 10121 "TARGET_EITHER"
56d27660 10122 "
18d50ae6 10123 if (crtl->calls_eh_return)
fb94f18b 10124 emit_insn (gen_force_register_use (gen_rtx_REG (Pmode, 2)));
25f905c2 10125 if (TARGET_THUMB1)
c3635784 10126 {
10127 thumb1_expand_epilogue ();
10128 emit_jump_insn (gen_rtx_UNSPEC_VOLATILE (VOIDmode,
10129 gen_rtvec (1, ret_rtx), VUNSPEC_EPILOGUE));
10130 }
10131 else if (HAVE_return)
10132 {
10133 /* HAVE_return is testing for USE_RETURN_INSN (FALSE). Hence,
10134 no need for explicit testing again. */
10135 emit_jump_insn (gen_return ());
10136 }
10137 else if (TARGET_32BIT)
10138 {
10139 arm_expand_epilogue (true);
10140 }
cffb2a26 10141 DONE;
10142 "
10143)
56d27660 10144
ef5651d0 10145;; Note - although unspec_volatile's USE all hard registers,
10146;; USEs are ignored after relaod has completed. Thus we need
10147;; to add an unspec of the link register to ensure that flow
10148;; does not think that it is unused by the sibcall branch that
10149;; will replace the standard function epilogue.
c3635784 10150(define_expand "sibcall_epilogue"
fb94f18b 10151 [(parallel [(unspec:SI [(reg:SI LR_REGNUM)] UNSPEC_REGISTER_USE)
c3635784 10152 (unspec_volatile [(return)] VUNSPEC_EPILOGUE)])]
10153 "TARGET_32BIT"
10154 "
10155 arm_expand_epilogue (false);
10156 DONE;
10157 "
1c494086 10158)
10159
cffb2a26 10160(define_expand "eh_epilogue"
7db9af5d 10161 [(use (match_operand:SI 0 "register_operand" ""))
10162 (use (match_operand:SI 1 "register_operand" ""))
10163 (use (match_operand:SI 2 "register_operand" ""))]
cffb2a26 10164 "TARGET_EITHER"
10165 "
215b30b3 10166 {
10167 cfun->machine->eh_epilogue_sp_ofs = operands[1];
0438d37f 10168 if (!REG_P (operands[2]) || REGNO (operands[2]) != 2)
215b30b3 10169 {
10170 rtx ra = gen_rtx_REG (Pmode, 2);
10171
10172 emit_move_insn (ra, operands[2]);
10173 operands[2] = ra;
10174 }
5cf3595a 10175 /* This is a hack -- we may have crystalized the function type too
10176 early. */
10177 cfun->machine->func_type = 0;
215b30b3 10178 }"
10179)
56d27660 10180
9c08d1fa 10181;; This split is only used during output to reduce the number of patterns
10182;; that need assembler instructions adding to them. We allowed the setting
10183;; of the conditions to be implicit during rtl generation so that
10184;; the conditional compare patterns would work. However this conflicts to
8a18b90c 10185;; some extent with the conditional data operations, so we have to split them
9c08d1fa 10186;; up again here.
10187
25f905c2 10188;; ??? Need to audit these splitters for Thumb-2. Why isn't normal
10189;; conditional execution sufficient?
10190
9c08d1fa 10191(define_split
10192 [(set (match_operand:SI 0 "s_register_operand" "")
8fa3ba89 10193 (if_then_else:SI (match_operator 1 "arm_comparison_operator"
10194 [(match_operand 2 "" "") (match_operand 3 "" "")])
10195 (match_dup 0)
10196 (match_operand 4 "" "")))
bd5b4116 10197 (clobber (reg:CC CC_REGNUM))]
ac8b093b 10198 "TARGET_ARM && reload_completed"
8fa3ba89 10199 [(set (match_dup 5) (match_dup 6))
10200 (cond_exec (match_dup 7)
10201 (set (match_dup 0) (match_dup 4)))]
10202 "
10203 {
10204 enum machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
10205 operands[2], operands[3]);
10206 enum rtx_code rc = GET_CODE (operands[1]);
10207
bd5b4116 10208 operands[5] = gen_rtx_REG (mode, CC_REGNUM);
8fa3ba89 10209 operands[6] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
10210 if (mode == CCFPmode || mode == CCFPEmode)
10211 rc = reverse_condition_maybe_unordered (rc);
10212 else
10213 rc = reverse_condition (rc);
10214
10215 operands[7] = gen_rtx_fmt_ee (rc, VOIDmode, operands[5], const0_rtx);
10216 }"
10217)
10218
10219(define_split
10220 [(set (match_operand:SI 0 "s_register_operand" "")
10221 (if_then_else:SI (match_operator 1 "arm_comparison_operator"
10222 [(match_operand 2 "" "") (match_operand 3 "" "")])
10223 (match_operand 4 "" "")
10224 (match_dup 0)))
bd5b4116 10225 (clobber (reg:CC CC_REGNUM))]
ac8b093b 10226 "TARGET_ARM && reload_completed"
8fa3ba89 10227 [(set (match_dup 5) (match_dup 6))
10228 (cond_exec (match_op_dup 1 [(match_dup 5) (const_int 0)])
10229 (set (match_dup 0) (match_dup 4)))]
10230 "
10231 {
10232 enum machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
10233 operands[2], operands[3]);
10234
bd5b4116 10235 operands[5] = gen_rtx_REG (mode, CC_REGNUM);
8fa3ba89 10236 operands[6] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
10237 }"
10238)
10239
10240(define_split
10241 [(set (match_operand:SI 0 "s_register_operand" "")
10242 (if_then_else:SI (match_operator 1 "arm_comparison_operator"
9c08d1fa 10243 [(match_operand 2 "" "") (match_operand 3 "" "")])
10244 (match_operand 4 "" "")
10245 (match_operand 5 "" "")))
bd5b4116 10246 (clobber (reg:CC CC_REGNUM))]
ac8b093b 10247 "TARGET_ARM && reload_completed"
8fa3ba89 10248 [(set (match_dup 6) (match_dup 7))
10249 (cond_exec (match_op_dup 1 [(match_dup 6) (const_int 0)])
10250 (set (match_dup 0) (match_dup 4)))
10251 (cond_exec (match_dup 8)
10252 (set (match_dup 0) (match_dup 5)))]
10253 "
10254 {
10255 enum machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
10256 operands[2], operands[3]);
10257 enum rtx_code rc = GET_CODE (operands[1]);
10258
bd5b4116 10259 operands[6] = gen_rtx_REG (mode, CC_REGNUM);
8fa3ba89 10260 operands[7] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
10261 if (mode == CCFPmode || mode == CCFPEmode)
10262 rc = reverse_condition_maybe_unordered (rc);
10263 else
10264 rc = reverse_condition (rc);
10265
10266 operands[8] = gen_rtx_fmt_ee (rc, VOIDmode, operands[6], const0_rtx);
10267 }"
10268)
10269
cffb2a26 10270(define_split
10271 [(set (match_operand:SI 0 "s_register_operand" "")
8fa3ba89 10272 (if_then_else:SI (match_operator 1 "arm_comparison_operator"
cffb2a26 10273 [(match_operand:SI 2 "s_register_operand" "")
10274 (match_operand:SI 3 "arm_add_operand" "")])
10275 (match_operand:SI 4 "arm_rhs_operand" "")
10276 (not:SI
10277 (match_operand:SI 5 "s_register_operand" ""))))
bd5b4116 10278 (clobber (reg:CC CC_REGNUM))]
ac8b093b 10279 "TARGET_ARM && reload_completed"
cffb2a26 10280 [(set (match_dup 6) (match_dup 7))
f6c53574 10281 (cond_exec (match_op_dup 1 [(match_dup 6) (const_int 0)])
10282 (set (match_dup 0) (match_dup 4)))
10283 (cond_exec (match_dup 8)
10284 (set (match_dup 0) (not:SI (match_dup 5))))]
cffb2a26 10285 "
215b30b3 10286 {
10287 enum machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
10288 operands[2], operands[3]);
f6c53574 10289 enum rtx_code rc = GET_CODE (operands[1]);
cffb2a26 10290
bd5b4116 10291 operands[6] = gen_rtx_REG (mode, CC_REGNUM);
1a83b3ff 10292 operands[7] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
f6c53574 10293 if (mode == CCFPmode || mode == CCFPEmode)
10294 rc = reverse_condition_maybe_unordered (rc);
10295 else
10296 rc = reverse_condition (rc);
10297
10298 operands[8] = gen_rtx_fmt_ee (rc, VOIDmode, operands[6], const0_rtx);
215b30b3 10299 }"
10300)
cffb2a26 10301
10302(define_insn "*cond_move_not"
10303 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8fa3ba89 10304 (if_then_else:SI (match_operator 4 "arm_comparison_operator"
cffb2a26 10305 [(match_operand 3 "cc_register" "") (const_int 0)])
10306 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
10307 (not:SI
10308 (match_operand:SI 2 "s_register_operand" "r,r"))))]
10309 "TARGET_ARM"
10310 "@
10311 mvn%D4\\t%0, %2
10312 mov%d4\\t%0, %1\;mvn%D4\\t%0, %2"
0d66636f 10313 [(set_attr "conds" "use")
1b7da4ac 10314 (set_attr "type" "mvn_reg,multiple")
0d66636f 10315 (set_attr "length" "4,8")]
10316)
cffb2a26 10317
9c08d1fa 10318;; The next two patterns occur when an AND operation is followed by a
10319;; scc insn sequence
10320
f7fbdd4a 10321(define_insn "*sign_extract_onebit"
9c08d1fa 10322 [(set (match_operand:SI 0 "s_register_operand" "=r")
10323 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
10324 (const_int 1)
ed750274 10325 (match_operand:SI 2 "const_int_operand" "n")))
10326 (clobber (reg:CC CC_REGNUM))]
cffb2a26 10327 "TARGET_ARM"
9c08d1fa 10328 "*
0d66636f 10329 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
10330 output_asm_insn (\"ands\\t%0, %1, %2\", operands);
10331 return \"mvnne\\t%0, #0\";
10332 "
10333 [(set_attr "conds" "clob")
1b7da4ac 10334 (set_attr "length" "8")
10335 (set_attr "type" "multiple")]
0d66636f 10336)
9c08d1fa 10337
f7fbdd4a 10338(define_insn "*not_signextract_onebit"
9c08d1fa 10339 [(set (match_operand:SI 0 "s_register_operand" "=r")
10340 (not:SI
10341 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
10342 (const_int 1)
ed750274 10343 (match_operand:SI 2 "const_int_operand" "n"))))
10344 (clobber (reg:CC CC_REGNUM))]
cffb2a26 10345 "TARGET_ARM"
9c08d1fa 10346 "*
0d66636f 10347 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
10348 output_asm_insn (\"tst\\t%1, %2\", operands);
10349 output_asm_insn (\"mvneq\\t%0, #0\", operands);
10350 return \"movne\\t%0, #0\";
10351 "
10352 [(set_attr "conds" "clob")
1b7da4ac 10353 (set_attr "length" "12")
10354 (set_attr "type" "multiple")]
0d66636f 10355)
25f905c2 10356;; ??? The above patterns need auditing for Thumb-2
87b22bf7 10357
0d66636f 10358;; Push multiple registers to the stack. Registers are in parallel (use ...)
10359;; expressions. For simplicity, the first register is also in the unspec
10360;; part.
08508cbf 10361;; To avoid the usage of GNU extension, the length attribute is computed
10362;; in a C function arm_attr_length_push_multi.
f7fbdd4a 10363(define_insn "*push_multi"
87b22bf7 10364 [(match_parallel 2 "multi_register_push"
7571d3f7 10365 [(set (match_operand:BLK 0 "push_mult_memory_operand" "")
3cc80a30 10366 (unspec:BLK [(match_operand:SI 1 "s_register_operand" "")]
e1159bbe 10367 UNSPEC_PUSH_MULT))])]
7571d3f7 10368 ""
87b22bf7 10369 "*
215b30b3 10370 {
10371 int num_saves = XVECLEN (operands[2], 0);
ed593f11 10372
215b30b3 10373 /* For the StrongARM at least it is faster to
25f905c2 10374 use STR to store only a single register.
542d5028 10375 In Thumb mode always use push, and the assembler will pick
10376 something appropriate. */
25f905c2 10377 if (num_saves == 1 && TARGET_ARM)
61309563 10378 output_asm_insn (\"str%?\\t%1, [%m0, #-4]!\", operands);
215b30b3 10379 else
10380 {
10381 int i;
10382 char pattern[100];
ed593f11 10383
25f905c2 10384 if (TARGET_ARM)
61309563 10385 strcpy (pattern, \"stm%(fd%)\\t%m0!, {%1\");
10386 else if (TARGET_THUMB2)
10387 strcpy (pattern, \"push%?\\t{%1\");
25f905c2 10388 else
10389 strcpy (pattern, \"push\\t{%1\");
215b30b3 10390
6079f055 10391 for (i = 1; i < num_saves; i++)
215b30b3 10392 {
10393 strcat (pattern, \", %|\");
10394 strcat (pattern,
10395 reg_names[REGNO (XEXP (XVECEXP (operands[2], 0, i), 0))]);
10396 }
10397
10398 strcat (pattern, \"}\");
10399 output_asm_insn (pattern, operands);
10400 }
10401
10402 return \"\";
10403 }"
a6864a24 10404 [(set_attr "type" "store4")
10405 (set (attr "length")
08508cbf 10406 (symbol_ref "arm_attr_length_push_multi (operands[2], operands[1])"))]
215b30b3 10407)
f7fbdd4a 10408
4c58c898 10409(define_insn "stack_tie"
10410 [(set (mem:BLK (scratch))
aaa37ad6 10411 (unspec:BLK [(match_operand:SI 0 "s_register_operand" "rk")
10412 (match_operand:SI 1 "s_register_operand" "rk")]
4c58c898 10413 UNSPEC_PRLG_STK))]
10414 ""
10415 ""
1b7da4ac 10416 [(set_attr "length" "0")
10417 (set_attr "type" "block")]
4c58c898 10418)
10419
426be8c5 10420;; Pop (as used in epilogue RTL)
10421;;
10422(define_insn "*load_multiple_with_writeback"
10423 [(match_parallel 0 "load_multiple_operation"
10424 [(set (match_operand:SI 1 "s_register_operand" "+rk")
10425 (plus:SI (match_dup 1)
809003b3 10426 (match_operand:SI 2 "const_int_I_operand" "I")))
426be8c5 10427 (set (match_operand:SI 3 "s_register_operand" "=rk")
10428 (mem:SI (match_dup 1)))
10429 ])]
10430 "TARGET_32BIT && (reload_in_progress || reload_completed)"
10431 "*
10432 {
10433 arm_output_multireg_pop (operands, /*return_pc=*/false,
10434 /*cond=*/const_true_rtx,
10435 /*reverse=*/false,
10436 /*update=*/true);
10437 return \"\";
10438 }
10439 "
10440 [(set_attr "type" "load4")
10441 (set_attr "predicable" "yes")]
10442)
10443
10444;; Pop with return (as used in epilogue RTL)
10445;;
10446;; This instruction is generated when the registers are popped at the end of
10447;; epilogue. Here, instead of popping the value into LR and then generating
10448;; jump to LR, value is popped into PC directly. Hence, the pattern is combined
10449;; with (return).
10450(define_insn "*pop_multiple_with_writeback_and_return"
10451 [(match_parallel 0 "pop_multiple_return"
10452 [(return)
10453 (set (match_operand:SI 1 "s_register_operand" "+rk")
10454 (plus:SI (match_dup 1)
809003b3 10455 (match_operand:SI 2 "const_int_I_operand" "I")))
426be8c5 10456 (set (match_operand:SI 3 "s_register_operand" "=rk")
10457 (mem:SI (match_dup 1)))
10458 ])]
10459 "TARGET_32BIT && (reload_in_progress || reload_completed)"
10460 "*
10461 {
10462 arm_output_multireg_pop (operands, /*return_pc=*/true,
10463 /*cond=*/const_true_rtx,
10464 /*reverse=*/false,
10465 /*update=*/true);
10466 return \"\";
10467 }
10468 "
10469 [(set_attr "type" "load4")
10470 (set_attr "predicable" "yes")]
10471)
10472
10473(define_insn "*pop_multiple_with_return"
10474 [(match_parallel 0 "pop_multiple_return"
10475 [(return)
10476 (set (match_operand:SI 2 "s_register_operand" "=rk")
10477 (mem:SI (match_operand:SI 1 "s_register_operand" "rk")))
10478 ])]
10479 "TARGET_32BIT && (reload_in_progress || reload_completed)"
10480 "*
10481 {
10482 arm_output_multireg_pop (operands, /*return_pc=*/true,
10483 /*cond=*/const_true_rtx,
10484 /*reverse=*/false,
10485 /*update=*/false);
10486 return \"\";
10487 }
10488 "
10489 [(set_attr "type" "load4")
10490 (set_attr "predicable" "yes")]
10491)
10492
10493;; Load into PC and return
10494(define_insn "*ldr_with_return"
10495 [(return)
10496 (set (reg:SI PC_REGNUM)
10497 (mem:SI (post_inc:SI (match_operand:SI 0 "s_register_operand" "+rk"))))]
10498 "TARGET_32BIT && (reload_in_progress || reload_completed)"
10499 "ldr%?\t%|pc, [%0], #4"
10500 [(set_attr "type" "load1")
10501 (set_attr "predicable" "yes")]
10502)
1a0b0f12 10503;; Pop for floating point registers (as used in epilogue RTL)
10504(define_insn "*vfp_pop_multiple_with_writeback"
10505 [(match_parallel 0 "pop_multiple_fp"
10506 [(set (match_operand:SI 1 "s_register_operand" "+rk")
10507 (plus:SI (match_dup 1)
809003b3 10508 (match_operand:SI 2 "const_int_I_operand" "I")))
2f2163a4 10509 (set (match_operand:DF 3 "vfp_hard_register_operand" "")
1a0b0f12 10510 (mem:DF (match_dup 1)))])]
10511 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
10512 "*
10513 {
10514 int num_regs = XVECLEN (operands[0], 0);
10515 char pattern[100];
10516 rtx op_list[2];
10517 strcpy (pattern, \"fldmfdd\\t\");
10518 strcat (pattern, reg_names[REGNO (SET_DEST (XVECEXP (operands[0], 0, 0)))]);
10519 strcat (pattern, \"!, {\");
10520 op_list[0] = XEXP (XVECEXP (operands[0], 0, 1), 0);
10521 strcat (pattern, \"%P0\");
10522 if ((num_regs - 1) > 1)
10523 {
10524 strcat (pattern, \"-%P1\");
10525 op_list [1] = XEXP (XVECEXP (operands[0], 0, num_regs - 1), 0);
10526 }
10527
10528 strcat (pattern, \"}\");
10529 output_asm_insn (pattern, op_list);
10530 return \"\";
10531 }
10532 "
10533 [(set_attr "type" "load4")
10534 (set_attr "conds" "unconditional")
10535 (set_attr "predicable" "no")]
10536)
10537
f7fbdd4a 10538;; Special patterns for dealing with the constant pool
10539
cffb2a26 10540(define_insn "align_4"
e1159bbe 10541 [(unspec_volatile [(const_int 0)] VUNSPEC_ALIGN)]
cffb2a26 10542 "TARGET_EITHER"
f7fbdd4a 10543 "*
cffb2a26 10544 assemble_align (32);
f7fbdd4a 10545 return \"\";
cffb2a26 10546 "
1b7da4ac 10547 [(set_attr "type" "no_insn")]
cffb2a26 10548)
f7fbdd4a 10549
755eb2b4 10550(define_insn "align_8"
10551 [(unspec_volatile [(const_int 0)] VUNSPEC_ALIGN8)]
f9273c43 10552 "TARGET_EITHER"
755eb2b4 10553 "*
10554 assemble_align (64);
10555 return \"\";
10556 "
1b7da4ac 10557 [(set_attr "type" "no_insn")]
755eb2b4 10558)
10559
cffb2a26 10560(define_insn "consttable_end"
e1159bbe 10561 [(unspec_volatile [(const_int 0)] VUNSPEC_POOL_END)]
cffb2a26 10562 "TARGET_EITHER"
f7fbdd4a 10563 "*
cffb2a26 10564 making_const_table = FALSE;
f7fbdd4a 10565 return \"\";
cffb2a26 10566 "
1b7da4ac 10567 [(set_attr "type" "no_insn")]
cffb2a26 10568)
f7fbdd4a 10569
cffb2a26 10570(define_insn "consttable_4"
e1159bbe 10571 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_4)]
cffb2a26 10572 "TARGET_EITHER"
10573 "*
10574 {
9b8516be 10575 rtx x = operands[0];
cffb2a26 10576 making_const_table = TRUE;
9b8516be 10577 switch (GET_MODE_CLASS (GET_MODE (x)))
cffb2a26 10578 {
10579 case MODE_FLOAT:
9b8516be 10580 if (GET_MODE (x) == HFmode)
10581 arm_emit_fp16_const (x);
10582 else
10583 {
10584 REAL_VALUE_TYPE r;
10585 REAL_VALUE_FROM_CONST_DOUBLE (r, x);
10586 assemble_real (r, GET_MODE (x), BITS_PER_WORD);
10587 }
10588 break;
cffb2a26 10589 default:
7b04c5d5 10590 /* XXX: Sometimes gcc does something really dumb and ends up with
10591 a HIGH in a constant pool entry, usually because it's trying to
10592 load into a VFP register. We know this will always be used in
10593 combination with a LO_SUM which ignores the high bits, so just
10594 strip off the HIGH. */
10595 if (GET_CODE (x) == HIGH)
10596 x = XEXP (x, 0);
9b8516be 10597 assemble_integer (x, 4, BITS_PER_WORD, 1);
10598 mark_symbol_refs_as_used (x);
cffb2a26 10599 break;
10600 }
10601 return \"\";
10602 }"
1b7da4ac 10603 [(set_attr "length" "4")
10604 (set_attr "type" "no_insn")]
cffb2a26 10605)
10606
10607(define_insn "consttable_8"
e1159bbe 10608 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_8)]
cffb2a26 10609 "TARGET_EITHER"
10610 "*
10611 {
10612 making_const_table = TRUE;
10613 switch (GET_MODE_CLASS (GET_MODE (operands[0])))
10614 {
10615 case MODE_FLOAT:
10616 {
badfe841 10617 REAL_VALUE_TYPE r;
10618 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[0]);
10619 assemble_real (r, GET_MODE (operands[0]), BITS_PER_WORD);
cffb2a26 10620 break;
10621 }
10622 default:
09d688ff 10623 assemble_integer (operands[0], 8, BITS_PER_WORD, 1);
cffb2a26 10624 break;
10625 }
10626 return \"\";
10627 }"
1b7da4ac 10628 [(set_attr "length" "8")
10629 (set_attr "type" "no_insn")]
cffb2a26 10630)
10631
d98a3884 10632(define_insn "consttable_16"
10633 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_16)]
10634 "TARGET_EITHER"
10635 "*
10636 {
10637 making_const_table = TRUE;
10638 switch (GET_MODE_CLASS (GET_MODE (operands[0])))
10639 {
10640 case MODE_FLOAT:
10641 {
10642 REAL_VALUE_TYPE r;
10643 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[0]);
10644 assemble_real (r, GET_MODE (operands[0]), BITS_PER_WORD);
10645 break;
10646 }
10647 default:
10648 assemble_integer (operands[0], 16, BITS_PER_WORD, 1);
10649 break;
10650 }
10651 return \"\";
10652 }"
1b7da4ac 10653 [(set_attr "length" "16")
10654 (set_attr "type" "no_insn")]
d98a3884 10655)
10656
331beb1a 10657;; V5 Instructions,
10658
8f4be2be 10659(define_insn "clzsi2"
10660 [(set (match_operand:SI 0 "s_register_operand" "=r")
10661 (clz:SI (match_operand:SI 1 "s_register_operand" "r")))]
25f905c2 10662 "TARGET_32BIT && arm_arch5"
ee7cbe0e 10663 "clz%?\\t%0, %1"
bcaec148 10664 [(set_attr "predicable" "yes")
4a510717 10665 (set_attr "predicable_short_it" "no")
bebe9bbb 10666 (set_attr "type" "clz")])
331beb1a 10667
099ad98b 10668(define_insn "rbitsi2"
10669 [(set (match_operand:SI 0 "s_register_operand" "=r")
10670 (unspec:SI [(match_operand:SI 1 "s_register_operand" "r")] UNSPEC_RBIT))]
10671 "TARGET_32BIT && arm_arch_thumb2"
10672 "rbit%?\\t%0, %1"
10673 [(set_attr "predicable" "yes")
4a510717 10674 (set_attr "predicable_short_it" "no")
bebe9bbb 10675 (set_attr "type" "clz")])
099ad98b 10676
10677(define_expand "ctzsi2"
10678 [(set (match_operand:SI 0 "s_register_operand" "")
10679 (ctz:SI (match_operand:SI 1 "s_register_operand" "")))]
10680 "TARGET_32BIT && arm_arch_thumb2"
10681 "
30191172 10682 {
10683 rtx tmp = gen_reg_rtx (SImode);
10684 emit_insn (gen_rbitsi2 (tmp, operands[1]));
10685 emit_insn (gen_clzsi2 (operands[0], tmp));
10686 }
099ad98b 10687 DONE;
10688 "
10689)
10690
e1159bbe 10691;; V5E instructions.
331beb1a 10692
10693(define_insn "prefetch"
f4e79814 10694 [(prefetch (match_operand:SI 0 "address_operand" "p")
10695 (match_operand:SI 1 "" "")
10696 (match_operand:SI 2 "" ""))]
25f905c2 10697 "TARGET_32BIT && arm_arch5e"
1b7da4ac 10698 "pld\\t%a0"
10699 [(set_attr "type" "load1")]
10700)
331beb1a 10701
0d66636f 10702;; General predication pattern
10703
10704(define_cond_exec
10705 [(match_operator 0 "arm_comparison_operator"
10706 [(match_operand 1 "cc_register" "")
10707 (const_int 0)])]
25f905c2 10708 "TARGET_32BIT"
0d66636f 10709 ""
c7a58118 10710[(set_attr "predicated" "yes")]
0d66636f 10711)
10712
fb94f18b 10713(define_insn "force_register_use"
10714 [(unspec:SI [(match_operand:SI 0 "register_operand" "")] UNSPEC_REGISTER_USE)]
063a05c7 10715 ""
fb94f18b 10716 "%@ %0 needed"
1b7da4ac 10717 [(set_attr "length" "0")
10718 (set_attr "type" "no_insn")]
063a05c7 10719)
7db9af5d 10720
4c44712e 10721
10722;; Patterns for exception handling
10723
10724(define_expand "eh_return"
10725 [(use (match_operand 0 "general_operand" ""))]
10726 "TARGET_EITHER"
10727 "
10728 {
25f905c2 10729 if (TARGET_32BIT)
4c44712e 10730 emit_insn (gen_arm_eh_return (operands[0]));
10731 else
10732 emit_insn (gen_thumb_eh_return (operands[0]));
10733 DONE;
10734 }"
10735)
10736
10737;; We can't expand this before we know where the link register is stored.
10738(define_insn_and_split "arm_eh_return"
10739 [(unspec_volatile [(match_operand:SI 0 "s_register_operand" "r")]
10740 VUNSPEC_EH_RETURN)
10741 (clobber (match_scratch:SI 1 "=&r"))]
10742 "TARGET_ARM"
10743 "#"
10744 "&& reload_completed"
10745 [(const_int 0)]
10746 "
10747 {
10748 arm_set_return_address (operands[0], operands[1]);
10749 DONE;
10750 }"
10751)
10752
f655717d 10753\f
10754;; TLS support
10755
10756(define_insn "load_tp_hard"
10757 [(set (match_operand:SI 0 "register_operand" "=r")
10758 (unspec:SI [(const_int 0)] UNSPEC_TLS))]
10759 "TARGET_HARD_TP"
10760 "mrc%?\\tp15, 0, %0, c13, c0, 3\\t@ load_tp_hard"
1b7da4ac 10761 [(set_attr "predicable" "yes")
4b5d7374 10762 (set_attr "type" "mrs")]
f655717d 10763)
10764
10765;; Doesn't clobber R1-R3. Must use r0 for the first operand.
10766(define_insn "load_tp_soft"
10767 [(set (reg:SI 0) (unspec:SI [(const_int 0)] UNSPEC_TLS))
10768 (clobber (reg:SI LR_REGNUM))
10769 (clobber (reg:SI IP_REGNUM))
10770 (clobber (reg:CC CC_REGNUM))]
10771 "TARGET_SOFT_TP"
10772 "bl\\t__aeabi_read_tp\\t@ load_tp_soft"
1b7da4ac 10773 [(set_attr "conds" "clob")
10774 (set_attr "type" "branch")]
f655717d 10775)
10776
f41e4452 10777;; tls descriptor call
10778(define_insn "tlscall"
10779 [(set (reg:SI R0_REGNUM)
10780 (unspec:SI [(reg:SI R0_REGNUM)
10781 (match_operand:SI 0 "" "X")
10782 (match_operand 1 "" "")] UNSPEC_TLS))
10783 (clobber (reg:SI R1_REGNUM))
10784 (clobber (reg:SI LR_REGNUM))
10785 (clobber (reg:SI CC_REGNUM))]
10786 "TARGET_GNU2_TLS"
10787 {
10788 targetm.asm_out.internal_label (asm_out_file, "LPIC",
10789 INTVAL (operands[1]));
10790 return "bl\\t%c0(tlscall)";
10791 }
10792 [(set_attr "conds" "clob")
1b7da4ac 10793 (set_attr "length" "4")
10794 (set_attr "type" "branch")]
f41e4452 10795)
10796
1fe0edab 10797;; For thread pointer builtin
10798(define_expand "get_thread_pointersi"
10799 [(match_operand:SI 0 "s_register_operand" "=r")]
10800 ""
10801 "
10802 {
10803 arm_load_tp (operands[0]);
10804 DONE;
10805 }")
10806
f41e4452 10807;;
10808
aabe09ac 10809;; We only care about the lower 16 bits of the constant
10810;; being inserted into the upper 16 bits of the register.
eca5c984 10811(define_insn "*arm_movtas_ze"
10812 [(set (zero_extract:SI (match_operand:SI 0 "s_register_operand" "+r")
10813 (const_int 16)
10814 (const_int 16))
10815 (match_operand:SI 1 "const_int_operand" ""))]
181ab277 10816 "arm_arch_thumb2"
aabe09ac 10817 "movt%?\t%0, %L1"
eca5c984 10818 [(set_attr "predicable" "yes")
7c36fe71 10819 (set_attr "predicable_short_it" "no")
1b7da4ac 10820 (set_attr "length" "4")
10821 (set_attr "type" "mov_imm")]
eca5c984 10822)
10823
c0fc3696 10824(define_insn "*arm_rev"
a486b499 10825 [(set (match_operand:SI 0 "s_register_operand" "=l,l,r")
10826 (bswap:SI (match_operand:SI 1 "s_register_operand" "l,l,r")))]
10827 "arm_arch6"
10828 "@
10829 rev\t%0, %1
10830 rev%?\t%0, %1
10831 rev%?\t%0, %1"
10832 [(set_attr "arch" "t1,t2,32")
1b7da4ac 10833 (set_attr "length" "2,2,4")
4a510717 10834 (set_attr "predicable" "no,yes,yes")
10835 (set_attr "predicable_short_it" "no")
1b7da4ac 10836 (set_attr "type" "rev")]
ff82f757 10837)
10838
10839(define_expand "arm_legacy_rev"
10840 [(set (match_operand:SI 2 "s_register_operand" "")
10841 (xor:SI (rotatert:SI (match_operand:SI 1 "s_register_operand" "")
10842 (const_int 16))
10843 (match_dup 1)))
10844 (set (match_dup 2)
10845 (lshiftrt:SI (match_dup 2)
10846 (const_int 8)))
10847 (set (match_operand:SI 3 "s_register_operand" "")
10848 (rotatert:SI (match_dup 1)
10849 (const_int 8)))
10850 (set (match_dup 2)
10851 (and:SI (match_dup 2)
10852 (const_int -65281)))
10853 (set (match_operand:SI 0 "s_register_operand" "")
10854 (xor:SI (match_dup 3)
10855 (match_dup 2)))]
10856 "TARGET_32BIT"
10857 ""
10858)
10859
10860;; Reuse temporaries to keep register pressure down.
10861(define_expand "thumb_legacy_rev"
10862 [(set (match_operand:SI 2 "s_register_operand" "")
10863 (ashift:SI (match_operand:SI 1 "s_register_operand" "")
10864 (const_int 24)))
10865 (set (match_operand:SI 3 "s_register_operand" "")
10866 (lshiftrt:SI (match_dup 1)
10867 (const_int 24)))
10868 (set (match_dup 3)
10869 (ior:SI (match_dup 3)
10870 (match_dup 2)))
10871 (set (match_operand:SI 4 "s_register_operand" "")
10872 (const_int 16))
10873 (set (match_operand:SI 5 "s_register_operand" "")
10874 (rotatert:SI (match_dup 1)
10875 (match_dup 4)))
10876 (set (match_dup 2)
10877 (ashift:SI (match_dup 5)
10878 (const_int 24)))
10879 (set (match_dup 5)
10880 (lshiftrt:SI (match_dup 5)
10881 (const_int 24)))
10882 (set (match_dup 5)
10883 (ior:SI (match_dup 5)
10884 (match_dup 2)))
10885 (set (match_dup 5)
10886 (rotatert:SI (match_dup 5)
10887 (match_dup 4)))
10888 (set (match_operand:SI 0 "s_register_operand" "")
10889 (ior:SI (match_dup 5)
10890 (match_dup 3)))]
10891 "TARGET_THUMB"
10892 ""
10893)
10894
10895(define_expand "bswapsi2"
10896 [(set (match_operand:SI 0 "s_register_operand" "=r")
10897 (bswap:SI (match_operand:SI 1 "s_register_operand" "r")))]
8d1af482 10898"TARGET_EITHER && (arm_arch6 || !optimize_size)"
ff82f757 10899"
8d1af482 10900 if (!arm_arch6)
10901 {
10902 rtx op2 = gen_reg_rtx (SImode);
10903 rtx op3 = gen_reg_rtx (SImode);
ff82f757 10904
8d1af482 10905 if (TARGET_THUMB)
10906 {
10907 rtx op4 = gen_reg_rtx (SImode);
10908 rtx op5 = gen_reg_rtx (SImode);
ff82f757 10909
8d1af482 10910 emit_insn (gen_thumb_legacy_rev (operands[0], operands[1],
10911 op2, op3, op4, op5));
10912 }
10913 else
10914 {
10915 emit_insn (gen_arm_legacy_rev (operands[0], operands[1],
10916 op2, op3));
10917 }
ff82f757 10918
8d1af482 10919 DONE;
10920 }
ff82f757 10921 "
10922)
10923
a486b499 10924;; bswap16 patterns: use revsh and rev16 instructions for the signed
10925;; and unsigned variants, respectively. For rev16, expose
10926;; byte-swapping in the lower 16 bits only.
10927(define_insn "*arm_revsh"
10928 [(set (match_operand:SI 0 "s_register_operand" "=l,l,r")
10929 (sign_extend:SI (bswap:HI (match_operand:HI 1 "s_register_operand" "l,l,r"))))]
10930 "arm_arch6"
10931 "@
10932 revsh\t%0, %1
10933 revsh%?\t%0, %1
10934 revsh%?\t%0, %1"
10935 [(set_attr "arch" "t1,t2,32")
1b7da4ac 10936 (set_attr "length" "2,2,4")
10937 (set_attr "type" "rev")]
a486b499 10938)
10939
10940(define_insn "*arm_rev16"
10941 [(set (match_operand:HI 0 "s_register_operand" "=l,l,r")
10942 (bswap:HI (match_operand:HI 1 "s_register_operand" "l,l,r")))]
10943 "arm_arch6"
10944 "@
10945 rev16\t%0, %1
10946 rev16%?\t%0, %1
10947 rev16%?\t%0, %1"
10948 [(set_attr "arch" "t1,t2,32")
1b7da4ac 10949 (set_attr "length" "2,2,4")
10950 (set_attr "type" "rev")]
09f69e55 10951)
10952
10953;; There are no canonicalisation rules for the position of the lshiftrt, ashift
10954;; operations within an IOR/AND RTX, therefore we have two patterns matching
10955;; each valid permutation.
10956
10957(define_insn "arm_rev16si2"
10958 [(set (match_operand:SI 0 "register_operand" "=l,l,r")
10959 (ior:SI (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "l,l,r")
10960 (const_int 8))
10961 (match_operand:SI 3 "const_int_operand" "n,n,n"))
10962 (and:SI (lshiftrt:SI (match_dup 1)
10963 (const_int 8))
10964 (match_operand:SI 2 "const_int_operand" "n,n,n"))))]
10965 "arm_arch6
10966 && aarch_rev16_shleft_mask_imm_p (operands[3], SImode)
10967 && aarch_rev16_shright_mask_imm_p (operands[2], SImode)"
10968 "rev16\\t%0, %1"
10969 [(set_attr "arch" "t1,t2,32")
10970 (set_attr "length" "2,2,4")
10971 (set_attr "type" "rev")]
10972)
10973
10974(define_insn "arm_rev16si2_alt"
10975 [(set (match_operand:SI 0 "register_operand" "=l,l,r")
10976 (ior:SI (and:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" "l,l,r")
10977 (const_int 8))
10978 (match_operand:SI 2 "const_int_operand" "n,n,n"))
10979 (and:SI (ashift:SI (match_dup 1)
10980 (const_int 8))
10981 (match_operand:SI 3 "const_int_operand" "n,n,n"))))]
10982 "arm_arch6
10983 && aarch_rev16_shleft_mask_imm_p (operands[3], SImode)
10984 && aarch_rev16_shright_mask_imm_p (operands[2], SImode)"
10985 "rev16\\t%0, %1"
10986 [(set_attr "arch" "t1,t2,32")
10987 (set_attr "length" "2,2,4")
10988 (set_attr "type" "rev")]
a486b499 10989)
10990
10991(define_expand "bswaphi2"
10992 [(set (match_operand:HI 0 "s_register_operand" "=r")
10993 (bswap:HI (match_operand:HI 1 "s_register_operand" "r")))]
10994"arm_arch6"
10995""
10996)
10997
1653cf17 10998;; Patterns for LDRD/STRD in Thumb2 mode
10999
11000(define_insn "*thumb2_ldrd"
11001 [(set (match_operand:SI 0 "s_register_operand" "=r")
11002 (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "rk")
11003 (match_operand:SI 2 "ldrd_strd_offset_operand" "Do"))))
11004 (set (match_operand:SI 3 "s_register_operand" "=r")
11005 (mem:SI (plus:SI (match_dup 1)
11006 (match_operand:SI 4 "const_int_operand" ""))))]
11007 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11008 && current_tune->prefer_ldrd_strd
11009 && ((INTVAL (operands[2]) + 4) == INTVAL (operands[4]))
11010 && (operands_ok_ldrd_strd (operands[0], operands[3],
11011 operands[1], INTVAL (operands[2]),
11012 false, true))"
11013 "ldrd%?\t%0, %3, [%1, %2]"
11014 [(set_attr "type" "load2")
d952d547 11015 (set_attr "predicable" "yes")
11016 (set_attr "predicable_short_it" "no")])
1653cf17 11017
11018(define_insn "*thumb2_ldrd_base"
11019 [(set (match_operand:SI 0 "s_register_operand" "=r")
11020 (mem:SI (match_operand:SI 1 "s_register_operand" "rk")))
11021 (set (match_operand:SI 2 "s_register_operand" "=r")
11022 (mem:SI (plus:SI (match_dup 1)
11023 (const_int 4))))]
11024 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11025 && current_tune->prefer_ldrd_strd
11026 && (operands_ok_ldrd_strd (operands[0], operands[2],
11027 operands[1], 0, false, true))"
11028 "ldrd%?\t%0, %2, [%1]"
11029 [(set_attr "type" "load2")
d952d547 11030 (set_attr "predicable" "yes")
11031 (set_attr "predicable_short_it" "no")])
1653cf17 11032
11033(define_insn "*thumb2_ldrd_base_neg"
11034 [(set (match_operand:SI 0 "s_register_operand" "=r")
11035 (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "rk")
11036 (const_int -4))))
11037 (set (match_operand:SI 2 "s_register_operand" "=r")
11038 (mem:SI (match_dup 1)))]
11039 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11040 && current_tune->prefer_ldrd_strd
11041 && (operands_ok_ldrd_strd (operands[0], operands[2],
11042 operands[1], -4, false, true))"
11043 "ldrd%?\t%0, %2, [%1, #-4]"
11044 [(set_attr "type" "load2")
d952d547 11045 (set_attr "predicable" "yes")
11046 (set_attr "predicable_short_it" "no")])
1653cf17 11047
11048(define_insn "*thumb2_strd"
11049 [(set (mem:SI (plus:SI (match_operand:SI 0 "s_register_operand" "rk")
11050 (match_operand:SI 1 "ldrd_strd_offset_operand" "Do")))
11051 (match_operand:SI 2 "s_register_operand" "r"))
11052 (set (mem:SI (plus:SI (match_dup 0)
11053 (match_operand:SI 3 "const_int_operand" "")))
11054 (match_operand:SI 4 "s_register_operand" "r"))]
11055 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11056 && current_tune->prefer_ldrd_strd
11057 && ((INTVAL (operands[1]) + 4) == INTVAL (operands[3]))
11058 && (operands_ok_ldrd_strd (operands[2], operands[4],
11059 operands[0], INTVAL (operands[1]),
11060 false, false))"
11061 "strd%?\t%2, %4, [%0, %1]"
11062 [(set_attr "type" "store2")
d952d547 11063 (set_attr "predicable" "yes")
11064 (set_attr "predicable_short_it" "no")])
1653cf17 11065
11066(define_insn "*thumb2_strd_base"
11067 [(set (mem:SI (match_operand:SI 0 "s_register_operand" "rk"))
11068 (match_operand:SI 1 "s_register_operand" "r"))
11069 (set (mem:SI (plus:SI (match_dup 0)
11070 (const_int 4)))
11071 (match_operand:SI 2 "s_register_operand" "r"))]
11072 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11073 && current_tune->prefer_ldrd_strd
11074 && (operands_ok_ldrd_strd (operands[1], operands[2],
11075 operands[0], 0, false, false))"
11076 "strd%?\t%1, %2, [%0]"
11077 [(set_attr "type" "store2")
d952d547 11078 (set_attr "predicable" "yes")
11079 (set_attr "predicable_short_it" "no")])
1653cf17 11080
11081(define_insn "*thumb2_strd_base_neg"
11082 [(set (mem:SI (plus:SI (match_operand:SI 0 "s_register_operand" "rk")
11083 (const_int -4)))
11084 (match_operand:SI 1 "s_register_operand" "r"))
11085 (set (mem:SI (match_dup 0))
11086 (match_operand:SI 2 "s_register_operand" "r"))]
11087 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11088 && current_tune->prefer_ldrd_strd
11089 && (operands_ok_ldrd_strd (operands[1], operands[2],
11090 operands[0], -4, false, false))"
11091 "strd%?\t%1, %2, [%0, #-4]"
11092 [(set_attr "type" "store2")
d952d547 11093 (set_attr "predicable" "yes")
11094 (set_attr "predicable_short_it" "no")])
1653cf17 11095
2a0c73f2 11096;; ARMv8 CRC32 instructions.
11097(define_insn "<crc_variant>"
11098 [(set (match_operand:SI 0 "s_register_operand" "=r")
11099 (unspec:SI [(match_operand:SI 1 "s_register_operand" "r")
11100 (match_operand:<crc_mode> 2 "s_register_operand" "r")]
11101 CRC))]
11102 "TARGET_CRC32"
11103 "<crc_variant>\\t%0, %1, %2"
11104 [(set_attr "type" "crc")
11105 (set_attr "conds" "unconditional")]
11106)
1653cf17 11107
353cf59a 11108;; Load the load/store double peephole optimizations.
11109(include "ldrdstrd.md")
11110
320ea44d 11111;; Load the load/store multiple patterns
11112(include "ldmstm.md")
426be8c5 11113
11114;; Patterns in ldmstm.md don't cover more than 4 registers. This pattern covers
11115;; large lists without explicit writeback generated for APCS_FRAME epilogue.
11116(define_insn "*load_multiple"
11117 [(match_parallel 0 "load_multiple_operation"
11118 [(set (match_operand:SI 2 "s_register_operand" "=rk")
11119 (mem:SI (match_operand:SI 1 "s_register_operand" "rk")))
11120 ])]
11121 "TARGET_32BIT"
11122 "*
11123 {
11124 arm_output_multireg_pop (operands, /*return_pc=*/false,
11125 /*cond=*/const_true_rtx,
11126 /*reverse=*/false,
11127 /*update=*/false);
11128 return \"\";
11129 }
11130 "
11131 [(set_attr "predicable" "yes")]
11132)
11133
d98a3884 11134;; Vector bits common to IWMMXT and Neon
11135(include "vec-common.md")
755eb2b4 11136;; Load the Intel Wireless Multimedia Extension patterns
11137(include "iwmmxt.md")
a2cd141b 11138;; Load the VFP co-processor patterns
11139(include "vfp.md")
bc360af8 11140;; Thumb-1 patterns
11141(include "thumb1.md")
25f905c2 11142;; Thumb-2 patterns
11143(include "thumb2.md")
d98a3884 11144;; Neon patterns
11145(include "neon.md")
e84fdf6e 11146;; Crypto patterns
11147(include "crypto.md")
06df6b17 11148;; Synchronization Primitives
11149(include "sync.md")
bbbe4599 11150;; Fixed-point patterns
11151(include "arm-fixed.md")