]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/config/arm/arm.md
[AArch64] Implement -m{cpu,tune,arch}=native using only /proc/cpuinfo
[thirdparty/gcc.git] / gcc / config / arm / arm.md
CommitLineData
129a2fe4 1;;- Machine description for ARM for GNU compiler
d353bf18 2;; Copyright (C) 1991-2015 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
9c08d1fa 25\f
e1159bbe 26;;---------------------------------------------------------------------------
27;; Constants
28
bffbb863 29;; Register numbers -- All machine registers should be defined here
e1159bbe 30(define_constants
bffbb863 31 [(R0_REGNUM 0) ; First CORE register
32 (R1_REGNUM 1) ; Second CORE register
33 (IP_REGNUM 12) ; Scratch register
34 (SP_REGNUM 13) ; Stack pointer
35 (LR_REGNUM 14) ; Return address register
36 (PC_REGNUM 15) ; Program counter
37 (LAST_ARM_REGNUM 15) ;
38 (CC_REGNUM 100) ; Condition code pseudo register
39 (VFPCC_REGNUM 101) ; VFP Condition code pseudo register
e1159bbe 40 ]
41)
3c5afce6 42;; 3rd operand to select_dominance_cc_mode
43(define_constants
44 [(DOM_CC_X_AND_Y 0)
45 (DOM_CC_NX_OR_Y 1)
46 (DOM_CC_X_OR_Y 2)
47 ]
48)
2ff91fec 49;; conditional compare combination
50(define_constants
51 [(CMP_CMP 0)
52 (CMN_CMP 1)
53 (CMP_CMN 2)
54 (CMN_CMN 3)
55 (NUM_OF_COND_CMP 4)
56 ]
57)
e1159bbe 58
b11cae9e 59\f
e1159bbe 60;;---------------------------------------------------------------------------
9c08d1fa 61;; Attributes
62
a651f34d 63;; Processor type. This is created automatically from arm-cores.def.
64(include "arm-tune.md")
65
861033d5 66;; Instruction classification types
67(include "types.md")
68
215b30b3 69; IS_THUMB is set to 'yes' when we are generating Thumb code, and 'no' when
70; generating ARM code. This is used to control the length of some insn
71; patterns that share the same RTL in both ARM and Thumb code.
1c494086 72(define_attr "is_thumb" "no,yes" (const (symbol_ref "thumb_code")))
cffb2a26 73
ef51b8e1 74; IS_ARCH6 is set to 'yes' when we are generating code form ARMv6.
75(define_attr "is_arch6" "no,yes" (const (symbol_ref "arm_arch6")))
76
747b7458 77; IS_THUMB1 is set to 'yes' iff we are generating Thumb-1 code.
78(define_attr "is_thumb1" "no,yes" (const (symbol_ref "thumb1_code")))
79
c7a58118 80; We use this attribute to disable alternatives that can produce 32-bit
81; instructions inside an IT-block in Thumb2 state. ARMv8 deprecates IT blocks
82; that contain 32-bit instructions.
83(define_attr "enabled_for_depr_it" "no,yes" (const_string "yes"))
84
85; This attribute is used to disable a predicated alternative when we have
86; arm_restrict_it.
87(define_attr "predicable_short_it" "no,yes" (const_string "yes"))
88
331beb1a 89;; Operand number of an input operand that is shifted. Zero if the
90;; given instruction does not shift one of its input operands.
331beb1a 91(define_attr "shift" "" (const_int 0))
92
55a94dda 93;; [For compatibility with AArch64 in pipeline models]
94;; Attribute that specifies whether or not the instruction touches fp
95;; registers.
96(define_attr "fp" "no,yes" (const_string "no"))
97
3d91c5d6 98; Floating Point Unit. If we only have floating point emulation, then there
99; is no point in scheduling the floating point insns. (Well, for best
100; performance we should try and group them together).
bffbb863 101(define_attr "fpu" "none,vfp"
c7f506fd 102 (const (symbol_ref "arm_fpu_attr")))
3d91c5d6 103
c7a58118 104(define_attr "predicated" "yes,no" (const_string "no"))
105
094e994f 106; LENGTH of an instruction (in bytes)
06df6b17 107(define_attr "length" ""
e1b93706 108 (const_int 4))
9c08d1fa 109
d5d4dc8d 110; The architecture which supports the instruction (or alternative).
111; This can be "a" for ARM, "t" for either of the Thumbs, "32" for
112; TARGET_32BIT, "t1" or "t2" to specify a specific Thumb mode. "v6"
113; for ARM or Thumb-2 with arm_arch6, and nov6 for ARM without
e4585731 114; arm_arch6. "v6t2" for Thumb-2 with arm_arch6. This attribute is
115; used to compute attribute "enabled", use type "any" to enable an
116; alternative in all cases.
117(define_attr "arch" "any,a,t,32,t1,t2,v6,nov6,v6t2,neon_for_64bits,avoid_neon_for_64bits,iwmmxt,iwmmxt2,armv6_or_vfpv3"
d5d4dc8d 118 (const_string "any"))
119
120(define_attr "arch_enabled" "no,yes"
121 (cond [(eq_attr "arch" "any")
122 (const_string "yes")
123
124 (and (eq_attr "arch" "a")
0bf497f5 125 (match_test "TARGET_ARM"))
d5d4dc8d 126 (const_string "yes")
127
128 (and (eq_attr "arch" "t")
0bf497f5 129 (match_test "TARGET_THUMB"))
d5d4dc8d 130 (const_string "yes")
131
132 (and (eq_attr "arch" "t1")
0bf497f5 133 (match_test "TARGET_THUMB1"))
d5d4dc8d 134 (const_string "yes")
135
136 (and (eq_attr "arch" "t2")
0bf497f5 137 (match_test "TARGET_THUMB2"))
d5d4dc8d 138 (const_string "yes")
139
140 (and (eq_attr "arch" "32")
0bf497f5 141 (match_test "TARGET_32BIT"))
d5d4dc8d 142 (const_string "yes")
143
144 (and (eq_attr "arch" "v6")
0bf497f5 145 (match_test "TARGET_32BIT && arm_arch6"))
d5d4dc8d 146 (const_string "yes")
147
148 (and (eq_attr "arch" "nov6")
0bf497f5 149 (match_test "TARGET_32BIT && !arm_arch6"))
a651f34d 150 (const_string "yes")
151
e4585731 152 (and (eq_attr "arch" "v6t2")
153 (match_test "TARGET_32BIT && arm_arch6 && arm_arch_thumb2"))
154 (const_string "yes")
155
b6779ddc 156 (and (eq_attr "arch" "avoid_neon_for_64bits")
157 (match_test "TARGET_NEON")
158 (not (match_test "TARGET_PREFER_NEON_64BITS")))
a651f34d 159 (const_string "yes")
160
b6779ddc 161 (and (eq_attr "arch" "neon_for_64bits")
162 (match_test "TARGET_NEON")
163 (match_test "TARGET_PREFER_NEON_64BITS"))
6b8f7c28 164 (const_string "yes")
165
166 (and (eq_attr "arch" "iwmmxt2")
167 (match_test "TARGET_REALLY_IWMMXT2"))
21cc9773 168 (const_string "yes")
169
170 (and (eq_attr "arch" "armv6_or_vfpv3")
171 (match_test "arm_arch6 || TARGET_VFP3"))
172 (const_string "yes")
173 ]
6b8f7c28 174
d5d4dc8d 175 (const_string "no")))
176
aa06c51c 177(define_attr "opt" "any,speed,size"
178 (const_string "any"))
179
180(define_attr "opt_enabled" "no,yes"
181 (cond [(eq_attr "opt" "any")
182 (const_string "yes")
183
184 (and (eq_attr "opt" "speed")
185 (match_test "optimize_function_for_speed_p (cfun)"))
186 (const_string "yes")
187
188 (and (eq_attr "opt" "size")
189 (match_test "optimize_function_for_size_p (cfun)"))
190 (const_string "yes")]
191 (const_string "no")))
192
861033d5 193(define_attr "use_literal_pool" "no,yes"
194 (cond [(and (eq_attr "type" "f_loads,f_loadd")
195 (match_test "CONSTANT_P (operands[1])"))
196 (const_string "yes")]
197 (const_string "no")))
198
d5d4dc8d 199; Enable all alternatives that are both arch_enabled and insn_enabled.
951a3f72 200; FIXME:: opt_enabled has been temporarily removed till the time we have
201; an attribute that allows the use of such alternatives.
202; This depends on caching of speed_p, size_p on a per
203; alternative basis. The problem is that the enabled attribute
204; cannot depend on any state that is not cached or is not constant
205; for a compilation unit. We probably need a generic "hot/cold"
206; alternative which if implemented can help with this. We disable this
207; until such a time as this is implemented and / or the improvements or
208; regressions with removing this attribute are double checked.
209; See ashldi3_neon and <shift>di3_neon in neon.md.
210
93b431d9 211 (define_attr "enabled" "no,yes"
0abea32c 212 (cond [(and (eq_attr "predicable_short_it" "no")
c7a58118 213 (and (eq_attr "predicated" "yes")
214 (match_test "arm_restrict_it")))
215 (const_string "no")
216
217 (and (eq_attr "enabled_for_depr_it" "no")
218 (match_test "arm_restrict_it"))
219 (const_string "no")
220
861033d5 221 (and (eq_attr "use_literal_pool" "yes")
222 (match_test "arm_disable_literal_pool"))
223 (const_string "no")
224
aa06c51c 225 (eq_attr "arch_enabled" "no")
aa06c51c 226 (const_string "no")]
227 (const_string "yes")))
d5d4dc8d 228
56d27660 229; POOL_RANGE is how far away from a constant pool entry that this insn
230; can be placed. If the distance is zero, then this insn will never
231; reference the pool.
42e1de19 232; Note that for Thumb constant pools the PC value is rounded down to the
233; nearest multiple of four. Therefore, THUMB2_POOL_RANGE (and POOL_RANGE for
234; Thumb insns) should be set to <max_range> - 2.
cffb2a26 235; NEG_POOL_RANGE is nonzero for insns that can reference a constant pool entry
8848d797 236; before its address. It is set to <max_range> - (8 + <data_size>).
cde1623a 237(define_attr "arm_pool_range" "" (const_int 0))
238(define_attr "thumb2_pool_range" "" (const_int 0))
239(define_attr "arm_neg_pool_range" "" (const_int 0))
240(define_attr "thumb2_neg_pool_range" "" (const_int 0))
241
242(define_attr "pool_range" ""
243 (cond [(eq_attr "is_thumb" "yes") (attr "thumb2_pool_range")]
244 (attr "arm_pool_range")))
245(define_attr "neg_pool_range" ""
246 (cond [(eq_attr "is_thumb" "yes") (attr "thumb2_neg_pool_range")]
247 (attr "arm_neg_pool_range")))
56d27660 248
215b30b3 249; An assembler sequence may clobber the condition codes without us knowing.
4d7a8451 250; If such an insn references the pool, then we have no way of knowing how,
251; so use the most conservative value for pool_range.
9c08d1fa 252(define_asm_attributes
4d7a8451 253 [(set_attr "conds" "clob")
254 (set_attr "length" "4")
255 (set_attr "pool_range" "250")])
9c08d1fa 256
9888ad6d 257; Load scheduling, set from the arm_ld_sched variable
4c834714 258; initialized by arm_option_override()
9888ad6d 259(define_attr "ldsched" "no,yes" (const (symbol_ref "arm_ld_sched")))
849170fd 260
f7fbdd4a 261; condition codes: this one is used by final_prescan_insn to speed up
262; conditionalizing instructions. It saves having to scan the rtl to see if
263; it uses or alters the condition codes.
215b30b3 264;
f7fbdd4a 265; USE means that the condition codes are used by the insn in the process of
215b30b3 266; outputting code, this means (at present) that we can't use the insn in
267; inlined branches
268;
f7fbdd4a 269; SET means that the purpose of the insn is to set the condition codes in a
215b30b3 270; well defined manner.
271;
f7fbdd4a 272; CLOB means that the condition codes are altered in an undefined manner, if
215b30b3 273; they are altered at all
274;
ad6d3e2a 275; UNCONDITIONAL means the instruction can not be conditionally executed and
276; that the instruction does not use or alter the condition codes.
c52acdd2 277;
ad6d3e2a 278; NOCOND means that the instruction does not use or alter the condition
279; codes but can be converted into a conditionally exectuted instruction.
f7fbdd4a 280
b0694be0 281(define_attr "conds" "use,set,clob,unconditional,nocond"
747b7458 282 (if_then_else
283 (ior (eq_attr "is_thumb1" "yes")
284 (eq_attr "type" "call"))
c1a66faf 285 (const_string "clob")
32093010 286 (if_then_else (eq_attr "is_neon_type" "no")
52432540 287 (const_string "nocond")
288 (const_string "unconditional"))))
f7fbdd4a 289
215b30b3 290; Predicable means that the insn can be conditionally executed based on
291; an automatically added predicate (additional patterns are generated by
292; gen...). We default to 'no' because no Thumb patterns match this rule
293; and not all ARM patterns do.
0d66636f 294(define_attr "predicable" "no,yes" (const_string "no"))
295
129a2fe4 296; Only model the write buffer for ARM6 and ARM7. Earlier processors don't
297; have one. Later ones, such as StrongARM, have write-back caches, so don't
8d232dc7 298; suffer blockages enough to warrant modelling this (and it can adversely
129a2fe4 299; affect the schedule).
74a71f7d 300(define_attr "model_wbuf" "no,yes" (const (symbol_ref "arm_tune_wbuf")))
129a2fe4 301
215b30b3 302; WRITE_CONFLICT implies that a read following an unrelated write is likely
303; to stall the processor. Used with model_wbuf above.
9c08d1fa 304(define_attr "write_conflict" "no,yes"
305 (if_then_else (eq_attr "type"
96854199 306 "block,call,load1")
9c08d1fa 307 (const_string "yes")
308 (const_string "no")))
309
215b30b3 310; Classify the insns into those that take one cycle and those that take more
311; than one on the main cpu execution unit.
f7fbdd4a 312(define_attr "core_cycles" "single,multi"
313 (if_then_else (eq_attr "type"
112eda6f 314 "adc_imm, adc_reg, adcs_imm, adcs_reg, adr, alu_ext, alu_imm, alu_sreg,\
315 alu_shift_imm, alu_shift_reg, alu_dsp_reg, alus_ext, alus_imm, alus_sreg,\
d82e788e 316 alus_shift_imm, alus_shift_reg, bfm, csel, rev, logic_imm, logic_reg,\
317 logic_shift_imm, logic_shift_reg, logics_imm, logics_reg,\
318 logics_shift_imm, logics_shift_reg, extend, shift_imm, float, fcsel,\
7cb6c048 319 wmmx_wor, wmmx_wxor, wmmx_wand, wmmx_wandn, wmmx_wmov, wmmx_tmcrr,\
320 wmmx_tmrrc, wmmx_wldr, wmmx_wstr, wmmx_tmcr, wmmx_tmrc, wmmx_wadd,\
321 wmmx_wsub, wmmx_wmul, wmmx_wmac, wmmx_wavg2, wmmx_tinsr, wmmx_textrm,\
322 wmmx_wshufh, wmmx_wcmpeq, wmmx_wcmpgt, wmmx_wmax, wmmx_wmin, wmmx_wpack,\
323 wmmx_wunpckih, wmmx_wunpckil, wmmx_wunpckeh, wmmx_wunpckel, wmmx_wror,\
324 wmmx_wsra, wmmx_wsrl, wmmx_wsll, wmmx_wmadd, wmmx_tmia, wmmx_tmiaph,\
325 wmmx_tmiaxy, wmmx_tbcst, wmmx_tmovmsk, wmmx_wacc, wmmx_waligni,\
326 wmmx_walignr, wmmx_tandc, wmmx_textrc, wmmx_torc, wmmx_torvsc, wmmx_wsad,\
327 wmmx_wabs, wmmx_wabsdiff, wmmx_waddsubhx, wmmx_wsubaddhx, wmmx_wavg4,\
328 wmmx_wmulw, wmmx_wqmulm, wmmx_wqmulwm, wmmx_waddbhus, wmmx_wqmiaxy,\
329 wmmx_wmiaxy, wmmx_wmiawxy, wmmx_wmerge")
f7fbdd4a 330 (const_string "single")
331 (const_string "multi")))
332
cffb2a26 333;; FAR_JUMP is "yes" if a BL instruction is used to generate a branch to a
215b30b3 334;; distant label. Only applicable to Thumb code.
cffb2a26 335(define_attr "far_jump" "yes,no" (const_string "no"))
336
d51f92df 337
25f905c2 338;; The number of machine instructions this pattern expands to.
339;; Used for Thumb-2 conditional execution.
340(define_attr "ce_count" "" (const_int 1))
341
4182b724 342;;---------------------------------------------------------------------------
343;; Unspecs
344
345(include "unspecs.md")
346
d51f92df 347;;---------------------------------------------------------------------------
fd781bb2 348;; Mode iterators
d51f92df 349
3de0dec6 350(include "iterators.md")
03770691 351
d51f92df 352;;---------------------------------------------------------------------------
353;; Predicates
354
9c9db025 355(include "predicates.md")
234f6557 356(include "constraints.md")
9c9db025 357
a2cd141b 358;;---------------------------------------------------------------------------
359;; Pipeline descriptions
215b30b3 360
e3879fd0 361(define_attr "tune_cortexr4" "yes,no"
362 (const (if_then_else
7d3cda8c 363 (eq_attr "tune" "cortexr4,cortexr4f,cortexr5")
e3879fd0 364 (const_string "yes")
365 (const_string "no"))))
366
a2cd141b 367;; True if the generic scheduling description should be used.
368
369(define_attr "generic_sched" "yes,no"
2546d93a 370 (const (if_then_else
e18862f3 371 (ior (eq_attr "tune" "fa526,fa626,fa606te,fa626te,fmp626,fa726te,\
372 arm926ejs,arm1020e,arm1026ejs,arm1136js,\
373 arm1136jfs,cortexa5,cortexa7,cortexa8,\
42e7b263 374 cortexa9,cortexa12,cortexa15,cortexa17,\
b1099bfd 375 cortexa53,cortexa57,cortexm4,cortexm7,\
376 marvell_pj4,xgene1")
2546d93a 377 (eq_attr "tune_cortexr4" "yes"))
4d5cb40d 378 (const_string "no")
379 (const_string "yes"))))
380
c0e1af52 381(define_attr "generic_vfp" "yes,no"
382 (const (if_then_else
383 (and (eq_attr "fpu" "vfp")
e18862f3 384 (eq_attr "tune" "!arm1020e,arm1022e,cortexa5,cortexa7,\
385 cortexa8,cortexa9,cortexa53,cortexm4,\
55a94dda 386 cortexm7,marvell_pj4,xgene1")
e3879fd0 387 (eq_attr "tune_cortexr4" "no"))
c0e1af52 388 (const_string "yes")
389 (const_string "no"))))
390
6b8f7c28 391(include "marvell-f-iwmmxt.md")
a2cd141b 392(include "arm-generic.md")
393(include "arm926ejs.md")
c0e1af52 394(include "arm1020e.md")
a2cd141b 395(include "arm1026ejs.md")
396(include "arm1136jfs.md")
0e266d06 397(include "fa526.md")
398(include "fa606te.md")
399(include "fa626te.md")
400(include "fmp626.md")
401(include "fa726te.md")
3f1e069f 402(include "cortex-a5.md")
d6b7f019 403(include "cortex-a7.md")
bcaec148 404(include "cortex-a8.md")
036068af 405(include "cortex-a9.md")
65f2f758 406(include "cortex-a15.md")
42e7b263 407(include "cortex-a17.md")
da10bc87 408(include "cortex-a53.md")
b1099bfd 409(include "cortex-a57.md")
934a1e72 410(include "cortex-r4.md")
e3879fd0 411(include "cortex-r4f.md")
e18862f3 412(include "cortex-m7.md")
2546d93a 413(include "cortex-m4.md")
414(include "cortex-m4-fpu.md")
55e3ada8 415(include "vfp11.md")
ea7d210b 416(include "marvell-pj4.md")
55a94dda 417(include "xgene1.md")
3586df96 418
9c08d1fa 419\f
215b30b3 420;;---------------------------------------------------------------------------
e1159bbe 421;; Insn patterns
422;;
a0f94409 423;; Addition insns.
215b30b3 424
9c08d1fa 425;; Note: For DImode insns, there is normally no reason why operands should
426;; not be in the same register, what we don't want is for something being
427;; written to partially overlap something that is an input.
428
cffb2a26 429(define_expand "adddi3"
430 [(parallel
215b30b3 431 [(set (match_operand:DI 0 "s_register_operand" "")
cffb2a26 432 (plus:DI (match_operand:DI 1 "s_register_operand" "")
10e5ccd5 433 (match_operand:DI 2 "arm_adddi_operand" "")))
bd5b4116 434 (clobber (reg:CC CC_REGNUM))])]
cffb2a26 435 "TARGET_EITHER"
436 "
25f905c2 437 if (TARGET_THUMB1)
cffb2a26 438 {
0438d37f 439 if (!REG_P (operands[1]))
bc5a93af 440 operands[1] = force_reg (DImode, operands[1]);
0438d37f 441 if (!REG_P (operands[2]))
bc5a93af 442 operands[2] = force_reg (DImode, operands[2]);
cffb2a26 443 }
444 "
445)
446
a0f94409 447(define_insn_and_split "*arm_adddi3"
10e5ccd5 448 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r,&r,&r,&r")
449 (plus:DI (match_operand:DI 1 "s_register_operand" "%0, 0, r, 0, r")
450 (match_operand:DI 2 "arm_adddi_operand" "r, 0, r, Dd, Dd")))
bd5b4116 451 (clobber (reg:CC CC_REGNUM))]
b805622c 452 "TARGET_32BIT && !TARGET_NEON"
33782ec7 453 "#"
94829feb 454 "TARGET_32BIT && reload_completed
455 && ! (TARGET_NEON && IS_VFP_REGNUM (REGNO (operands[0])))"
a0f94409 456 [(parallel [(set (reg:CC_C CC_REGNUM)
457 (compare:CC_C (plus:SI (match_dup 1) (match_dup 2))
458 (match_dup 1)))
459 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
080c0b9a 460 (set (match_dup 3) (plus:SI (plus:SI (match_dup 4) (match_dup 5))
461 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
a0f94409 462 "
463 {
464 operands[3] = gen_highpart (SImode, operands[0]);
465 operands[0] = gen_lowpart (SImode, operands[0]);
466 operands[4] = gen_highpart (SImode, operands[1]);
467 operands[1] = gen_lowpart (SImode, operands[1]);
10e5ccd5 468 operands[5] = gen_highpart_mode (SImode, DImode, operands[2]);
a0f94409 469 operands[2] = gen_lowpart (SImode, operands[2]);
470 }"
cffb2a26 471 [(set_attr "conds" "clob")
1b7da4ac 472 (set_attr "length" "8")
473 (set_attr "type" "multiple")]
cffb2a26 474)
9c08d1fa 475
a0f94409 476(define_insn_and_split "*adddi_sesidi_di"
9c08d1fa 477 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
478 (plus:DI (sign_extend:DI
97499065 479 (match_operand:SI 2 "s_register_operand" "r,r"))
e5fea38e 480 (match_operand:DI 1 "s_register_operand" "0,r")))
bd5b4116 481 (clobber (reg:CC CC_REGNUM))]
b805622c 482 "TARGET_32BIT"
33782ec7 483 "#"
25f905c2 484 "TARGET_32BIT && reload_completed"
a0f94409 485 [(parallel [(set (reg:CC_C CC_REGNUM)
486 (compare:CC_C (plus:SI (match_dup 1) (match_dup 2))
487 (match_dup 1)))
488 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
080c0b9a 489 (set (match_dup 3) (plus:SI (plus:SI (ashiftrt:SI (match_dup 2)
a0f94409 490 (const_int 31))
080c0b9a 491 (match_dup 4))
492 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
a0f94409 493 "
494 {
495 operands[3] = gen_highpart (SImode, operands[0]);
496 operands[0] = gen_lowpart (SImode, operands[0]);
497 operands[4] = gen_highpart (SImode, operands[1]);
498 operands[1] = gen_lowpart (SImode, operands[1]);
499 operands[2] = gen_lowpart (SImode, operands[2]);
500 }"
215b30b3 501 [(set_attr "conds" "clob")
1b7da4ac 502 (set_attr "length" "8")
503 (set_attr "type" "multiple")]
215b30b3 504)
9c08d1fa 505
a0f94409 506(define_insn_and_split "*adddi_zesidi_di"
9c08d1fa 507 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
508 (plus:DI (zero_extend:DI
97499065 509 (match_operand:SI 2 "s_register_operand" "r,r"))
e5fea38e 510 (match_operand:DI 1 "s_register_operand" "0,r")))
a0f94409 511 (clobber (reg:CC CC_REGNUM))]
b805622c 512 "TARGET_32BIT"
33782ec7 513 "#"
25f905c2 514 "TARGET_32BIT && reload_completed"
a0f94409 515 [(parallel [(set (reg:CC_C CC_REGNUM)
516 (compare:CC_C (plus:SI (match_dup 1) (match_dup 2))
517 (match_dup 1)))
518 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
080c0b9a 519 (set (match_dup 3) (plus:SI (plus:SI (match_dup 4) (const_int 0))
520 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
a0f94409 521 "
522 {
523 operands[3] = gen_highpart (SImode, operands[0]);
524 operands[0] = gen_lowpart (SImode, operands[0]);
525 operands[4] = gen_highpart (SImode, operands[1]);
526 operands[1] = gen_lowpart (SImode, operands[1]);
527 operands[2] = gen_lowpart (SImode, operands[2]);
528 }"
cffb2a26 529 [(set_attr "conds" "clob")
1b7da4ac 530 (set_attr "length" "8")
531 (set_attr "type" "multiple")]
cffb2a26 532)
b11cae9e 533
87b22bf7 534(define_expand "addsi3"
cffb2a26 535 [(set (match_operand:SI 0 "s_register_operand" "")
87b22bf7 536 (plus:SI (match_operand:SI 1 "s_register_operand" "")
537 (match_operand:SI 2 "reg_or_int_operand" "")))]
cffb2a26 538 "TARGET_EITHER"
87b22bf7 539 "
0438d37f 540 if (TARGET_32BIT && CONST_INT_P (operands[2]))
87b22bf7 541 {
96f57e36 542 arm_split_constant (PLUS, SImode, NULL_RTX,
543 INTVAL (operands[2]), operands[0], operands[1],
e1ba4a27 544 optimize && can_create_pseudo_p ());
87b22bf7 545 DONE;
546 }
cffb2a26 547 "
548)
87b22bf7 549
5bd751ff 550; If there is a scratch available, this will be faster than synthesizing the
a0f94409 551; addition.
552(define_peephole2
553 [(match_scratch:SI 3 "r")
372575c7 554 (set (match_operand:SI 0 "arm_general_register_operand" "")
555 (plus:SI (match_operand:SI 1 "arm_general_register_operand" "")
cffb2a26 556 (match_operand:SI 2 "const_int_operand" "")))]
25f905c2 557 "TARGET_32BIT &&
a0f94409 558 !(const_ok_for_arm (INTVAL (operands[2]))
559 || const_ok_for_arm (-INTVAL (operands[2])))
560 && const_ok_for_arm (~INTVAL (operands[2]))"
561 [(set (match_dup 3) (match_dup 2))
562 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 3)))]
563 ""
564)
87b22bf7 565
2f02c19f 566;; The r/r/k alternative is required when reloading the address
567;; (plus (reg rN) (reg sp)) into (reg rN). In this case reload will
568;; put the duplicated register first, and not try the commutative version.
a0f94409 569(define_insn_and_split "*arm_addsi3"
7c36fe71 570 [(set (match_operand:SI 0 "s_register_operand" "=rk,l,l ,l ,r ,k ,r,r ,k ,r ,k,k,r ,k ,r")
571 (plus:SI (match_operand:SI 1 "s_register_operand" "%0 ,l,0 ,l ,rk,k ,r,rk,k ,rk,k,r,rk,k ,rk")
572 (match_operand:SI 2 "reg_or_int_operand" "rk ,l,Py,Pd,rI,rI,k,Pj,Pj,L ,L,L,PJ,PJ,?n")))]
25f905c2 573 "TARGET_32BIT"
5565501b 574 "@
c24d855d 575 add%?\\t%0, %0, %2
5565501b 576 add%?\\t%0, %1, %2
a0b3420a 577 add%?\\t%0, %1, %2
7c36fe71 578 add%?\\t%0, %1, %2
579 add%?\\t%0, %1, %2
aaa37ad6 580 add%?\\t%0, %1, %2
2f02c19f 581 add%?\\t%0, %2, %1
d5cbae34 582 addw%?\\t%0, %1, %2
583 addw%?\\t%0, %1, %2
aaa37ad6 584 sub%?\\t%0, %1, #%n2
87b22bf7 585 sub%?\\t%0, %1, #%n2
d7757711 586 sub%?\\t%0, %1, #%n2
d5cbae34 587 subw%?\\t%0, %1, #%n2
588 subw%?\\t%0, %1, #%n2
87b22bf7 589 #"
a3ffc315 590 "TARGET_32BIT
0438d37f 591 && CONST_INT_P (operands[2])
d5cbae34 592 && !const_ok_for_op (INTVAL (operands[2]), PLUS)
a3ffc315 593 && (reload_completed || !arm_eliminable_register (operands[1]))"
a0f94409 594 [(clobber (const_int 0))]
595 "
96f57e36 596 arm_split_constant (PLUS, SImode, curr_insn,
597 INTVAL (operands[2]), operands[0],
a0f94409 598 operands[1], 0);
599 DONE;
600 "
7c36fe71 601 [(set_attr "length" "2,4,4,4,4,4,4,4,4,4,4,4,4,4,16")
d5cbae34 602 (set_attr "predicable" "yes")
7c36fe71 603 (set_attr "predicable_short_it" "yes,yes,yes,yes,no,no,no,no,no,no,no,no,no,no,no")
604 (set_attr "arch" "t2,t2,t2,t2,*,*,*,t2,t2,*,*,a,t2,t2,*")
65f68e55 605 (set (attr "type") (if_then_else (match_operand 2 "const_int_operand" "")
d82e788e 606 (const_string "alu_imm")
112eda6f 607 (const_string "alu_sreg")))
65f68e55 608 ]
cffb2a26 609)
610
90c2bcf0 611(define_insn "addsi3_compare0"
bd5b4116 612 [(set (reg:CC_NOOV CC_REGNUM)
5565501b 613 (compare:CC_NOOV
65f68e55 614 (plus:SI (match_operand:SI 1 "s_register_operand" "r, r,r")
615 (match_operand:SI 2 "arm_add_operand" "I,L,r"))
5565501b 616 (const_int 0)))
65f68e55 617 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9c08d1fa 618 (plus:SI (match_dup 1) (match_dup 2)))]
ec792a7b 619 "TARGET_ARM"
5565501b 620 "@
25f905c2 621 add%.\\t%0, %1, %2
65f68e55 622 sub%.\\t%0, %1, #%n2
623 add%.\\t%0, %1, %2"
624 [(set_attr "conds" "set")
112eda6f 625 (set_attr "type" "alus_imm,alus_imm,alus_sreg")]
cffb2a26 626)
9c08d1fa 627
aea4c774 628(define_insn "*addsi3_compare0_scratch"
bd5b4116 629 [(set (reg:CC_NOOV CC_REGNUM)
aea4c774 630 (compare:CC_NOOV
65f68e55 631 (plus:SI (match_operand:SI 0 "s_register_operand" "r, r, r")
632 (match_operand:SI 1 "arm_add_operand" "I,L, r"))
aea4c774 633 (const_int 0)))]
ec792a7b 634 "TARGET_ARM"
cffb2a26 635 "@
636 cmn%?\\t%0, %1
65f68e55 637 cmp%?\\t%0, #%n1
638 cmn%?\\t%0, %1"
596e5e8f 639 [(set_attr "conds" "set")
65f68e55 640 (set_attr "predicable" "yes")
112eda6f 641 (set_attr "type" "alus_imm,alus_imm,alus_sreg")]
0d66636f 642)
cffb2a26 643
aed179ae 644(define_insn "*compare_negsi_si"
645 [(set (reg:CC_Z CC_REGNUM)
646 (compare:CC_Z
7c36fe71 647 (neg:SI (match_operand:SI 0 "s_register_operand" "l,r"))
648 (match_operand:SI 1 "s_register_operand" "l,r")))]
25f905c2 649 "TARGET_32BIT"
aed179ae 650 "cmn%?\\t%1, %0"
596e5e8f 651 [(set_attr "conds" "set")
7c36fe71 652 (set_attr "predicable" "yes")
653 (set_attr "arch" "t2,*")
654 (set_attr "length" "2,4")
1b7da4ac 655 (set_attr "predicable_short_it" "yes,no")
112eda6f 656 (set_attr "type" "alus_sreg")]
0d66636f 657)
aea4c774 658
203c488f 659;; This is the canonicalization of addsi3_compare0_for_combiner when the
660;; addend is a constant.
190efb17 661(define_insn "cmpsi2_addneg"
203c488f 662 [(set (reg:CC CC_REGNUM)
663 (compare:CC
664 (match_operand:SI 1 "s_register_operand" "r,r")
2a977b78 665 (match_operand:SI 2 "arm_addimm_operand" "L,I")))
203c488f 666 (set (match_operand:SI 0 "s_register_operand" "=r,r")
667 (plus:SI (match_dup 1)
2a977b78 668 (match_operand:SI 3 "arm_addimm_operand" "I,L")))]
25f905c2 669 "TARGET_32BIT && INTVAL (operands[2]) == -INTVAL (operands[3])"
203c488f 670 "@
2a977b78 671 add%.\\t%0, %1, %3
672 sub%.\\t%0, %1, #%n3"
1b7da4ac 673 [(set_attr "conds" "set")
112eda6f 674 (set_attr "type" "alus_sreg")]
203c488f 675)
676
677;; Convert the sequence
678;; sub rd, rn, #1
679;; cmn rd, #1 (equivalent to cmp rd, #-1)
680;; bne dest
681;; into
682;; subs rd, rn, #1
683;; bcs dest ((unsigned)rn >= 1)
684;; similarly for the beq variant using bcc.
685;; This is a common looping idiom (while (n--))
686(define_peephole2
372575c7 687 [(set (match_operand:SI 0 "arm_general_register_operand" "")
688 (plus:SI (match_operand:SI 1 "arm_general_register_operand" "")
203c488f 689 (const_int -1)))
690 (set (match_operand 2 "cc_register" "")
691 (compare (match_dup 0) (const_int -1)))
692 (set (pc)
693 (if_then_else (match_operator 3 "equality_operator"
694 [(match_dup 2) (const_int 0)])
695 (match_operand 4 "" "")
696 (match_operand 5 "" "")))]
25f905c2 697 "TARGET_32BIT && peep2_reg_dead_p (3, operands[2])"
203c488f 698 [(parallel[
699 (set (match_dup 2)
700 (compare:CC
701 (match_dup 1) (const_int 1)))
702 (set (match_dup 0) (plus:SI (match_dup 1) (const_int -1)))])
703 (set (pc)
704 (if_then_else (match_op_dup 3 [(match_dup 2) (const_int 0)])
705 (match_dup 4)
706 (match_dup 5)))]
707 "operands[2] = gen_rtx_REG (CCmode, CC_REGNUM);
708 operands[3] = gen_rtx_fmt_ee ((GET_CODE (operands[3]) == NE
709 ? GEU : LTU),
710 VOIDmode,
711 operands[2], const0_rtx);"
712)
713
ebcc79bc 714;; The next four insns work because they compare the result with one of
715;; the operands, and we know that the use of the condition code is
716;; either GEU or LTU, so we can use the carry flag from the addition
717;; instead of doing the compare a second time.
718(define_insn "*addsi3_compare_op1"
bd5b4116 719 [(set (reg:CC_C CC_REGNUM)
ebcc79bc 720 (compare:CC_C
65f68e55 721 (plus:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
722 (match_operand:SI 2 "arm_add_operand" "I,L,r"))
ebcc79bc 723 (match_dup 1)))
65f68e55 724 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
ebcc79bc 725 (plus:SI (match_dup 1) (match_dup 2)))]
25f905c2 726 "TARGET_32BIT"
ebcc79bc 727 "@
25f905c2 728 add%.\\t%0, %1, %2
65f68e55 729 sub%.\\t%0, %1, #%n2
730 add%.\\t%0, %1, %2"
731 [(set_attr "conds" "set")
112eda6f 732 (set_attr "type" "alus_imm,alus_imm,alus_sreg")]
0d66636f 733)
ebcc79bc 734
735(define_insn "*addsi3_compare_op2"
bd5b4116 736 [(set (reg:CC_C CC_REGNUM)
ebcc79bc 737 (compare:CC_C
65f68e55 738 (plus:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
739 (match_operand:SI 2 "arm_add_operand" "I,L,r"))
ebcc79bc 740 (match_dup 2)))
65f68e55 741 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9c08d1fa 742 (plus:SI (match_dup 1) (match_dup 2)))]
25f905c2 743 "TARGET_32BIT"
5565501b 744 "@
65f68e55 745 add%.\\t%0, %1, %2
25f905c2 746 add%.\\t%0, %1, %2
747 sub%.\\t%0, %1, #%n2"
65f68e55 748 [(set_attr "conds" "set")
112eda6f 749 (set_attr "type" "alus_imm,alus_imm,alus_sreg")]
0d66636f 750)
9c08d1fa 751
ebcc79bc 752(define_insn "*compare_addsi2_op0"
bd5b4116 753 [(set (reg:CC_C CC_REGNUM)
7c36fe71 754 (compare:CC_C
755 (plus:SI (match_operand:SI 0 "s_register_operand" "l,l,r,r,r")
756 (match_operand:SI 1 "arm_add_operand" "Pv,l,I,L,r"))
757 (match_dup 0)))]
25f905c2 758 "TARGET_32BIT"
ebcc79bc 759 "@
7c36fe71 760 cmp%?\\t%0, #%n1
761 cmn%?\\t%0, %1
ebcc79bc 762 cmn%?\\t%0, %1
65f68e55 763 cmp%?\\t%0, #%n1
764 cmn%?\\t%0, %1"
596e5e8f 765 [(set_attr "conds" "set")
65f68e55 766 (set_attr "predicable" "yes")
7c36fe71 767 (set_attr "arch" "t2,t2,*,*,*")
768 (set_attr "predicable_short_it" "yes,yes,no,no,no")
769 (set_attr "length" "2,2,4,4,4")
112eda6f 770 (set_attr "type" "alus_imm,alus_sreg,alus_imm,alus_imm,alus_sreg")]
0d66636f 771)
ebcc79bc 772
773(define_insn "*compare_addsi2_op1"
bd5b4116 774 [(set (reg:CC_C CC_REGNUM)
7c36fe71 775 (compare:CC_C
776 (plus:SI (match_operand:SI 0 "s_register_operand" "l,l,r,r,r")
777 (match_operand:SI 1 "arm_add_operand" "Pv,l,I,L,r"))
778 (match_dup 1)))]
25f905c2 779 "TARGET_32BIT"
ebcc79bc 780 "@
7c36fe71 781 cmp%?\\t%0, #%n1
782 cmn%?\\t%0, %1
ebcc79bc 783 cmn%?\\t%0, %1
65f68e55 784 cmp%?\\t%0, #%n1
785 cmn%?\\t%0, %1"
596e5e8f 786 [(set_attr "conds" "set")
65f68e55 787 (set_attr "predicable" "yes")
7c36fe71 788 (set_attr "arch" "t2,t2,*,*,*")
789 (set_attr "predicable_short_it" "yes,yes,no,no,no")
790 (set_attr "length" "2,2,4,4,4")
112eda6f 791 (set_attr "type" "alus_imm,alus_sreg,alus_imm,alus_imm,alus_sreg")]
7c36fe71 792 )
ebcc79bc 793
080c0b9a 794(define_insn "*addsi3_carryin_<optab>"
7c36fe71 795 [(set (match_operand:SI 0 "s_register_operand" "=l,r,r")
796 (plus:SI (plus:SI (match_operand:SI 1 "s_register_operand" "%l,r,r")
797 (match_operand:SI 2 "arm_not_operand" "0,rI,K"))
798 (LTUGEU:SI (reg:<cnb> CC_REGNUM) (const_int 0))))]
25f905c2 799 "TARGET_32BIT"
10e5ccd5 800 "@
a0b3420a 801 adc%?\\t%0, %1, %2
10e5ccd5 802 adc%?\\t%0, %1, %2
803 sbc%?\\t%0, %1, #%B2"
a7de272d 804 [(set_attr "conds" "use")
7c36fe71 805 (set_attr "predicable" "yes")
806 (set_attr "arch" "t2,*,*")
807 (set_attr "length" "4")
1b7da4ac 808 (set_attr "predicable_short_it" "yes,no,no")
809 (set_attr "type" "adc_reg,adc_reg,adc_imm")]
cffb2a26 810)
ebcc79bc 811
080c0b9a 812(define_insn "*addsi3_carryin_alt2_<optab>"
7c36fe71 813 [(set (match_operand:SI 0 "s_register_operand" "=l,r,r")
814 (plus:SI (plus:SI (LTUGEU:SI (reg:<cnb> CC_REGNUM) (const_int 0))
815 (match_operand:SI 1 "s_register_operand" "%l,r,r"))
816 (match_operand:SI 2 "arm_rhs_operand" "l,rI,K")))]
25f905c2 817 "TARGET_32BIT"
10e5ccd5 818 "@
a0b3420a 819 adc%?\\t%0, %1, %2
10e5ccd5 820 adc%?\\t%0, %1, %2
821 sbc%?\\t%0, %1, #%B2"
a7de272d 822 [(set_attr "conds" "use")
7c36fe71 823 (set_attr "predicable" "yes")
824 (set_attr "arch" "t2,*,*")
825 (set_attr "length" "4")
1b7da4ac 826 (set_attr "predicable_short_it" "yes,no,no")
827 (set_attr "type" "adc_reg,adc_reg,adc_imm")]
0d66636f 828)
ebcc79bc 829
080c0b9a 830(define_insn "*addsi3_carryin_shift_<optab>"
ebcc79bc 831 [(set (match_operand:SI 0 "s_register_operand" "=r")
080c0b9a 832 (plus:SI (plus:SI
833 (match_operator:SI 2 "shift_operator"
834 [(match_operand:SI 3 "s_register_operand" "r")
835 (match_operand:SI 4 "reg_or_int_operand" "rM")])
836 (match_operand:SI 1 "s_register_operand" "r"))
837 (LTUGEU:SI (reg:<cnb> CC_REGNUM) (const_int 0))))]
25f905c2 838 "TARGET_32BIT"
080c0b9a 839 "adc%?\\t%0, %1, %3%S2"
840 [(set_attr "conds" "use")
a7de272d 841 (set_attr "predicable" "yes")
7c36fe71 842 (set_attr "predicable_short_it" "no")
080c0b9a 843 (set (attr "type") (if_then_else (match_operand 4 "const_int_operand" "")
d82e788e 844 (const_string "alu_shift_imm")
845 (const_string "alu_shift_reg")))]
cffb2a26 846)
ebcc79bc 847
922b6913 848(define_insn "*addsi3_carryin_clobercc_<optab>"
849 [(set (match_operand:SI 0 "s_register_operand" "=r")
850 (plus:SI (plus:SI (match_operand:SI 1 "s_register_operand" "%r")
851 (match_operand:SI 2 "arm_rhs_operand" "rI"))
852 (LTUGEU:SI (reg:<cnb> CC_REGNUM) (const_int 0))))
853 (clobber (reg:CC CC_REGNUM))]
854 "TARGET_32BIT"
855 "adc%.\\t%0, %1, %2"
1b7da4ac 856 [(set_attr "conds" "set")
857 (set_attr "type" "adcs_reg")]
922b6913 858)
859
9154bd82 860(define_insn "*subsi3_carryin"
861 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
862 (minus:SI (minus:SI (match_operand:SI 1 "reg_or_int_operand" "r,I")
863 (match_operand:SI 2 "s_register_operand" "r,r"))
864 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
865 "TARGET_32BIT"
866 "@
867 sbc%?\\t%0, %1, %2
868 rsc%?\\t%0, %2, %1"
869 [(set_attr "conds" "use")
870 (set_attr "arch" "*,a")
7c36fe71 871 (set_attr "predicable" "yes")
1b7da4ac 872 (set_attr "predicable_short_it" "no")
873 (set_attr "type" "adc_reg,adc_imm")]
9154bd82 874)
875
876(define_insn "*subsi3_carryin_const"
877 [(set (match_operand:SI 0 "s_register_operand" "=r")
878 (minus:SI (plus:SI (match_operand:SI 1 "reg_or_int_operand" "r")
879 (match_operand:SI 2 "arm_not_operand" "K"))
880 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
881 "TARGET_32BIT"
882 "sbc\\t%0, %1, #%B2"
1b7da4ac 883 [(set_attr "conds" "use")
884 (set_attr "type" "adc_imm")]
9154bd82 885)
886
887(define_insn "*subsi3_carryin_compare"
888 [(set (reg:CC CC_REGNUM)
889 (compare:CC (match_operand:SI 1 "s_register_operand" "r")
890 (match_operand:SI 2 "s_register_operand" "r")))
891 (set (match_operand:SI 0 "s_register_operand" "=r")
892 (minus:SI (minus:SI (match_dup 1)
893 (match_dup 2))
894 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
895 "TARGET_32BIT"
896 "sbcs\\t%0, %1, %2"
1b7da4ac 897 [(set_attr "conds" "set")
898 (set_attr "type" "adcs_reg")]
9154bd82 899)
900
901(define_insn "*subsi3_carryin_compare_const"
902 [(set (reg:CC CC_REGNUM)
903 (compare:CC (match_operand:SI 1 "reg_or_int_operand" "r")
904 (match_operand:SI 2 "arm_not_operand" "K")))
905 (set (match_operand:SI 0 "s_register_operand" "=r")
906 (minus:SI (plus:SI (match_dup 1)
907 (match_dup 2))
908 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
909 "TARGET_32BIT"
910 "sbcs\\t%0, %1, #%B2"
1b7da4ac 911 [(set_attr "conds" "set")
912 (set_attr "type" "adcs_imm")]
9154bd82 913)
914
915(define_insn "*subsi3_carryin_shift"
916 [(set (match_operand:SI 0 "s_register_operand" "=r")
917 (minus:SI (minus:SI
918 (match_operand:SI 1 "s_register_operand" "r")
919 (match_operator:SI 2 "shift_operator"
920 [(match_operand:SI 3 "s_register_operand" "r")
921 (match_operand:SI 4 "reg_or_int_operand" "rM")]))
922 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
923 "TARGET_32BIT"
924 "sbc%?\\t%0, %1, %3%S2"
925 [(set_attr "conds" "use")
926 (set_attr "predicable" "yes")
927 (set (attr "type") (if_then_else (match_operand 4 "const_int_operand" "")
d82e788e 928 (const_string "alu_shift_imm")
929 (const_string "alu_shift_reg")))]
9154bd82 930)
931
932(define_insn "*rsbsi3_carryin_shift"
933 [(set (match_operand:SI 0 "s_register_operand" "=r")
934 (minus:SI (minus:SI
935 (match_operator:SI 2 "shift_operator"
936 [(match_operand:SI 3 "s_register_operand" "r")
937 (match_operand:SI 4 "reg_or_int_operand" "rM")])
938 (match_operand:SI 1 "s_register_operand" "r"))
939 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
940 "TARGET_ARM"
941 "rsc%?\\t%0, %1, %3%S2"
942 [(set_attr "conds" "use")
943 (set_attr "predicable" "yes")
944 (set (attr "type") (if_then_else (match_operand 4 "const_int_operand" "")
d82e788e 945 (const_string "alu_shift_imm")
946 (const_string "alu_shift_reg")))]
9154bd82 947)
948
d795fb69 949; transform ((x << y) - 1) to ~(~(x-1) << y) Where X is a constant.
950(define_split
951 [(set (match_operand:SI 0 "s_register_operand" "")
952 (plus:SI (ashift:SI (match_operand:SI 1 "const_int_operand" "")
953 (match_operand:SI 2 "s_register_operand" ""))
954 (const_int -1)))
955 (clobber (match_operand:SI 3 "s_register_operand" ""))]
25f905c2 956 "TARGET_32BIT"
d795fb69 957 [(set (match_dup 3) (match_dup 1))
958 (set (match_dup 0) (not:SI (ashift:SI (match_dup 3) (match_dup 2))))]
959 "
960 operands[1] = GEN_INT (~(INTVAL (operands[1]) - 1));
961")
962
604f3a0a 963(define_expand "addsf3"
964 [(set (match_operand:SF 0 "s_register_operand" "")
965 (plus:SF (match_operand:SF 1 "s_register_operand" "")
d86c91f6 966 (match_operand:SF 2 "s_register_operand" "")))]
25f905c2 967 "TARGET_32BIT && TARGET_HARD_FLOAT"
604f3a0a 968 "
604f3a0a 969")
970
604f3a0a 971(define_expand "adddf3"
972 [(set (match_operand:DF 0 "s_register_operand" "")
973 (plus:DF (match_operand:DF 1 "s_register_operand" "")
d86c91f6 974 (match_operand:DF 2 "s_register_operand" "")))]
a50d7267 975 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
604f3a0a 976 "
604f3a0a 977")
978
cffb2a26 979(define_expand "subdi3"
980 [(parallel
981 [(set (match_operand:DI 0 "s_register_operand" "")
982 (minus:DI (match_operand:DI 1 "s_register_operand" "")
983 (match_operand:DI 2 "s_register_operand" "")))
bd5b4116 984 (clobber (reg:CC CC_REGNUM))])]
cffb2a26 985 "TARGET_EITHER"
986 "
25f905c2 987 if (TARGET_THUMB1)
cffb2a26 988 {
0438d37f 989 if (!REG_P (operands[1]))
5aa8c5f0 990 operands[1] = force_reg (DImode, operands[1]);
0438d37f 991 if (!REG_P (operands[2]))
5aa8c5f0 992 operands[2] = force_reg (DImode, operands[2]);
cffb2a26 993 }
994 "
995)
996
2f9b23e3 997(define_insn_and_split "*arm_subdi3"
cffb2a26 998 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r,&r")
9c08d1fa 999 (minus:DI (match_operand:DI 1 "s_register_operand" "0,r,0")
1000 (match_operand:DI 2 "s_register_operand" "r,0,0")))
bd5b4116 1001 (clobber (reg:CC CC_REGNUM))]
94829feb 1002 "TARGET_32BIT && !TARGET_NEON"
2f9b23e3 1003 "#" ; "subs\\t%Q0, %Q1, %Q2\;sbc\\t%R0, %R1, %R2"
1004 "&& reload_completed"
1005 [(parallel [(set (reg:CC CC_REGNUM)
1006 (compare:CC (match_dup 1) (match_dup 2)))
1007 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
1008 (set (match_dup 3) (minus:SI (minus:SI (match_dup 4) (match_dup 5))
1009 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1010 {
1011 operands[3] = gen_highpart (SImode, operands[0]);
1012 operands[0] = gen_lowpart (SImode, operands[0]);
1013 operands[4] = gen_highpart (SImode, operands[1]);
1014 operands[1] = gen_lowpart (SImode, operands[1]);
1015 operands[5] = gen_highpart (SImode, operands[2]);
1016 operands[2] = gen_lowpart (SImode, operands[2]);
1017 }
cffb2a26 1018 [(set_attr "conds" "clob")
1b7da4ac 1019 (set_attr "length" "8")
1020 (set_attr "type" "multiple")]
cffb2a26 1021)
1022
2f9b23e3 1023(define_insn_and_split "*subdi_di_zesidi"
cffb2a26 1024 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
e5fea38e 1025 (minus:DI (match_operand:DI 1 "s_register_operand" "0,r")
9c08d1fa 1026 (zero_extend:DI
cffb2a26 1027 (match_operand:SI 2 "s_register_operand" "r,r"))))
bd5b4116 1028 (clobber (reg:CC CC_REGNUM))]
25f905c2 1029 "TARGET_32BIT"
2f9b23e3 1030 "#" ; "subs\\t%Q0, %Q1, %2\;sbc\\t%R0, %R1, #0"
1031 "&& reload_completed"
1032 [(parallel [(set (reg:CC CC_REGNUM)
1033 (compare:CC (match_dup 1) (match_dup 2)))
1034 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
1035 (set (match_dup 3) (minus:SI (plus:SI (match_dup 4) (match_dup 5))
1036 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1037 {
1038 operands[3] = gen_highpart (SImode, operands[0]);
1039 operands[0] = gen_lowpart (SImode, operands[0]);
1040 operands[4] = gen_highpart (SImode, operands[1]);
1041 operands[1] = gen_lowpart (SImode, operands[1]);
1042 operands[5] = GEN_INT (~0);
1043 }
cffb2a26 1044 [(set_attr "conds" "clob")
1b7da4ac 1045 (set_attr "length" "8")
1046 (set_attr "type" "multiple")]
cffb2a26 1047)
9c08d1fa 1048
2f9b23e3 1049(define_insn_and_split "*subdi_di_sesidi"
cffb2a26 1050 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
e5fea38e 1051 (minus:DI (match_operand:DI 1 "s_register_operand" "0,r")
9c08d1fa 1052 (sign_extend:DI
cffb2a26 1053 (match_operand:SI 2 "s_register_operand" "r,r"))))
bd5b4116 1054 (clobber (reg:CC CC_REGNUM))]
25f905c2 1055 "TARGET_32BIT"
2f9b23e3 1056 "#" ; "subs\\t%Q0, %Q1, %2\;sbc\\t%R0, %R1, %2, asr #31"
1057 "&& reload_completed"
1058 [(parallel [(set (reg:CC CC_REGNUM)
1059 (compare:CC (match_dup 1) (match_dup 2)))
1060 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
1061 (set (match_dup 3) (minus:SI (minus:SI (match_dup 4)
1062 (ashiftrt:SI (match_dup 2)
1063 (const_int 31)))
1064 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1065 {
1066 operands[3] = gen_highpart (SImode, operands[0]);
1067 operands[0] = gen_lowpart (SImode, operands[0]);
1068 operands[4] = gen_highpart (SImode, operands[1]);
1069 operands[1] = gen_lowpart (SImode, operands[1]);
1070 }
cffb2a26 1071 [(set_attr "conds" "clob")
1b7da4ac 1072 (set_attr "length" "8")
1073 (set_attr "type" "multiple")]
cffb2a26 1074)
9c08d1fa 1075
2f9b23e3 1076(define_insn_and_split "*subdi_zesidi_di"
cffb2a26 1077 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
9c08d1fa 1078 (minus:DI (zero_extend:DI
cffb2a26 1079 (match_operand:SI 2 "s_register_operand" "r,r"))
e5fea38e 1080 (match_operand:DI 1 "s_register_operand" "0,r")))
bd5b4116 1081 (clobber (reg:CC CC_REGNUM))]
cffb2a26 1082 "TARGET_ARM"
2f9b23e3 1083 "#" ; "rsbs\\t%Q0, %Q1, %2\;rsc\\t%R0, %R1, #0"
1084 ; is equivalent to:
1085 ; "subs\\t%Q0, %2, %Q1\;rsc\\t%R0, %R1, #0"
1086 "&& reload_completed"
1087 [(parallel [(set (reg:CC CC_REGNUM)
1088 (compare:CC (match_dup 2) (match_dup 1)))
1089 (set (match_dup 0) (minus:SI (match_dup 2) (match_dup 1)))])
1090 (set (match_dup 3) (minus:SI (minus:SI (const_int 0) (match_dup 4))
1091 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1092 {
1093 operands[3] = gen_highpart (SImode, operands[0]);
1094 operands[0] = gen_lowpart (SImode, operands[0]);
1095 operands[4] = gen_highpart (SImode, operands[1]);
1096 operands[1] = gen_lowpart (SImode, operands[1]);
1097 }
cffb2a26 1098 [(set_attr "conds" "clob")
1b7da4ac 1099 (set_attr "length" "8")
1100 (set_attr "type" "multiple")]
cffb2a26 1101)
9c08d1fa 1102
2f9b23e3 1103(define_insn_and_split "*subdi_sesidi_di"
cffb2a26 1104 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
9c08d1fa 1105 (minus:DI (sign_extend:DI
cffb2a26 1106 (match_operand:SI 2 "s_register_operand" "r,r"))
e5fea38e 1107 (match_operand:DI 1 "s_register_operand" "0,r")))
bd5b4116 1108 (clobber (reg:CC CC_REGNUM))]
cffb2a26 1109 "TARGET_ARM"
2f9b23e3 1110 "#" ; "rsbs\\t%Q0, %Q1, %2\;rsc\\t%R0, %R1, %2, asr #31"
1111 ; is equivalent to:
1112 ; "subs\\t%Q0, %2, %Q1\;rsc\\t%R0, %R1, %2, asr #31"
1113 "&& reload_completed"
1114 [(parallel [(set (reg:CC CC_REGNUM)
1115 (compare:CC (match_dup 2) (match_dup 1)))
1116 (set (match_dup 0) (minus:SI (match_dup 2) (match_dup 1)))])
1117 (set (match_dup 3) (minus:SI (minus:SI
1118 (ashiftrt:SI (match_dup 2)
1119 (const_int 31))
1120 (match_dup 4))
1121 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1122 {
1123 operands[3] = gen_highpart (SImode, operands[0]);
1124 operands[0] = gen_lowpart (SImode, operands[0]);
1125 operands[4] = gen_highpart (SImode, operands[1]);
1126 operands[1] = gen_lowpart (SImode, operands[1]);
1127 }
cffb2a26 1128 [(set_attr "conds" "clob")
1b7da4ac 1129 (set_attr "length" "8")
1130 (set_attr "type" "multiple")]
cffb2a26 1131)
9c08d1fa 1132
2f9b23e3 1133(define_insn_and_split "*subdi_zesidi_zesidi"
cffb2a26 1134 [(set (match_operand:DI 0 "s_register_operand" "=r")
9c08d1fa 1135 (minus:DI (zero_extend:DI
cffb2a26 1136 (match_operand:SI 1 "s_register_operand" "r"))
9c08d1fa 1137 (zero_extend:DI
cffb2a26 1138 (match_operand:SI 2 "s_register_operand" "r"))))
bd5b4116 1139 (clobber (reg:CC CC_REGNUM))]
25f905c2 1140 "TARGET_32BIT"
2f9b23e3 1141 "#" ; "subs\\t%Q0, %1, %2\;sbc\\t%R0, %1, %1"
1142 "&& reload_completed"
1143 [(parallel [(set (reg:CC CC_REGNUM)
1144 (compare:CC (match_dup 1) (match_dup 2)))
1145 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
1146 (set (match_dup 3) (minus:SI (minus:SI (match_dup 1) (match_dup 1))
1147 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1148 {
1149 operands[3] = gen_highpart (SImode, operands[0]);
1150 operands[0] = gen_lowpart (SImode, operands[0]);
1151 }
cffb2a26 1152 [(set_attr "conds" "clob")
1b7da4ac 1153 (set_attr "length" "8")
1154 (set_attr "type" "multiple")]
cffb2a26 1155)
b11cae9e 1156
87b22bf7 1157(define_expand "subsi3"
cffb2a26 1158 [(set (match_operand:SI 0 "s_register_operand" "")
87b22bf7 1159 (minus:SI (match_operand:SI 1 "reg_or_int_operand" "")
1160 (match_operand:SI 2 "s_register_operand" "")))]
cffb2a26 1161 "TARGET_EITHER"
87b22bf7 1162 "
0438d37f 1163 if (CONST_INT_P (operands[1]))
87b22bf7 1164 {
25f905c2 1165 if (TARGET_32BIT)
cffb2a26 1166 {
96f57e36 1167 arm_split_constant (MINUS, SImode, NULL_RTX,
1168 INTVAL (operands[1]), operands[0],
e1ba4a27 1169 operands[2], optimize && can_create_pseudo_p ());
cffb2a26 1170 DONE;
1171 }
25f905c2 1172 else /* TARGET_THUMB1 */
cffb2a26 1173 operands[1] = force_reg (SImode, operands[1]);
87b22bf7 1174 }
cffb2a26 1175 "
1176)
87b22bf7 1177
25f905c2 1178; ??? Check Thumb-2 split length
a0f94409 1179(define_insn_and_split "*arm_subsi3_insn"
7c36fe71 1180 [(set (match_operand:SI 0 "s_register_operand" "=l,l ,l ,l ,r ,r,r,rk,r")
1181 (minus:SI (match_operand:SI 1 "reg_or_int_operand" "l ,0 ,l ,Pz,rI,r,r,k ,?n")
1182 (match_operand:SI 2 "reg_or_int_operand" "l ,Py,Pd,l ,r ,I,r,r ,r")))]
25f905c2 1183 "TARGET_32BIT"
e2348bcb 1184 "@
7c36fe71 1185 sub%?\\t%0, %1, %2
1186 sub%?\\t%0, %2
1187 sub%?\\t%0, %1, %2
1188 rsb%?\\t%0, %2, %1
87b22bf7 1189 rsb%?\\t%0, %2, %1
aaa37ad6 1190 sub%?\\t%0, %1, %2
080c0b9a 1191 sub%?\\t%0, %1, %2
65f68e55 1192 sub%?\\t%0, %1, %2
87b22bf7 1193 #"
0438d37f 1194 "&& (CONST_INT_P (operands[1])
91a5e339 1195 && !const_ok_for_arm (INTVAL (operands[1])))"
87b22bf7 1196 [(clobber (const_int 0))]
1197 "
96f57e36 1198 arm_split_constant (MINUS, SImode, curr_insn,
1199 INTVAL (operands[1]), operands[0], operands[2], 0);
87b22bf7 1200 DONE;
cffb2a26 1201 "
7c36fe71 1202 [(set_attr "length" "4,4,4,4,4,4,4,4,16")
1203 (set_attr "arch" "t2,t2,t2,t2,*,*,*,*,*")
65f68e55 1204 (set_attr "predicable" "yes")
7c36fe71 1205 (set_attr "predicable_short_it" "yes,yes,yes,yes,no,no,no,no,no")
112eda6f 1206 (set_attr "type" "alu_sreg,alu_sreg,alu_sreg,alu_sreg,alu_imm,alu_imm,alu_sreg,alu_sreg,multiple")]
a0f94409 1207)
1208
1209(define_peephole2
1210 [(match_scratch:SI 3 "r")
372575c7 1211 (set (match_operand:SI 0 "arm_general_register_operand" "")
a0f94409 1212 (minus:SI (match_operand:SI 1 "const_int_operand" "")
372575c7 1213 (match_operand:SI 2 "arm_general_register_operand" "")))]
25f905c2 1214 "TARGET_32BIT
a0f94409 1215 && !const_ok_for_arm (INTVAL (operands[1]))
1216 && const_ok_for_arm (~INTVAL (operands[1]))"
1217 [(set (match_dup 3) (match_dup 1))
1218 (set (match_dup 0) (minus:SI (match_dup 3) (match_dup 2)))]
1219 ""
cffb2a26 1220)
b11cae9e 1221
f7fbdd4a 1222(define_insn "*subsi3_compare0"
bd5b4116 1223 [(set (reg:CC_NOOV CC_REGNUM)
215b30b3 1224 (compare:CC_NOOV
65f68e55 1225 (minus:SI (match_operand:SI 1 "arm_rhs_operand" "r,r,I")
1226 (match_operand:SI 2 "arm_rhs_operand" "I,r,r"))
215b30b3 1227 (const_int 0)))
65f68e55 1228 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9c08d1fa 1229 (minus:SI (match_dup 1) (match_dup 2)))]
25f905c2 1230 "TARGET_32BIT"
e2348bcb 1231 "@
65f68e55 1232 sub%.\\t%0, %1, %2
25f905c2 1233 sub%.\\t%0, %1, %2
1234 rsb%.\\t%0, %2, %1"
65f68e55 1235 [(set_attr "conds" "set")
112eda6f 1236 (set_attr "type" "alus_imm,alus_sreg,alus_sreg")]
cffb2a26 1237)
9c08d1fa 1238
190efb17 1239(define_insn "subsi3_compare"
080c0b9a 1240 [(set (reg:CC CC_REGNUM)
65f68e55 1241 (compare:CC (match_operand:SI 1 "arm_rhs_operand" "r,r,I")
1242 (match_operand:SI 2 "arm_rhs_operand" "I,r,r")))
1243 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
2df9477b 1244 (minus:SI (match_dup 1) (match_dup 2)))]
1245 "TARGET_32BIT"
1246 "@
65f68e55 1247 sub%.\\t%0, %1, %2
2df9477b 1248 sub%.\\t%0, %1, %2
1249 rsb%.\\t%0, %2, %1"
65f68e55 1250 [(set_attr "conds" "set")
112eda6f 1251 (set_attr "type" "alus_imm,alus_sreg,alus_sreg")]
2df9477b 1252)
1253
604f3a0a 1254(define_expand "subsf3"
1255 [(set (match_operand:SF 0 "s_register_operand" "")
d86c91f6 1256 (minus:SF (match_operand:SF 1 "s_register_operand" "")
1257 (match_operand:SF 2 "s_register_operand" "")))]
25f905c2 1258 "TARGET_32BIT && TARGET_HARD_FLOAT"
604f3a0a 1259 "
604f3a0a 1260")
1261
604f3a0a 1262(define_expand "subdf3"
1263 [(set (match_operand:DF 0 "s_register_operand" "")
d86c91f6 1264 (minus:DF (match_operand:DF 1 "s_register_operand" "")
1265 (match_operand:DF 2 "s_register_operand" "")))]
a50d7267 1266 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
604f3a0a 1267 "
604f3a0a 1268")
1269
b11cae9e 1270\f
1271;; Multiplication insns
1272
4422d91f 1273(define_expand "mulhi3"
1274 [(set (match_operand:HI 0 "s_register_operand" "")
1275 (mult:HI (match_operand:HI 1 "s_register_operand" "")
1276 (match_operand:HI 2 "s_register_operand" "")))]
1277 "TARGET_DSP_MULTIPLY"
1278 "
1279 {
1280 rtx result = gen_reg_rtx (SImode);
1281 emit_insn (gen_mulhisi3 (result, operands[1], operands[2]));
1282 emit_move_insn (operands[0], gen_lowpart (HImode, result));
1283 DONE;
1284 }"
1285)
1286
cffb2a26 1287(define_expand "mulsi3"
1288 [(set (match_operand:SI 0 "s_register_operand" "")
1289 (mult:SI (match_operand:SI 2 "s_register_operand" "")
1290 (match_operand:SI 1 "s_register_operand" "")))]
1291 "TARGET_EITHER"
1292 ""
1293)
1294
9c08d1fa 1295;; Use `&' and then `0' to prevent the operands 0 and 1 being the same
cffb2a26 1296(define_insn "*arm_mulsi3"
1297 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r")
9c08d1fa 1298 (mult:SI (match_operand:SI 2 "s_register_operand" "r,r")
e5fea38e 1299 (match_operand:SI 1 "s_register_operand" "%0,r")))]
58d7d654 1300 "TARGET_32BIT && !arm_arch6"
f7fbdd4a 1301 "mul%?\\t%0, %2, %1"
9da0ec36 1302 [(set_attr "type" "mul")
0d66636f 1303 (set_attr "predicable" "yes")]
cffb2a26 1304)
1305
58d7d654 1306(define_insn "*arm_mulsi3_v6"
d952d547 1307 [(set (match_operand:SI 0 "s_register_operand" "=l,l,r")
1308 (mult:SI (match_operand:SI 1 "s_register_operand" "0,l,r")
1309 (match_operand:SI 2 "s_register_operand" "l,0,r")))]
58d7d654 1310 "TARGET_32BIT && arm_arch6"
1311 "mul%?\\t%0, %1, %2"
9da0ec36 1312 [(set_attr "type" "mul")
d952d547 1313 (set_attr "predicable" "yes")
1314 (set_attr "arch" "t2,t2,*")
1315 (set_attr "length" "4")
1316 (set_attr "predicable_short_it" "yes,yes,no")]
58d7d654 1317)
1318
f7fbdd4a 1319(define_insn "*mulsi3_compare0"
bd5b4116 1320 [(set (reg:CC_NOOV CC_REGNUM)
9c08d1fa 1321 (compare:CC_NOOV (mult:SI
1322 (match_operand:SI 2 "s_register_operand" "r,r")
e5fea38e 1323 (match_operand:SI 1 "s_register_operand" "%0,r"))
9c08d1fa 1324 (const_int 0)))
1325 (set (match_operand:SI 0 "s_register_operand" "=&r,&r")
1326 (mult:SI (match_dup 2) (match_dup 1)))]
58d7d654 1327 "TARGET_ARM && !arm_arch6"
1328 "mul%.\\t%0, %2, %1"
1329 [(set_attr "conds" "set")
9da0ec36 1330 (set_attr "type" "muls")]
58d7d654 1331)
1332
1333(define_insn "*mulsi3_compare0_v6"
1334 [(set (reg:CC_NOOV CC_REGNUM)
1335 (compare:CC_NOOV (mult:SI
1336 (match_operand:SI 2 "s_register_operand" "r")
1337 (match_operand:SI 1 "s_register_operand" "r"))
1338 (const_int 0)))
1339 (set (match_operand:SI 0 "s_register_operand" "=r")
1340 (mult:SI (match_dup 2) (match_dup 1)))]
1341 "TARGET_ARM && arm_arch6 && optimize_size"
25f905c2 1342 "mul%.\\t%0, %2, %1"
cffb2a26 1343 [(set_attr "conds" "set")
9da0ec36 1344 (set_attr "type" "muls")]
cffb2a26 1345)
9c08d1fa 1346
f7fbdd4a 1347(define_insn "*mulsi_compare0_scratch"
bd5b4116 1348 [(set (reg:CC_NOOV CC_REGNUM)
9c08d1fa 1349 (compare:CC_NOOV (mult:SI
1350 (match_operand:SI 2 "s_register_operand" "r,r")
e5fea38e 1351 (match_operand:SI 1 "s_register_operand" "%0,r"))
9c08d1fa 1352 (const_int 0)))
1353 (clobber (match_scratch:SI 0 "=&r,&r"))]
58d7d654 1354 "TARGET_ARM && !arm_arch6"
1355 "mul%.\\t%0, %2, %1"
1356 [(set_attr "conds" "set")
9da0ec36 1357 (set_attr "type" "muls")]
58d7d654 1358)
1359
1360(define_insn "*mulsi_compare0_scratch_v6"
1361 [(set (reg:CC_NOOV CC_REGNUM)
1362 (compare:CC_NOOV (mult:SI
1363 (match_operand:SI 2 "s_register_operand" "r")
1364 (match_operand:SI 1 "s_register_operand" "r"))
1365 (const_int 0)))
1366 (clobber (match_scratch:SI 0 "=r"))]
1367 "TARGET_ARM && arm_arch6 && optimize_size"
25f905c2 1368 "mul%.\\t%0, %2, %1"
cffb2a26 1369 [(set_attr "conds" "set")
9da0ec36 1370 (set_attr "type" "muls")]
cffb2a26 1371)
9c08d1fa 1372
b11cae9e 1373;; Unnamed templates to match MLA instruction.
1374
f7fbdd4a 1375(define_insn "*mulsi3addsi"
9c08d1fa 1376 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r,&r")
c8f69309 1377 (plus:SI
9c08d1fa 1378 (mult:SI (match_operand:SI 2 "s_register_operand" "r,r,r,r")
e5fea38e 1379 (match_operand:SI 1 "s_register_operand" "%0,r,0,r"))
1380 (match_operand:SI 3 "s_register_operand" "r,r,0,0")))]
58d7d654 1381 "TARGET_32BIT && !arm_arch6"
1382 "mla%?\\t%0, %2, %1, %3"
9da0ec36 1383 [(set_attr "type" "mla")
58d7d654 1384 (set_attr "predicable" "yes")]
1385)
1386
1387(define_insn "*mulsi3addsi_v6"
1388 [(set (match_operand:SI 0 "s_register_operand" "=r")
1389 (plus:SI
1390 (mult:SI (match_operand:SI 2 "s_register_operand" "r")
1391 (match_operand:SI 1 "s_register_operand" "r"))
1392 (match_operand:SI 3 "s_register_operand" "r")))]
1393 "TARGET_32BIT && arm_arch6"
f7fbdd4a 1394 "mla%?\\t%0, %2, %1, %3"
9da0ec36 1395 [(set_attr "type" "mla")
d952d547 1396 (set_attr "predicable" "yes")
1397 (set_attr "predicable_short_it" "no")]
0d66636f 1398)
b11cae9e 1399
f7fbdd4a 1400(define_insn "*mulsi3addsi_compare0"
bd5b4116 1401 [(set (reg:CC_NOOV CC_REGNUM)
215b30b3 1402 (compare:CC_NOOV
1403 (plus:SI (mult:SI
1404 (match_operand:SI 2 "s_register_operand" "r,r,r,r")
e5fea38e 1405 (match_operand:SI 1 "s_register_operand" "%0,r,0,r"))
1406 (match_operand:SI 3 "s_register_operand" "r,r,0,0"))
215b30b3 1407 (const_int 0)))
9c08d1fa 1408 (set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r,&r")
1409 (plus:SI (mult:SI (match_dup 2) (match_dup 1))
1410 (match_dup 3)))]
58d7d654 1411 "TARGET_ARM && arm_arch6"
1412 "mla%.\\t%0, %2, %1, %3"
1413 [(set_attr "conds" "set")
9da0ec36 1414 (set_attr "type" "mlas")]
58d7d654 1415)
1416
1417(define_insn "*mulsi3addsi_compare0_v6"
1418 [(set (reg:CC_NOOV CC_REGNUM)
1419 (compare:CC_NOOV
1420 (plus:SI (mult:SI
1421 (match_operand:SI 2 "s_register_operand" "r")
1422 (match_operand:SI 1 "s_register_operand" "r"))
1423 (match_operand:SI 3 "s_register_operand" "r"))
1424 (const_int 0)))
1425 (set (match_operand:SI 0 "s_register_operand" "=r")
1426 (plus:SI (mult:SI (match_dup 2) (match_dup 1))
1427 (match_dup 3)))]
1428 "TARGET_ARM && arm_arch6 && optimize_size"
25f905c2 1429 "mla%.\\t%0, %2, %1, %3"
0d66636f 1430 [(set_attr "conds" "set")
9da0ec36 1431 (set_attr "type" "mlas")]
0d66636f 1432)
9c08d1fa 1433
f7fbdd4a 1434(define_insn "*mulsi3addsi_compare0_scratch"
bd5b4116 1435 [(set (reg:CC_NOOV CC_REGNUM)
215b30b3 1436 (compare:CC_NOOV
1437 (plus:SI (mult:SI
1438 (match_operand:SI 2 "s_register_operand" "r,r,r,r")
e5fea38e 1439 (match_operand:SI 1 "s_register_operand" "%0,r,0,r"))
215b30b3 1440 (match_operand:SI 3 "s_register_operand" "?r,r,0,0"))
1441 (const_int 0)))
9c08d1fa 1442 (clobber (match_scratch:SI 0 "=&r,&r,&r,&r"))]
58d7d654 1443 "TARGET_ARM && !arm_arch6"
1444 "mla%.\\t%0, %2, %1, %3"
1445 [(set_attr "conds" "set")
9da0ec36 1446 (set_attr "type" "mlas")]
58d7d654 1447)
1448
1449(define_insn "*mulsi3addsi_compare0_scratch_v6"
1450 [(set (reg:CC_NOOV CC_REGNUM)
1451 (compare:CC_NOOV
1452 (plus:SI (mult:SI
1453 (match_operand:SI 2 "s_register_operand" "r")
1454 (match_operand:SI 1 "s_register_operand" "r"))
1455 (match_operand:SI 3 "s_register_operand" "r"))
1456 (const_int 0)))
1457 (clobber (match_scratch:SI 0 "=r"))]
1458 "TARGET_ARM && arm_arch6 && optimize_size"
25f905c2 1459 "mla%.\\t%0, %2, %1, %3"
cffb2a26 1460 [(set_attr "conds" "set")
9da0ec36 1461 (set_attr "type" "mlas")]
cffb2a26 1462)
f7fbdd4a 1463
89545238 1464(define_insn "*mulsi3subsi"
1465 [(set (match_operand:SI 0 "s_register_operand" "=r")
1466 (minus:SI
1467 (match_operand:SI 3 "s_register_operand" "r")
1468 (mult:SI (match_operand:SI 2 "s_register_operand" "r")
1469 (match_operand:SI 1 "s_register_operand" "r"))))]
1470 "TARGET_32BIT && arm_arch_thumb2"
1471 "mls%?\\t%0, %2, %1, %3"
9da0ec36 1472 [(set_attr "type" "mla")
d952d547 1473 (set_attr "predicable" "yes")
1474 (set_attr "predicable_short_it" "no")]
89545238 1475)
1476
5cdca009 1477(define_expand "maddsidi4"
1478 [(set (match_operand:DI 0 "s_register_operand" "")
1479 (plus:DI
1480 (mult:DI
1481 (sign_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1482 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "")))
1483 (match_operand:DI 3 "s_register_operand" "")))]
1484 "TARGET_32BIT && arm_arch3m"
1485 "")
82b85d08 1486
1487(define_insn "*mulsidi3adddi"
fe8dbf85 1488 [(set (match_operand:DI 0 "s_register_operand" "=&r")
82b85d08 1489 (plus:DI
215b30b3 1490 (mult:DI
fe8dbf85 1491 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "%r"))
1492 (sign_extend:DI (match_operand:SI 3 "s_register_operand" "r")))
1493 (match_operand:DI 1 "s_register_operand" "0")))]
58d7d654 1494 "TARGET_32BIT && arm_arch3m && !arm_arch6"
1495 "smlal%?\\t%Q0, %R0, %3, %2"
9da0ec36 1496 [(set_attr "type" "smlal")
58d7d654 1497 (set_attr "predicable" "yes")]
1498)
1499
1500(define_insn "*mulsidi3adddi_v6"
1501 [(set (match_operand:DI 0 "s_register_operand" "=r")
1502 (plus:DI
1503 (mult:DI
1504 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r"))
1505 (sign_extend:DI (match_operand:SI 3 "s_register_operand" "r")))
1506 (match_operand:DI 1 "s_register_operand" "0")))]
1507 "TARGET_32BIT && arm_arch6"
fe8dbf85 1508 "smlal%?\\t%Q0, %R0, %3, %2"
9da0ec36 1509 [(set_attr "type" "smlal")
d952d547 1510 (set_attr "predicable" "yes")
1511 (set_attr "predicable_short_it" "no")]
0d66636f 1512)
82b85d08 1513
957788b0 1514;; 32x32->64 widening multiply.
1515;; As with mulsi3, the only difference between the v3-5 and v6+
1516;; versions of these patterns is the requirement that the output not
1517;; overlap the inputs, but that still means we have to have a named
1518;; expander and two different starred insns.
1519
1520(define_expand "mulsidi3"
1521 [(set (match_operand:DI 0 "s_register_operand" "")
1522 (mult:DI
1523 (sign_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1524 (sign_extend:DI (match_operand:SI 2 "s_register_operand" ""))))]
1525 "TARGET_32BIT && arm_arch3m"
1526 ""
1527)
1528
1529(define_insn "*mulsidi3_nov6"
f7fbdd4a 1530 [(set (match_operand:DI 0 "s_register_operand" "=&r")
215b30b3 1531 (mult:DI
1532 (sign_extend:DI (match_operand:SI 1 "s_register_operand" "%r"))
1533 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))]
58d7d654 1534 "TARGET_32BIT && arm_arch3m && !arm_arch6"
1535 "smull%?\\t%Q0, %R0, %1, %2"
9da0ec36 1536 [(set_attr "type" "smull")
58d7d654 1537 (set_attr "predicable" "yes")]
1538)
1539
957788b0 1540(define_insn "*mulsidi3_v6"
58d7d654 1541 [(set (match_operand:DI 0 "s_register_operand" "=r")
1542 (mult:DI
1543 (sign_extend:DI (match_operand:SI 1 "s_register_operand" "r"))
1544 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))]
1545 "TARGET_32BIT && arm_arch6"
97499065 1546 "smull%?\\t%Q0, %R0, %1, %2"
9da0ec36 1547 [(set_attr "type" "smull")
d952d547 1548 (set_attr "predicable" "yes")
1549 (set_attr "predicable_short_it" "no")]
0d66636f 1550)
f7fbdd4a 1551
957788b0 1552(define_expand "umulsidi3"
1553 [(set (match_operand:DI 0 "s_register_operand" "")
1554 (mult:DI
1555 (zero_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1556 (zero_extend:DI (match_operand:SI 2 "s_register_operand" ""))))]
1557 "TARGET_32BIT && arm_arch3m"
1558 ""
1559)
1560
1561(define_insn "*umulsidi3_nov6"
f7fbdd4a 1562 [(set (match_operand:DI 0 "s_register_operand" "=&r")
215b30b3 1563 (mult:DI
1564 (zero_extend:DI (match_operand:SI 1 "s_register_operand" "%r"))
1565 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))]
58d7d654 1566 "TARGET_32BIT && arm_arch3m && !arm_arch6"
1567 "umull%?\\t%Q0, %R0, %1, %2"
9da0ec36 1568 [(set_attr "type" "umull")
58d7d654 1569 (set_attr "predicable" "yes")]
1570)
1571
957788b0 1572(define_insn "*umulsidi3_v6"
58d7d654 1573 [(set (match_operand:DI 0 "s_register_operand" "=r")
1574 (mult:DI
1575 (zero_extend:DI (match_operand:SI 1 "s_register_operand" "r"))
1576 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))]
1577 "TARGET_32BIT && arm_arch6"
97499065 1578 "umull%?\\t%Q0, %R0, %1, %2"
9da0ec36 1579 [(set_attr "type" "umull")
d952d547 1580 (set_attr "predicable" "yes")
1581 (set_attr "predicable_short_it" "no")]
0d66636f 1582)
b11cae9e 1583
5cdca009 1584(define_expand "umaddsidi4"
1585 [(set (match_operand:DI 0 "s_register_operand" "")
1586 (plus:DI
1587 (mult:DI
1588 (zero_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1589 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "")))
1590 (match_operand:DI 3 "s_register_operand" "")))]
1591 "TARGET_32BIT && arm_arch3m"
1592 "")
82b85d08 1593
1594(define_insn "*umulsidi3adddi"
8ead09f9 1595 [(set (match_operand:DI 0 "s_register_operand" "=&r")
82b85d08 1596 (plus:DI
215b30b3 1597 (mult:DI
fe8dbf85 1598 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "%r"))
1599 (zero_extend:DI (match_operand:SI 3 "s_register_operand" "r")))
1600 (match_operand:DI 1 "s_register_operand" "0")))]
58d7d654 1601 "TARGET_32BIT && arm_arch3m && !arm_arch6"
1602 "umlal%?\\t%Q0, %R0, %3, %2"
9da0ec36 1603 [(set_attr "type" "umlal")
58d7d654 1604 (set_attr "predicable" "yes")]
1605)
1606
1607(define_insn "*umulsidi3adddi_v6"
1608 [(set (match_operand:DI 0 "s_register_operand" "=r")
1609 (plus:DI
1610 (mult:DI
1611 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r"))
1612 (zero_extend:DI (match_operand:SI 3 "s_register_operand" "r")))
1613 (match_operand:DI 1 "s_register_operand" "0")))]
1614 "TARGET_32BIT && arm_arch6"
fe8dbf85 1615 "umlal%?\\t%Q0, %R0, %3, %2"
9da0ec36 1616 [(set_attr "type" "umlal")
d952d547 1617 (set_attr "predicable" "yes")
1618 (set_attr "predicable_short_it" "no")]
0d66636f 1619)
82b85d08 1620
957788b0 1621(define_expand "smulsi3_highpart"
1622 [(parallel
1623 [(set (match_operand:SI 0 "s_register_operand" "")
1624 (truncate:SI
1625 (lshiftrt:DI
1626 (mult:DI
1627 (sign_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1628 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "")))
1629 (const_int 32))))
1630 (clobber (match_scratch:SI 3 ""))])]
1631 "TARGET_32BIT && arm_arch3m"
1632 ""
1633)
1634
1635(define_insn "*smulsi3_highpart_nov6"
f082f1c4 1636 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r")
1637 (truncate:SI
1638 (lshiftrt:DI
215b30b3 1639 (mult:DI
e5fea38e 1640 (sign_extend:DI (match_operand:SI 1 "s_register_operand" "%0,r"))
215b30b3 1641 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r,r")))
f082f1c4 1642 (const_int 32))))
1643 (clobber (match_scratch:SI 3 "=&r,&r"))]
58d7d654 1644 "TARGET_32BIT && arm_arch3m && !arm_arch6"
1645 "smull%?\\t%3, %0, %2, %1"
9da0ec36 1646 [(set_attr "type" "smull")
58d7d654 1647 (set_attr "predicable" "yes")]
1648)
1649
957788b0 1650(define_insn "*smulsi3_highpart_v6"
58d7d654 1651 [(set (match_operand:SI 0 "s_register_operand" "=r")
1652 (truncate:SI
1653 (lshiftrt:DI
1654 (mult:DI
1655 (sign_extend:DI (match_operand:SI 1 "s_register_operand" "r"))
1656 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r")))
1657 (const_int 32))))
1658 (clobber (match_scratch:SI 3 "=r"))]
1659 "TARGET_32BIT && arm_arch6"
f082f1c4 1660 "smull%?\\t%3, %0, %2, %1"
9da0ec36 1661 [(set_attr "type" "smull")
d952d547 1662 (set_attr "predicable" "yes")
1663 (set_attr "predicable_short_it" "no")]
cffb2a26 1664)
f082f1c4 1665
957788b0 1666(define_expand "umulsi3_highpart"
1667 [(parallel
1668 [(set (match_operand:SI 0 "s_register_operand" "")
1669 (truncate:SI
1670 (lshiftrt:DI
1671 (mult:DI
1672 (zero_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1673 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "")))
1674 (const_int 32))))
1675 (clobber (match_scratch:SI 3 ""))])]
1676 "TARGET_32BIT && arm_arch3m"
1677 ""
1678)
1679
1680(define_insn "*umulsi3_highpart_nov6"
f082f1c4 1681 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r")
1682 (truncate:SI
1683 (lshiftrt:DI
215b30b3 1684 (mult:DI
e5fea38e 1685 (zero_extend:DI (match_operand:SI 1 "s_register_operand" "%0,r"))
215b30b3 1686 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r,r")))
f082f1c4 1687 (const_int 32))))
1688 (clobber (match_scratch:SI 3 "=&r,&r"))]
58d7d654 1689 "TARGET_32BIT && arm_arch3m && !arm_arch6"
1690 "umull%?\\t%3, %0, %2, %1"
9da0ec36 1691 [(set_attr "type" "umull")
58d7d654 1692 (set_attr "predicable" "yes")]
1693)
1694
957788b0 1695(define_insn "*umulsi3_highpart_v6"
58d7d654 1696 [(set (match_operand:SI 0 "s_register_operand" "=r")
1697 (truncate:SI
1698 (lshiftrt:DI
1699 (mult:DI
1700 (zero_extend:DI (match_operand:SI 1 "s_register_operand" "r"))
1701 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r")))
1702 (const_int 32))))
1703 (clobber (match_scratch:SI 3 "=r"))]
1704 "TARGET_32BIT && arm_arch6"
f082f1c4 1705 "umull%?\\t%3, %0, %2, %1"
9da0ec36 1706 [(set_attr "type" "umull")
d952d547 1707 (set_attr "predicable" "yes")
1708 (set_attr "predicable_short_it" "no")]
cffb2a26 1709)
f082f1c4 1710
331beb1a 1711(define_insn "mulhisi3"
1712 [(set (match_operand:SI 0 "s_register_operand" "=r")
1713 (mult:SI (sign_extend:SI
1714 (match_operand:HI 1 "s_register_operand" "%r"))
1715 (sign_extend:SI
1716 (match_operand:HI 2 "s_register_operand" "r"))))]
25f905c2 1717 "TARGET_DSP_MULTIPLY"
61a2d04c 1718 "smulbb%?\\t%0, %1, %2"
9da0ec36 1719 [(set_attr "type" "smulxy")
fec538d9 1720 (set_attr "predicable" "yes")]
1721)
1722
1723(define_insn "*mulhisi3tb"
1724 [(set (match_operand:SI 0 "s_register_operand" "=r")
1725 (mult:SI (ashiftrt:SI
1726 (match_operand:SI 1 "s_register_operand" "r")
1727 (const_int 16))
1728 (sign_extend:SI
1729 (match_operand:HI 2 "s_register_operand" "r"))))]
25f905c2 1730 "TARGET_DSP_MULTIPLY"
fec538d9 1731 "smultb%?\\t%0, %1, %2"
9da0ec36 1732 [(set_attr "type" "smulxy")
d952d547 1733 (set_attr "predicable" "yes")
1734 (set_attr "predicable_short_it" "no")]
fec538d9 1735)
1736
1737(define_insn "*mulhisi3bt"
1738 [(set (match_operand:SI 0 "s_register_operand" "=r")
1739 (mult:SI (sign_extend:SI
1740 (match_operand:HI 1 "s_register_operand" "r"))
1741 (ashiftrt:SI
1742 (match_operand:SI 2 "s_register_operand" "r")
1743 (const_int 16))))]
25f905c2 1744 "TARGET_DSP_MULTIPLY"
fec538d9 1745 "smulbt%?\\t%0, %1, %2"
9da0ec36 1746 [(set_attr "type" "smulxy")
d952d547 1747 (set_attr "predicable" "yes")
1748 (set_attr "predicable_short_it" "no")]
fec538d9 1749)
1750
1751(define_insn "*mulhisi3tt"
1752 [(set (match_operand:SI 0 "s_register_operand" "=r")
1753 (mult:SI (ashiftrt:SI
1754 (match_operand:SI 1 "s_register_operand" "r")
1755 (const_int 16))
1756 (ashiftrt:SI
1757 (match_operand:SI 2 "s_register_operand" "r")
1758 (const_int 16))))]
25f905c2 1759 "TARGET_DSP_MULTIPLY"
fec538d9 1760 "smultt%?\\t%0, %1, %2"
9da0ec36 1761 [(set_attr "type" "smulxy")
d952d547 1762 (set_attr "predicable" "yes")
1763 (set_attr "predicable_short_it" "no")]
331beb1a 1764)
1765
5cdca009 1766(define_insn "maddhisi4"
331beb1a 1767 [(set (match_operand:SI 0 "s_register_operand" "=r")
cfa6c608 1768 (plus:SI (mult:SI (sign_extend:SI
1769 (match_operand:HI 1 "s_register_operand" "r"))
331beb1a 1770 (sign_extend:SI
cfa6c608 1771 (match_operand:HI 2 "s_register_operand" "r")))
1772 (match_operand:SI 3 "s_register_operand" "r")))]
25f905c2 1773 "TARGET_DSP_MULTIPLY"
5cdca009 1774 "smlabb%?\\t%0, %1, %2, %3"
9da0ec36 1775 [(set_attr "type" "smlaxy")
d952d547 1776 (set_attr "predicable" "yes")
1777 (set_attr "predicable_short_it" "no")]
331beb1a 1778)
1779
9a92f368 1780;; Note: there is no maddhisi4ibt because this one is canonical form
1781(define_insn "*maddhisi4tb"
1782 [(set (match_operand:SI 0 "s_register_operand" "=r")
1783 (plus:SI (mult:SI (ashiftrt:SI
1784 (match_operand:SI 1 "s_register_operand" "r")
1785 (const_int 16))
1786 (sign_extend:SI
1787 (match_operand:HI 2 "s_register_operand" "r")))
1788 (match_operand:SI 3 "s_register_operand" "r")))]
1789 "TARGET_DSP_MULTIPLY"
1790 "smlatb%?\\t%0, %1, %2, %3"
9da0ec36 1791 [(set_attr "type" "smlaxy")
d952d547 1792 (set_attr "predicable" "yes")
1793 (set_attr "predicable_short_it" "no")]
9a92f368 1794)
1795
1796(define_insn "*maddhisi4tt"
1797 [(set (match_operand:SI 0 "s_register_operand" "=r")
1798 (plus:SI (mult:SI (ashiftrt:SI
1799 (match_operand:SI 1 "s_register_operand" "r")
1800 (const_int 16))
1801 (ashiftrt:SI
1802 (match_operand:SI 2 "s_register_operand" "r")
1803 (const_int 16)))
1804 (match_operand:SI 3 "s_register_operand" "r")))]
1805 "TARGET_DSP_MULTIPLY"
1806 "smlatt%?\\t%0, %1, %2, %3"
9da0ec36 1807 [(set_attr "type" "smlaxy")
d952d547 1808 (set_attr "predicable" "yes")
1809 (set_attr "predicable_short_it" "no")]
9a92f368 1810)
1811
aff5fb4d 1812(define_insn "maddhidi4"
331beb1a 1813 [(set (match_operand:DI 0 "s_register_operand" "=r")
1814 (plus:DI
331beb1a 1815 (mult:DI (sign_extend:DI
d952d547 1816 (match_operand:HI 1 "s_register_operand" "r"))
331beb1a 1817 (sign_extend:DI
cfa6c608 1818 (match_operand:HI 2 "s_register_operand" "r")))
1819 (match_operand:DI 3 "s_register_operand" "0")))]
25f905c2 1820 "TARGET_DSP_MULTIPLY"
5cdca009 1821 "smlalbb%?\\t%Q0, %R0, %1, %2"
9da0ec36 1822 [(set_attr "type" "smlalxy")
d952d547 1823 (set_attr "predicable" "yes")
1824 (set_attr "predicable_short_it" "no")])
331beb1a 1825
9a92f368 1826;; Note: there is no maddhidi4ibt because this one is canonical form
1827(define_insn "*maddhidi4tb"
1828 [(set (match_operand:DI 0 "s_register_operand" "=r")
1829 (plus:DI
1830 (mult:DI (sign_extend:DI
1831 (ashiftrt:SI
1832 (match_operand:SI 1 "s_register_operand" "r")
1833 (const_int 16)))
1834 (sign_extend:DI
1835 (match_operand:HI 2 "s_register_operand" "r")))
1836 (match_operand:DI 3 "s_register_operand" "0")))]
1837 "TARGET_DSP_MULTIPLY"
1838 "smlaltb%?\\t%Q0, %R0, %1, %2"
9da0ec36 1839 [(set_attr "type" "smlalxy")
d952d547 1840 (set_attr "predicable" "yes")
1841 (set_attr "predicable_short_it" "no")])
9a92f368 1842
1843(define_insn "*maddhidi4tt"
1844 [(set (match_operand:DI 0 "s_register_operand" "=r")
1845 (plus:DI
1846 (mult:DI (sign_extend:DI
1847 (ashiftrt:SI
1848 (match_operand:SI 1 "s_register_operand" "r")
1849 (const_int 16)))
1850 (sign_extend:DI
1851 (ashiftrt:SI
1852 (match_operand:SI 2 "s_register_operand" "r")
1853 (const_int 16))))
1854 (match_operand:DI 3 "s_register_operand" "0")))]
1855 "TARGET_DSP_MULTIPLY"
1856 "smlaltt%?\\t%Q0, %R0, %1, %2"
9da0ec36 1857 [(set_attr "type" "smlalxy")
d952d547 1858 (set_attr "predicable" "yes")
1859 (set_attr "predicable_short_it" "no")])
9a92f368 1860
604f3a0a 1861(define_expand "mulsf3"
1862 [(set (match_operand:SF 0 "s_register_operand" "")
1863 (mult:SF (match_operand:SF 1 "s_register_operand" "")
d86c91f6 1864 (match_operand:SF 2 "s_register_operand" "")))]
25f905c2 1865 "TARGET_32BIT && TARGET_HARD_FLOAT"
604f3a0a 1866 "
604f3a0a 1867")
1868
604f3a0a 1869(define_expand "muldf3"
1870 [(set (match_operand:DF 0 "s_register_operand" "")
1871 (mult:DF (match_operand:DF 1 "s_register_operand" "")
d86c91f6 1872 (match_operand:DF 2 "s_register_operand" "")))]
a50d7267 1873 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
604f3a0a 1874 "
604f3a0a 1875")
b11cae9e 1876\f
1877;; Division insns
1878
7db9af5d 1879(define_expand "divsf3"
1880 [(set (match_operand:SF 0 "s_register_operand" "")
d86c91f6 1881 (div:SF (match_operand:SF 1 "s_register_operand" "")
1882 (match_operand:SF 2 "s_register_operand" "")))]
994606f8 1883 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
7db9af5d 1884 "")
9c08d1fa 1885
7db9af5d 1886(define_expand "divdf3"
1887 [(set (match_operand:DF 0 "s_register_operand" "")
d86c91f6 1888 (div:DF (match_operand:DF 1 "s_register_operand" "")
1889 (match_operand:DF 2 "s_register_operand" "")))]
994606f8 1890 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
7db9af5d 1891 "")
b11cae9e 1892\f
1893;; Boolean and,ior,xor insns
1894
f6ebffac 1895;; Split up double word logical operations
1896
1897;; Split up simple DImode logical operations. Simply perform the logical
1898;; operation on the upper and lower halves of the registers.
1899(define_split
1900 [(set (match_operand:DI 0 "s_register_operand" "")
1901 (match_operator:DI 6 "logical_binary_operator"
1902 [(match_operand:DI 1 "s_register_operand" "")
1903 (match_operand:DI 2 "s_register_operand" "")]))]
25f905c2 1904 "TARGET_32BIT && reload_completed
e2669ea7 1905 && ! (TARGET_NEON && IS_VFP_REGNUM (REGNO (operands[0])))
25f905c2 1906 && ! IS_IWMMXT_REGNUM (REGNO (operands[0]))"
f6ebffac 1907 [(set (match_dup 0) (match_op_dup:SI 6 [(match_dup 1) (match_dup 2)]))
1908 (set (match_dup 3) (match_op_dup:SI 6 [(match_dup 4) (match_dup 5)]))]
1909 "
215b30b3 1910 {
1911 operands[3] = gen_highpart (SImode, operands[0]);
1912 operands[0] = gen_lowpart (SImode, operands[0]);
1913 operands[4] = gen_highpart (SImode, operands[1]);
1914 operands[1] = gen_lowpart (SImode, operands[1]);
1915 operands[5] = gen_highpart (SImode, operands[2]);
1916 operands[2] = gen_lowpart (SImode, operands[2]);
1917 }"
1918)
f6ebffac 1919
f6ebffac 1920(define_split
1921 [(set (match_operand:DI 0 "s_register_operand" "")
1922 (match_operator:DI 6 "logical_binary_operator"
1923 [(sign_extend:DI (match_operand:SI 2 "s_register_operand" ""))
1924 (match_operand:DI 1 "s_register_operand" "")]))]
25f905c2 1925 "TARGET_32BIT && reload_completed"
f6ebffac 1926 [(set (match_dup 0) (match_op_dup:SI 6 [(match_dup 1) (match_dup 2)]))
1927 (set (match_dup 3) (match_op_dup:SI 6
1928 [(ashiftrt:SI (match_dup 2) (const_int 31))
1929 (match_dup 4)]))]
1930 "
215b30b3 1931 {
1932 operands[3] = gen_highpart (SImode, operands[0]);
1933 operands[0] = gen_lowpart (SImode, operands[0]);
1934 operands[4] = gen_highpart (SImode, operands[1]);
1935 operands[1] = gen_lowpart (SImode, operands[1]);
1936 operands[5] = gen_highpart (SImode, operands[2]);
1937 operands[2] = gen_lowpart (SImode, operands[2]);
1938 }"
1939)
f6ebffac 1940
f6ebffac 1941;; The zero extend of operand 2 means we can just copy the high part of
1942;; operand1 into operand0.
1943(define_split
1944 [(set (match_operand:DI 0 "s_register_operand" "")
1945 (ior:DI
1946 (zero_extend:DI (match_operand:SI 2 "s_register_operand" ""))
1947 (match_operand:DI 1 "s_register_operand" "")))]
25f905c2 1948 "TARGET_32BIT && operands[0] != operands[1] && reload_completed"
f6ebffac 1949 [(set (match_dup 0) (ior:SI (match_dup 1) (match_dup 2)))
1950 (set (match_dup 3) (match_dup 4))]
1951 "
215b30b3 1952 {
1953 operands[4] = gen_highpart (SImode, operands[1]);
1954 operands[3] = gen_highpart (SImode, operands[0]);
1955 operands[0] = gen_lowpart (SImode, operands[0]);
1956 operands[1] = gen_lowpart (SImode, operands[1]);
1957 }"
1958)
f6ebffac 1959
1960;; The zero extend of operand 2 means we can just copy the high part of
1961;; operand1 into operand0.
1962(define_split
1963 [(set (match_operand:DI 0 "s_register_operand" "")
1964 (xor:DI
1965 (zero_extend:DI (match_operand:SI 2 "s_register_operand" ""))
1966 (match_operand:DI 1 "s_register_operand" "")))]
25f905c2 1967 "TARGET_32BIT && operands[0] != operands[1] && reload_completed"
f6ebffac 1968 [(set (match_dup 0) (xor:SI (match_dup 1) (match_dup 2)))
1969 (set (match_dup 3) (match_dup 4))]
1970 "
215b30b3 1971 {
1972 operands[4] = gen_highpart (SImode, operands[1]);
1973 operands[3] = gen_highpart (SImode, operands[0]);
1974 operands[0] = gen_lowpart (SImode, operands[0]);
1975 operands[1] = gen_lowpart (SImode, operands[1]);
1976 }"
1977)
f6ebffac 1978
e2669ea7 1979(define_expand "anddi3"
1980 [(set (match_operand:DI 0 "s_register_operand" "")
1981 (and:DI (match_operand:DI 1 "s_register_operand" "")
1982 (match_operand:DI 2 "neon_inv_logic_op2" "")))]
1983 "TARGET_32BIT"
1984 ""
1985)
1986
f6bbdcf6 1987(define_insn_and_split "*anddi3_insn"
0a314dcd 1988 [(set (match_operand:DI 0 "s_register_operand" "=w,w ,&r,&r,&r,&r,?w,?w")
1989 (and:DI (match_operand:DI 1 "s_register_operand" "%w,0 ,0 ,r ,0 ,r ,w ,0")
1990 (match_operand:DI 2 "arm_anddi_operand_neon" "w ,DL,r ,r ,De,De,w ,DL")))]
f6bbdcf6 1991 "TARGET_32BIT && !TARGET_IWMMXT"
1992{
1993 switch (which_alternative)
1994 {
0a314dcd 1995 case 0: /* fall through */
1996 case 6: return "vand\t%P0, %P1, %P2";
1997 case 1: /* fall through */
1998 case 7: return neon_output_logic_immediate ("vand", &operands[2],
1999 DImode, 1, VALID_NEON_QREG_MODE (DImode));
f6bbdcf6 2000 case 2:
0a314dcd 2001 case 3:
2002 case 4:
f6bbdcf6 2003 case 5: /* fall through */
0a314dcd 2004 return "#";
f6bbdcf6 2005 default: gcc_unreachable ();
2006 }
2007}
0a314dcd 2008 "TARGET_32BIT && !TARGET_IWMMXT && reload_completed
2009 && !(IS_VFP_REGNUM (REGNO (operands[0])))"
f6bbdcf6 2010 [(set (match_dup 3) (match_dup 4))
2011 (set (match_dup 5) (match_dup 6))]
2012 "
2013 {
2014 operands[3] = gen_lowpart (SImode, operands[0]);
2015 operands[5] = gen_highpart (SImode, operands[0]);
2016
2017 operands[4] = simplify_gen_binary (AND, SImode,
2018 gen_lowpart (SImode, operands[1]),
2019 gen_lowpart (SImode, operands[2]));
2020 operands[6] = simplify_gen_binary (AND, SImode,
2021 gen_highpart (SImode, operands[1]),
2022 gen_highpart_mode (SImode, DImode, operands[2]));
2023
2024 }"
32093010 2025 [(set_attr "type" "neon_logic,neon_logic,multiple,multiple,\
2026 multiple,multiple,neon_logic,neon_logic")
0a314dcd 2027 (set_attr "arch" "neon_for_64bits,neon_for_64bits,*,*,*,*,
f6bbdcf6 2028 avoid_neon_for_64bits,avoid_neon_for_64bits")
0a314dcd 2029 (set_attr "length" "*,*,8,8,8,8,*,*")
2030 ]
215b30b3 2031)
b11cae9e 2032
a0f94409 2033(define_insn_and_split "*anddi_zesidi_di"
9c08d1fa 2034 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2035 (and:DI (zero_extend:DI
2036 (match_operand:SI 2 "s_register_operand" "r,r"))
e5fea38e 2037 (match_operand:DI 1 "s_register_operand" "0,r")))]
25f905c2 2038 "TARGET_32BIT"
f6ebffac 2039 "#"
25f905c2 2040 "TARGET_32BIT && reload_completed"
a0f94409 2041 ; The zero extend of operand 2 clears the high word of the output
2042 ; operand.
2043 [(set (match_dup 0) (and:SI (match_dup 1) (match_dup 2)))
2044 (set (match_dup 3) (const_int 0))]
2045 "
2046 {
2047 operands[3] = gen_highpart (SImode, operands[0]);
2048 operands[0] = gen_lowpart (SImode, operands[0]);
2049 operands[1] = gen_lowpart (SImode, operands[1]);
2050 }"
1b7da4ac 2051 [(set_attr "length" "8")
2052 (set_attr "type" "multiple")]
215b30b3 2053)
b11cae9e 2054
f7fbdd4a 2055(define_insn "*anddi_sesdi_di"
cffb2a26 2056 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
9c08d1fa 2057 (and:DI (sign_extend:DI
2058 (match_operand:SI 2 "s_register_operand" "r,r"))
e5fea38e 2059 (match_operand:DI 1 "s_register_operand" "0,r")))]
25f905c2 2060 "TARGET_32BIT"
f6ebffac 2061 "#"
1b7da4ac 2062 [(set_attr "length" "8")
2063 (set_attr "type" "multiple")]
cffb2a26 2064)
b11cae9e 2065
87b22bf7 2066(define_expand "andsi3"
cffb2a26 2067 [(set (match_operand:SI 0 "s_register_operand" "")
87b22bf7 2068 (and:SI (match_operand:SI 1 "s_register_operand" "")
2069 (match_operand:SI 2 "reg_or_int_operand" "")))]
cffb2a26 2070 "TARGET_EITHER"
87b22bf7 2071 "
25f905c2 2072 if (TARGET_32BIT)
87b22bf7 2073 {
0438d37f 2074 if (CONST_INT_P (operands[2]))
cffb2a26 2075 {
47b5b27b 2076 if (INTVAL (operands[2]) == 255 && arm_arch6)
2077 {
2078 operands[1] = convert_to_mode (QImode, operands[1], 1);
2079 emit_insn (gen_thumb2_zero_extendqisi2_v6 (operands[0],
2080 operands[1]));
2081 }
2082 else
2083 arm_split_constant (AND, SImode, NULL_RTX,
2084 INTVAL (operands[2]), operands[0],
2085 operands[1],
2086 optimize && can_create_pseudo_p ());
615caa51 2087
cffb2a26 2088 DONE;
2089 }
87b22bf7 2090 }
25f905c2 2091 else /* TARGET_THUMB1 */
cffb2a26 2092 {
0438d37f 2093 if (!CONST_INT_P (operands[2]))
923ffadb 2094 {
2095 rtx tmp = force_reg (SImode, operands[2]);
2096 if (rtx_equal_p (operands[0], operands[1]))
2097 operands[2] = tmp;
2098 else
2099 {
2100 operands[2] = operands[1];
2101 operands[1] = tmp;
2102 }
2103 }
cffb2a26 2104 else
2105 {
2106 int i;
2107
215b30b3 2108 if (((unsigned HOST_WIDE_INT) ~INTVAL (operands[2])) < 256)
cffb2a26 2109 {
215b30b3 2110 operands[2] = force_reg (SImode,
2111 GEN_INT (~INTVAL (operands[2])));
cffb2a26 2112
747b7458 2113 emit_insn (gen_thumb1_bicsi3 (operands[0], operands[2], operands[1]));
cffb2a26 2114
2115 DONE;
2116 }
87b22bf7 2117
cffb2a26 2118 for (i = 9; i <= 31; i++)
2119 {
2120 if ((((HOST_WIDE_INT) 1) << i) - 1 == INTVAL (operands[2]))
2121 {
2122 emit_insn (gen_extzv (operands[0], operands[1], GEN_INT (i),
2123 const0_rtx));
2124 DONE;
2125 }
215b30b3 2126 else if ((((HOST_WIDE_INT) 1) << i) - 1
2127 == ~INTVAL (operands[2]))
cffb2a26 2128 {
2129 rtx shift = GEN_INT (i);
2130 rtx reg = gen_reg_rtx (SImode);
2131
2132 emit_insn (gen_lshrsi3 (reg, operands[1], shift));
2133 emit_insn (gen_ashlsi3 (operands[0], reg, shift));
2134
2135 DONE;
2136 }
2137 }
2138
2139 operands[2] = force_reg (SImode, operands[2]);
2140 }
215b30b3 2141 }
2142 "
cffb2a26 2143)
2144
25f905c2 2145; ??? Check split length for Thumb-2
a0f94409 2146(define_insn_and_split "*arm_andsi3_insn"
29e234a3 2147 [(set (match_operand:SI 0 "s_register_operand" "=r,l,r,r,r")
2148 (and:SI (match_operand:SI 1 "s_register_operand" "%r,0,r,r,r")
2149 (match_operand:SI 2 "reg_or_int_operand" "I,l,K,r,?n")))]
25f905c2 2150 "TARGET_32BIT"
5565501b 2151 "@
29e234a3 2152 and%?\\t%0, %1, %2
5565501b 2153 and%?\\t%0, %1, %2
87b22bf7 2154 bic%?\\t%0, %1, #%B2
65f68e55 2155 and%?\\t%0, %1, %2
87b22bf7 2156 #"
25f905c2 2157 "TARGET_32BIT
0438d37f 2158 && CONST_INT_P (operands[2])
a0f94409 2159 && !(const_ok_for_arm (INTVAL (operands[2]))
2160 || const_ok_for_arm (~INTVAL (operands[2])))"
2161 [(clobber (const_int 0))]
2162 "
96f57e36 2163 arm_split_constant (AND, SImode, curr_insn,
2164 INTVAL (operands[2]), operands[0], operands[1], 0);
a0f94409 2165 DONE;
2166 "
29e234a3 2167 [(set_attr "length" "4,4,4,4,16")
65f68e55 2168 (set_attr "predicable" "yes")
29e234a3 2169 (set_attr "predicable_short_it" "no,yes,no,no,no")
d82e788e 2170 (set_attr "type" "logic_imm,logic_imm,logic_reg,logic_reg,logic_imm")]
cffb2a26 2171)
2172
f7fbdd4a 2173(define_insn "*andsi3_compare0"
bd5b4116 2174 [(set (reg:CC_NOOV CC_REGNUM)
5565501b 2175 (compare:CC_NOOV
65f68e55 2176 (and:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
2177 (match_operand:SI 2 "arm_not_operand" "I,K,r"))
5565501b 2178 (const_int 0)))
65f68e55 2179 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9c08d1fa 2180 (and:SI (match_dup 1) (match_dup 2)))]
25f905c2 2181 "TARGET_32BIT"
5565501b 2182 "@
25f905c2 2183 and%.\\t%0, %1, %2
65f68e55 2184 bic%.\\t%0, %1, #%B2
2185 and%.\\t%0, %1, %2"
2186 [(set_attr "conds" "set")
d82e788e 2187 (set_attr "type" "logics_imm,logics_imm,logics_reg")]
cffb2a26 2188)
9c08d1fa 2189
f7fbdd4a 2190(define_insn "*andsi3_compare0_scratch"
bd5b4116 2191 [(set (reg:CC_NOOV CC_REGNUM)
5565501b 2192 (compare:CC_NOOV
65f68e55 2193 (and:SI (match_operand:SI 0 "s_register_operand" "r,r,r")
2194 (match_operand:SI 1 "arm_not_operand" "I,K,r"))
5565501b 2195 (const_int 0)))
65f68e55 2196 (clobber (match_scratch:SI 2 "=X,r,X"))]
25f905c2 2197 "TARGET_32BIT"
5565501b 2198 "@
2199 tst%?\\t%0, %1
65f68e55 2200 bic%.\\t%2, %0, #%B1
2201 tst%?\\t%0, %1"
2202 [(set_attr "conds" "set")
d82e788e 2203 (set_attr "type" "logics_imm,logics_imm,logics_reg")]
0d66636f 2204)
9c08d1fa 2205
f7fbdd4a 2206(define_insn "*zeroextractsi_compare0_scratch"
bd5b4116 2207 [(set (reg:CC_NOOV CC_REGNUM)
9c08d1fa 2208 (compare:CC_NOOV (zero_extract:SI
2209 (match_operand:SI 0 "s_register_operand" "r")
d952d547 2210 (match_operand 1 "const_int_operand" "n")
206ee9a2 2211 (match_operand 2 "const_int_operand" "n"))
9c08d1fa 2212 (const_int 0)))]
25f905c2 2213 "TARGET_32BIT
cffb2a26 2214 && (INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) < 32
2215 && INTVAL (operands[1]) > 0
2216 && INTVAL (operands[1]) + (INTVAL (operands[2]) & 1) <= 8
2217 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32)"
9c08d1fa 2218 "*
5c49a439 2219 operands[1] = GEN_INT (((1 << INTVAL (operands[1])) - 1)
2220 << INTVAL (operands[2]));
40dbec34 2221 output_asm_insn (\"tst%?\\t%0, %1\", operands);
e2348bcb 2222 return \"\";
0d66636f 2223 "
596e5e8f 2224 [(set_attr "conds" "set")
65f68e55 2225 (set_attr "predicable" "yes")
d952d547 2226 (set_attr "predicable_short_it" "no")
d82e788e 2227 (set_attr "type" "logics_imm")]
0d66636f 2228)
9c08d1fa 2229
f4462328 2230(define_insn_and_split "*ne_zeroextractsi"
c4034607 2231 [(set (match_operand:SI 0 "s_register_operand" "=r")
2232 (ne:SI (zero_extract:SI
2233 (match_operand:SI 1 "s_register_operand" "r")
2234 (match_operand:SI 2 "const_int_operand" "n")
2235 (match_operand:SI 3 "const_int_operand" "n"))
3b8c7f7a 2236 (const_int 0)))
2237 (clobber (reg:CC CC_REGNUM))]
25f905c2 2238 "TARGET_32BIT
cffb2a26 2239 && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
2240 && INTVAL (operands[2]) > 0
2241 && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
2242 && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)"
f4462328 2243 "#"
25f905c2 2244 "TARGET_32BIT
f4462328 2245 && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
2246 && INTVAL (operands[2]) > 0
2247 && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
2248 && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)"
2249 [(parallel [(set (reg:CC_NOOV CC_REGNUM)
2250 (compare:CC_NOOV (and:SI (match_dup 1) (match_dup 2))
2251 (const_int 0)))
2252 (set (match_dup 0) (and:SI (match_dup 1) (match_dup 2)))])
2253 (set (match_dup 0)
2254 (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
2255 (match_dup 0) (const_int 1)))]
2256 "
2257 operands[2] = GEN_INT (((1 << INTVAL (operands[2])) - 1)
2258 << INTVAL (operands[3]));
2259 "
2260 [(set_attr "conds" "clob")
25f905c2 2261 (set (attr "length")
2262 (if_then_else (eq_attr "is_thumb" "yes")
2263 (const_int 12)
1b7da4ac 2264 (const_int 8)))
2265 (set_attr "type" "multiple")]
f4462328 2266)
2267
2268(define_insn_and_split "*ne_zeroextractsi_shifted"
2269 [(set (match_operand:SI 0 "s_register_operand" "=r")
2270 (ne:SI (zero_extract:SI
2271 (match_operand:SI 1 "s_register_operand" "r")
2272 (match_operand:SI 2 "const_int_operand" "n")
2273 (const_int 0))
2274 (const_int 0)))
2275 (clobber (reg:CC CC_REGNUM))]
2276 "TARGET_ARM"
2277 "#"
2278 "TARGET_ARM"
2279 [(parallel [(set (reg:CC_NOOV CC_REGNUM)
2280 (compare:CC_NOOV (ashift:SI (match_dup 1) (match_dup 2))
2281 (const_int 0)))
2282 (set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 2)))])
2283 (set (match_dup 0)
2284 (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
2285 (match_dup 0) (const_int 1)))]
2286 "
2287 operands[2] = GEN_INT (32 - INTVAL (operands[2]));
2288 "
2289 [(set_attr "conds" "clob")
1b7da4ac 2290 (set_attr "length" "8")
2291 (set_attr "type" "multiple")]
f4462328 2292)
2293
2294(define_insn_and_split "*ite_ne_zeroextractsi"
2295 [(set (match_operand:SI 0 "s_register_operand" "=r")
2296 (if_then_else:SI (ne (zero_extract:SI
2297 (match_operand:SI 1 "s_register_operand" "r")
2298 (match_operand:SI 2 "const_int_operand" "n")
2299 (match_operand:SI 3 "const_int_operand" "n"))
2300 (const_int 0))
2301 (match_operand:SI 4 "arm_not_operand" "rIK")
2302 (const_int 0)))
2303 (clobber (reg:CC CC_REGNUM))]
2304 "TARGET_ARM
2305 && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
2306 && INTVAL (operands[2]) > 0
2307 && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
f8d7bf2f 2308 && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)
2309 && !reg_overlap_mentioned_p (operands[0], operands[4])"
f4462328 2310 "#"
2311 "TARGET_ARM
2312 && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
2313 && INTVAL (operands[2]) > 0
2314 && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
f8d7bf2f 2315 && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)
2316 && !reg_overlap_mentioned_p (operands[0], operands[4])"
f4462328 2317 [(parallel [(set (reg:CC_NOOV CC_REGNUM)
2318 (compare:CC_NOOV (and:SI (match_dup 1) (match_dup 2))
2319 (const_int 0)))
2320 (set (match_dup 0) (and:SI (match_dup 1) (match_dup 2)))])
2321 (set (match_dup 0)
2322 (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
2323 (match_dup 0) (match_dup 4)))]
2324 "
c4034607 2325 operands[2] = GEN_INT (((1 << INTVAL (operands[2])) - 1)
f4462328 2326 << INTVAL (operands[3]));
2327 "
2328 [(set_attr "conds" "clob")
1b7da4ac 2329 (set_attr "length" "8")
2330 (set_attr "type" "multiple")]
f4462328 2331)
2332
2333(define_insn_and_split "*ite_ne_zeroextractsi_shifted"
2334 [(set (match_operand:SI 0 "s_register_operand" "=r")
2335 (if_then_else:SI (ne (zero_extract:SI
2336 (match_operand:SI 1 "s_register_operand" "r")
2337 (match_operand:SI 2 "const_int_operand" "n")
2338 (const_int 0))
2339 (const_int 0))
2340 (match_operand:SI 3 "arm_not_operand" "rIK")
2341 (const_int 0)))
2342 (clobber (reg:CC CC_REGNUM))]
f8d7bf2f 2343 "TARGET_ARM && !reg_overlap_mentioned_p (operands[0], operands[3])"
f4462328 2344 "#"
f8d7bf2f 2345 "TARGET_ARM && !reg_overlap_mentioned_p (operands[0], operands[3])"
f4462328 2346 [(parallel [(set (reg:CC_NOOV CC_REGNUM)
2347 (compare:CC_NOOV (ashift:SI (match_dup 1) (match_dup 2))
2348 (const_int 0)))
2349 (set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 2)))])
2350 (set (match_dup 0)
2351 (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
2352 (match_dup 0) (match_dup 3)))]
2353 "
2354 operands[2] = GEN_INT (32 - INTVAL (operands[2]));
0d66636f 2355 "
2356 [(set_attr "conds" "clob")
1b7da4ac 2357 (set_attr "length" "8")
2358 (set_attr "type" "multiple")]
215b30b3 2359)
9c08d1fa 2360
25f905c2 2361;; ??? Use Thumb-2 has bitfield insert/extract instructions.
d7863cfe 2362(define_split
2363 [(set (match_operand:SI 0 "s_register_operand" "")
2364 (match_operator:SI 1 "shiftable_operator"
2365 [(zero_extract:SI (match_operand:SI 2 "s_register_operand" "")
2366 (match_operand:SI 3 "const_int_operand" "")
2367 (match_operand:SI 4 "const_int_operand" ""))
2368 (match_operand:SI 5 "s_register_operand" "")]))
2369 (clobber (match_operand:SI 6 "s_register_operand" ""))]
2370 "TARGET_ARM"
2371 [(set (match_dup 6) (ashift:SI (match_dup 2) (match_dup 3)))
2372 (set (match_dup 0)
2373 (match_op_dup 1
2374 [(lshiftrt:SI (match_dup 6) (match_dup 4))
2375 (match_dup 5)]))]
2376 "{
2377 HOST_WIDE_INT temp = INTVAL (operands[3]);
2378
2379 operands[3] = GEN_INT (32 - temp - INTVAL (operands[4]));
2380 operands[4] = GEN_INT (32 - temp);
2381 }"
2382)
2383
d7863cfe 2384(define_split
2385 [(set (match_operand:SI 0 "s_register_operand" "")
2386 (match_operator:SI 1 "shiftable_operator"
2387 [(sign_extract:SI (match_operand:SI 2 "s_register_operand" "")
2388 (match_operand:SI 3 "const_int_operand" "")
2389 (match_operand:SI 4 "const_int_operand" ""))
2390 (match_operand:SI 5 "s_register_operand" "")]))
2391 (clobber (match_operand:SI 6 "s_register_operand" ""))]
2392 "TARGET_ARM"
2393 [(set (match_dup 6) (ashift:SI (match_dup 2) (match_dup 3)))
2394 (set (match_dup 0)
2395 (match_op_dup 1
2396 [(ashiftrt:SI (match_dup 6) (match_dup 4))
2397 (match_dup 5)]))]
2398 "{
2399 HOST_WIDE_INT temp = INTVAL (operands[3]);
2400
2401 operands[3] = GEN_INT (32 - temp - INTVAL (operands[4]));
2402 operands[4] = GEN_INT (32 - temp);
2403 }"
2404)
2405
a42059fd 2406;;; ??? This pattern is bogus. If operand3 has bits outside the range
2407;;; represented by the bitfield, then this will produce incorrect results.
2408;;; Somewhere, the value needs to be truncated. On targets like the m68k,
ceb2fe0f 2409;;; which have a real bit-field insert instruction, the truncation happens
2410;;; in the bit-field insert instruction itself. Since arm does not have a
2411;;; bit-field insert instruction, we would have to emit code here to truncate
a42059fd 2412;;; the value before we insert. This loses some of the advantage of having
2413;;; this insv pattern, so this pattern needs to be reevalutated.
2414
8a18b90c 2415(define_expand "insv"
eb04cafb 2416 [(set (zero_extract (match_operand 0 "nonimmediate_operand" "")
2417 (match_operand 1 "general_operand" "")
2418 (match_operand 2 "general_operand" ""))
2419 (match_operand 3 "reg_or_int_operand" ""))]
8b054d5a 2420 "TARGET_ARM || arm_arch_thumb2"
8a18b90c 2421 "
215b30b3 2422 {
2423 int start_bit = INTVAL (operands[2]);
2424 int width = INTVAL (operands[1]);
2425 HOST_WIDE_INT mask = (((HOST_WIDE_INT)1) << width) - 1;
2426 rtx target, subtarget;
2427
8b054d5a 2428 if (arm_arch_thumb2)
2429 {
eb04cafb 2430 if (unaligned_access && MEM_P (operands[0])
2431 && s_register_operand (operands[3], GET_MODE (operands[3]))
2432 && (width == 16 || width == 32) && (start_bit % BITS_PER_UNIT) == 0)
8b054d5a 2433 {
eb04cafb 2434 rtx base_addr;
2435
2436 if (BYTES_BIG_ENDIAN)
2437 start_bit = GET_MODE_BITSIZE (GET_MODE (operands[3])) - width
2438 - start_bit;
8b054d5a 2439
eb04cafb 2440 if (width == 32)
8b054d5a 2441 {
eb04cafb 2442 base_addr = adjust_address (operands[0], SImode,
2443 start_bit / BITS_PER_UNIT);
2444 emit_insn (gen_unaligned_storesi (base_addr, operands[3]));
8b054d5a 2445 }
eb04cafb 2446 else
2447 {
2448 rtx tmp = gen_reg_rtx (HImode);
8b054d5a 2449
eb04cafb 2450 base_addr = adjust_address (operands[0], HImode,
2451 start_bit / BITS_PER_UNIT);
2452 emit_move_insn (tmp, gen_lowpart (HImode, operands[3]));
2453 emit_insn (gen_unaligned_storehi (base_addr, tmp));
2454 }
2455 DONE;
8b054d5a 2456 }
eb04cafb 2457 else if (s_register_operand (operands[0], GET_MODE (operands[0])))
8b054d5a 2458 {
eb04cafb 2459 bool use_bfi = TRUE;
8b054d5a 2460
0438d37f 2461 if (CONST_INT_P (operands[3]))
eb04cafb 2462 {
2463 HOST_WIDE_INT val = INTVAL (operands[3]) & mask;
2464
2465 if (val == 0)
2466 {
2467 emit_insn (gen_insv_zero (operands[0], operands[1],
2468 operands[2]));
2469 DONE;
2470 }
2471
2472 /* See if the set can be done with a single orr instruction. */
2473 if (val == mask && const_ok_for_arm (val << start_bit))
2474 use_bfi = FALSE;
2475 }
2476
2477 if (use_bfi)
2478 {
0438d37f 2479 if (!REG_P (operands[3]))
eb04cafb 2480 operands[3] = force_reg (SImode, operands[3]);
2481
2482 emit_insn (gen_insv_t2 (operands[0], operands[1], operands[2],
2483 operands[3]));
2484 DONE;
2485 }
8b054d5a 2486 }
eb04cafb 2487 else
2488 FAIL;
8b054d5a 2489 }
2490
eb04cafb 2491 if (!s_register_operand (operands[0], GET_MODE (operands[0])))
2492 FAIL;
2493
3f8fde42 2494 target = copy_rtx (operands[0]);
215b30b3 2495 /* Avoid using a subreg as a subtarget, and avoid writing a paradoxical
2496 subreg as the final target. */
2497 if (GET_CODE (target) == SUBREG)
2498 {
2499 subtarget = gen_reg_rtx (SImode);
2500 if (GET_MODE_SIZE (GET_MODE (SUBREG_REG (target)))
2501 < GET_MODE_SIZE (SImode))
2502 target = SUBREG_REG (target);
2503 }
2504 else
2505 subtarget = target;
8a18b90c 2506
0438d37f 2507 if (CONST_INT_P (operands[3]))
215b30b3 2508 {
2509 /* Since we are inserting a known constant, we may be able to
2510 reduce the number of bits that we have to clear so that
2511 the mask becomes simple. */
2512 /* ??? This code does not check to see if the new mask is actually
2513 simpler. It may not be. */
2514 rtx op1 = gen_reg_rtx (SImode);
2515 /* ??? Truncate operand3 to fit in the bitfield. See comment before
2516 start of this pattern. */
2517 HOST_WIDE_INT op3_value = mask & INTVAL (operands[3]);
2518 HOST_WIDE_INT mask2 = ((mask & ~op3_value) << start_bit);
2519
c5b3a71b 2520 emit_insn (gen_andsi3 (op1, operands[0],
2521 gen_int_mode (~mask2, SImode)));
215b30b3 2522 emit_insn (gen_iorsi3 (subtarget, op1,
4292ca6b 2523 gen_int_mode (op3_value << start_bit, SImode)));
215b30b3 2524 }
2525 else if (start_bit == 0
2526 && !(const_ok_for_arm (mask)
2527 || const_ok_for_arm (~mask)))
2528 {
2529 /* A Trick, since we are setting the bottom bits in the word,
2530 we can shift operand[3] up, operand[0] down, OR them together
2531 and rotate the result back again. This takes 3 insns, and
5910bb95 2532 the third might be mergeable into another op. */
215b30b3 2533 /* The shift up copes with the possibility that operand[3] is
2534 wider than the bitfield. */
2535 rtx op0 = gen_reg_rtx (SImode);
2536 rtx op1 = gen_reg_rtx (SImode);
2537
2538 emit_insn (gen_ashlsi3 (op0, operands[3], GEN_INT (32 - width)));
2539 emit_insn (gen_lshrsi3 (op1, operands[0], operands[1]));
2540 emit_insn (gen_iorsi3 (op1, op1, op0));
2541 emit_insn (gen_rotlsi3 (subtarget, op1, operands[1]));
2542 }
2543 else if ((width + start_bit == 32)
2544 && !(const_ok_for_arm (mask)
2545 || const_ok_for_arm (~mask)))
2546 {
2547 /* Similar trick, but slightly less efficient. */
8a18b90c 2548
215b30b3 2549 rtx op0 = gen_reg_rtx (SImode);
2550 rtx op1 = gen_reg_rtx (SImode);
8a18b90c 2551
215b30b3 2552 emit_insn (gen_ashlsi3 (op0, operands[3], GEN_INT (32 - width)));
2553 emit_insn (gen_ashlsi3 (op1, operands[0], operands[1]));
2554 emit_insn (gen_lshrsi3 (op1, op1, operands[1]));
2555 emit_insn (gen_iorsi3 (subtarget, op1, op0));
2556 }
2557 else
2558 {
c5b3a71b 2559 rtx op0 = gen_int_mode (mask, SImode);
215b30b3 2560 rtx op1 = gen_reg_rtx (SImode);
2561 rtx op2 = gen_reg_rtx (SImode);
8a18b90c 2562
215b30b3 2563 if (!(const_ok_for_arm (mask) || const_ok_for_arm (~mask)))
2564 {
2565 rtx tmp = gen_reg_rtx (SImode);
8a18b90c 2566
215b30b3 2567 emit_insn (gen_movsi (tmp, op0));
2568 op0 = tmp;
2569 }
8a18b90c 2570
215b30b3 2571 /* Mask out any bits in operand[3] that are not needed. */
2572 emit_insn (gen_andsi3 (op1, operands[3], op0));
8a18b90c 2573
0438d37f 2574 if (CONST_INT_P (op0)
215b30b3 2575 && (const_ok_for_arm (mask << start_bit)
2576 || const_ok_for_arm (~(mask << start_bit))))
2577 {
c5b3a71b 2578 op0 = gen_int_mode (~(mask << start_bit), SImode);
215b30b3 2579 emit_insn (gen_andsi3 (op2, operands[0], op0));
2580 }
2581 else
2582 {
0438d37f 2583 if (CONST_INT_P (op0))
215b30b3 2584 {
2585 rtx tmp = gen_reg_rtx (SImode);
8a18b90c 2586
215b30b3 2587 emit_insn (gen_movsi (tmp, op0));
2588 op0 = tmp;
2589 }
2590
2591 if (start_bit != 0)
2592 emit_insn (gen_ashlsi3 (op0, op0, operands[2]));
a42059fd 2593
215b30b3 2594 emit_insn (gen_andsi_notsi_si (op2, operands[0], op0));
2595 }
8a18b90c 2596
215b30b3 2597 if (start_bit != 0)
2598 emit_insn (gen_ashlsi3 (op1, op1, operands[2]));
8a18b90c 2599
215b30b3 2600 emit_insn (gen_iorsi3 (subtarget, op1, op2));
2601 }
f082f1c4 2602
215b30b3 2603 if (subtarget != target)
2604 {
2605 /* If TARGET is still a SUBREG, then it must be wider than a word,
2606 so we must be careful only to set the subword we were asked to. */
2607 if (GET_CODE (target) == SUBREG)
2608 emit_move_insn (target, subtarget);
2609 else
2610 emit_move_insn (target, gen_lowpart (GET_MODE (target), subtarget));
2611 }
8a18b90c 2612
215b30b3 2613 DONE;
2614 }"
2615)
8a18b90c 2616
8b054d5a 2617(define_insn "insv_zero"
2618 [(set (zero_extract:SI (match_operand:SI 0 "s_register_operand" "+r")
809003b3 2619 (match_operand:SI 1 "const_int_M_operand" "M")
2620 (match_operand:SI 2 "const_int_M_operand" "M"))
8b054d5a 2621 (const_int 0))]
2622 "arm_arch_thumb2"
2623 "bfc%?\t%0, %2, %1"
2624 [(set_attr "length" "4")
d952d547 2625 (set_attr "predicable" "yes")
d82e788e 2626 (set_attr "predicable_short_it" "no")
2627 (set_attr "type" "bfm")]
8b054d5a 2628)
2629
2630(define_insn "insv_t2"
2631 [(set (zero_extract:SI (match_operand:SI 0 "s_register_operand" "+r")
809003b3 2632 (match_operand:SI 1 "const_int_M_operand" "M")
2633 (match_operand:SI 2 "const_int_M_operand" "M"))
8b054d5a 2634 (match_operand:SI 3 "s_register_operand" "r"))]
2635 "arm_arch_thumb2"
2636 "bfi%?\t%0, %3, %2, %1"
2637 [(set_attr "length" "4")
d952d547 2638 (set_attr "predicable" "yes")
d82e788e 2639 (set_attr "predicable_short_it" "no")
2640 (set_attr "type" "bfm")]
8b054d5a 2641)
2642
215b30b3 2643; constants for op 2 will never be given to these patterns.
a0f94409 2644(define_insn_and_split "*anddi_notdi_di"
9c08d1fa 2645 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
e5fea38e 2646 (and:DI (not:DI (match_operand:DI 1 "s_register_operand" "0,r"))
2647 (match_operand:DI 2 "s_register_operand" "r,0")))]
25f905c2 2648 "TARGET_32BIT"
f6ebffac 2649 "#"
e2669ea7 2650 "TARGET_32BIT && reload_completed
2651 && ! (TARGET_NEON && IS_VFP_REGNUM (REGNO (operands[0])))
2652 && ! IS_IWMMXT_REGNUM (REGNO (operands[0]))"
a0f94409 2653 [(set (match_dup 0) (and:SI (not:SI (match_dup 1)) (match_dup 2)))
2654 (set (match_dup 3) (and:SI (not:SI (match_dup 4)) (match_dup 5)))]
2655 "
2656 {
2657 operands[3] = gen_highpart (SImode, operands[0]);
2658 operands[0] = gen_lowpart (SImode, operands[0]);
2659 operands[4] = gen_highpart (SImode, operands[1]);
2660 operands[1] = gen_lowpart (SImode, operands[1]);
2661 operands[5] = gen_highpart (SImode, operands[2]);
2662 operands[2] = gen_lowpart (SImode, operands[2]);
2663 }"
0d66636f 2664 [(set_attr "length" "8")
1b7da4ac 2665 (set_attr "predicable" "yes")
2666 (set_attr "type" "multiple")]
0d66636f 2667)
d952d547 2668
a0f94409 2669(define_insn_and_split "*anddi_notzesidi_di"
9c08d1fa 2670 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2671 (and:DI (not:DI (zero_extend:DI
2672 (match_operand:SI 2 "s_register_operand" "r,r")))
e2348bcb 2673 (match_operand:DI 1 "s_register_operand" "0,?r")))]
25f905c2 2674 "TARGET_32BIT"
e2348bcb 2675 "@
97499065 2676 bic%?\\t%Q0, %Q1, %2
f6ebffac 2677 #"
a0f94409 2678 ; (not (zero_extend ...)) allows us to just copy the high word from
2679 ; operand1 to operand0.
25f905c2 2680 "TARGET_32BIT
a0f94409 2681 && reload_completed
2682 && operands[0] != operands[1]"
5a097f7d 2683 [(set (match_dup 0) (and:SI (not:SI (match_dup 2)) (match_dup 1)))
a0f94409 2684 (set (match_dup 3) (match_dup 4))]
2685 "
2686 {
2687 operands[3] = gen_highpart (SImode, operands[0]);
2688 operands[0] = gen_lowpart (SImode, operands[0]);
2689 operands[4] = gen_highpart (SImode, operands[1]);
2690 operands[1] = gen_lowpart (SImode, operands[1]);
2691 }"
0d66636f 2692 [(set_attr "length" "4,8")
d952d547 2693 (set_attr "predicable" "yes")
1b7da4ac 2694 (set_attr "predicable_short_it" "no")
2695 (set_attr "type" "multiple")]
0d66636f 2696)
d952d547 2697
d8cd5fa0 2698(define_insn_and_split "*anddi_notdi_zesidi"
2699 [(set (match_operand:DI 0 "s_register_operand" "=r")
2700 (and:DI (not:DI (match_operand:DI 2 "s_register_operand" "r"))
2701 (zero_extend:DI
2702 (match_operand:SI 1 "s_register_operand" "r"))))]
2703 "TARGET_32BIT"
2704 "#"
2705 "TARGET_32BIT && reload_completed"
2706 [(set (match_dup 0) (and:SI (not:SI (match_dup 2)) (match_dup 1)))
2707 (set (match_dup 3) (const_int 0))]
2708 "
2709 {
2710 operands[3] = gen_highpart (SImode, operands[0]);
2711 operands[0] = gen_lowpart (SImode, operands[0]);
2712 operands[2] = gen_lowpart (SImode, operands[2]);
2713 }"
2714 [(set_attr "length" "8")
2715 (set_attr "predicable" "yes")
2716 (set_attr "predicable_short_it" "no")
2717 (set_attr "type" "multiple")]
2718)
2719
a0f94409 2720(define_insn_and_split "*anddi_notsesidi_di"
9c08d1fa 2721 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2722 (and:DI (not:DI (sign_extend:DI
2723 (match_operand:SI 2 "s_register_operand" "r,r")))
5a097f7d 2724 (match_operand:DI 1 "s_register_operand" "0,r")))]
25f905c2 2725 "TARGET_32BIT"
f6ebffac 2726 "#"
25f905c2 2727 "TARGET_32BIT && reload_completed"
5a097f7d 2728 [(set (match_dup 0) (and:SI (not:SI (match_dup 2)) (match_dup 1)))
a0f94409 2729 (set (match_dup 3) (and:SI (not:SI
2730 (ashiftrt:SI (match_dup 2) (const_int 31)))
2731 (match_dup 4)))]
2732 "
2733 {
2734 operands[3] = gen_highpart (SImode, operands[0]);
2735 operands[0] = gen_lowpart (SImode, operands[0]);
2736 operands[4] = gen_highpart (SImode, operands[1]);
2737 operands[1] = gen_lowpart (SImode, operands[1]);
2738 }"
0d66636f 2739 [(set_attr "length" "8")
d952d547 2740 (set_attr "predicable" "yes")
1b7da4ac 2741 (set_attr "predicable_short_it" "no")
2742 (set_attr "type" "multiple")]
0d66636f 2743)
d952d547 2744
8a18b90c 2745(define_insn "andsi_notsi_si"
9c08d1fa 2746 [(set (match_operand:SI 0 "s_register_operand" "=r")
2747 (and:SI (not:SI (match_operand:SI 2 "s_register_operand" "r"))
2748 (match_operand:SI 1 "s_register_operand" "r")))]
25f905c2 2749 "TARGET_32BIT"
0d66636f 2750 "bic%?\\t%0, %1, %2"
d952d547 2751 [(set_attr "predicable" "yes")
1b7da4ac 2752 (set_attr "predicable_short_it" "no")
2753 (set_attr "type" "logic_reg")]
0d66636f 2754)
b11cae9e 2755
8a18b90c 2756(define_insn "andsi_not_shiftsi_si"
a2cd141b 2757 [(set (match_operand:SI 0 "s_register_operand" "=r")
2758 (and:SI (not:SI (match_operator:SI 4 "shift_operator"
2759 [(match_operand:SI 2 "s_register_operand" "r")
2760 (match_operand:SI 3 "arm_rhs_operand" "rM")]))
2761 (match_operand:SI 1 "s_register_operand" "r")))]
cffb2a26 2762 "TARGET_ARM"
6c4c2133 2763 "bic%?\\t%0, %1, %2%S4"
344495ea 2764 [(set_attr "predicable" "yes")
331beb1a 2765 (set_attr "shift" "2")
a2cd141b 2766 (set (attr "type") (if_then_else (match_operand 3 "const_int_operand" "")
d82e788e 2767 (const_string "logic_shift_imm")
2768 (const_string "logic_shift_reg")))]
6c4c2133 2769)
8a18b90c 2770
f7fbdd4a 2771(define_insn "*andsi_notsi_si_compare0"
bd5b4116 2772 [(set (reg:CC_NOOV CC_REGNUM)
e2348bcb 2773 (compare:CC_NOOV
2774 (and:SI (not:SI (match_operand:SI 2 "s_register_operand" "r"))
2775 (match_operand:SI 1 "s_register_operand" "r"))
2776 (const_int 0)))
9c08d1fa 2777 (set (match_operand:SI 0 "s_register_operand" "=r")
2778 (and:SI (not:SI (match_dup 2)) (match_dup 1)))]
25f905c2 2779 "TARGET_32BIT"
2780 "bic%.\\t%0, %1, %2"
d82e788e 2781 [(set_attr "conds" "set")
2782 (set_attr "type" "logics_shift_reg")]
0d66636f 2783)
9c08d1fa 2784
f7fbdd4a 2785(define_insn "*andsi_notsi_si_compare0_scratch"
bd5b4116 2786 [(set (reg:CC_NOOV CC_REGNUM)
e2348bcb 2787 (compare:CC_NOOV
2788 (and:SI (not:SI (match_operand:SI 2 "s_register_operand" "r"))
2789 (match_operand:SI 1 "s_register_operand" "r"))
2790 (const_int 0)))
9c08d1fa 2791 (clobber (match_scratch:SI 0 "=r"))]
25f905c2 2792 "TARGET_32BIT"
2793 "bic%.\\t%0, %1, %2"
d82e788e 2794 [(set_attr "conds" "set")
2795 (set_attr "type" "logics_shift_reg")]
0d66636f 2796)
9c08d1fa 2797
e2669ea7 2798(define_expand "iordi3"
2799 [(set (match_operand:DI 0 "s_register_operand" "")
2800 (ior:DI (match_operand:DI 1 "s_register_operand" "")
2801 (match_operand:DI 2 "neon_logic_op2" "")))]
2802 "TARGET_32BIT"
2803 ""
2804)
2805
74d6113f 2806(define_insn_and_split "*iordi3_insn"
2807 [(set (match_operand:DI 0 "s_register_operand" "=w,w ,&r,&r,&r,&r,?w,?w")
2808 (ior:DI (match_operand:DI 1 "s_register_operand" "%w,0 ,0 ,r ,0 ,r ,w ,0")
e0fe6977 2809 (match_operand:DI 2 "arm_iordi_operand_neon" "w ,Dl,r ,r ,Df,Df,w ,Dl")))]
74d6113f 2810 "TARGET_32BIT && !TARGET_IWMMXT"
2811 {
2812 switch (which_alternative)
2813 {
2814 case 0: /* fall through */
2815 case 6: return "vorr\t%P0, %P1, %P2";
2816 case 1: /* fall through */
2817 case 7: return neon_output_logic_immediate ("vorr", &operands[2],
2818 DImode, 0, VALID_NEON_QREG_MODE (DImode));
2819 case 2:
2820 case 3:
2821 case 4:
2822 case 5:
2823 return "#";
2824 default: gcc_unreachable ();
2825 }
2826 }
2827 "TARGET_32BIT && !TARGET_IWMMXT && reload_completed
2828 && !(IS_VFP_REGNUM (REGNO (operands[0])))"
2829 [(set (match_dup 3) (match_dup 4))
2830 (set (match_dup 5) (match_dup 6))]
2831 "
2832 {
2833 operands[3] = gen_lowpart (SImode, operands[0]);
2834 operands[5] = gen_highpart (SImode, operands[0]);
2835
2836 operands[4] = simplify_gen_binary (IOR, SImode,
2837 gen_lowpart (SImode, operands[1]),
2838 gen_lowpart (SImode, operands[2]));
2839 operands[6] = simplify_gen_binary (IOR, SImode,
2840 gen_highpart (SImode, operands[1]),
2841 gen_highpart_mode (SImode, DImode, operands[2]));
2842
2843 }"
32093010 2844 [(set_attr "type" "neon_logic,neon_logic,multiple,multiple,multiple,\
2845 multiple,neon_logic,neon_logic")
e0fe6977 2846 (set_attr "length" "*,*,8,8,8,8,*,*")
74d6113f 2847 (set_attr "arch" "neon_for_64bits,neon_for_64bits,*,*,*,*,avoid_neon_for_64bits,avoid_neon_for_64bits")]
cffb2a26 2848)
9c08d1fa 2849
f7fbdd4a 2850(define_insn "*iordi_zesidi_di"
9c08d1fa 2851 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2852 (ior:DI (zero_extend:DI
2853 (match_operand:SI 2 "s_register_operand" "r,r"))
e2348bcb 2854 (match_operand:DI 1 "s_register_operand" "0,?r")))]
25f905c2 2855 "TARGET_32BIT"
e2348bcb 2856 "@
97499065 2857 orr%?\\t%Q0, %Q1, %2
f6ebffac 2858 #"
0d66636f 2859 [(set_attr "length" "4,8")
d952d547 2860 (set_attr "predicable" "yes")
1b7da4ac 2861 (set_attr "predicable_short_it" "no")
2862 (set_attr "type" "logic_reg,multiple")]
cffb2a26 2863)
9c08d1fa 2864
f7fbdd4a 2865(define_insn "*iordi_sesidi_di"
9c08d1fa 2866 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2867 (ior:DI (sign_extend:DI
2868 (match_operand:SI 2 "s_register_operand" "r,r"))
e5fea38e 2869 (match_operand:DI 1 "s_register_operand" "0,r")))]
25f905c2 2870 "TARGET_32BIT"
f6ebffac 2871 "#"
0d66636f 2872 [(set_attr "length" "8")
1b7da4ac 2873 (set_attr "predicable" "yes")
2874 (set_attr "type" "multiple")]
cffb2a26 2875)
9c08d1fa 2876
87b22bf7 2877(define_expand "iorsi3"
cffb2a26 2878 [(set (match_operand:SI 0 "s_register_operand" "")
87b22bf7 2879 (ior:SI (match_operand:SI 1 "s_register_operand" "")
2880 (match_operand:SI 2 "reg_or_int_operand" "")))]
cffb2a26 2881 "TARGET_EITHER"
87b22bf7 2882 "
0438d37f 2883 if (CONST_INT_P (operands[2]))
87b22bf7 2884 {
25f905c2 2885 if (TARGET_32BIT)
cffb2a26 2886 {
96f57e36 2887 arm_split_constant (IOR, SImode, NULL_RTX,
2888 INTVAL (operands[2]), operands[0], operands[1],
e1ba4a27 2889 optimize && can_create_pseudo_p ());
cffb2a26 2890 DONE;
2891 }
25f905c2 2892 else /* TARGET_THUMB1 */
923ffadb 2893 {
2894 rtx tmp = force_reg (SImode, operands[2]);
2895 if (rtx_equal_p (operands[0], operands[1]))
2896 operands[2] = tmp;
2897 else
2898 {
2899 operands[2] = operands[1];
2900 operands[1] = tmp;
2901 }
2902 }
87b22bf7 2903 }
cffb2a26 2904 "
2905)
87b22bf7 2906
d5d4dc8d 2907(define_insn_and_split "*iorsi3_insn"
29e234a3 2908 [(set (match_operand:SI 0 "s_register_operand" "=r,l,r,r,r")
2909 (ior:SI (match_operand:SI 1 "s_register_operand" "%r,0,r,r,r")
2910 (match_operand:SI 2 "reg_or_int_operand" "I,l,K,r,?n")))]
d5d4dc8d 2911 "TARGET_32BIT"
87b22bf7 2912 "@
29e234a3 2913 orr%?\\t%0, %1, %2
87b22bf7 2914 orr%?\\t%0, %1, %2
d5d4dc8d 2915 orn%?\\t%0, %1, #%B2
65f68e55 2916 orr%?\\t%0, %1, %2
87b22bf7 2917 #"
d5d4dc8d 2918 "TARGET_32BIT
0438d37f 2919 && CONST_INT_P (operands[2])
d5d4dc8d 2920 && !(const_ok_for_arm (INTVAL (operands[2]))
2921 || (TARGET_THUMB2 && const_ok_for_arm (~INTVAL (operands[2]))))"
a0f94409 2922 [(clobber (const_int 0))]
d5d4dc8d 2923{
29e234a3 2924 arm_split_constant (IOR, SImode, curr_insn,
96f57e36 2925 INTVAL (operands[2]), operands[0], operands[1], 0);
a0f94409 2926 DONE;
d5d4dc8d 2927}
29e234a3 2928 [(set_attr "length" "4,4,4,4,16")
2929 (set_attr "arch" "32,t2,t2,32,32")
65f68e55 2930 (set_attr "predicable" "yes")
29e234a3 2931 (set_attr "predicable_short_it" "no,yes,no,no,no")
d82e788e 2932 (set_attr "type" "logic_imm,logic_reg,logic_imm,logic_reg,logic_reg")]
65f68e55 2933)
cffb2a26 2934
a0f94409 2935(define_peephole2
2936 [(match_scratch:SI 3 "r")
372575c7 2937 (set (match_operand:SI 0 "arm_general_register_operand" "")
2938 (ior:SI (match_operand:SI 1 "arm_general_register_operand" "")
87b22bf7 2939 (match_operand:SI 2 "const_int_operand" "")))]
90560cad 2940 "TARGET_ARM
a0f94409 2941 && !const_ok_for_arm (INTVAL (operands[2]))
2942 && const_ok_for_arm (~INTVAL (operands[2]))"
2943 [(set (match_dup 3) (match_dup 2))
2944 (set (match_dup 0) (ior:SI (match_dup 1) (match_dup 3)))]
2945 ""
215b30b3 2946)
a0f94409 2947
f7fbdd4a 2948(define_insn "*iorsi3_compare0"
bd5b4116 2949 [(set (reg:CC_NOOV CC_REGNUM)
65f68e55 2950 (compare:CC_NOOV (ior:SI (match_operand:SI 1 "s_register_operand" "%r,r")
2951 (match_operand:SI 2 "arm_rhs_operand" "I,r"))
9c08d1fa 2952 (const_int 0)))
65f68e55 2953 (set (match_operand:SI 0 "s_register_operand" "=r,r")
9c08d1fa 2954 (ior:SI (match_dup 1) (match_dup 2)))]
25f905c2 2955 "TARGET_32BIT"
2956 "orr%.\\t%0, %1, %2"
65f68e55 2957 [(set_attr "conds" "set")
d82e788e 2958 (set_attr "type" "logics_imm,logics_reg")]
cffb2a26 2959)
9c08d1fa 2960
f7fbdd4a 2961(define_insn "*iorsi3_compare0_scratch"
bd5b4116 2962 [(set (reg:CC_NOOV CC_REGNUM)
65f68e55 2963 (compare:CC_NOOV (ior:SI (match_operand:SI 1 "s_register_operand" "%r,r")
2964 (match_operand:SI 2 "arm_rhs_operand" "I,r"))
9c08d1fa 2965 (const_int 0)))
65f68e55 2966 (clobber (match_scratch:SI 0 "=r,r"))]
25f905c2 2967 "TARGET_32BIT"
2968 "orr%.\\t%0, %1, %2"
65f68e55 2969 [(set_attr "conds" "set")
d82e788e 2970 (set_attr "type" "logics_imm,logics_reg")]
0d66636f 2971)
9c08d1fa 2972
e2669ea7 2973(define_expand "xordi3"
2974 [(set (match_operand:DI 0 "s_register_operand" "")
2975 (xor:DI (match_operand:DI 1 "s_register_operand" "")
8ee7dc6f 2976 (match_operand:DI 2 "arm_xordi_operand" "")))]
e2669ea7 2977 "TARGET_32BIT"
2978 ""
2979)
2980
8ee7dc6f 2981(define_insn_and_split "*xordi3_insn"
2982 [(set (match_operand:DI 0 "s_register_operand" "=w,&r,&r,&r,&r,?w")
205c3b0a 2983 (xor:DI (match_operand:DI 1 "s_register_operand" "%w ,0,r ,0 ,r ,w")
8ee7dc6f 2984 (match_operand:DI 2 "arm_xordi_operand" "w ,r ,r ,Dg,Dg,w")))]
2985 "TARGET_32BIT && !TARGET_IWMMXT"
2986{
2987 switch (which_alternative)
2988 {
2989 case 1:
2990 case 2:
2991 case 3:
2992 case 4: /* fall through */
2993 return "#";
2994 case 0: /* fall through */
2995 case 5: return "veor\t%P0, %P1, %P2";
2996 default: gcc_unreachable ();
2997 }
2998}
2999 "TARGET_32BIT && !TARGET_IWMMXT && reload_completed
3000 && !(IS_VFP_REGNUM (REGNO (operands[0])))"
3001 [(set (match_dup 3) (match_dup 4))
3002 (set (match_dup 5) (match_dup 6))]
3003 "
3004 {
3005 operands[3] = gen_lowpart (SImode, operands[0]);
3006 operands[5] = gen_highpart (SImode, operands[0]);
3007
3008 operands[4] = simplify_gen_binary (XOR, SImode,
3009 gen_lowpart (SImode, operands[1]),
3010 gen_lowpart (SImode, operands[2]));
3011 operands[6] = simplify_gen_binary (XOR, SImode,
3012 gen_highpart (SImode, operands[1]),
3013 gen_highpart_mode (SImode, DImode, operands[2]));
3014
3015 }"
3016 [(set_attr "length" "*,8,8,8,8,*")
32093010 3017 (set_attr "type" "neon_logic,multiple,multiple,multiple,multiple,neon_logic")
8ee7dc6f 3018 (set_attr "arch" "neon_for_64bits,*,*,*,*,avoid_neon_for_64bits")]
cffb2a26 3019)
9c08d1fa 3020
f7fbdd4a 3021(define_insn "*xordi_zesidi_di"
9c08d1fa 3022 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
3023 (xor:DI (zero_extend:DI
3024 (match_operand:SI 2 "s_register_operand" "r,r"))
e2348bcb 3025 (match_operand:DI 1 "s_register_operand" "0,?r")))]
25f905c2 3026 "TARGET_32BIT"
e2348bcb 3027 "@
97499065 3028 eor%?\\t%Q0, %Q1, %2
f6ebffac 3029 #"
0d66636f 3030 [(set_attr "length" "4,8")
d952d547 3031 (set_attr "predicable" "yes")
1b7da4ac 3032 (set_attr "predicable_short_it" "no")
3033 (set_attr "type" "logic_reg")]
cffb2a26 3034)
9c08d1fa 3035
f7fbdd4a 3036(define_insn "*xordi_sesidi_di"
9c08d1fa 3037 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
3038 (xor:DI (sign_extend:DI
3039 (match_operand:SI 2 "s_register_operand" "r,r"))
e5fea38e 3040 (match_operand:DI 1 "s_register_operand" "0,r")))]
25f905c2 3041 "TARGET_32BIT"
f6ebffac 3042 "#"
0d66636f 3043 [(set_attr "length" "8")
1b7da4ac 3044 (set_attr "predicable" "yes")
3045 (set_attr "type" "multiple")]
cffb2a26 3046)
9c08d1fa 3047
cffb2a26 3048(define_expand "xorsi3"
3049 [(set (match_operand:SI 0 "s_register_operand" "")
3050 (xor:SI (match_operand:SI 1 "s_register_operand" "")
923ffadb 3051 (match_operand:SI 2 "reg_or_int_operand" "")))]
cffb2a26 3052 "TARGET_EITHER"
0438d37f 3053 "if (CONST_INT_P (operands[2]))
923ffadb 3054 {
3055 if (TARGET_32BIT)
3056 {
3057 arm_split_constant (XOR, SImode, NULL_RTX,
3058 INTVAL (operands[2]), operands[0], operands[1],
3059 optimize && can_create_pseudo_p ());
3060 DONE;
3061 }
3062 else /* TARGET_THUMB1 */
3063 {
3064 rtx tmp = force_reg (SImode, operands[2]);
3065 if (rtx_equal_p (operands[0], operands[1]))
3066 operands[2] = tmp;
3067 else
3068 {
3069 operands[2] = operands[1];
3070 operands[1] = tmp;
3071 }
3072 }
3073 }"
cffb2a26 3074)
3075
5dcb35d9 3076(define_insn_and_split "*arm_xorsi3"
29e234a3 3077 [(set (match_operand:SI 0 "s_register_operand" "=r,l,r,r")
3078 (xor:SI (match_operand:SI 1 "s_register_operand" "%r,0,r,r")
3079 (match_operand:SI 2 "reg_or_int_operand" "I,l,r,?n")))]
25f905c2 3080 "TARGET_32BIT"
5dcb35d9 3081 "@
29e234a3 3082 eor%?\\t%0, %1, %2
65f68e55 3083 eor%?\\t%0, %1, %2
5dcb35d9 3084 eor%?\\t%0, %1, %2
3085 #"
3086 "TARGET_32BIT
0438d37f 3087 && CONST_INT_P (operands[2])
5dcb35d9 3088 && !const_ok_for_arm (INTVAL (operands[2]))"
3089 [(clobber (const_int 0))]
3090{
3091 arm_split_constant (XOR, SImode, curr_insn,
3092 INTVAL (operands[2]), operands[0], operands[1], 0);
3093 DONE;
3094}
29e234a3 3095 [(set_attr "length" "4,4,4,16")
65f68e55 3096 (set_attr "predicable" "yes")
29e234a3 3097 (set_attr "predicable_short_it" "no,yes,no,no")
1b7da4ac 3098 (set_attr "type" "logic_imm,logic_reg,logic_reg,multiple")]
cffb2a26 3099)
3100
f7fbdd4a 3101(define_insn "*xorsi3_compare0"
bd5b4116 3102 [(set (reg:CC_NOOV CC_REGNUM)
65f68e55 3103 (compare:CC_NOOV (xor:SI (match_operand:SI 1 "s_register_operand" "r,r")
3104 (match_operand:SI 2 "arm_rhs_operand" "I,r"))
9c08d1fa 3105 (const_int 0)))
65f68e55 3106 (set (match_operand:SI 0 "s_register_operand" "=r,r")
9c08d1fa 3107 (xor:SI (match_dup 1) (match_dup 2)))]
25f905c2 3108 "TARGET_32BIT"
3109 "eor%.\\t%0, %1, %2"
65f68e55 3110 [(set_attr "conds" "set")
d82e788e 3111 (set_attr "type" "logics_imm,logics_reg")]
0d66636f 3112)
9c08d1fa 3113
f7fbdd4a 3114(define_insn "*xorsi3_compare0_scratch"
bd5b4116 3115 [(set (reg:CC_NOOV CC_REGNUM)
65f68e55 3116 (compare:CC_NOOV (xor:SI (match_operand:SI 0 "s_register_operand" "r,r")
3117 (match_operand:SI 1 "arm_rhs_operand" "I,r"))
9c08d1fa 3118 (const_int 0)))]
25f905c2 3119 "TARGET_32BIT"
40dbec34 3120 "teq%?\\t%0, %1"
65f68e55 3121 [(set_attr "conds" "set")
d82e788e 3122 (set_attr "type" "logics_imm,logics_reg")]
cffb2a26 3123)
9c08d1fa 3124
215b30b3 3125; By splitting (IOR (AND (NOT A) (NOT B)) C) as D = AND (IOR A B) (NOT C),
3126; (NOT D) we can sometimes merge the final NOT into one of the following
3127; insns.
9c08d1fa 3128
3129(define_split
a058e94a 3130 [(set (match_operand:SI 0 "s_register_operand" "")
3131 (ior:SI (and:SI (not:SI (match_operand:SI 1 "s_register_operand" ""))
3132 (not:SI (match_operand:SI 2 "arm_rhs_operand" "")))
3133 (match_operand:SI 3 "arm_rhs_operand" "")))
3134 (clobber (match_operand:SI 4 "s_register_operand" ""))]
25f905c2 3135 "TARGET_32BIT"
9c08d1fa 3136 [(set (match_dup 4) (and:SI (ior:SI (match_dup 1) (match_dup 2))
3137 (not:SI (match_dup 3))))
3138 (set (match_dup 0) (not:SI (match_dup 4)))]
3139 ""
3140)
3141
ba6a3b2f 3142(define_insn_and_split "*andsi_iorsi3_notsi"
9c08d1fa 3143 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r")
e5fea38e 3144 (and:SI (ior:SI (match_operand:SI 1 "s_register_operand" "%0,r,r")
9c08d1fa 3145 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI"))
3146 (not:SI (match_operand:SI 3 "arm_rhs_operand" "rI,rI,rI"))))]
25f905c2 3147 "TARGET_32BIT"
ba6a3b2f 3148 "#" ; "orr%?\\t%0, %1, %2\;bic%?\\t%0, %0, %3"
3149 "&& reload_completed"
3150 [(set (match_dup 0) (ior:SI (match_dup 1) (match_dup 2)))
3151 (set (match_dup 0) (and:SI (not:SI (match_dup 3)) (match_dup 0)))]
3152 ""
0d66636f 3153 [(set_attr "length" "8")
25f905c2 3154 (set_attr "ce_count" "2")
d952d547 3155 (set_attr "predicable" "yes")
1b7da4ac 3156 (set_attr "predicable_short_it" "no")
3157 (set_attr "type" "multiple")]
cffb2a26 3158)
9c08d1fa 3159
25f905c2 3160; ??? Are these four splitters still beneficial when the Thumb-2 bitfield
3161; insns are available?
d7863cfe 3162(define_split
3163 [(set (match_operand:SI 0 "s_register_operand" "")
3164 (match_operator:SI 1 "logical_binary_operator"
3165 [(zero_extract:SI (match_operand:SI 2 "s_register_operand" "")
3166 (match_operand:SI 3 "const_int_operand" "")
3167 (match_operand:SI 4 "const_int_operand" ""))
3168 (match_operator:SI 9 "logical_binary_operator"
3169 [(lshiftrt:SI (match_operand:SI 5 "s_register_operand" "")
3170 (match_operand:SI 6 "const_int_operand" ""))
3171 (match_operand:SI 7 "s_register_operand" "")])]))
3172 (clobber (match_operand:SI 8 "s_register_operand" ""))]
25f905c2 3173 "TARGET_32BIT
d7863cfe 3174 && GET_CODE (operands[1]) == GET_CODE (operands[9])
3175 && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
3176 [(set (match_dup 8)
3177 (match_op_dup 1
3178 [(ashift:SI (match_dup 2) (match_dup 4))
3179 (match_dup 5)]))
3180 (set (match_dup 0)
3181 (match_op_dup 1
3182 [(lshiftrt:SI (match_dup 8) (match_dup 6))
3183 (match_dup 7)]))]
3184 "
3185 operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
3186")
3187
3188(define_split
3189 [(set (match_operand:SI 0 "s_register_operand" "")
3190 (match_operator:SI 1 "logical_binary_operator"
3191 [(match_operator:SI 9 "logical_binary_operator"
3192 [(lshiftrt:SI (match_operand:SI 5 "s_register_operand" "")
3193 (match_operand:SI 6 "const_int_operand" ""))
3194 (match_operand:SI 7 "s_register_operand" "")])
3195 (zero_extract:SI (match_operand:SI 2 "s_register_operand" "")
3196 (match_operand:SI 3 "const_int_operand" "")
3197 (match_operand:SI 4 "const_int_operand" ""))]))
3198 (clobber (match_operand:SI 8 "s_register_operand" ""))]
25f905c2 3199 "TARGET_32BIT
d7863cfe 3200 && GET_CODE (operands[1]) == GET_CODE (operands[9])
3201 && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
3202 [(set (match_dup 8)
3203 (match_op_dup 1
3204 [(ashift:SI (match_dup 2) (match_dup 4))
3205 (match_dup 5)]))
3206 (set (match_dup 0)
3207 (match_op_dup 1
3208 [(lshiftrt:SI (match_dup 8) (match_dup 6))
3209 (match_dup 7)]))]
3210 "
3211 operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
3212")
3213
3214(define_split
3215 [(set (match_operand:SI 0 "s_register_operand" "")
3216 (match_operator:SI 1 "logical_binary_operator"
3217 [(sign_extract:SI (match_operand:SI 2 "s_register_operand" "")
3218 (match_operand:SI 3 "const_int_operand" "")
3219 (match_operand:SI 4 "const_int_operand" ""))
3220 (match_operator:SI 9 "logical_binary_operator"
3221 [(ashiftrt:SI (match_operand:SI 5 "s_register_operand" "")
3222 (match_operand:SI 6 "const_int_operand" ""))
3223 (match_operand:SI 7 "s_register_operand" "")])]))
3224 (clobber (match_operand:SI 8 "s_register_operand" ""))]
25f905c2 3225 "TARGET_32BIT
d7863cfe 3226 && GET_CODE (operands[1]) == GET_CODE (operands[9])
3227 && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
3228 [(set (match_dup 8)
3229 (match_op_dup 1
3230 [(ashift:SI (match_dup 2) (match_dup 4))
3231 (match_dup 5)]))
3232 (set (match_dup 0)
3233 (match_op_dup 1
3234 [(ashiftrt:SI (match_dup 8) (match_dup 6))
3235 (match_dup 7)]))]
3236 "
3237 operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
3238")
3239
3240(define_split
3241 [(set (match_operand:SI 0 "s_register_operand" "")
3242 (match_operator:SI 1 "logical_binary_operator"
3243 [(match_operator:SI 9 "logical_binary_operator"
3244 [(ashiftrt:SI (match_operand:SI 5 "s_register_operand" "")
3245 (match_operand:SI 6 "const_int_operand" ""))
3246 (match_operand:SI 7 "s_register_operand" "")])
3247 (sign_extract:SI (match_operand:SI 2 "s_register_operand" "")
3248 (match_operand:SI 3 "const_int_operand" "")
3249 (match_operand:SI 4 "const_int_operand" ""))]))
3250 (clobber (match_operand:SI 8 "s_register_operand" ""))]
25f905c2 3251 "TARGET_32BIT
d7863cfe 3252 && GET_CODE (operands[1]) == GET_CODE (operands[9])
3253 && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
3254 [(set (match_dup 8)
3255 (match_op_dup 1
3256 [(ashift:SI (match_dup 2) (match_dup 4))
3257 (match_dup 5)]))
3258 (set (match_dup 0)
3259 (match_op_dup 1
3260 [(ashiftrt:SI (match_dup 8) (match_dup 6))
3261 (match_dup 7)]))]
3262 "
3263 operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
3264")
9c08d1fa 3265\f
3266
3267;; Minimum and maximum insns
3268
8b9dc177 3269(define_expand "smaxsi3"
3270 [(parallel [
3271 (set (match_operand:SI 0 "s_register_operand" "")
3272 (smax:SI (match_operand:SI 1 "s_register_operand" "")
3273 (match_operand:SI 2 "arm_rhs_operand" "")))
3274 (clobber (reg:CC CC_REGNUM))])]
25f905c2 3275 "TARGET_32BIT"
8b9dc177 3276 "
8774928b 3277 if (operands[2] == const0_rtx || operands[2] == constm1_rtx)
8b9dc177 3278 {
3279 /* No need for a clobber of the condition code register here. */
3280 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
3281 gen_rtx_SMAX (SImode, operands[1],
3282 operands[2])));
3283 DONE;
3284 }
3285")
3286
3287(define_insn "*smax_0"
3288 [(set (match_operand:SI 0 "s_register_operand" "=r")
3289 (smax:SI (match_operand:SI 1 "s_register_operand" "r")
3290 (const_int 0)))]
25f905c2 3291 "TARGET_32BIT"
8b9dc177 3292 "bic%?\\t%0, %1, %1, asr #31"
d952d547 3293 [(set_attr "predicable" "yes")
1b7da4ac 3294 (set_attr "predicable_short_it" "no")
3295 (set_attr "type" "logic_shift_reg")]
8b9dc177 3296)
3297
8774928b 3298(define_insn "*smax_m1"
3299 [(set (match_operand:SI 0 "s_register_operand" "=r")
3300 (smax:SI (match_operand:SI 1 "s_register_operand" "r")
3301 (const_int -1)))]
25f905c2 3302 "TARGET_32BIT"
8774928b 3303 "orr%?\\t%0, %1, %1, asr #31"
d952d547 3304 [(set_attr "predicable" "yes")
1b7da4ac 3305 (set_attr "predicable_short_it" "no")
3306 (set_attr "type" "logic_shift_reg")]
8774928b 3307)
3308
3dc953f2 3309(define_insn_and_split "*arm_smax_insn"
8b9dc177 3310 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
3311 (smax:SI (match_operand:SI 1 "s_register_operand" "%0,?r")
3312 (match_operand:SI 2 "arm_rhs_operand" "rI,rI")))
bd5b4116 3313 (clobber (reg:CC CC_REGNUM))]
cffb2a26 3314 "TARGET_ARM"
3dc953f2 3315 "#"
3316 ; cmp\\t%1, %2\;movlt\\t%0, %2
3317 ; cmp\\t%1, %2\;movge\\t%0, %1\;movlt\\t%0, %2"
3318 "TARGET_ARM"
3319 [(set (reg:CC CC_REGNUM)
3320 (compare:CC (match_dup 1) (match_dup 2)))
3321 (set (match_dup 0)
3322 (if_then_else:SI (ge:SI (reg:CC CC_REGNUM) (const_int 0))
3323 (match_dup 1)
3324 (match_dup 2)))]
3325 ""
cffb2a26 3326 [(set_attr "conds" "clob")
1b7da4ac 3327 (set_attr "length" "8,12")
3328 (set_attr "type" "multiple")]
cffb2a26 3329)
9c08d1fa 3330
8b9dc177 3331(define_expand "sminsi3"
3332 [(parallel [
3333 (set (match_operand:SI 0 "s_register_operand" "")
3334 (smin:SI (match_operand:SI 1 "s_register_operand" "")
3335 (match_operand:SI 2 "arm_rhs_operand" "")))
3336 (clobber (reg:CC CC_REGNUM))])]
25f905c2 3337 "TARGET_32BIT"
8b9dc177 3338 "
3339 if (operands[2] == const0_rtx)
3340 {
3341 /* No need for a clobber of the condition code register here. */
3342 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
3343 gen_rtx_SMIN (SImode, operands[1],
3344 operands[2])));
3345 DONE;
3346 }
3347")
3348
3349(define_insn "*smin_0"
3350 [(set (match_operand:SI 0 "s_register_operand" "=r")
3351 (smin:SI (match_operand:SI 1 "s_register_operand" "r")
3352 (const_int 0)))]
25f905c2 3353 "TARGET_32BIT"
8b9dc177 3354 "and%?\\t%0, %1, %1, asr #31"
d952d547 3355 [(set_attr "predicable" "yes")
1b7da4ac 3356 (set_attr "predicable_short_it" "no")
3357 (set_attr "type" "logic_shift_reg")]
8b9dc177 3358)
3359
3dc953f2 3360(define_insn_and_split "*arm_smin_insn"
8b9dc177 3361 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
3362 (smin:SI (match_operand:SI 1 "s_register_operand" "%0,?r")
3363 (match_operand:SI 2 "arm_rhs_operand" "rI,rI")))
bd5b4116 3364 (clobber (reg:CC CC_REGNUM))]
cffb2a26 3365 "TARGET_ARM"
3dc953f2 3366 "#"
3367 ; cmp\\t%1, %2\;movge\\t%0, %2
3368 ; cmp\\t%1, %2\;movlt\\t%0, %1\;movge\\t%0, %2"
3369 "TARGET_ARM"
3370 [(set (reg:CC CC_REGNUM)
3371 (compare:CC (match_dup 1) (match_dup 2)))
3372 (set (match_dup 0)
3373 (if_then_else:SI (lt:SI (reg:CC CC_REGNUM) (const_int 0))
3374 (match_dup 1)
3375 (match_dup 2)))]
3376 ""
0d66636f 3377 [(set_attr "conds" "clob")
1b7da4ac 3378 (set_attr "length" "8,12")
3379 (set_attr "type" "multiple,multiple")]
0d66636f 3380)
9c08d1fa 3381
25f905c2 3382(define_expand "umaxsi3"
3383 [(parallel [
3384 (set (match_operand:SI 0 "s_register_operand" "")
3385 (umax:SI (match_operand:SI 1 "s_register_operand" "")
3386 (match_operand:SI 2 "arm_rhs_operand" "")))
3387 (clobber (reg:CC CC_REGNUM))])]
3388 "TARGET_32BIT"
3389 ""
3390)
3391
3dc953f2 3392(define_insn_and_split "*arm_umaxsi3"
9c08d1fa 3393 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
3394 (umax:SI (match_operand:SI 1 "s_register_operand" "0,r,?r")
3395 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
bd5b4116 3396 (clobber (reg:CC CC_REGNUM))]
cffb2a26 3397 "TARGET_ARM"
3dc953f2 3398 "#"
3399 ; cmp\\t%1, %2\;movcc\\t%0, %2
3400 ; cmp\\t%1, %2\;movcs\\t%0, %1
3401 ; cmp\\t%1, %2\;movcs\\t%0, %1\;movcc\\t%0, %2"
3402 "TARGET_ARM"
3403 [(set (reg:CC CC_REGNUM)
3404 (compare:CC (match_dup 1) (match_dup 2)))
3405 (set (match_dup 0)
3406 (if_then_else:SI (geu:SI (reg:CC CC_REGNUM) (const_int 0))
3407 (match_dup 1)
3408 (match_dup 2)))]
3409 ""
0d66636f 3410 [(set_attr "conds" "clob")
1b7da4ac 3411 (set_attr "length" "8,8,12")
3412 (set_attr "type" "store1")]
0d66636f 3413)
9c08d1fa 3414
25f905c2 3415(define_expand "uminsi3"
3416 [(parallel [
3417 (set (match_operand:SI 0 "s_register_operand" "")
3418 (umin:SI (match_operand:SI 1 "s_register_operand" "")
3419 (match_operand:SI 2 "arm_rhs_operand" "")))
3420 (clobber (reg:CC CC_REGNUM))])]
3421 "TARGET_32BIT"
3422 ""
3423)
3424
3dc953f2 3425(define_insn_and_split "*arm_uminsi3"
9c08d1fa 3426 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
3427 (umin:SI (match_operand:SI 1 "s_register_operand" "0,r,?r")
3428 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
bd5b4116 3429 (clobber (reg:CC CC_REGNUM))]
cffb2a26 3430 "TARGET_ARM"
3dc953f2 3431 "#"
3432 ; cmp\\t%1, %2\;movcs\\t%0, %2
3433 ; cmp\\t%1, %2\;movcc\\t%0, %1
3434 ; cmp\\t%1, %2\;movcc\\t%0, %1\;movcs\\t%0, %2"
3435 "TARGET_ARM"
3436 [(set (reg:CC CC_REGNUM)
3437 (compare:CC (match_dup 1) (match_dup 2)))
3438 (set (match_dup 0)
3439 (if_then_else:SI (ltu:SI (reg:CC CC_REGNUM) (const_int 0))
3440 (match_dup 1)
3441 (match_dup 2)))]
3442 ""
0d66636f 3443 [(set_attr "conds" "clob")
1b7da4ac 3444 (set_attr "length" "8,8,12")
3445 (set_attr "type" "store1")]
0d66636f 3446)
9c08d1fa 3447
8a18b90c 3448(define_insn "*store_minmaxsi"
9c08d1fa 3449 [(set (match_operand:SI 0 "memory_operand" "=m")
3450 (match_operator:SI 3 "minmax_operator"
3451 [(match_operand:SI 1 "s_register_operand" "r")
3452 (match_operand:SI 2 "s_register_operand" "r")]))
bd5b4116 3453 (clobber (reg:CC CC_REGNUM))]
b207d152 3454 "TARGET_32BIT && optimize_function_for_size_p (cfun) && !arm_restrict_it"
9c08d1fa 3455 "*
dc55b8a9 3456 operands[3] = gen_rtx_fmt_ee (minmax_code (operands[3]), SImode,
3457 operands[1], operands[2]);
e2348bcb 3458 output_asm_insn (\"cmp\\t%1, %2\", operands);
25f905c2 3459 if (TARGET_THUMB2)
3460 output_asm_insn (\"ite\t%d3\", operands);
e2348bcb 3461 output_asm_insn (\"str%d3\\t%1, %0\", operands);
3462 output_asm_insn (\"str%D3\\t%2, %0\", operands);
3463 return \"\";
0d66636f 3464 "
3465 [(set_attr "conds" "clob")
25f905c2 3466 (set (attr "length")
3467 (if_then_else (eq_attr "is_thumb" "yes")
3468 (const_int 14)
3469 (const_int 12)))
0d66636f 3470 (set_attr "type" "store1")]
3471)
9c08d1fa 3472
8a18b90c 3473; Reject the frame pointer in operand[1], since reloading this after
3474; it has been eliminated can cause carnage.
f7fbdd4a 3475(define_insn "*minmax_arithsi"
9c08d1fa 3476 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
3477 (match_operator:SI 4 "shiftable_operator"
3478 [(match_operator:SI 5 "minmax_operator"
3479 [(match_operand:SI 2 "s_register_operand" "r,r")
3480 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
3481 (match_operand:SI 1 "s_register_operand" "0,?r")]))
bd5b4116 3482 (clobber (reg:CC CC_REGNUM))]
7c36fe71 3483 "TARGET_32BIT && !arm_eliminable_register (operands[1]) && !arm_restrict_it"
9c08d1fa 3484 "*
0d66636f 3485 {
3486 enum rtx_code code = GET_CODE (operands[4]);
25f905c2 3487 bool need_else;
3488
3489 if (which_alternative != 0 || operands[3] != const0_rtx
ca0fc5a2 3490 || (code != PLUS && code != IOR && code != XOR))
25f905c2 3491 need_else = true;
3492 else
3493 need_else = false;
0d66636f 3494
dc55b8a9 3495 operands[5] = gen_rtx_fmt_ee (minmax_code (operands[5]), SImode,
3496 operands[2], operands[3]);
0d66636f 3497 output_asm_insn (\"cmp\\t%2, %3\", operands);
25f905c2 3498 if (TARGET_THUMB2)
3499 {
3500 if (need_else)
3501 output_asm_insn (\"ite\\t%d5\", operands);
3502 else
3503 output_asm_insn (\"it\\t%d5\", operands);
3504 }
0d66636f 3505 output_asm_insn (\"%i4%d5\\t%0, %1, %2\", operands);
25f905c2 3506 if (need_else)
0d66636f 3507 output_asm_insn (\"%i4%D5\\t%0, %1, %3\", operands);
3508 return \"\";
215b30b3 3509 }"
0d66636f 3510 [(set_attr "conds" "clob")
25f905c2 3511 (set (attr "length")
3512 (if_then_else (eq_attr "is_thumb" "yes")
3513 (const_int 14)
1b7da4ac 3514 (const_int 12)))
3515 (set_attr "type" "multiple")]
0d66636f 3516)
9c08d1fa 3517
4164bca1 3518; Reject the frame pointer in operand[1], since reloading this after
3519; it has been eliminated can cause carnage.
3520(define_insn_and_split "*minmax_arithsi_non_canon"
7c36fe71 3521 [(set (match_operand:SI 0 "s_register_operand" "=Ts,Ts")
4164bca1 3522 (minus:SI
7c36fe71 3523 (match_operand:SI 1 "s_register_operand" "0,?Ts")
4164bca1 3524 (match_operator:SI 4 "minmax_operator"
7c36fe71 3525 [(match_operand:SI 2 "s_register_operand" "Ts,Ts")
3526 (match_operand:SI 3 "arm_rhs_operand" "TsI,TsI")])))
4164bca1 3527 (clobber (reg:CC CC_REGNUM))]
7c36fe71 3528 "TARGET_32BIT && !arm_eliminable_register (operands[1])
3529 && !(arm_restrict_it && CONST_INT_P (operands[3]))"
4164bca1 3530 "#"
3531 "TARGET_32BIT && !arm_eliminable_register (operands[1]) && reload_completed"
3532 [(set (reg:CC CC_REGNUM)
3533 (compare:CC (match_dup 2) (match_dup 3)))
3534
3535 (cond_exec (match_op_dup 4 [(reg:CC CC_REGNUM) (const_int 0)])
3536 (set (match_dup 0)
3537 (minus:SI (match_dup 1)
3538 (match_dup 2))))
3539 (cond_exec (match_op_dup 5 [(reg:CC CC_REGNUM) (const_int 0)])
3540 (set (match_dup 0)
36ee0cde 3541 (match_dup 6)))]
4164bca1 3542 {
3754d046 3543 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
4164bca1 3544 operands[2], operands[3]);
3545 enum rtx_code rc = minmax_code (operands[4]);
3546 operands[4] = gen_rtx_fmt_ee (rc, VOIDmode,
3547 operands[2], operands[3]);
3548
3549 if (mode == CCFPmode || mode == CCFPEmode)
3550 rc = reverse_condition_maybe_unordered (rc);
3551 else
3552 rc = reverse_condition (rc);
3553 operands[5] = gen_rtx_fmt_ee (rc, SImode, operands[2], operands[3]);
36ee0cde 3554 if (CONST_INT_P (operands[3]))
3555 operands[6] = plus_constant (SImode, operands[1], -INTVAL (operands[3]));
3556 else
3557 operands[6] = gen_rtx_MINUS (SImode, operands[1], operands[3]);
4164bca1 3558 }
3559 [(set_attr "conds" "clob")
3560 (set (attr "length")
3561 (if_then_else (eq_attr "is_thumb" "yes")
3562 (const_int 14)
1b7da4ac 3563 (const_int 12)))
3564 (set_attr "type" "multiple")]
4164bca1 3565)
3566
b49e3742 3567(define_code_iterator SAT [smin smax])
3568(define_code_iterator SATrev [smin smax])
3569(define_code_attr SATlo [(smin "1") (smax "2")])
3570(define_code_attr SAThi [(smin "2") (smax "1")])
3571
3572(define_insn "*satsi_<SAT:code>"
3573 [(set (match_operand:SI 0 "s_register_operand" "=r")
3574 (SAT:SI (SATrev:SI (match_operand:SI 3 "s_register_operand" "r")
3575 (match_operand:SI 1 "const_int_operand" "i"))
3576 (match_operand:SI 2 "const_int_operand" "i")))]
3577 "TARGET_32BIT && arm_arch6 && <SAT:CODE> != <SATrev:CODE>
3578 && arm_sat_operator_match (operands[<SAT:SATlo>], operands[<SAT:SAThi>], NULL, NULL)"
3579{
3580 int mask;
3581 bool signed_sat;
3582 if (!arm_sat_operator_match (operands[<SAT:SATlo>], operands[<SAT:SAThi>],
3583 &mask, &signed_sat))
3584 gcc_unreachable ();
3585
3586 operands[1] = GEN_INT (mask);
3587 if (signed_sat)
3588 return "ssat%?\t%0, %1, %3";
3589 else
3590 return "usat%?\t%0, %1, %3";
3591}
7c36fe71 3592 [(set_attr "predicable" "yes")
1b7da4ac 3593 (set_attr "predicable_short_it" "no")
3594 (set_attr "type" "alus_imm")]
bebe9bbb 3595)
b49e3742 3596
3597(define_insn "*satsi_<SAT:code>_shift"
3598 [(set (match_operand:SI 0 "s_register_operand" "=r")
3599 (SAT:SI (SATrev:SI (match_operator:SI 3 "sat_shift_operator"
3600 [(match_operand:SI 4 "s_register_operand" "r")
3601 (match_operand:SI 5 "const_int_operand" "i")])
3602 (match_operand:SI 1 "const_int_operand" "i"))
3603 (match_operand:SI 2 "const_int_operand" "i")))]
3604 "TARGET_32BIT && arm_arch6 && <SAT:CODE> != <SATrev:CODE>
3605 && arm_sat_operator_match (operands[<SAT:SATlo>], operands[<SAT:SAThi>], NULL, NULL)"
3606{
3607 int mask;
3608 bool signed_sat;
3609 if (!arm_sat_operator_match (operands[<SAT:SATlo>], operands[<SAT:SAThi>],
3610 &mask, &signed_sat))
3611 gcc_unreachable ();
3612
3613 operands[1] = GEN_INT (mask);
3614 if (signed_sat)
3615 return "ssat%?\t%0, %1, %4%S3";
3616 else
3617 return "usat%?\t%0, %1, %4%S3";
3618}
3619 [(set_attr "predicable" "yes")
7c36fe71 3620 (set_attr "predicable_short_it" "no")
b49e3742 3621 (set_attr "shift" "3")
d82e788e 3622 (set_attr "type" "logic_shift_reg")])
b11cae9e 3623\f
3624;; Shift and rotation insns
3625
a2cd141b 3626(define_expand "ashldi3"
3627 [(set (match_operand:DI 0 "s_register_operand" "")
3628 (ashift:DI (match_operand:DI 1 "s_register_operand" "")
aa06c51c 3629 (match_operand:SI 2 "general_operand" "")))]
25f905c2 3630 "TARGET_32BIT"
a2cd141b 3631 "
aa06c51c 3632 if (TARGET_NEON)
3633 {
3634 /* Delay the decision whether to use NEON or core-regs until
3635 register allocation. */
3636 emit_insn (gen_ashldi3_neon (operands[0], operands[1], operands[2]));
3637 DONE;
3638 }
3639 else
3640 {
3641 /* Only the NEON case can handle in-memory shift counts. */
3642 if (!reg_or_int_operand (operands[2], SImode))
3643 operands[2] = force_reg (SImode, operands[2]);
3644 }
3645
b805622c 3646 if (!CONST_INT_P (operands[2]) && TARGET_REALLY_IWMMXT)
ffcc986d 3647 ; /* No special preparation statements; expand pattern as above. */
3648 else
a2cd141b 3649 {
ffcc986d 3650 rtx scratch1, scratch2;
3651
3652 if (CONST_INT_P (operands[2])
3653 && (HOST_WIDE_INT) INTVAL (operands[2]) == 1)
a2cd141b 3654 {
3655 emit_insn (gen_arm_ashldi3_1bit (operands[0], operands[1]));
3656 DONE;
3657 }
ffcc986d 3658
3659 /* Ideally we should use iwmmxt here if we could know that operands[1]
3660 ends up already living in an iwmmxt register. Otherwise it's
3661 cheaper to have the alternate code being generated than moving
3662 values to iwmmxt regs and back. */
3663
3664 /* If we're optimizing for size, we prefer the libgcc calls. */
3665 if (optimize_function_for_size_p (cfun))
3666 FAIL;
3667
3668 /* Expand operation using core-registers.
3669 'FAIL' would achieve the same thing, but this is a bit smarter. */
3670 scratch1 = gen_reg_rtx (SImode);
3671 scratch2 = gen_reg_rtx (SImode);
3672 arm_emit_coreregs_64bit_shift (ASHIFT, operands[0], operands[1],
3673 operands[2], scratch1, scratch2);
3674 DONE;
a2cd141b 3675 }
a2cd141b 3676 "
3677)
3678
2837e3fb 3679(define_insn "arm_ashldi3_1bit"
50ad1bf9 3680 [(set (match_operand:DI 0 "s_register_operand" "=r,&r")
e5fea38e 3681 (ashift:DI (match_operand:DI 1 "s_register_operand" "0,r")
a2cd141b 3682 (const_int 1)))
3683 (clobber (reg:CC CC_REGNUM))]
25f905c2 3684 "TARGET_32BIT"
2837e3fb 3685 "movs\\t%Q0, %Q1, asl #1\;adc\\t%R0, %R1, %R1"
a2cd141b 3686 [(set_attr "conds" "clob")
1b7da4ac 3687 (set_attr "length" "8")
3688 (set_attr "type" "multiple")]
a2cd141b 3689)
3690
87b22bf7 3691(define_expand "ashlsi3"
cffb2a26 3692 [(set (match_operand:SI 0 "s_register_operand" "")
87b22bf7 3693 (ashift:SI (match_operand:SI 1 "s_register_operand" "")
3694 (match_operand:SI 2 "arm_rhs_operand" "")))]
cffb2a26 3695 "TARGET_EITHER"
87b22bf7 3696 "
0438d37f 3697 if (CONST_INT_P (operands[2])
87b22bf7 3698 && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) > 31)
3699 {
3700 emit_insn (gen_movsi (operands[0], const0_rtx));
3701 DONE;
3702 }
cffb2a26 3703 "
3704)
3705
a2cd141b 3706(define_expand "ashrdi3"
3707 [(set (match_operand:DI 0 "s_register_operand" "")
3708 (ashiftrt:DI (match_operand:DI 1 "s_register_operand" "")
3709 (match_operand:SI 2 "reg_or_int_operand" "")))]
25f905c2 3710 "TARGET_32BIT"
a2cd141b 3711 "
aa06c51c 3712 if (TARGET_NEON)
3713 {
3714 /* Delay the decision whether to use NEON or core-regs until
3715 register allocation. */
3716 emit_insn (gen_ashrdi3_neon (operands[0], operands[1], operands[2]));
3717 DONE;
3718 }
3719
b805622c 3720 if (!CONST_INT_P (operands[2]) && TARGET_REALLY_IWMMXT)
ffcc986d 3721 ; /* No special preparation statements; expand pattern as above. */
3722 else
a2cd141b 3723 {
ffcc986d 3724 rtx scratch1, scratch2;
3725
3726 if (CONST_INT_P (operands[2])
3727 && (HOST_WIDE_INT) INTVAL (operands[2]) == 1)
a2cd141b 3728 {
3729 emit_insn (gen_arm_ashrdi3_1bit (operands[0], operands[1]));
3730 DONE;
3731 }
ffcc986d 3732
3733 /* Ideally we should use iwmmxt here if we could know that operands[1]
3734 ends up already living in an iwmmxt register. Otherwise it's
3735 cheaper to have the alternate code being generated than moving
3736 values to iwmmxt regs and back. */
3737
3738 /* If we're optimizing for size, we prefer the libgcc calls. */
3739 if (optimize_function_for_size_p (cfun))
3740 FAIL;
3741
3742 /* Expand operation using core-registers.
3743 'FAIL' would achieve the same thing, but this is a bit smarter. */
3744 scratch1 = gen_reg_rtx (SImode);
3745 scratch2 = gen_reg_rtx (SImode);
3746 arm_emit_coreregs_64bit_shift (ASHIFTRT, operands[0], operands[1],
3747 operands[2], scratch1, scratch2);
3748 DONE;
a2cd141b 3749 }
a2cd141b 3750 "
3751)
3752
2837e3fb 3753(define_insn "arm_ashrdi3_1bit"
50ad1bf9 3754 [(set (match_operand:DI 0 "s_register_operand" "=r,&r")
e5fea38e 3755 (ashiftrt:DI (match_operand:DI 1 "s_register_operand" "0,r")
a2cd141b 3756 (const_int 1)))
3757 (clobber (reg:CC CC_REGNUM))]
25f905c2 3758 "TARGET_32BIT"
2837e3fb 3759 "movs\\t%R0, %R1, asr #1\;mov\\t%Q0, %Q1, rrx"
a2cd141b 3760 [(set_attr "conds" "clob")
1b7da4ac 3761 (set_attr "length" "8")
3762 (set_attr "type" "multiple")]
a2cd141b 3763)
3764
87b22bf7 3765(define_expand "ashrsi3"
cffb2a26 3766 [(set (match_operand:SI 0 "s_register_operand" "")
87b22bf7 3767 (ashiftrt:SI (match_operand:SI 1 "s_register_operand" "")
3768 (match_operand:SI 2 "arm_rhs_operand" "")))]
cffb2a26 3769 "TARGET_EITHER"
87b22bf7 3770 "
0438d37f 3771 if (CONST_INT_P (operands[2])
87b22bf7 3772 && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) > 31)
3773 operands[2] = GEN_INT (31);
cffb2a26 3774 "
3775)
3776
a2cd141b 3777(define_expand "lshrdi3"
3778 [(set (match_operand:DI 0 "s_register_operand" "")
3779 (lshiftrt:DI (match_operand:DI 1 "s_register_operand" "")
3780 (match_operand:SI 2 "reg_or_int_operand" "")))]
25f905c2 3781 "TARGET_32BIT"
a2cd141b 3782 "
aa06c51c 3783 if (TARGET_NEON)
3784 {
3785 /* Delay the decision whether to use NEON or core-regs until
3786 register allocation. */
3787 emit_insn (gen_lshrdi3_neon (operands[0], operands[1], operands[2]));
3788 DONE;
3789 }
3790
b805622c 3791 if (!CONST_INT_P (operands[2]) && TARGET_REALLY_IWMMXT)
ffcc986d 3792 ; /* No special preparation statements; expand pattern as above. */
3793 else
a2cd141b 3794 {
ffcc986d 3795 rtx scratch1, scratch2;
3796
3797 if (CONST_INT_P (operands[2])
3798 && (HOST_WIDE_INT) INTVAL (operands[2]) == 1)
a2cd141b 3799 {
3800 emit_insn (gen_arm_lshrdi3_1bit (operands[0], operands[1]));
3801 DONE;
3802 }
ffcc986d 3803
3804 /* Ideally we should use iwmmxt here if we could know that operands[1]
3805 ends up already living in an iwmmxt register. Otherwise it's
3806 cheaper to have the alternate code being generated than moving
3807 values to iwmmxt regs and back. */
3808
3809 /* If we're optimizing for size, we prefer the libgcc calls. */
3810 if (optimize_function_for_size_p (cfun))
3811 FAIL;
3812
3813 /* Expand operation using core-registers.
3814 'FAIL' would achieve the same thing, but this is a bit smarter. */
3815 scratch1 = gen_reg_rtx (SImode);
3816 scratch2 = gen_reg_rtx (SImode);
3817 arm_emit_coreregs_64bit_shift (LSHIFTRT, operands[0], operands[1],
3818 operands[2], scratch1, scratch2);
3819 DONE;
a2cd141b 3820 }
a2cd141b 3821 "
3822)
3823
2837e3fb 3824(define_insn "arm_lshrdi3_1bit"
50ad1bf9 3825 [(set (match_operand:DI 0 "s_register_operand" "=r,&r")
e5fea38e 3826 (lshiftrt:DI (match_operand:DI 1 "s_register_operand" "0,r")
a2cd141b 3827 (const_int 1)))
3828 (clobber (reg:CC CC_REGNUM))]
25f905c2 3829 "TARGET_32BIT"
2837e3fb 3830 "movs\\t%R0, %R1, lsr #1\;mov\\t%Q0, %Q1, rrx"
a2cd141b 3831 [(set_attr "conds" "clob")
1b7da4ac 3832 (set_attr "length" "8")
3833 (set_attr "type" "multiple")]
a2cd141b 3834)
3835
87b22bf7 3836(define_expand "lshrsi3"
cffb2a26 3837 [(set (match_operand:SI 0 "s_register_operand" "")
87b22bf7 3838 (lshiftrt:SI (match_operand:SI 1 "s_register_operand" "")
3839 (match_operand:SI 2 "arm_rhs_operand" "")))]
cffb2a26 3840 "TARGET_EITHER"
87b22bf7 3841 "
0438d37f 3842 if (CONST_INT_P (operands[2])
87b22bf7 3843 && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) > 31)
3844 {
3845 emit_insn (gen_movsi (operands[0], const0_rtx));
3846 DONE;
3847 }
cffb2a26 3848 "
3849)
3850
87b22bf7 3851(define_expand "rotlsi3"
cffb2a26 3852 [(set (match_operand:SI 0 "s_register_operand" "")
87b22bf7 3853 (rotatert:SI (match_operand:SI 1 "s_register_operand" "")
3854 (match_operand:SI 2 "reg_or_int_operand" "")))]
25f905c2 3855 "TARGET_32BIT"
87b22bf7 3856 "
0438d37f 3857 if (CONST_INT_P (operands[2]))
87b22bf7 3858 operands[2] = GEN_INT ((32 - INTVAL (operands[2])) % 32);
3859 else
b11cae9e 3860 {
87b22bf7 3861 rtx reg = gen_reg_rtx (SImode);
3862 emit_insn (gen_subsi3 (reg, GEN_INT (32), operands[2]));
3863 operands[2] = reg;
b11cae9e 3864 }
cffb2a26 3865 "
3866)
9c08d1fa 3867
87b22bf7 3868(define_expand "rotrsi3"
cffb2a26 3869 [(set (match_operand:SI 0 "s_register_operand" "")
87b22bf7 3870 (rotatert:SI (match_operand:SI 1 "s_register_operand" "")
3871 (match_operand:SI 2 "arm_rhs_operand" "")))]
cffb2a26 3872 "TARGET_EITHER"
87b22bf7 3873 "
25f905c2 3874 if (TARGET_32BIT)
cffb2a26 3875 {
0438d37f 3876 if (CONST_INT_P (operands[2])
cffb2a26 3877 && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) > 31)
3878 operands[2] = GEN_INT (INTVAL (operands[2]) % 32);
3879 }
25f905c2 3880 else /* TARGET_THUMB1 */
cffb2a26 3881 {
0438d37f 3882 if (CONST_INT_P (operands [2]))
cffb2a26 3883 operands [2] = force_reg (SImode, operands[2]);
3884 }
3885 "
3886)
87b22bf7 3887
cffb2a26 3888(define_insn "*arm_shiftsi3"
88c29385 3889 [(set (match_operand:SI 0 "s_register_operand" "=l,l,r,r")
cffb2a26 3890 (match_operator:SI 3 "shift_operator"
88c29385 3891 [(match_operand:SI 1 "s_register_operand" "0,l,r,r")
3892 (match_operand:SI 2 "reg_or_int_operand" "l,M,M,r")]))]
25f905c2 3893 "TARGET_32BIT"
3894 "* return arm_output_shift(operands, 0);"
344495ea 3895 [(set_attr "predicable" "yes")
88c29385 3896 (set_attr "arch" "t2,t2,*,*")
3897 (set_attr "predicable_short_it" "yes,yes,no,no")
7c36fe71 3898 (set_attr "length" "4")
331beb1a 3899 (set_attr "shift" "1")
88c29385 3900 (set_attr "type" "alu_shift_reg,alu_shift_imm,alu_shift_imm,alu_shift_reg")]
6c4c2133 3901)
87b22bf7 3902
f7fbdd4a 3903(define_insn "*shiftsi3_compare0"
bd5b4116 3904 [(set (reg:CC_NOOV CC_REGNUM)
87b22bf7 3905 (compare:CC_NOOV (match_operator:SI 3 "shift_operator"
6b6abc9c 3906 [(match_operand:SI 1 "s_register_operand" "r,r")
3907 (match_operand:SI 2 "arm_rhs_operand" "M,r")])
9c08d1fa 3908 (const_int 0)))
6b6abc9c 3909 (set (match_operand:SI 0 "s_register_operand" "=r,r")
87b22bf7 3910 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))]
25f905c2 3911 "TARGET_32BIT"
3912 "* return arm_output_shift(operands, 1);"
344495ea 3913 [(set_attr "conds" "set")
331beb1a 3914 (set_attr "shift" "1")
d82e788e 3915 (set_attr "type" "alus_shift_imm,alus_shift_reg")]
0d66636f 3916)
9c08d1fa 3917
f7fbdd4a 3918(define_insn "*shiftsi3_compare0_scratch"
bd5b4116 3919 [(set (reg:CC_NOOV CC_REGNUM)
87b22bf7 3920 (compare:CC_NOOV (match_operator:SI 3 "shift_operator"
6b6abc9c 3921 [(match_operand:SI 1 "s_register_operand" "r,r")
3922 (match_operand:SI 2 "arm_rhs_operand" "M,r")])
9c08d1fa 3923 (const_int 0)))
6b6abc9c 3924 (clobber (match_scratch:SI 0 "=r,r"))]
25f905c2 3925 "TARGET_32BIT"
3926 "* return arm_output_shift(operands, 1);"
344495ea 3927 [(set_attr "conds" "set")
6b6abc9c 3928 (set_attr "shift" "1")
d82e788e 3929 (set_attr "type" "shift_imm,shift_reg")]
0d66636f 3930)
9c08d1fa 3931
d5d4dc8d 3932(define_insn "*not_shiftsi"
3933 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
87b22bf7 3934 (not:SI (match_operator:SI 3 "shift_operator"
d5d4dc8d 3935 [(match_operand:SI 1 "s_register_operand" "r,r")
3936 (match_operand:SI 2 "shift_amount_operand" "M,rM")])))]
3937 "TARGET_32BIT"
6c4c2133 3938 "mvn%?\\t%0, %1%S3"
344495ea 3939 [(set_attr "predicable" "yes")
d952d547 3940 (set_attr "predicable_short_it" "no")
331beb1a 3941 (set_attr "shift" "1")
d5d4dc8d 3942 (set_attr "arch" "32,a")
1aed5204 3943 (set_attr "type" "mvn_shift,mvn_shift_reg")])
9c08d1fa 3944
d5d4dc8d 3945(define_insn "*not_shiftsi_compare0"
bd5b4116 3946 [(set (reg:CC_NOOV CC_REGNUM)
d5d4dc8d 3947 (compare:CC_NOOV
3948 (not:SI (match_operator:SI 3 "shift_operator"
3949 [(match_operand:SI 1 "s_register_operand" "r,r")
3950 (match_operand:SI 2 "shift_amount_operand" "M,rM")]))
3951 (const_int 0)))
3952 (set (match_operand:SI 0 "s_register_operand" "=r,r")
87b22bf7 3953 (not:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)])))]
d5d4dc8d 3954 "TARGET_32BIT"
25f905c2 3955 "mvn%.\\t%0, %1%S3"
344495ea 3956 [(set_attr "conds" "set")
331beb1a 3957 (set_attr "shift" "1")
d5d4dc8d 3958 (set_attr "arch" "32,a")
1aed5204 3959 (set_attr "type" "mvn_shift,mvn_shift_reg")])
9c08d1fa 3960
d5d4dc8d 3961(define_insn "*not_shiftsi_compare0_scratch"
bd5b4116 3962 [(set (reg:CC_NOOV CC_REGNUM)
d5d4dc8d 3963 (compare:CC_NOOV
3964 (not:SI (match_operator:SI 3 "shift_operator"
3965 [(match_operand:SI 1 "s_register_operand" "r,r")
3966 (match_operand:SI 2 "shift_amount_operand" "M,rM")]))
3967 (const_int 0)))
3968 (clobber (match_scratch:SI 0 "=r,r"))]
3969 "TARGET_32BIT"
25f905c2 3970 "mvn%.\\t%0, %1%S3"
344495ea 3971 [(set_attr "conds" "set")
331beb1a 3972 (set_attr "shift" "1")
d5d4dc8d 3973 (set_attr "arch" "32,a")
1aed5204 3974 (set_attr "type" "mvn_shift,mvn_shift_reg")])
9c08d1fa 3975
cffb2a26 3976;; We don't really have extzv, but defining this using shifts helps
3977;; to reduce register pressure later on.
3978
3979(define_expand "extzv"
eb04cafb 3980 [(set (match_operand 0 "s_register_operand" "")
3981 (zero_extract (match_operand 1 "nonimmediate_operand" "")
3982 (match_operand 2 "const_int_operand" "")
3983 (match_operand 3 "const_int_operand" "")))]
8b054d5a 3984 "TARGET_THUMB1 || arm_arch_thumb2"
cffb2a26 3985 "
3986 {
3987 HOST_WIDE_INT lshift = 32 - INTVAL (operands[2]) - INTVAL (operands[3]);
3988 HOST_WIDE_INT rshift = 32 - INTVAL (operands[2]);
3989
8b054d5a 3990 if (arm_arch_thumb2)
3991 {
eb04cafb 3992 HOST_WIDE_INT width = INTVAL (operands[2]);
3993 HOST_WIDE_INT bitpos = INTVAL (operands[3]);
3994
3995 if (unaligned_access && MEM_P (operands[1])
3996 && (width == 16 || width == 32) && (bitpos % BITS_PER_UNIT) == 0)
3997 {
3998 rtx base_addr;
3999
4000 if (BYTES_BIG_ENDIAN)
4001 bitpos = GET_MODE_BITSIZE (GET_MODE (operands[0])) - width
4002 - bitpos;
4003
4004 if (width == 32)
4005 {
4006 base_addr = adjust_address (operands[1], SImode,
4007 bitpos / BITS_PER_UNIT);
4008 emit_insn (gen_unaligned_loadsi (operands[0], base_addr));
4009 }
4010 else
4011 {
4012 rtx dest = operands[0];
4013 rtx tmp = gen_reg_rtx (SImode);
4014
4015 /* We may get a paradoxical subreg here. Strip it off. */
4016 if (GET_CODE (dest) == SUBREG
4017 && GET_MODE (dest) == SImode
4018 && GET_MODE (SUBREG_REG (dest)) == HImode)
4019 dest = SUBREG_REG (dest);
4020
4021 if (GET_MODE_BITSIZE (GET_MODE (dest)) != width)
4022 FAIL;
4023
4024 base_addr = adjust_address (operands[1], HImode,
4025 bitpos / BITS_PER_UNIT);
4026 emit_insn (gen_unaligned_loadhiu (tmp, base_addr));
4027 emit_move_insn (gen_lowpart (SImode, dest), tmp);
4028 }
4029 DONE;
4030 }
4031 else if (s_register_operand (operands[1], GET_MODE (operands[1])))
4032 {
4033 emit_insn (gen_extzv_t2 (operands[0], operands[1], operands[2],
4034 operands[3]));
4035 DONE;
4036 }
4037 else
4038 FAIL;
8b054d5a 4039 }
eb04cafb 4040
4041 if (!s_register_operand (operands[1], GET_MODE (operands[1])))
4042 FAIL;
8b054d5a 4043
cffb2a26 4044 operands[3] = GEN_INT (rshift);
4045
4046 if (lshift == 0)
4047 {
4048 emit_insn (gen_lshrsi3 (operands[0], operands[1], operands[3]));
4049 DONE;
4050 }
4051
eb04cafb 4052 emit_insn (gen_extzv_t1 (operands[0], operands[1], GEN_INT (lshift),
4053 operands[3], gen_reg_rtx (SImode)));
4054 DONE;
215b30b3 4055 }"
cffb2a26 4056)
4057
eb04cafb 4058;; Helper for extzv, for the Thumb-1 register-shifts case.
4059
4060(define_expand "extzv_t1"
4061 [(set (match_operand:SI 4 "s_register_operand" "")
4062 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
4063 (match_operand:SI 2 "const_int_operand" "")))
4064 (set (match_operand:SI 0 "s_register_operand" "")
4065 (lshiftrt:SI (match_dup 4)
4066 (match_operand:SI 3 "const_int_operand" "")))]
4067 "TARGET_THUMB1"
4068 "")
4069
4070(define_expand "extv"
4071 [(set (match_operand 0 "s_register_operand" "")
4072 (sign_extract (match_operand 1 "nonimmediate_operand" "")
4073 (match_operand 2 "const_int_operand" "")
4074 (match_operand 3 "const_int_operand" "")))]
4075 "arm_arch_thumb2"
4076{
4077 HOST_WIDE_INT width = INTVAL (operands[2]);
4078 HOST_WIDE_INT bitpos = INTVAL (operands[3]);
4079
4080 if (unaligned_access && MEM_P (operands[1]) && (width == 16 || width == 32)
4081 && (bitpos % BITS_PER_UNIT) == 0)
4082 {
4083 rtx base_addr;
4084
4085 if (BYTES_BIG_ENDIAN)
4086 bitpos = GET_MODE_BITSIZE (GET_MODE (operands[0])) - width - bitpos;
4087
4088 if (width == 32)
4089 {
4090 base_addr = adjust_address (operands[1], SImode,
4091 bitpos / BITS_PER_UNIT);
4092 emit_insn (gen_unaligned_loadsi (operands[0], base_addr));
4093 }
4094 else
4095 {
4096 rtx dest = operands[0];
4097 rtx tmp = gen_reg_rtx (SImode);
4098
4099 /* We may get a paradoxical subreg here. Strip it off. */
4100 if (GET_CODE (dest) == SUBREG
4101 && GET_MODE (dest) == SImode
4102 && GET_MODE (SUBREG_REG (dest)) == HImode)
4103 dest = SUBREG_REG (dest);
4104
4105 if (GET_MODE_BITSIZE (GET_MODE (dest)) != width)
4106 FAIL;
4107
4108 base_addr = adjust_address (operands[1], HImode,
4109 bitpos / BITS_PER_UNIT);
4110 emit_insn (gen_unaligned_loadhis (tmp, base_addr));
4111 emit_move_insn (gen_lowpart (SImode, dest), tmp);
4112 }
4113
4114 DONE;
4115 }
4116 else if (!s_register_operand (operands[1], GET_MODE (operands[1])))
4117 FAIL;
4118 else if (GET_MODE (operands[0]) == SImode
4119 && GET_MODE (operands[1]) == SImode)
4120 {
4121 emit_insn (gen_extv_regsi (operands[0], operands[1], operands[2],
4122 operands[3]));
4123 DONE;
4124 }
4125
4126 FAIL;
4127})
4128
4129; Helper to expand register forms of extv with the proper modes.
4130
4131(define_expand "extv_regsi"
4132 [(set (match_operand:SI 0 "s_register_operand" "")
4133 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "")
4134 (match_operand 2 "const_int_operand" "")
4135 (match_operand 3 "const_int_operand" "")))]
4136 ""
4137{
4138})
4139
4140; ARMv6+ unaligned load/store instructions (used for packed structure accesses).
4141
4142(define_insn "unaligned_loadsi"
4143 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
4144 (unspec:SI [(match_operand:SI 1 "memory_operand" "Uw,m")]
4145 UNSPEC_UNALIGNED_LOAD))]
4146 "unaligned_access && TARGET_32BIT"
4147 "ldr%?\t%0, %1\t@ unaligned"
4148 [(set_attr "arch" "t2,any")
4149 (set_attr "length" "2,4")
4150 (set_attr "predicable" "yes")
d952d547 4151 (set_attr "predicable_short_it" "yes,no")
eb04cafb 4152 (set_attr "type" "load1")])
4153
4154(define_insn "unaligned_loadhis"
4155 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
4156 (sign_extend:SI
e3f4ccee 4157 (unspec:HI [(match_operand:HI 1 "memory_operand" "Uw,Uh")]
eb04cafb 4158 UNSPEC_UNALIGNED_LOAD)))]
4159 "unaligned_access && TARGET_32BIT"
4160 "ldr%(sh%)\t%0, %1\t@ unaligned"
4161 [(set_attr "arch" "t2,any")
4162 (set_attr "length" "2,4")
4163 (set_attr "predicable" "yes")
d952d547 4164 (set_attr "predicable_short_it" "yes,no")
eb04cafb 4165 (set_attr "type" "load_byte")])
4166
4167(define_insn "unaligned_loadhiu"
4168 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
4169 (zero_extend:SI
4170 (unspec:HI [(match_operand:HI 1 "memory_operand" "Uw,m")]
4171 UNSPEC_UNALIGNED_LOAD)))]
4172 "unaligned_access && TARGET_32BIT"
4173 "ldr%(h%)\t%0, %1\t@ unaligned"
4174 [(set_attr "arch" "t2,any")
4175 (set_attr "length" "2,4")
4176 (set_attr "predicable" "yes")
d952d547 4177 (set_attr "predicable_short_it" "yes,no")
eb04cafb 4178 (set_attr "type" "load_byte")])
4179
4180(define_insn "unaligned_storesi"
4181 [(set (match_operand:SI 0 "memory_operand" "=Uw,m")
4182 (unspec:SI [(match_operand:SI 1 "s_register_operand" "l,r")]
4183 UNSPEC_UNALIGNED_STORE))]
4184 "unaligned_access && TARGET_32BIT"
4185 "str%?\t%1, %0\t@ unaligned"
4186 [(set_attr "arch" "t2,any")
4187 (set_attr "length" "2,4")
4188 (set_attr "predicable" "yes")
d952d547 4189 (set_attr "predicable_short_it" "yes,no")
eb04cafb 4190 (set_attr "type" "store1")])
4191
4192(define_insn "unaligned_storehi"
4193 [(set (match_operand:HI 0 "memory_operand" "=Uw,m")
4194 (unspec:HI [(match_operand:HI 1 "s_register_operand" "l,r")]
4195 UNSPEC_UNALIGNED_STORE))]
4196 "unaligned_access && TARGET_32BIT"
4197 "str%(h%)\t%1, %0\t@ unaligned"
4198 [(set_attr "arch" "t2,any")
4199 (set_attr "length" "2,4")
4200 (set_attr "predicable" "yes")
d952d547 4201 (set_attr "predicable_short_it" "yes,no")
eb04cafb 4202 (set_attr "type" "store1")])
4203
ae51a965 4204;; Unaligned double-word load and store.
4205;; Split after reload into two unaligned single-word accesses.
4206;; It prevents lower_subreg from splitting some other aligned
4207;; double-word accesses too early. Used for internal memcpy.
4208
4209(define_insn_and_split "unaligned_loaddi"
4210 [(set (match_operand:DI 0 "s_register_operand" "=l,r")
4211 (unspec:DI [(match_operand:DI 1 "memory_operand" "o,o")]
4212 UNSPEC_UNALIGNED_LOAD))]
4213 "unaligned_access && TARGET_32BIT"
4214 "#"
4215 "&& reload_completed"
4216 [(set (match_dup 0) (unspec:SI [(match_dup 1)] UNSPEC_UNALIGNED_LOAD))
4217 (set (match_dup 2) (unspec:SI [(match_dup 3)] UNSPEC_UNALIGNED_LOAD))]
4218 {
4219 operands[2] = gen_highpart (SImode, operands[0]);
4220 operands[0] = gen_lowpart (SImode, operands[0]);
4221 operands[3] = gen_highpart (SImode, operands[1]);
4222 operands[1] = gen_lowpart (SImode, operands[1]);
4223
4224 /* If the first destination register overlaps with the base address,
4225 swap the order in which the loads are emitted. */
4226 if (reg_overlap_mentioned_p (operands[0], operands[1]))
4227 {
f145bcba 4228 std::swap (operands[1], operands[3]);
4229 std::swap (operands[0], operands[2]);
ae51a965 4230 }
4231 }
4232 [(set_attr "arch" "t2,any")
4233 (set_attr "length" "4,8")
4234 (set_attr "predicable" "yes")
4235 (set_attr "type" "load2")])
4236
4237(define_insn_and_split "unaligned_storedi"
4238 [(set (match_operand:DI 0 "memory_operand" "=o,o")
4239 (unspec:DI [(match_operand:DI 1 "s_register_operand" "l,r")]
4240 UNSPEC_UNALIGNED_STORE))]
4241 "unaligned_access && TARGET_32BIT"
4242 "#"
4243 "&& reload_completed"
4244 [(set (match_dup 0) (unspec:SI [(match_dup 1)] UNSPEC_UNALIGNED_STORE))
4245 (set (match_dup 2) (unspec:SI [(match_dup 3)] UNSPEC_UNALIGNED_STORE))]
4246 {
4247 operands[2] = gen_highpart (SImode, operands[0]);
4248 operands[0] = gen_lowpart (SImode, operands[0]);
4249 operands[3] = gen_highpart (SImode, operands[1]);
4250 operands[1] = gen_lowpart (SImode, operands[1]);
4251 }
4252 [(set_attr "arch" "t2,any")
4253 (set_attr "length" "4,8")
4254 (set_attr "predicable" "yes")
4255 (set_attr "type" "store2")])
4256
4257
eb04cafb 4258(define_insn "*extv_reg"
8b054d5a 4259 [(set (match_operand:SI 0 "s_register_operand" "=r")
4260 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
809003b3 4261 (match_operand:SI 2 "const_int_M_operand" "M")
4262 (match_operand:SI 3 "const_int_M_operand" "M")))]
8b054d5a 4263 "arm_arch_thumb2"
4264 "sbfx%?\t%0, %1, %3, %2"
4265 [(set_attr "length" "4")
d952d547 4266 (set_attr "predicable" "yes")
d82e788e 4267 (set_attr "predicable_short_it" "no")
4268 (set_attr "type" "bfm")]
8b054d5a 4269)
4270
4271(define_insn "extzv_t2"
4272 [(set (match_operand:SI 0 "s_register_operand" "=r")
4273 (zero_extract:SI (match_operand:SI 1 "s_register_operand" "r")
809003b3 4274 (match_operand:SI 2 "const_int_M_operand" "M")
4275 (match_operand:SI 3 "const_int_M_operand" "M")))]
8b054d5a 4276 "arm_arch_thumb2"
4277 "ubfx%?\t%0, %1, %3, %2"
4278 [(set_attr "length" "4")
d952d547 4279 (set_attr "predicable" "yes")
d82e788e 4280 (set_attr "predicable_short_it" "no")
4281 (set_attr "type" "bfm")]
8b054d5a 4282)
4283
7d3cda8c 4284
4285;; Division instructions
4286(define_insn "divsi3"
4287 [(set (match_operand:SI 0 "s_register_operand" "=r")
4288 (div:SI (match_operand:SI 1 "s_register_operand" "r")
4289 (match_operand:SI 2 "s_register_operand" "r")))]
4290 "TARGET_IDIV"
4291 "sdiv%?\t%0, %1, %2"
4292 [(set_attr "predicable" "yes")
d952d547 4293 (set_attr "predicable_short_it" "no")
9da0ec36 4294 (set_attr "type" "sdiv")]
7d3cda8c 4295)
4296
4297(define_insn "udivsi3"
4298 [(set (match_operand:SI 0 "s_register_operand" "=r")
4299 (udiv:SI (match_operand:SI 1 "s_register_operand" "r")
4300 (match_operand:SI 2 "s_register_operand" "r")))]
4301 "TARGET_IDIV"
4302 "udiv%?\t%0, %1, %2"
4303 [(set_attr "predicable" "yes")
d952d547 4304 (set_attr "predicable_short_it" "no")
9da0ec36 4305 (set_attr "type" "udiv")]
7d3cda8c 4306)
4307
b11cae9e 4308\f
4309;; Unary arithmetic insns
4310
cffb2a26 4311(define_expand "negdi2"
4312 [(parallel
8135a42b 4313 [(set (match_operand:DI 0 "s_register_operand" "")
4314 (neg:DI (match_operand:DI 1 "s_register_operand" "")))
bd5b4116 4315 (clobber (reg:CC CC_REGNUM))])]
cffb2a26 4316 "TARGET_EITHER"
774d2fbb 4317 {
4318 if (TARGET_NEON)
4319 {
4320 emit_insn (gen_negdi2_neon (operands[0], operands[1]));
4321 DONE;
4322 }
4323 }
cffb2a26 4324)
4325
4326;; The constraints here are to prevent a *partial* overlap (where %Q0 == %R1).
e5fea38e 4327;; The first alternative allows the common case of a *full* overlap.
ba6a3b2f 4328(define_insn_and_split "*arm_negdi2"
458a8706 4329 [(set (match_operand:DI 0 "s_register_operand" "=r,&r")
e5fea38e 4330 (neg:DI (match_operand:DI 1 "s_register_operand" "0,r")))
bd5b4116 4331 (clobber (reg:CC CC_REGNUM))]
cffb2a26 4332 "TARGET_ARM"
ba6a3b2f 4333 "#" ; "rsbs\\t%Q0, %Q1, #0\;rsc\\t%R0, %R1, #0"
4334 "&& reload_completed"
4335 [(parallel [(set (reg:CC CC_REGNUM)
4336 (compare:CC (const_int 0) (match_dup 1)))
4337 (set (match_dup 0) (minus:SI (const_int 0) (match_dup 1)))])
4338 (set (match_dup 2) (minus:SI (minus:SI (const_int 0) (match_dup 3))
4339 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
4340 {
4341 operands[2] = gen_highpart (SImode, operands[0]);
4342 operands[0] = gen_lowpart (SImode, operands[0]);
4343 operands[3] = gen_highpart (SImode, operands[1]);
4344 operands[1] = gen_lowpart (SImode, operands[1]);
4345 }
cffb2a26 4346 [(set_attr "conds" "clob")
1b7da4ac 4347 (set_attr "length" "8")
4348 (set_attr "type" "multiple")]
cffb2a26 4349)
b11cae9e 4350
cffb2a26 4351(define_expand "negsi2"
4352 [(set (match_operand:SI 0 "s_register_operand" "")
4353 (neg:SI (match_operand:SI 1 "s_register_operand" "")))]
4354 "TARGET_EITHER"
b11cae9e 4355 ""
cffb2a26 4356)
4357
4358(define_insn "*arm_negsi2"
d952d547 4359 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
4360 (neg:SI (match_operand:SI 1 "s_register_operand" "l,r")))]
25f905c2 4361 "TARGET_32BIT"
cffb2a26 4362 "rsb%?\\t%0, %1, #0"
d952d547 4363 [(set_attr "predicable" "yes")
4364 (set_attr "predicable_short_it" "yes,no")
4365 (set_attr "arch" "t2,*")
1b7da4ac 4366 (set_attr "length" "4")
112eda6f 4367 (set_attr "type" "alu_sreg")]
cffb2a26 4368)
4369
604f3a0a 4370(define_expand "negsf2"
4371 [(set (match_operand:SF 0 "s_register_operand" "")
4372 (neg:SF (match_operand:SF 1 "s_register_operand" "")))]
994606f8 4373 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
604f3a0a 4374 ""
4375)
4376
4377(define_expand "negdf2"
4378 [(set (match_operand:DF 0 "s_register_operand" "")
4379 (neg:DF (match_operand:DF 1 "s_register_operand" "")))]
994606f8 4380 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
604f3a0a 4381 "")
4382
7eaf2be0 4383(define_insn_and_split "*zextendsidi_negsi"
4384 [(set (match_operand:DI 0 "s_register_operand" "=r")
4385 (zero_extend:DI (neg:SI (match_operand:SI 1 "s_register_operand" "r"))))]
4386 "TARGET_32BIT"
4387 "#"
4388 ""
4389 [(set (match_dup 2)
4390 (neg:SI (match_dup 1)))
4391 (set (match_dup 3)
4392 (const_int 0))]
4393 {
4394 operands[2] = gen_lowpart (SImode, operands[0]);
4395 operands[3] = gen_highpart (SImode, operands[0]);
4396 }
4397 [(set_attr "length" "8")
4398 (set_attr "type" "multiple")]
4399)
4400
83e2b922 4401;; Negate an extended 32-bit value.
4402(define_insn_and_split "*negdi_extendsidi"
61fa8ff2 4403 [(set (match_operand:DI 0 "s_register_operand" "=l,r")
4404 (neg:DI (sign_extend:DI
4405 (match_operand:SI 1 "s_register_operand" "l,r"))))
83e2b922 4406 (clobber (reg:CC CC_REGNUM))]
4407 "TARGET_32BIT"
61fa8ff2 4408 "#"
83e2b922 4409 "&& reload_completed"
4410 [(const_int 0)]
4411 {
61fa8ff2 4412 rtx low = gen_lowpart (SImode, operands[0]);
4413 rtx high = gen_highpart (SImode, operands[0]);
4414
4415 if (reg_overlap_mentioned_p (low, operands[1]))
4416 {
4417 /* Input overlaps the low word of the output. Use:
4418 asr Rhi, Rin, #31
4419 rsbs Rlo, Rin, #0
4420 rsc Rhi, Rhi, #0 (thumb2: sbc Rhi, Rhi, Rhi, lsl #1). */
4421 rtx cc_reg = gen_rtx_REG (CC_Cmode, CC_REGNUM);
4422
4423 emit_insn (gen_rtx_SET (VOIDmode, high,
4424 gen_rtx_ASHIFTRT (SImode, operands[1],
4425 GEN_INT (31))));
4426
4427 emit_insn (gen_subsi3_compare (low, const0_rtx, operands[1]));
4428 if (TARGET_ARM)
4429 emit_insn (gen_rtx_SET (VOIDmode, high,
4430 gen_rtx_MINUS (SImode,
4431 gen_rtx_MINUS (SImode,
4432 const0_rtx,
4433 high),
4434 gen_rtx_LTU (SImode,
4435 cc_reg,
4436 const0_rtx))));
4437 else
4438 {
4439 rtx two_x = gen_rtx_ASHIFT (SImode, high, GEN_INT (1));
4440 emit_insn (gen_rtx_SET (VOIDmode, high,
4441 gen_rtx_MINUS (SImode,
4442 gen_rtx_MINUS (SImode,
4443 high,
4444 two_x),
4445 gen_rtx_LTU (SImode,
4446 cc_reg,
4447 const0_rtx))));
4448 }
4449 }
4450 else
4451 {
4452 /* No overlap, or overlap on high word. Use:
4453 rsb Rlo, Rin, #0
4454 bic Rhi, Rlo, Rin
4455 asr Rhi, Rhi, #31
4456 Flags not needed for this sequence. */
4457 emit_insn (gen_rtx_SET (VOIDmode, low,
4458 gen_rtx_NEG (SImode, operands[1])));
4459 emit_insn (gen_rtx_SET (VOIDmode, high,
4460 gen_rtx_AND (SImode,
4461 gen_rtx_NOT (SImode, operands[1]),
4462 low)));
4463 emit_insn (gen_rtx_SET (VOIDmode, high,
4464 gen_rtx_ASHIFTRT (SImode, high,
4465 GEN_INT (31))));
4466 }
4467 DONE;
83e2b922 4468 }
61fa8ff2 4469 [(set_attr "length" "12")
4470 (set_attr "arch" "t2,*")
1b7da4ac 4471 (set_attr "type" "multiple")]
83e2b922 4472)
4473
4474(define_insn_and_split "*negdi_zero_extendsidi"
4475 [(set (match_operand:DI 0 "s_register_operand" "=r,&r")
4476 (neg:DI (zero_extend:DI (match_operand:SI 1 "s_register_operand" "0,r"))))
4477 (clobber (reg:CC CC_REGNUM))]
4478 "TARGET_32BIT"
4479 "#" ; "rsbs\\t%Q0, %1, #0\;sbc\\t%R0,%R0,%R0"
4480 ;; Don't care what register is input to sbc,
4481 ;; since we just just need to propagate the carry.
4482 "&& reload_completed"
4483 [(parallel [(set (reg:CC CC_REGNUM)
4484 (compare:CC (const_int 0) (match_dup 1)))
4485 (set (match_dup 0) (minus:SI (const_int 0) (match_dup 1)))])
4486 (set (match_dup 2) (minus:SI (minus:SI (match_dup 2) (match_dup 2))
4487 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
4488 {
4489 operands[2] = gen_highpart (SImode, operands[0]);
4490 operands[0] = gen_lowpart (SImode, operands[0]);
4491 }
4492 [(set_attr "conds" "clob")
1b7da4ac 4493 (set_attr "length" "8")
4494 (set_attr "type" "multiple")] ;; length in thumb is 4
83e2b922 4495)
4496
9c08d1fa 4497;; abssi2 doesn't really clobber the condition codes if a different register
4498;; is being set. To keep things simple, assume during rtl manipulations that
4499;; it does, but tell the final scan operator the truth. Similarly for
4500;; (neg (abs...))
4501
604f3a0a 4502(define_expand "abssi2"
4503 [(parallel
4504 [(set (match_operand:SI 0 "s_register_operand" "")
4505 (abs:SI (match_operand:SI 1 "s_register_operand" "")))
ba156559 4506 (clobber (match_dup 2))])]
4507 "TARGET_EITHER"
4508 "
25f905c2 4509 if (TARGET_THUMB1)
ba156559 4510 operands[2] = gen_rtx_SCRATCH (SImode);
4511 else
4512 operands[2] = gen_rtx_REG (CCmode, CC_REGNUM);
4513")
604f3a0a 4514
ba6a3b2f 4515(define_insn_and_split "*arm_abssi2"
ba156559 4516 [(set (match_operand:SI 0 "s_register_operand" "=r,&r")
9c08d1fa 4517 (abs:SI (match_operand:SI 1 "s_register_operand" "0,r")))
bd5b4116 4518 (clobber (reg:CC CC_REGNUM))]
cffb2a26 4519 "TARGET_ARM"
ba6a3b2f 4520 "#"
4521 "&& reload_completed"
4522 [(const_int 0)]
4523 {
4524 /* if (which_alternative == 0) */
4525 if (REGNO(operands[0]) == REGNO(operands[1]))
4526 {
4527 /* Emit the pattern:
4528 cmp\\t%0, #0\;rsblt\\t%0, %0, #0
4529 [(set (reg:CC CC_REGNUM)
4530 (compare:CC (match_dup 0) (const_int 0)))
4531 (cond_exec (lt:CC (reg:CC CC_REGNUM) (const_int 0))
4532 (set (match_dup 0) (minus:SI (const_int 0) (match_dup 1))))]
4533 */
4534 emit_insn (gen_rtx_SET (VOIDmode,
4535 gen_rtx_REG (CCmode, CC_REGNUM),
4536 gen_rtx_COMPARE (CCmode, operands[0], const0_rtx)));
4537 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
4538 (gen_rtx_LT (SImode,
4539 gen_rtx_REG (CCmode, CC_REGNUM),
4540 const0_rtx)),
4541 (gen_rtx_SET (VOIDmode,
4542 operands[0],
4543 (gen_rtx_MINUS (SImode,
4544 const0_rtx,
4545 operands[1]))))));
4546 DONE;
4547 }
4548 else
4549 {
4550 /* Emit the pattern:
4551 alt1: eor%?\\t%0, %1, %1, asr #31\;sub%?\\t%0, %0, %1, asr #31
4552 [(set (match_dup 0)
4553 (xor:SI (match_dup 1)
4554 (ashiftrt:SI (match_dup 1) (const_int 31))))
4555 (set (match_dup 0)
4556 (minus:SI (match_dup 0)
4557 (ashiftrt:SI (match_dup 1) (const_int 31))))]
4558 */
4559 emit_insn (gen_rtx_SET (VOIDmode,
4560 operands[0],
4561 gen_rtx_XOR (SImode,
4562 gen_rtx_ASHIFTRT (SImode,
4563 operands[1],
4564 GEN_INT (31)),
4565 operands[1])));
4566 emit_insn (gen_rtx_SET (VOIDmode,
4567 operands[0],
4568 gen_rtx_MINUS (SImode,
4569 operands[0],
4570 gen_rtx_ASHIFTRT (SImode,
4571 operands[1],
4572 GEN_INT (31)))));
4573 DONE;
4574 }
4575 }
cffb2a26 4576 [(set_attr "conds" "clob,*")
331beb1a 4577 (set_attr "shift" "1")
2ad08b65 4578 (set_attr "predicable" "no, yes")
1b7da4ac 4579 (set_attr "length" "8")
4580 (set_attr "type" "multiple")]
cffb2a26 4581)
9c08d1fa 4582
ba6a3b2f 4583(define_insn_and_split "*arm_neg_abssi2"
9c08d1fa 4584 [(set (match_operand:SI 0 "s_register_operand" "=r,&r")
4585 (neg:SI (abs:SI (match_operand:SI 1 "s_register_operand" "0,r"))))
bd5b4116 4586 (clobber (reg:CC CC_REGNUM))]
cffb2a26 4587 "TARGET_ARM"
ba6a3b2f 4588 "#"
4589 "&& reload_completed"
4590 [(const_int 0)]
4591 {
4592 /* if (which_alternative == 0) */
4593 if (REGNO (operands[0]) == REGNO (operands[1]))
4594 {
4595 /* Emit the pattern:
4596 cmp\\t%0, #0\;rsbgt\\t%0, %0, #0
4597 */
4598 emit_insn (gen_rtx_SET (VOIDmode,
4599 gen_rtx_REG (CCmode, CC_REGNUM),
4600 gen_rtx_COMPARE (CCmode, operands[0], const0_rtx)));
4601 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
4602 gen_rtx_GT (SImode,
4603 gen_rtx_REG (CCmode, CC_REGNUM),
4604 const0_rtx),
4605 gen_rtx_SET (VOIDmode,
4606 operands[0],
4607 (gen_rtx_MINUS (SImode,
4608 const0_rtx,
4609 operands[1])))));
4610 }
4611 else
4612 {
4613 /* Emit the pattern:
4614 eor%?\\t%0, %1, %1, asr #31\;rsb%?\\t%0, %0, %1, asr #31
4615 */
4616 emit_insn (gen_rtx_SET (VOIDmode,
4617 operands[0],
4618 gen_rtx_XOR (SImode,
4619 gen_rtx_ASHIFTRT (SImode,
4620 operands[1],
4621 GEN_INT (31)),
4622 operands[1])));
4623 emit_insn (gen_rtx_SET (VOIDmode,
4624 operands[0],
4625 gen_rtx_MINUS (SImode,
4626 gen_rtx_ASHIFTRT (SImode,
4627 operands[1],
4628 GEN_INT (31)),
4629 operands[0])));
4630 }
4631 DONE;
4632 }
cffb2a26 4633 [(set_attr "conds" "clob,*")
331beb1a 4634 (set_attr "shift" "1")
2ad08b65 4635 (set_attr "predicable" "no, yes")
1b7da4ac 4636 (set_attr "length" "8")
4637 (set_attr "type" "multiple")]
cffb2a26 4638)
b11cae9e 4639
604f3a0a 4640(define_expand "abssf2"
4641 [(set (match_operand:SF 0 "s_register_operand" "")
4642 (abs:SF (match_operand:SF 1 "s_register_operand" "")))]
25f905c2 4643 "TARGET_32BIT && TARGET_HARD_FLOAT"
604f3a0a 4644 "")
4645
604f3a0a 4646(define_expand "absdf2"
4647 [(set (match_operand:DF 0 "s_register_operand" "")
4648 (abs:DF (match_operand:DF 1 "s_register_operand" "")))]
a50d7267 4649 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
604f3a0a 4650 "")
4651
7db9af5d 4652(define_expand "sqrtsf2"
4653 [(set (match_operand:SF 0 "s_register_operand" "")
4654 (sqrt:SF (match_operand:SF 1 "s_register_operand" "")))]
994606f8 4655 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
7db9af5d 4656 "")
9c08d1fa 4657
7db9af5d 4658(define_expand "sqrtdf2"
4659 [(set (match_operand:DF 0 "s_register_operand" "")
4660 (sqrt:DF (match_operand:DF 1 "s_register_operand" "")))]
994606f8 4661 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
7db9af5d 4662 "")
9c08d1fa 4663
a0f94409 4664(define_insn_and_split "one_cmpldi2"
10efb95f 4665 [(set (match_operand:DI 0 "s_register_operand" "=w,&r,&r,?w")
4666 (not:DI (match_operand:DI 1 "s_register_operand" " w, 0, r, w")))]
25f905c2 4667 "TARGET_32BIT"
10efb95f 4668 "@
4669 vmvn\t%P0, %P1
4670 #
4671 #
4672 vmvn\t%P0, %P1"
4673 "TARGET_32BIT && reload_completed
4674 && arm_general_register_operand (operands[0], DImode)"
a0f94409 4675 [(set (match_dup 0) (not:SI (match_dup 1)))
4676 (set (match_dup 2) (not:SI (match_dup 3)))]
4677 "
4678 {
4679 operands[2] = gen_highpart (SImode, operands[0]);
4680 operands[0] = gen_lowpart (SImode, operands[0]);
4681 operands[3] = gen_highpart (SImode, operands[1]);
4682 operands[1] = gen_lowpart (SImode, operands[1]);
4683 }"
10efb95f 4684 [(set_attr "length" "*,8,8,*")
4685 (set_attr "predicable" "no,yes,yes,no")
32093010 4686 (set_attr "type" "neon_move,multiple,multiple,neon_move")
b6779ddc 4687 (set_attr "arch" "neon_for_64bits,*,*,avoid_neon_for_64bits")]
cffb2a26 4688)
b11cae9e 4689
cffb2a26 4690(define_expand "one_cmplsi2"
4691 [(set (match_operand:SI 0 "s_register_operand" "")
4692 (not:SI (match_operand:SI 1 "s_register_operand" "")))]
4693 "TARGET_EITHER"
b11cae9e 4694 ""
cffb2a26 4695)
4696
4697(define_insn "*arm_one_cmplsi2"
d952d547 4698 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
4699 (not:SI (match_operand:SI 1 "s_register_operand" "l,r")))]
25f905c2 4700 "TARGET_32BIT"
cffb2a26 4701 "mvn%?\\t%0, %1"
d2a518d1 4702 [(set_attr "predicable" "yes")
d952d547 4703 (set_attr "predicable_short_it" "yes,no")
4704 (set_attr "arch" "t2,*")
4705 (set_attr "length" "4")
1aed5204 4706 (set_attr "type" "mvn_reg")]
cffb2a26 4707)
4708
f7fbdd4a 4709(define_insn "*notsi_compare0"
bd5b4116 4710 [(set (reg:CC_NOOV CC_REGNUM)
9c08d1fa 4711 (compare:CC_NOOV (not:SI (match_operand:SI 1 "s_register_operand" "r"))
4712 (const_int 0)))
4713 (set (match_operand:SI 0 "s_register_operand" "=r")
4714 (not:SI (match_dup 1)))]
25f905c2 4715 "TARGET_32BIT"
4716 "mvn%.\\t%0, %1"
d2a518d1 4717 [(set_attr "conds" "set")
1aed5204 4718 (set_attr "type" "mvn_reg")]
cffb2a26 4719)
9c08d1fa 4720
f7fbdd4a 4721(define_insn "*notsi_compare0_scratch"
bd5b4116 4722 [(set (reg:CC_NOOV CC_REGNUM)
9c08d1fa 4723 (compare:CC_NOOV (not:SI (match_operand:SI 1 "s_register_operand" "r"))
4724 (const_int 0)))
4725 (clobber (match_scratch:SI 0 "=r"))]
25f905c2 4726 "TARGET_32BIT"
4727 "mvn%.\\t%0, %1"
d2a518d1 4728 [(set_attr "conds" "set")
1aed5204 4729 (set_attr "type" "mvn_reg")]
cffb2a26 4730)
b11cae9e 4731\f
4732;; Fixed <--> Floating conversion insns
4733
9b8516be 4734(define_expand "floatsihf2"
4735 [(set (match_operand:HF 0 "general_operand" "")
4736 (float:HF (match_operand:SI 1 "general_operand" "")))]
4737 "TARGET_EITHER"
4738 "
4739 {
4740 rtx op1 = gen_reg_rtx (SFmode);
4741 expand_float (op1, operands[1], 0);
4742 op1 = convert_to_mode (HFmode, op1, 0);
4743 emit_move_insn (operands[0], op1);
4744 DONE;
4745 }"
4746)
4747
4748(define_expand "floatdihf2"
4749 [(set (match_operand:HF 0 "general_operand" "")
4750 (float:HF (match_operand:DI 1 "general_operand" "")))]
4751 "TARGET_EITHER"
4752 "
4753 {
4754 rtx op1 = gen_reg_rtx (SFmode);
4755 expand_float (op1, operands[1], 0);
4756 op1 = convert_to_mode (HFmode, op1, 0);
4757 emit_move_insn (operands[0], op1);
4758 DONE;
4759 }"
4760)
4761
604f3a0a 4762(define_expand "floatsisf2"
4763 [(set (match_operand:SF 0 "s_register_operand" "")
4764 (float:SF (match_operand:SI 1 "s_register_operand" "")))]
25f905c2 4765 "TARGET_32BIT && TARGET_HARD_FLOAT"
604f3a0a 4766 "
604f3a0a 4767")
4768
604f3a0a 4769(define_expand "floatsidf2"
4770 [(set (match_operand:DF 0 "s_register_operand" "")
4771 (float:DF (match_operand:SI 1 "s_register_operand" "")))]
a50d7267 4772 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
604f3a0a 4773 "
604f3a0a 4774")
4775
9b8516be 4776(define_expand "fix_trunchfsi2"
4777 [(set (match_operand:SI 0 "general_operand" "")
4778 (fix:SI (fix:HF (match_operand:HF 1 "general_operand" ""))))]
4779 "TARGET_EITHER"
4780 "
4781 {
4782 rtx op1 = convert_to_mode (SFmode, operands[1], 0);
4783 expand_fix (operands[0], op1, 0);
4784 DONE;
4785 }"
4786)
4787
4788(define_expand "fix_trunchfdi2"
4789 [(set (match_operand:DI 0 "general_operand" "")
4790 (fix:DI (fix:HF (match_operand:HF 1 "general_operand" ""))))]
4791 "TARGET_EITHER"
4792 "
4793 {
4794 rtx op1 = convert_to_mode (SFmode, operands[1], 0);
4795 expand_fix (operands[0], op1, 0);
4796 DONE;
4797 }"
4798)
4799
604f3a0a 4800(define_expand "fix_truncsfsi2"
4801 [(set (match_operand:SI 0 "s_register_operand" "")
a33d5c9c 4802 (fix:SI (fix:SF (match_operand:SF 1 "s_register_operand" ""))))]
25f905c2 4803 "TARGET_32BIT && TARGET_HARD_FLOAT"
604f3a0a 4804 "
604f3a0a 4805")
4806
604f3a0a 4807(define_expand "fix_truncdfsi2"
4808 [(set (match_operand:SI 0 "s_register_operand" "")
a33d5c9c 4809 (fix:SI (fix:DF (match_operand:DF 1 "s_register_operand" ""))))]
a50d7267 4810 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
604f3a0a 4811 "
604f3a0a 4812")
4813
f544c6d2 4814;; Truncation insns
b11cae9e 4815
604f3a0a 4816(define_expand "truncdfsf2"
4817 [(set (match_operand:SF 0 "s_register_operand" "")
4818 (float_truncate:SF
4819 (match_operand:DF 1 "s_register_operand" "")))]
a50d7267 4820 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
604f3a0a 4821 ""
4822)
9b8516be 4823
4824/* DFmode -> HFmode conversions have to go through SFmode. */
4825(define_expand "truncdfhf2"
4826 [(set (match_operand:HF 0 "general_operand" "")
4827 (float_truncate:HF
4828 (match_operand:DF 1 "general_operand" "")))]
4829 "TARGET_EITHER"
4830 "
4831 {
4832 rtx op1;
4833 op1 = convert_to_mode (SFmode, operands[1], 0);
4834 op1 = convert_to_mode (HFmode, op1, 0);
4835 emit_move_insn (operands[0], op1);
4836 DONE;
4837 }"
4838)
b11cae9e 4839\f
9c08d1fa 4840;; Zero and sign extension instructions.
b11cae9e 4841
848e66ac 4842(define_insn "zero_extend<mode>di2"
6aa689e8 4843 [(set (match_operand:DI 0 "s_register_operand" "=w,r,?r,w")
6d97728e 4844 (zero_extend:DI (match_operand:QHSI 1 "<qhs_zextenddi_op>"
4845 "<qhs_zextenddi_cstr>")))]
848e66ac 4846 "TARGET_32BIT <qhs_zextenddi_cond>"
4847 "#"
6aa689e8 4848 [(set_attr "length" "8,4,8,8")
b6779ddc 4849 (set_attr "arch" "neon_for_64bits,*,*,avoid_neon_for_64bits")
848e66ac 4850 (set_attr "ce_count" "2")
efbb5e19 4851 (set_attr "predicable" "yes")
4852 (set_attr "type" "multiple,mov_reg,multiple,multiple")]
25f905c2 4853)
4854
848e66ac 4855(define_insn "extend<mode>di2"
6aa689e8 4856 [(set (match_operand:DI 0 "s_register_operand" "=w,r,?r,?r,w")
63d204a8 4857 (sign_extend:DI (match_operand:QHSI 1 "<qhs_extenddi_op>"
4858 "<qhs_extenddi_cstr>")))]
848e66ac 4859 "TARGET_32BIT <qhs_sextenddi_cond>"
4860 "#"
6aa689e8 4861 [(set_attr "length" "8,4,8,8,8")
848e66ac 4862 (set_attr "ce_count" "2")
4863 (set_attr "shift" "1")
8012d2c2 4864 (set_attr "predicable" "yes")
1b7da4ac 4865 (set_attr "arch" "neon_for_64bits,*,a,t,avoid_neon_for_64bits")
4866 (set_attr "type" "multiple,mov_reg,multiple,multiple,multiple")]
0d66636f 4867)
9c08d1fa 4868
848e66ac 4869;; Splits for all extensions to DImode
4870(define_split
4871 [(set (match_operand:DI 0 "s_register_operand" "")
4872 (zero_extend:DI (match_operand 1 "nonimmediate_operand" "")))]
6aa689e8 4873 "TARGET_32BIT && reload_completed && !IS_VFP_REGNUM (REGNO (operands[0]))"
848e66ac 4874 [(set (match_dup 0) (match_dup 1))]
4875{
848e66ac 4876 rtx lo_part = gen_lowpart (SImode, operands[0]);
3754d046 4877 machine_mode src_mode = GET_MODE (operands[1]);
848e66ac 4878
4879 if (REG_P (operands[0])
4880 && !reg_overlap_mentioned_p (operands[0], operands[1]))
4881 emit_clobber (operands[0]);
4882 if (!REG_P (lo_part) || src_mode != SImode
4883 || !rtx_equal_p (lo_part, operands[1]))
4884 {
4885 if (src_mode == SImode)
4886 emit_move_insn (lo_part, operands[1]);
4887 else
4888 emit_insn (gen_rtx_SET (VOIDmode, lo_part,
4889 gen_rtx_ZERO_EXTEND (SImode, operands[1])));
4890 operands[1] = lo_part;
4891 }
4892 operands[0] = gen_highpart (SImode, operands[0]);
4893 operands[1] = const0_rtx;
4894})
9c08d1fa 4895
848e66ac 4896(define_split
25f905c2 4897 [(set (match_operand:DI 0 "s_register_operand" "")
848e66ac 4898 (sign_extend:DI (match_operand 1 "nonimmediate_operand" "")))]
6aa689e8 4899 "TARGET_32BIT && reload_completed && !IS_VFP_REGNUM (REGNO (operands[0]))"
848e66ac 4900 [(set (match_dup 0) (ashiftrt:SI (match_dup 1) (const_int 31)))]
4901{
4902 rtx lo_part = gen_lowpart (SImode, operands[0]);
3754d046 4903 machine_mode src_mode = GET_MODE (operands[1]);
25f905c2 4904
848e66ac 4905 if (REG_P (operands[0])
4906 && !reg_overlap_mentioned_p (operands[0], operands[1]))
4907 emit_clobber (operands[0]);
4908
4909 if (!REG_P (lo_part) || src_mode != SImode
4910 || !rtx_equal_p (lo_part, operands[1]))
4911 {
4912 if (src_mode == SImode)
4913 emit_move_insn (lo_part, operands[1]);
4914 else
4915 emit_insn (gen_rtx_SET (VOIDmode, lo_part,
4916 gen_rtx_SIGN_EXTEND (SImode, operands[1])));
4917 operands[1] = lo_part;
4918 }
4919 operands[0] = gen_highpart (SImode, operands[0]);
4920})
9c08d1fa 4921
4922(define_expand "zero_extendhisi2"
ef51b8e1 4923 [(set (match_operand:SI 0 "s_register_operand" "")
4924 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
cffb2a26 4925 "TARGET_EITHER"
ef51b8e1 4926{
4927 if (TARGET_ARM && !arm_arch4 && MEM_P (operands[1]))
f7fbdd4a 4928 {
ef51b8e1 4929 emit_insn (gen_movhi_bytes (operands[0], operands[1]));
4930 DONE;
25f7a26e 4931 }
ef51b8e1 4932 if (!arm_arch6 && !MEM_P (operands[1]))
4933 {
4934 rtx t = gen_lowpart (SImode, operands[1]);
4935 rtx tmp = gen_reg_rtx (SImode);
4936 emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (16)));
4937 emit_insn (gen_lshrsi3 (operands[0], tmp, GEN_INT (16)));
4938 DONE;
4939 }
4940})
9c08d1fa 4941
ef51b8e1 4942(define_split
b146458f 4943 [(set (match_operand:SI 0 "s_register_operand" "")
4944 (zero_extend:SI (match_operand:HI 1 "s_register_operand" "")))]
ef51b8e1 4945 "!TARGET_THUMB2 && !arm_arch6"
4946 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
4947 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 16)))]
4948{
4949 operands[2] = gen_lowpart (SImode, operands[1]);
4950})
4951
cffb2a26 4952(define_insn "*arm_zero_extendhisi2"
ef51b8e1 4953 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4954 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
a2cd141b 4955 "TARGET_ARM && arm_arch4 && !arm_arch6"
ef51b8e1 4956 "@
4957 #
4958 ldr%(h%)\\t%0, %1"
d82e788e 4959 [(set_attr "type" "alu_shift_reg,load_byte")
848e66ac 4960 (set_attr "predicable" "yes")]
cffb2a26 4961)
f7fbdd4a 4962
a2cd141b 4963(define_insn "*arm_zero_extendhisi2_v6"
4964 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
e3f4ccee 4965 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,Uh")))]
a2cd141b 4966 "TARGET_ARM && arm_arch6"
4967 "@
4968 uxth%?\\t%0, %1
25f905c2 4969 ldr%(h%)\\t%0, %1"
65f68e55 4970 [(set_attr "predicable" "yes")
6b6abc9c 4971 (set_attr "type" "extend,load_byte")]
a2cd141b 4972)
4973
4974(define_insn "*arm_zero_extendhisi2addsi"
4975 [(set (match_operand:SI 0 "s_register_operand" "=r")
4976 (plus:SI (zero_extend:SI (match_operand:HI 1 "s_register_operand" "r"))
4977 (match_operand:SI 2 "s_register_operand" "r")))]
25f905c2 4978 "TARGET_INT_SIMD"
a2cd141b 4979 "uxtah%?\\t%0, %2, %1"
d82e788e 4980 [(set_attr "type" "alu_shift_reg")
d952d547 4981 (set_attr "predicable" "yes")
4982 (set_attr "predicable_short_it" "no")]
a2cd141b 4983)
4984
87b22bf7 4985(define_expand "zero_extendqisi2"
cffb2a26 4986 [(set (match_operand:SI 0 "s_register_operand" "")
4987 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))]
4988 "TARGET_EITHER"
ef51b8e1 4989{
0438d37f 4990 if (TARGET_ARM && !arm_arch6 && !MEM_P (operands[1]))
87b22bf7 4991 {
ef51b8e1 4992 emit_insn (gen_andsi3 (operands[0],
4993 gen_lowpart (SImode, operands[1]),
4994 GEN_INT (255)));
4995 DONE;
4996 }
4997 if (!arm_arch6 && !MEM_P (operands[1]))
4998 {
4999 rtx t = gen_lowpart (SImode, operands[1]);
5000 rtx tmp = gen_reg_rtx (SImode);
5001 emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (24)));
5002 emit_insn (gen_lshrsi3 (operands[0], tmp, GEN_INT (24)));
5003 DONE;
5004 }
5005})
cffb2a26 5006
ef51b8e1 5007(define_split
b146458f 5008 [(set (match_operand:SI 0 "s_register_operand" "")
5009 (zero_extend:SI (match_operand:QI 1 "s_register_operand" "")))]
ef51b8e1 5010 "!arm_arch6"
5011 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 24)))
5012 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 24)))]
5013{
5014 operands[2] = simplify_gen_subreg (SImode, operands[1], QImode, 0);
5015 if (TARGET_ARM)
5016 {
5017 emit_insn (gen_andsi3 (operands[0], operands[2], GEN_INT (255)));
87b22bf7 5018 DONE;
5019 }
ef51b8e1 5020})
9c08d1fa 5021
cffb2a26 5022(define_insn "*arm_zero_extendqisi2"
ef51b8e1 5023 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5024 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
a2cd141b 5025 "TARGET_ARM && !arm_arch6"
ef51b8e1 5026 "@
5027 #
5028 ldr%(b%)\\t%0, %1\\t%@ zero_extendqisi2"
5029 [(set_attr "length" "8,4")
d82e788e 5030 (set_attr "type" "alu_shift_reg,load_byte")
848e66ac 5031 (set_attr "predicable" "yes")]
cffb2a26 5032)
87b22bf7 5033
a2cd141b 5034(define_insn "*arm_zero_extendqisi2_v6"
5035 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
e3f4ccee 5036 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "r,Uh")))]
a2cd141b 5037 "TARGET_ARM && arm_arch6"
5038 "@
25f905c2 5039 uxtb%(%)\\t%0, %1
5040 ldr%(b%)\\t%0, %1\\t%@ zero_extendqisi2"
6b6abc9c 5041 [(set_attr "type" "extend,load_byte")
848e66ac 5042 (set_attr "predicable" "yes")]
a2cd141b 5043)
5044
5045(define_insn "*arm_zero_extendqisi2addsi"
5046 [(set (match_operand:SI 0 "s_register_operand" "=r")
5047 (plus:SI (zero_extend:SI (match_operand:QI 1 "s_register_operand" "r"))
5048 (match_operand:SI 2 "s_register_operand" "r")))]
25f905c2 5049 "TARGET_INT_SIMD"
a2cd141b 5050 "uxtab%?\\t%0, %2, %1"
5051 [(set_attr "predicable" "yes")
d952d547 5052 (set_attr "predicable_short_it" "no")
d82e788e 5053 (set_attr "type" "alu_shift_reg")]
a2cd141b 5054)
5055
87b22bf7 5056(define_split
5057 [(set (match_operand:SI 0 "s_register_operand" "")
5058 (zero_extend:SI (subreg:QI (match_operand:SI 1 "" "") 0)))
5059 (clobber (match_operand:SI 2 "s_register_operand" ""))]
0438d37f 5060 "TARGET_32BIT && (!MEM_P (operands[1])) && ! BYTES_BIG_ENDIAN"
87b22bf7 5061 [(set (match_dup 2) (match_dup 1))
5062 (set (match_dup 0) (and:SI (match_dup 2) (const_int 255)))]
cffb2a26 5063 ""
5064)
9c08d1fa 5065
8a4d25d6 5066(define_split
5067 [(set (match_operand:SI 0 "s_register_operand" "")
5068 (zero_extend:SI (subreg:QI (match_operand:SI 1 "" "") 3)))
5069 (clobber (match_operand:SI 2 "s_register_operand" ""))]
0438d37f 5070 "TARGET_32BIT && (!MEM_P (operands[1])) && BYTES_BIG_ENDIAN"
8a4d25d6 5071 [(set (match_dup 2) (match_dup 1))
5072 (set (match_dup 0) (and:SI (match_dup 2) (const_int 255)))]
5073 ""
5074)
5075
1c274529 5076
5077(define_split
5078 [(set (match_operand:SI 0 "s_register_operand" "")
5079 (ior_xor:SI (and:SI (ashift:SI
5080 (match_operand:SI 1 "s_register_operand" "")
5081 (match_operand:SI 2 "const_int_operand" ""))
5082 (match_operand:SI 3 "const_int_operand" ""))
5083 (zero_extend:SI
5084 (match_operator 5 "subreg_lowpart_operator"
5085 [(match_operand:SI 4 "s_register_operand" "")]))))]
5086 "TARGET_32BIT
63787642 5087 && ((unsigned HOST_WIDE_INT) INTVAL (operands[3])
1c274529 5088 == (GET_MODE_MASK (GET_MODE (operands[5]))
5089 & (GET_MODE_MASK (GET_MODE (operands[5]))
5090 << (INTVAL (operands[2])))))"
5091 [(set (match_dup 0) (ior_xor:SI (ashift:SI (match_dup 1) (match_dup 2))
5092 (match_dup 4)))
5093 (set (match_dup 0) (zero_extend:SI (match_dup 5)))]
5094 "operands[5] = gen_lowpart (GET_MODE (operands[5]), operands[0]);"
5095)
5096
f7fbdd4a 5097(define_insn "*compareqi_eq0"
bd5b4116 5098 [(set (reg:CC_Z CC_REGNUM)
206ee9a2 5099 (compare:CC_Z (match_operand:QI 0 "s_register_operand" "r")
87b22bf7 5100 (const_int 0)))]
25f905c2 5101 "TARGET_32BIT"
596e5e8f 5102 "tst%?\\t%0, #255"
5103 [(set_attr "conds" "set")
d952d547 5104 (set_attr "predicable" "yes")
1b7da4ac 5105 (set_attr "predicable_short_it" "no")
5106 (set_attr "type" "logic_imm")]
cffb2a26 5107)
b11cae9e 5108
b11cae9e 5109(define_expand "extendhisi2"
ef51b8e1 5110 [(set (match_operand:SI 0 "s_register_operand" "")
5111 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
cffb2a26 5112 "TARGET_EITHER"
ef51b8e1 5113{
5114 if (TARGET_THUMB1)
5115 {
5116 emit_insn (gen_thumb1_extendhisi2 (operands[0], operands[1]));
5117 DONE;
5118 }
5119 if (MEM_P (operands[1]) && TARGET_ARM && !arm_arch4)
5120 {
5121 emit_insn (gen_extendhisi2_mem (operands[0], operands[1]));
5122 DONE;
5123 }
ed29c566 5124
ef51b8e1 5125 if (!arm_arch6 && !MEM_P (operands[1]))
5126 {
5127 rtx t = gen_lowpart (SImode, operands[1]);
5128 rtx tmp = gen_reg_rtx (SImode);
5129 emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (16)));
5130 emit_insn (gen_ashrsi3 (operands[0], tmp, GEN_INT (16)));
5131 DONE;
5132 }
5133})
cffb2a26 5134
ef51b8e1 5135(define_split
5136 [(parallel
5137 [(set (match_operand:SI 0 "register_operand" "")
5138 (sign_extend:SI (match_operand:HI 1 "register_operand" "")))
5139 (clobber (match_scratch:SI 2 ""))])]
5140 "!arm_arch6"
5141 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
5142 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 16)))]
5143{
5144 operands[2] = simplify_gen_subreg (SImode, operands[1], HImode, 0);
5145})
25f7a26e 5146
25f905c2 5147;; This pattern will only be used when ldsh is not available
25f7a26e 5148(define_expand "extendhisi2_mem"
eab14235 5149 [(set (match_dup 2) (zero_extend:SI (match_operand:HI 1 "" "")))
25f7a26e 5150 (set (match_dup 3)
eab14235 5151 (zero_extend:SI (match_dup 7)))
25f7a26e 5152 (set (match_dup 6) (ashift:SI (match_dup 4) (const_int 24)))
5153 (set (match_operand:SI 0 "" "")
5154 (ior:SI (ashiftrt:SI (match_dup 6) (const_int 16)) (match_dup 5)))]
cffb2a26 5155 "TARGET_ARM"
25f7a26e 5156 "
215b30b3 5157 {
5158 rtx mem1, mem2;
5159 rtx addr = copy_to_mode_reg (SImode, XEXP (operands[1], 0));
5160
788fcce0 5161 mem1 = change_address (operands[1], QImode, addr);
29c05e22 5162 mem2 = change_address (operands[1], QImode,
5163 plus_constant (Pmode, addr, 1));
215b30b3 5164 operands[0] = gen_lowpart (SImode, operands[0]);
5165 operands[1] = mem1;
5166 operands[2] = gen_reg_rtx (SImode);
5167 operands[3] = gen_reg_rtx (SImode);
5168 operands[6] = gen_reg_rtx (SImode);
5169 operands[7] = mem2;
25f7a26e 5170
215b30b3 5171 if (BYTES_BIG_ENDIAN)
5172 {
5173 operands[4] = operands[2];
5174 operands[5] = operands[3];
5175 }
5176 else
5177 {
5178 operands[4] = operands[3];
5179 operands[5] = operands[2];
5180 }
5181 }"
5182)
b11cae9e 5183
ef51b8e1 5184(define_split
5185 [(set (match_operand:SI 0 "register_operand" "")
5186 (sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
5187 "!arm_arch6"
5188 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
5189 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 16)))]
5190{
5191 operands[2] = simplify_gen_subreg (SImode, operands[1], HImode, 0);
5192})
5193
a2cd141b 5194(define_insn "*arm_extendhisi2"
ef51b8e1 5195 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
e3f4ccee 5196 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,Uh")))]
a2cd141b 5197 "TARGET_ARM && arm_arch4 && !arm_arch6"
ef51b8e1 5198 "@
5199 #
5200 ldr%(sh%)\\t%0, %1"
5201 [(set_attr "length" "8,4")
d82e788e 5202 (set_attr "type" "alu_shift_reg,load_byte")
e3f4ccee 5203 (set_attr "predicable" "yes")]
cffb2a26 5204)
f7fbdd4a 5205
25f905c2 5206;; ??? Check Thumb-2 pool range
a2cd141b 5207(define_insn "*arm_extendhisi2_v6"
5208 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
e3f4ccee 5209 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,Uh")))]
25f905c2 5210 "TARGET_32BIT && arm_arch6"
a2cd141b 5211 "@
5212 sxth%?\\t%0, %1
25f905c2 5213 ldr%(sh%)\\t%0, %1"
6b6abc9c 5214 [(set_attr "type" "extend,load_byte")
a2cd141b 5215 (set_attr "predicable" "yes")
e3f4ccee 5216 (set_attr "predicable_short_it" "no")]
a2cd141b 5217)
5218
5219(define_insn "*arm_extendhisi2addsi"
5220 [(set (match_operand:SI 0 "s_register_operand" "=r")
5221 (plus:SI (sign_extend:SI (match_operand:HI 1 "s_register_operand" "r"))
5222 (match_operand:SI 2 "s_register_operand" "r")))]
25f905c2 5223 "TARGET_INT_SIMD"
a2cd141b 5224 "sxtah%?\\t%0, %2, %1"
1b7da4ac 5225 [(set_attr "type" "alu_shift_reg")]
a2cd141b 5226)
5227
c8f69309 5228(define_expand "extendqihi2"
5229 [(set (match_dup 2)
bed7d9a5 5230 (ashift:SI (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "")
c8f69309 5231 (const_int 24)))
9c08d1fa 5232 (set (match_operand:HI 0 "s_register_operand" "")
c8f69309 5233 (ashiftrt:SI (match_dup 2)
5234 (const_int 24)))]
cffb2a26 5235 "TARGET_ARM"
c8f69309 5236 "
215b30b3 5237 {
0438d37f 5238 if (arm_arch4 && MEM_P (operands[1]))
215b30b3 5239 {
5240 emit_insn (gen_rtx_SET (VOIDmode,
5241 operands[0],
5242 gen_rtx_SIGN_EXTEND (HImode, operands[1])));
5243 DONE;
5244 }
5245 if (!s_register_operand (operands[1], QImode))
5246 operands[1] = copy_to_mode_reg (QImode, operands[1]);
5247 operands[0] = gen_lowpart (SImode, operands[0]);
5248 operands[1] = gen_lowpart (SImode, operands[1]);
5249 operands[2] = gen_reg_rtx (SImode);
5250 }"
5251)
f7fbdd4a 5252
25f905c2 5253(define_insn "*arm_extendqihi_insn"
b4e8a300 5254 [(set (match_operand:HI 0 "s_register_operand" "=r")
bed7d9a5 5255 (sign_extend:HI (match_operand:QI 1 "arm_extendqisi_mem_op" "Uq")))]
cffb2a26 5256 "TARGET_ARM && arm_arch4"
25f905c2 5257 "ldr%(sb%)\\t%0, %1"
a2cd141b 5258 [(set_attr "type" "load_byte")
e3f4ccee 5259 (set_attr "predicable" "yes")]
cffb2a26 5260)
3fc2009e 5261
b11cae9e 5262(define_expand "extendqisi2"
ef51b8e1 5263 [(set (match_operand:SI 0 "s_register_operand" "")
5264 (sign_extend:SI (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "")))]
cffb2a26 5265 "TARGET_EITHER"
ef51b8e1 5266{
5267 if (!arm_arch4 && MEM_P (operands[1]))
5268 operands[1] = copy_to_mode_reg (QImode, operands[1]);
a2cd141b 5269
ef51b8e1 5270 if (!arm_arch6 && !MEM_P (operands[1]))
5271 {
5272 rtx t = gen_lowpart (SImode, operands[1]);
5273 rtx tmp = gen_reg_rtx (SImode);
5274 emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (24)));
5275 emit_insn (gen_ashrsi3 (operands[0], tmp, GEN_INT (24)));
5276 DONE;
5277 }
5278})
a2cd141b 5279
ef51b8e1 5280(define_split
5281 [(set (match_operand:SI 0 "register_operand" "")
5282 (sign_extend:SI (match_operand:QI 1 "register_operand" "")))]
5283 "!arm_arch6"
5284 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 24)))
5285 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 24)))]
5286{
5287 operands[2] = simplify_gen_subreg (SImode, operands[1], QImode, 0);
5288})
f7fbdd4a 5289
a2cd141b 5290(define_insn "*arm_extendqisi"
ef51b8e1 5291 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5292 (sign_extend:SI (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "r,Uq")))]
a2cd141b 5293 "TARGET_ARM && arm_arch4 && !arm_arch6"
ef51b8e1 5294 "@
5295 #
5296 ldr%(sb%)\\t%0, %1"
5297 [(set_attr "length" "8,4")
d82e788e 5298 (set_attr "type" "alu_shift_reg,load_byte")
e3f4ccee 5299 (set_attr "predicable" "yes")]
cffb2a26 5300)
3fc2009e 5301
a2cd141b 5302(define_insn "*arm_extendqisi_v6"
5303 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
bed7d9a5 5304 (sign_extend:SI
5305 (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "r,Uq")))]
a2cd141b 5306 "TARGET_ARM && arm_arch6"
b4e8a300 5307 "@
5308 sxtb%?\\t%0, %1
25f905c2 5309 ldr%(sb%)\\t%0, %1"
6b6abc9c 5310 [(set_attr "type" "extend,load_byte")
e3f4ccee 5311 (set_attr "predicable" "yes")]
a2cd141b 5312)
5313
5314(define_insn "*arm_extendqisi2addsi"
5315 [(set (match_operand:SI 0 "s_register_operand" "=r")
5316 (plus:SI (sign_extend:SI (match_operand:QI 1 "s_register_operand" "r"))
5317 (match_operand:SI 2 "s_register_operand" "r")))]
25f905c2 5318 "TARGET_INT_SIMD"
a2cd141b 5319 "sxtab%?\\t%0, %2, %1"
d82e788e 5320 [(set_attr "type" "alu_shift_reg")
d952d547 5321 (set_attr "predicable" "yes")
5322 (set_attr "predicable_short_it" "no")]
a2cd141b 5323)
5324
caedf871 5325(define_expand "extendsfdf2"
5326 [(set (match_operand:DF 0 "s_register_operand" "")
5327 (float_extend:DF (match_operand:SF 1 "s_register_operand" "")))]
a50d7267 5328 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
caedf871 5329 ""
5330)
9b8516be 5331
5332/* HFmode -> DFmode conversions have to go through SFmode. */
5333(define_expand "extendhfdf2"
5334 [(set (match_operand:DF 0 "general_operand" "")
5335 (float_extend:DF (match_operand:HF 1 "general_operand" "")))]
5336 "TARGET_EITHER"
5337 "
5338 {
5339 rtx op1;
5340 op1 = convert_to_mode (SFmode, operands[1], 0);
5341 op1 = convert_to_mode (DFmode, op1, 0);
5342 emit_insn (gen_movdf (operands[0], op1));
5343 DONE;
5344 }"
5345)
b11cae9e 5346\f
5347;; Move insns (including loads and stores)
5348
5349;; XXX Just some ideas about movti.
9c08d1fa 5350;; I don't think these are a good idea on the arm, there just aren't enough
5351;; registers
b11cae9e 5352;;(define_expand "loadti"
9c08d1fa 5353;; [(set (match_operand:TI 0 "s_register_operand" "")
b11cae9e 5354;; (mem:TI (match_operand:SI 1 "address_operand" "")))]
5355;; "" "")
5356
5357;;(define_expand "storeti"
5358;; [(set (mem:TI (match_operand:TI 0 "address_operand" ""))
9c08d1fa 5359;; (match_operand:TI 1 "s_register_operand" ""))]
b11cae9e 5360;; "" "")
5361
5362;;(define_expand "movti"
5363;; [(set (match_operand:TI 0 "general_operand" "")
5364;; (match_operand:TI 1 "general_operand" ""))]
5365;; ""
5366;; "
5367;;{
5368;; rtx insn;
5369;;
0438d37f 5370;; if (MEM_P (operands[0]) && MEM_P (operands[1]))
b11cae9e 5371;; operands[1] = copy_to_reg (operands[1]);
0438d37f 5372;; if (MEM_P (operands[0]))
b11cae9e 5373;; insn = gen_storeti (XEXP (operands[0], 0), operands[1]);
0438d37f 5374;; else if (MEM_P (operands[1]))
b11cae9e 5375;; insn = gen_loadti (operands[0], XEXP (operands[1], 0));
5376;; else
5377;; FAIL;
5378;;
5379;; emit_insn (insn);
5380;; DONE;
5381;;}")
5382
a2f10574 5383;; Recognize garbage generated above.
b11cae9e 5384
5385;;(define_insn ""
5386;; [(set (match_operand:TI 0 "general_operand" "=r,r,r,<,>,m")
5387;; (match_operand:TI 1 "general_operand" "<,>,m,r,r,r"))]
5388;; ""
5389;; "*
5390;; {
5391;; register mem = (which_alternative < 3);
0d66636f 5392;; register const char *template;
b11cae9e 5393;;
5394;; operands[mem] = XEXP (operands[mem], 0);
5395;; switch (which_alternative)
5396;; {
5397;; case 0: template = \"ldmdb\\t%1!, %M0\"; break;
5398;; case 1: template = \"ldmia\\t%1!, %M0\"; break;
5399;; case 2: template = \"ldmia\\t%1, %M0\"; break;
5400;; case 3: template = \"stmdb\\t%0!, %M1\"; break;
5401;; case 4: template = \"stmia\\t%0!, %M1\"; break;
5402;; case 5: template = \"stmia\\t%0, %M1\"; break;
5403;; }
e2348bcb 5404;; output_asm_insn (template, operands);
5405;; return \"\";
b11cae9e 5406;; }")
5407
cffb2a26 5408(define_expand "movdi"
5409 [(set (match_operand:DI 0 "general_operand" "")
5410 (match_operand:DI 1 "general_operand" ""))]
5411 "TARGET_EITHER"
5412 "
e1ba4a27 5413 if (can_create_pseudo_p ())
cffb2a26 5414 {
0438d37f 5415 if (!REG_P (operands[0]))
b2778788 5416 operands[1] = force_reg (DImode, operands[1]);
cffb2a26 5417 }
5418 "
5419)
b11cae9e 5420
cffb2a26 5421(define_insn "*arm_movdi"
353cf59a 5422 [(set (match_operand:DI 0 "nonimmediate_di_operand" "=r, r, r, q, m")
5423 (match_operand:DI 1 "di_operand" "rDa,Db,Dc,mi,q"))]
cde1623a 5424 "TARGET_32BIT
b805622c 5425 && !(TARGET_HARD_FLOAT && TARGET_VFP)
b2778788 5426 && !TARGET_IWMMXT
5427 && ( register_operand (operands[0], DImode)
5428 || register_operand (operands[1], DImode))"
b11cae9e 5429 "*
d51f92df 5430 switch (which_alternative)
5431 {
5432 case 0:
5433 case 1:
5434 case 2:
5435 return \"#\";
5436 default:
26ff80c0 5437 return output_move_double (operands, true, NULL);
d51f92df 5438 }
cffb2a26 5439 "
359a6e9f 5440 [(set_attr "length" "8,12,16,8,8")
1b7da4ac 5441 (set_attr "type" "multiple,multiple,multiple,load2,store2")
cde1623a 5442 (set_attr "arm_pool_range" "*,*,*,1020,*")
8848d797 5443 (set_attr "arm_neg_pool_range" "*,*,*,1004,*")
42e1de19 5444 (set_attr "thumb2_pool_range" "*,*,*,4094,*")
cde1623a 5445 (set_attr "thumb2_neg_pool_range" "*,*,*,0,*")]
cffb2a26 5446)
5447
d51f92df 5448(define_split
5449 [(set (match_operand:ANY64 0 "arm_general_register_operand" "")
e6dd3afa 5450 (match_operand:ANY64 1 "immediate_operand" ""))]
25f905c2 5451 "TARGET_32BIT
d51f92df 5452 && reload_completed
5453 && (arm_const_double_inline_cost (operands[1])
861033d5 5454 <= arm_max_const_double_inline_cost ())"
d51f92df 5455 [(const_int 0)]
5456 "
5457 arm_split_constant (SET, SImode, curr_insn,
5458 INTVAL (gen_lowpart (SImode, operands[1])),
5459 gen_lowpart (SImode, operands[0]), NULL_RTX, 0);
5460 arm_split_constant (SET, SImode, curr_insn,
5461 INTVAL (gen_highpart_mode (SImode,
5462 GET_MODE (operands[0]),
5463 operands[1])),
5464 gen_highpart (SImode, operands[0]), NULL_RTX, 0);
5465 DONE;
5466 "
5467)
5468
e5ba9289 5469; If optimizing for size, or if we have load delay slots, then
5470; we want to split the constant into two separate operations.
5471; In both cases this may split a trivial part into a single data op
5472; leaving a single complex constant to load. We can also get longer
5473; offsets in a LDR which means we get better chances of sharing the pool
5474; entries. Finally, we can normally do a better job of scheduling
5475; LDR instructions than we can with LDM.
5476; This pattern will only match if the one above did not.
5477(define_split
5478 [(set (match_operand:ANY64 0 "arm_general_register_operand" "")
5479 (match_operand:ANY64 1 "const_double_operand" ""))]
5480 "TARGET_ARM && reload_completed
5481 && arm_const_double_by_parts (operands[1])"
5482 [(set (match_dup 0) (match_dup 1))
5483 (set (match_dup 2) (match_dup 3))]
5484 "
5485 operands[2] = gen_highpart (SImode, operands[0]);
5486 operands[3] = gen_highpart_mode (SImode, GET_MODE (operands[0]),
5487 operands[1]);
5488 operands[0] = gen_lowpart (SImode, operands[0]);
5489 operands[1] = gen_lowpart (SImode, operands[1]);
5490 "
5491)
5492
d51f92df 5493(define_split
5494 [(set (match_operand:ANY64 0 "arm_general_register_operand" "")
5495 (match_operand:ANY64 1 "arm_general_register_operand" ""))]
5496 "TARGET_EITHER && reload_completed"
5497 [(set (match_dup 0) (match_dup 1))
5498 (set (match_dup 2) (match_dup 3))]
5499 "
5500 operands[2] = gen_highpart (SImode, operands[0]);
5501 operands[3] = gen_highpart (SImode, operands[1]);
5502 operands[0] = gen_lowpart (SImode, operands[0]);
5503 operands[1] = gen_lowpart (SImode, operands[1]);
5504
5505 /* Handle a partial overlap. */
5506 if (rtx_equal_p (operands[0], operands[3]))
5507 {
5508 rtx tmp0 = operands[0];
5509 rtx tmp1 = operands[1];
5510
5511 operands[0] = operands[2];
5512 operands[1] = operands[3];
5513 operands[2] = tmp0;
5514 operands[3] = tmp1;
5515 }
5516 "
5517)
5518
a8a3b539 5519;; We can't actually do base+index doubleword loads if the index and
5520;; destination overlap. Split here so that we at least have chance to
5521;; schedule.
5522(define_split
5523 [(set (match_operand:DI 0 "s_register_operand" "")
5524 (mem:DI (plus:SI (match_operand:SI 1 "s_register_operand" "")
5525 (match_operand:SI 2 "s_register_operand" ""))))]
5526 "TARGET_LDRD
5527 && reg_overlap_mentioned_p (operands[0], operands[1])
5528 && reg_overlap_mentioned_p (operands[0], operands[2])"
5529 [(set (match_dup 4)
5530 (plus:SI (match_dup 1)
5531 (match_dup 2)))
5532 (set (match_dup 0)
5533 (mem:DI (match_dup 4)))]
5534 "
5535 operands[4] = gen_rtx_REG (SImode, REGNO(operands[0]));
5536 "
5537)
5538
9c08d1fa 5539(define_expand "movsi"
5540 [(set (match_operand:SI 0 "general_operand" "")
5541 (match_operand:SI 1 "general_operand" ""))]
cffb2a26 5542 "TARGET_EITHER"
9c08d1fa 5543 "
befb0bac 5544 {
e348ff3e 5545 rtx base, offset, tmp;
5546
25f905c2 5547 if (TARGET_32BIT)
9c08d1fa 5548 {
674a8f0b 5549 /* Everything except mem = const or mem = mem can be done easily. */
0438d37f 5550 if (MEM_P (operands[0]))
cffb2a26 5551 operands[1] = force_reg (SImode, operands[1]);
a2cd141b 5552 if (arm_general_register_operand (operands[0], SImode)
0438d37f 5553 && CONST_INT_P (operands[1])
cffb2a26 5554 && !(const_ok_for_arm (INTVAL (operands[1]))
5555 || const_ok_for_arm (~INTVAL (operands[1]))))
5556 {
96f57e36 5557 arm_split_constant (SET, SImode, NULL_RTX,
5558 INTVAL (operands[1]), operands[0], NULL_RTX,
e1ba4a27 5559 optimize && can_create_pseudo_p ());
cffb2a26 5560 DONE;
5561 }
5562 }
25f905c2 5563 else /* TARGET_THUMB1... */
cffb2a26 5564 {
e1ba4a27 5565 if (can_create_pseudo_p ())
cffb2a26 5566 {
0438d37f 5567 if (!REG_P (operands[0]))
cffb2a26 5568 operands[1] = force_reg (SImode, operands[1]);
5569 }
9c08d1fa 5570 }
f655717d 5571
e348ff3e 5572 if (ARM_OFFSETS_MUST_BE_WITHIN_SECTIONS_P)
5573 {
5574 split_const (operands[1], &base, &offset);
5575 if (GET_CODE (base) == SYMBOL_REF
5576 && !offset_within_block_p (base, INTVAL (offset)))
5577 {
b308ddcf 5578 tmp = can_create_pseudo_p () ? gen_reg_rtx (SImode) : operands[0];
e348ff3e 5579 emit_move_insn (tmp, base);
5580 emit_insn (gen_addsi3 (operands[0], tmp, offset));
5581 DONE;
5582 }
5583 }
5584
f655717d 5585 /* Recognize the case where operand[1] is a reference to thread-local
5586 data and load its address to a register. */
5587 if (arm_tls_referenced_p (operands[1]))
5588 {
5589 rtx tmp = operands[1];
5590 rtx addend = NULL;
5591
5592 if (GET_CODE (tmp) == CONST && GET_CODE (XEXP (tmp, 0)) == PLUS)
5593 {
5594 addend = XEXP (XEXP (tmp, 0), 1);
5595 tmp = XEXP (XEXP (tmp, 0), 0);
5596 }
5597
5598 gcc_assert (GET_CODE (tmp) == SYMBOL_REF);
5599 gcc_assert (SYMBOL_REF_TLS_MODEL (tmp) != 0);
5600
e1ba4a27 5601 tmp = legitimize_tls_address (tmp,
5602 !can_create_pseudo_p () ? operands[0] : 0);
f655717d 5603 if (addend)
5604 {
5605 tmp = gen_rtx_PLUS (SImode, tmp, addend);
5606 tmp = force_operand (tmp, operands[0]);
5607 }
5608 operands[1] = tmp;
5609 }
5610 else if (flag_pic
5611 && (CONSTANT_P (operands[1])
5612 || symbol_mentioned_p (operands[1])
5613 || label_mentioned_p (operands[1])))
5614 operands[1] = legitimize_pic_address (operands[1], SImode,
e1ba4a27 5615 (!can_create_pseudo_p ()
5616 ? operands[0]
5617 : 0));
befb0bac 5618 }
215b30b3 5619 "
5620)
9c08d1fa 5621
d0e6a121 5622;; The ARM LO_SUM and HIGH are backwards - HIGH sets the low bits, and
5623;; LO_SUM adds in the high bits. Fortunately these are opaque operations
5624;; so this does not matter.
5625(define_insn "*arm_movt"
5626 [(set (match_operand:SI 0 "nonimmediate_operand" "=r")
5627 (lo_sum:SI (match_operand:SI 1 "nonimmediate_operand" "0")
5628 (match_operand:SI 2 "general_operand" "i")))]
c9b2ce40 5629 "arm_arch_thumb2"
d0e6a121 5630 "movt%?\t%0, #:upper16:%c2"
5631 [(set_attr "predicable" "yes")
d952d547 5632 (set_attr "predicable_short_it" "no")
1b7da4ac 5633 (set_attr "length" "4")
5634 (set_attr "type" "mov_imm")]
d0e6a121 5635)
5636
cffb2a26 5637(define_insn "*arm_movsi_insn"
aaa37ad6 5638 [(set (match_operand:SI 0 "nonimmediate_operand" "=rk,r,r,r,rk,m")
110eae03 5639 (match_operand:SI 1 "general_operand" "rk, I,K,j,mi,rk"))]
755eb2b4 5640 "TARGET_ARM && ! TARGET_IWMMXT
a2cd141b 5641 && !(TARGET_HARD_FLOAT && TARGET_VFP)
cffb2a26 5642 && ( register_operand (operands[0], SImode)
5643 || register_operand (operands[1], SImode))"
f7fbdd4a 5644 "@
aaa37ad6 5645 mov%?\\t%0, %1
f7fbdd4a 5646 mov%?\\t%0, %1
5647 mvn%?\\t%0, #%B1
25f905c2 5648 movw%?\\t%0, %1
f7fbdd4a 5649 ldr%?\\t%0, %1
5650 str%?\\t%1, %0"
1aed5204 5651 [(set_attr "type" "mov_reg,mov_imm,mvn_imm,mov_imm,load1,store1")
0d66636f 5652 (set_attr "predicable" "yes")
aaa37ad6 5653 (set_attr "pool_range" "*,*,*,*,4096,*")
5654 (set_attr "neg_pool_range" "*,*,*,*,4084,*")]
cffb2a26 5655)
87b22bf7 5656
5657(define_split
a2cd141b 5658 [(set (match_operand:SI 0 "arm_general_register_operand" "")
87b22bf7 5659 (match_operand:SI 1 "const_int_operand" ""))]
25f905c2 5660 "TARGET_32BIT
215b30b3 5661 && (!(const_ok_for_arm (INTVAL (operands[1]))
5662 || const_ok_for_arm (~INTVAL (operands[1]))))"
87b22bf7 5663 [(clobber (const_int 0))]
5664 "
96f57e36 5665 arm_split_constant (SET, SImode, NULL_RTX,
5666 INTVAL (operands[1]), operands[0], NULL_RTX, 0);
87b22bf7 5667 DONE;
215b30b3 5668 "
5669)
9c08d1fa 5670
861033d5 5671;; A normal way to do (symbol + offset) requires three instructions at least
5672;; (depends on how big the offset is) as below:
5673;; movw r0, #:lower16:g
5674;; movw r0, #:upper16:g
5675;; adds r0, #4
5676;;
5677;; A better way would be:
5678;; movw r0, #:lower16:g+4
5679;; movw r0, #:upper16:g+4
5680;;
5681;; The limitation of this way is that the length of offset should be a 16-bit
5682;; signed value, because current assembler only supports REL type relocation for
5683;; such case. If the more powerful RELA type is supported in future, we should
5684;; update this pattern to go with better way.
5685(define_split
5686 [(set (match_operand:SI 0 "arm_general_register_operand" "")
5687 (const:SI (plus:SI (match_operand:SI 1 "general_operand" "")
5688 (match_operand:SI 2 "const_int_operand" ""))))]
5689 "TARGET_THUMB2
5690 && arm_disable_literal_pool
5691 && reload_completed
5692 && GET_CODE (operands[1]) == SYMBOL_REF"
5693 [(clobber (const_int 0))]
5694 "
5695 int offset = INTVAL (operands[2]);
5696
5697 if (offset < -0x8000 || offset > 0x7fff)
5698 {
5699 arm_emit_movpair (operands[0], operands[1]);
5700 emit_insn (gen_rtx_SET (SImode, operands[0],
5701 gen_rtx_PLUS (SImode, operands[0], operands[2])));
5702 }
5703 else
5704 {
5705 rtx op = gen_rtx_CONST (SImode,
5706 gen_rtx_PLUS (SImode, operands[1], operands[2]));
5707 arm_emit_movpair (operands[0], op);
5708 }
5709 "
5710)
5711
b8d5d078 5712;; Split symbol_refs at the later stage (after cprop), instead of generating
5713;; movt/movw pair directly at expand. Otherwise corresponding high_sum
5714;; and lo_sum would be merged back into memory load at cprop. However,
5715;; if the default is to prefer movt/movw rather than a load from the constant
5716;; pool, the performance is better.
5717(define_split
5718 [(set (match_operand:SI 0 "arm_general_register_operand" "")
5719 (match_operand:SI 1 "general_operand" ""))]
5720 "TARGET_32BIT
5721 && TARGET_USE_MOVT && GET_CODE (operands[1]) == SYMBOL_REF
5722 && !flag_pic && !target_word_relocations
5723 && !arm_tls_referenced_p (operands[1])"
5724 [(clobber (const_int 0))]
5725{
5726 arm_emit_movpair (operands[0], operands[1]);
5727 DONE;
5728})
5729
bc360af8 5730;; When generating pic, we need to load the symbol offset into a register.
5731;; So that the optimizer does not confuse this with a normal symbol load
5732;; we use an unspec. The offset will be loaded from a constant pool entry,
5733;; since that is the only type of relocation we can use.
cffb2a26 5734
bc360af8 5735;; Wrap calculation of the whole PIC address in a single pattern for the
5736;; benefit of optimizers, particularly, PRE and HOIST. Calculation of
5737;; a PIC address involves two loads from memory, so we want to CSE it
5738;; as often as possible.
5739;; This pattern will be split into one of the pic_load_addr_* patterns
5740;; and a move after GCSE optimizations.
5741;;
5742;; Note: Update arm.c: legitimize_pic_address() when changing this pattern.
5743(define_expand "calculate_pic_address"
94f8caca 5744 [(set (match_operand:SI 0 "register_operand" "")
5745 (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "")
5746 (unspec:SI [(match_operand:SI 2 "" "")]
5747 UNSPEC_PIC_SYM))))]
5748 "flag_pic"
5749)
5750
5751;; Split calculate_pic_address into pic_load_addr_* and a move.
5752(define_split
5753 [(set (match_operand:SI 0 "register_operand" "")
5754 (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "")
5755 (unspec:SI [(match_operand:SI 2 "" "")]
5756 UNSPEC_PIC_SYM))))]
5757 "flag_pic"
5758 [(set (match_dup 3) (unspec:SI [(match_dup 2)] UNSPEC_PIC_SYM))
5759 (set (match_dup 0) (mem:SI (plus:SI (match_dup 1) (match_dup 3))))]
5760 "operands[3] = can_create_pseudo_p () ? gen_reg_rtx (SImode) : operands[0];"
5761)
5762
350ccca5 5763;; operand1 is the memory address to go into
5764;; pic_load_addr_32bit.
5765;; operand2 is the PIC label to be emitted
5766;; from pic_add_dot_plus_eight.
5767;; We do this to allow hoisting of the entire insn.
5768(define_insn_and_split "pic_load_addr_unified"
5769 [(set (match_operand:SI 0 "s_register_operand" "=r,r,l")
5770 (unspec:SI [(match_operand:SI 1 "" "mX,mX,mX")
5771 (match_operand:SI 2 "" "")]
5772 UNSPEC_PIC_UNIFIED))]
5773 "flag_pic"
5774 "#"
5775 "&& reload_completed"
5776 [(set (match_dup 0) (unspec:SI [(match_dup 1)] UNSPEC_PIC_SYM))
5777 (set (match_dup 0) (unspec:SI [(match_dup 0) (match_dup 3)
5778 (match_dup 2)] UNSPEC_PIC_BASE))]
5779 "operands[3] = TARGET_THUMB ? GEN_INT (4) : GEN_INT (8);"
5780 [(set_attr "type" "load1,load1,load1")
42e1de19 5781 (set_attr "pool_range" "4096,4094,1022")
350ccca5 5782 (set_attr "neg_pool_range" "4084,0,0")
5783 (set_attr "arch" "a,t2,t1")
5784 (set_attr "length" "8,6,4")]
5785)
5786
67336bcf 5787;; The rather odd constraints on the following are to force reload to leave
5788;; the insn alone, and to force the minipool generation pass to then move
5789;; the GOT symbol to memory.
849170fd 5790
b3cd5f55 5791(define_insn "pic_load_addr_32bit"
849170fd 5792 [(set (match_operand:SI 0 "s_register_operand" "=r")
e1159bbe 5793 (unspec:SI [(match_operand:SI 1 "" "mX")] UNSPEC_PIC_SYM))]
b3cd5f55 5794 "TARGET_32BIT && flag_pic"
67336bcf 5795 "ldr%?\\t%0, %1"
a2cd141b 5796 [(set_attr "type" "load1")
42e1de19 5797 (set (attr "pool_range")
5798 (if_then_else (eq_attr "is_thumb" "no")
5799 (const_int 4096)
5800 (const_int 4094)))
b3cd5f55 5801 (set (attr "neg_pool_range")
5802 (if_then_else (eq_attr "is_thumb" "no")
5803 (const_int 4084)
5804 (const_int 0)))]
8c4d8060 5805)
5806
25f905c2 5807(define_insn "pic_load_addr_thumb1"
8c4d8060 5808 [(set (match_operand:SI 0 "s_register_operand" "=l")
e1159bbe 5809 (unspec:SI [(match_operand:SI 1 "" "mX")] UNSPEC_PIC_SYM))]
25f905c2 5810 "TARGET_THUMB1 && flag_pic"
8c4d8060 5811 "ldr\\t%0, %1"
a2cd141b 5812 [(set_attr "type" "load1")
42e1de19 5813 (set (attr "pool_range") (const_int 1018))]
cffb2a26 5814)
849170fd 5815
cffb2a26 5816(define_insn "pic_add_dot_plus_four"
15d5d060 5817 [(set (match_operand:SI 0 "register_operand" "=r")
c0c1fba5 5818 (unspec:SI [(match_operand:SI 1 "register_operand" "0")
5819 (const_int 4)
beef0fb5 5820 (match_operand 2 "" "")]
5821 UNSPEC_PIC_BASE))]
b3cd5f55 5822 "TARGET_THUMB"
cffb2a26 5823 "*
6cdcb15c 5824 (*targetm.asm_out.internal_label) (asm_out_file, \"LPIC\",
5825 INTVAL (operands[2]));
cffb2a26 5826 return \"add\\t%0, %|pc\";
5827 "
1b7da4ac 5828 [(set_attr "length" "2")
112eda6f 5829 (set_attr "type" "alu_sreg")]
cffb2a26 5830)
849170fd 5831
5832(define_insn "pic_add_dot_plus_eight"
15d5d060 5833 [(set (match_operand:SI 0 "register_operand" "=r")
c0c1fba5 5834 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
5835 (const_int 8)
beef0fb5 5836 (match_operand 2 "" "")]
5837 UNSPEC_PIC_BASE))]
f655717d 5838 "TARGET_ARM"
c4034607 5839 "*
6cdcb15c 5840 (*targetm.asm_out.internal_label) (asm_out_file, \"LPIC\",
5841 INTVAL (operands[2]));
15d5d060 5842 return \"add%?\\t%0, %|pc, %1\";
cffb2a26 5843 "
1b7da4ac 5844 [(set_attr "predicable" "yes")
112eda6f 5845 (set_attr "type" "alu_sreg")]
cffb2a26 5846)
849170fd 5847
f655717d 5848(define_insn "tls_load_dot_plus_eight"
cc071db6 5849 [(set (match_operand:SI 0 "register_operand" "=r")
c0c1fba5 5850 (mem:SI (unspec:SI [(match_operand:SI 1 "register_operand" "r")
5851 (const_int 8)
beef0fb5 5852 (match_operand 2 "" "")]
5853 UNSPEC_PIC_BASE)))]
f655717d 5854 "TARGET_ARM"
5855 "*
6cdcb15c 5856 (*targetm.asm_out.internal_label) (asm_out_file, \"LPIC\",
5857 INTVAL (operands[2]));
f655717d 5858 return \"ldr%?\\t%0, [%|pc, %1]\t\t@ tls_load_dot_plus_eight\";
5859 "
1b7da4ac 5860 [(set_attr "predicable" "yes")
5861 (set_attr "type" "load1")]
f655717d 5862)
5863
5864;; PIC references to local variables can generate pic_add_dot_plus_eight
5865;; followed by a load. These sequences can be crunched down to
5866;; tls_load_dot_plus_eight by a peephole.
5867
5868(define_peephole2
c0c1fba5 5869 [(set (match_operand:SI 0 "register_operand" "")
5870 (unspec:SI [(match_operand:SI 3 "register_operand" "")
5871 (const_int 8)
5872 (match_operand 1 "" "")]
5873 UNSPEC_PIC_BASE))
2d05dfad 5874 (set (match_operand:SI 2 "arm_general_register_operand" "")
5875 (mem:SI (match_dup 0)))]
f655717d 5876 "TARGET_ARM && peep2_reg_dead_p (2, operands[0])"
c0c1fba5 5877 [(set (match_dup 2)
5878 (mem:SI (unspec:SI [(match_dup 3)
5879 (const_int 8)
5880 (match_dup 1)]
5881 UNSPEC_PIC_BASE)))]
f655717d 5882 ""
5883)
5884
bac7fc85 5885(define_insn "pic_offset_arm"
5886 [(set (match_operand:SI 0 "register_operand" "=r")
5887 (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
5888 (unspec:SI [(match_operand:SI 2 "" "X")]
5889 UNSPEC_PIC_OFFSET))))]
5890 "TARGET_VXWORKS_RTP && TARGET_ARM && flag_pic"
5891 "ldr%?\\t%0, [%1,%2]"
5892 [(set_attr "type" "load1")]
5893)
5894
95373f08 5895(define_expand "builtin_setjmp_receiver"
5896 [(label_ref (match_operand 0 "" ""))]
5897 "flag_pic"
5898 "
5899{
b935b306 5900 /* r3 is clobbered by set/longjmp, so we can use it as a scratch
5901 register. */
2cb7d577 5902 if (arm_pic_register != INVALID_REGNUM)
5903 arm_load_pic_register (1UL << 3);
95373f08 5904 DONE;
5905}")
5906
9c08d1fa 5907;; If copying one reg to another we can set the condition codes according to
5908;; its value. Such a move is common after a return from subroutine and the
5909;; result is being tested against zero.
5910
f7fbdd4a 5911(define_insn "*movsi_compare0"
bd5b4116 5912 [(set (reg:CC CC_REGNUM)
cffb2a26 5913 (compare:CC (match_operand:SI 1 "s_register_operand" "0,r")
5914 (const_int 0)))
5915 (set (match_operand:SI 0 "s_register_operand" "=r,r")
5916 (match_dup 1))]
25f905c2 5917 "TARGET_32BIT"
e2348bcb 5918 "@
40dbec34 5919 cmp%?\\t%0, #0
25f905c2 5920 sub%.\\t%0, %1, #0"
65f68e55 5921 [(set_attr "conds" "set")
d82e788e 5922 (set_attr "type" "alus_imm,alus_imm")]
cffb2a26 5923)
b11cae9e 5924
b11cae9e 5925;; Subroutine to store a half word from a register into memory.
5926;; Operand 0 is the source register (HImode)
c8f69309 5927;; Operand 1 is the destination address in a register (SImode)
b11cae9e 5928
9c08d1fa 5929;; In both this routine and the next, we must be careful not to spill
01cc3b75 5930;; a memory address of reg+large_const into a separate PLUS insn, since this
9c08d1fa 5931;; can generate unrecognizable rtl.
5932
b11cae9e 5933(define_expand "storehi"
c8f69309 5934 [;; store the low byte
f082f1c4 5935 (set (match_operand 1 "" "") (match_dup 3))
b11cae9e 5936 ;; extract the high byte
c8f69309 5937 (set (match_dup 2)
5938 (ashiftrt:SI (match_operand 0 "" "") (const_int 8)))
b11cae9e 5939 ;; store the high byte
787f8210 5940 (set (match_dup 4) (match_dup 5))]
cffb2a26 5941 "TARGET_ARM"
b11cae9e 5942 "
215b30b3 5943 {
537ffcfc 5944 rtx op1 = operands[1];
5945 rtx addr = XEXP (op1, 0);
215b30b3 5946 enum rtx_code code = GET_CODE (addr);
5947
0438d37f 5948 if ((code == PLUS && !CONST_INT_P (XEXP (addr, 1)))
215b30b3 5949 || code == MINUS)
537ffcfc 5950 op1 = replace_equiv_address (operands[1], force_reg (SImode, addr));
215b30b3 5951
537ffcfc 5952 operands[4] = adjust_address (op1, QImode, 1);
e513d163 5953 operands[1] = adjust_address (operands[1], QImode, 0);
215b30b3 5954 operands[3] = gen_lowpart (QImode, operands[0]);
5955 operands[0] = gen_lowpart (SImode, operands[0]);
787f8210 5956 operands[2] = gen_reg_rtx (SImode);
5957 operands[5] = gen_lowpart (QImode, operands[2]);
215b30b3 5958 }"
5959)
b11cae9e 5960
c7597b5d 5961(define_expand "storehi_bigend"
f082f1c4 5962 [(set (match_dup 4) (match_dup 3))
c7597b5d 5963 (set (match_dup 2)
5964 (ashiftrt:SI (match_operand 0 "" "") (const_int 8)))
787f8210 5965 (set (match_operand 1 "" "") (match_dup 5))]
cffb2a26 5966 "TARGET_ARM"
b11cae9e 5967 "
215b30b3 5968 {
537ffcfc 5969 rtx op1 = operands[1];
5970 rtx addr = XEXP (op1, 0);
215b30b3 5971 enum rtx_code code = GET_CODE (addr);
5972
0438d37f 5973 if ((code == PLUS && !CONST_INT_P (XEXP (addr, 1)))
215b30b3 5974 || code == MINUS)
537ffcfc 5975 op1 = replace_equiv_address (op1, force_reg (SImode, addr));
215b30b3 5976
537ffcfc 5977 operands[4] = adjust_address (op1, QImode, 1);
e513d163 5978 operands[1] = adjust_address (operands[1], QImode, 0);
215b30b3 5979 operands[3] = gen_lowpart (QImode, operands[0]);
5980 operands[0] = gen_lowpart (SImode, operands[0]);
5981 operands[2] = gen_reg_rtx (SImode);
787f8210 5982 operands[5] = gen_lowpart (QImode, operands[2]);
215b30b3 5983 }"
5984)
c7597b5d 5985
5986;; Subroutine to store a half word integer constant into memory.
5987(define_expand "storeinthi"
f082f1c4 5988 [(set (match_operand 0 "" "")
787f8210 5989 (match_operand 1 "" ""))
9e8503e6 5990 (set (match_dup 3) (match_dup 2))]
cffb2a26 5991 "TARGET_ARM"
c7597b5d 5992 "
215b30b3 5993 {
5994 HOST_WIDE_INT value = INTVAL (operands[1]);
5995 rtx addr = XEXP (operands[0], 0);
537ffcfc 5996 rtx op0 = operands[0];
215b30b3 5997 enum rtx_code code = GET_CODE (addr);
c7597b5d 5998
0438d37f 5999 if ((code == PLUS && !CONST_INT_P (XEXP (addr, 1)))
215b30b3 6000 || code == MINUS)
537ffcfc 6001 op0 = replace_equiv_address (op0, force_reg (SImode, addr));
c7597b5d 6002
215b30b3 6003 operands[1] = gen_reg_rtx (SImode);
6004 if (BYTES_BIG_ENDIAN)
6005 {
6006 emit_insn (gen_movsi (operands[1], GEN_INT ((value >> 8) & 255)));
6007 if ((value & 255) == ((value >> 8) & 255))
6008 operands[2] = operands[1];
6009 else
6010 {
6011 operands[2] = gen_reg_rtx (SImode);
6012 emit_insn (gen_movsi (operands[2], GEN_INT (value & 255)));
6013 }
6014 }
6015 else
6016 {
6017 emit_insn (gen_movsi (operands[1], GEN_INT (value & 255)));
6018 if ((value & 255) == ((value >> 8) & 255))
6019 operands[2] = operands[1];
6020 else
6021 {
6022 operands[2] = gen_reg_rtx (SImode);
6023 emit_insn (gen_movsi (operands[2], GEN_INT ((value >> 8) & 255)));
6024 }
6025 }
c7597b5d 6026
537ffcfc 6027 operands[3] = adjust_address (op0, QImode, 1);
e513d163 6028 operands[0] = adjust_address (operands[0], QImode, 0);
9e8503e6 6029 operands[2] = gen_lowpart (QImode, operands[2]);
787f8210 6030 operands[1] = gen_lowpart (QImode, operands[1]);
215b30b3 6031 }"
6032)
b11cae9e 6033
f7fbdd4a 6034(define_expand "storehi_single_op"
6035 [(set (match_operand:HI 0 "memory_operand" "")
6036 (match_operand:HI 1 "general_operand" ""))]
25f905c2 6037 "TARGET_32BIT && arm_arch4"
f7fbdd4a 6038 "
215b30b3 6039 if (!s_register_operand (operands[1], HImode))
f7fbdd4a 6040 operands[1] = copy_to_mode_reg (HImode, operands[1]);
215b30b3 6041 "
6042)
f7fbdd4a 6043
b11cae9e 6044(define_expand "movhi"
6045 [(set (match_operand:HI 0 "general_operand" "")
c8f69309 6046 (match_operand:HI 1 "general_operand" ""))]
cffb2a26 6047 "TARGET_EITHER"
b11cae9e 6048 "
cffb2a26 6049 if (TARGET_ARM)
b11cae9e 6050 {
e1ba4a27 6051 if (can_create_pseudo_p ())
cffb2a26 6052 {
0438d37f 6053 if (MEM_P (operands[0]))
b11cae9e 6054 {
cffb2a26 6055 if (arm_arch4)
6056 {
6057 emit_insn (gen_storehi_single_op (operands[0], operands[1]));
6058 DONE;
6059 }
0438d37f 6060 if (CONST_INT_P (operands[1]))
cffb2a26 6061 emit_insn (gen_storeinthi (operands[0], operands[1]));
c7597b5d 6062 else
cffb2a26 6063 {
0438d37f 6064 if (MEM_P (operands[1]))
cffb2a26 6065 operands[1] = force_reg (HImode, operands[1]);
6066 if (BYTES_BIG_ENDIAN)
6067 emit_insn (gen_storehi_bigend (operands[1], operands[0]));
6068 else
6069 emit_insn (gen_storehi (operands[1], operands[0]));
6070 }
6071 DONE;
b11cae9e 6072 }
cffb2a26 6073 /* Sign extend a constant, and keep it in an SImode reg. */
0438d37f 6074 else if (CONST_INT_P (operands[1]))
9c08d1fa 6075 {
cffb2a26 6076 rtx reg = gen_reg_rtx (SImode);
6077 HOST_WIDE_INT val = INTVAL (operands[1]) & 0xffff;
6078
6079 /* If the constant is already valid, leave it alone. */
215b30b3 6080 if (!const_ok_for_arm (val))
cffb2a26 6081 {
6082 /* If setting all the top bits will make the constant
6083 loadable in a single instruction, then set them.
6084 Otherwise, sign extend the number. */
6085
215b30b3 6086 if (const_ok_for_arm (~(val | ~0xffff)))
cffb2a26 6087 val |= ~0xffff;
6088 else if (val & 0x8000)
6089 val |= ~0xffff;
6090 }
6091
6092 emit_insn (gen_movsi (reg, GEN_INT (val)));
9e8503e6 6093 operands[1] = gen_lowpart (HImode, reg);
9c08d1fa 6094 }
e1ba4a27 6095 else if (arm_arch4 && optimize && can_create_pseudo_p ()
0438d37f 6096 && MEM_P (operands[1]))
0045890a 6097 {
6098 rtx reg = gen_reg_rtx (SImode);
6099
6100 emit_insn (gen_zero_extendhisi2 (reg, operands[1]));
6101 operands[1] = gen_lowpart (HImode, reg);
6102 }
215b30b3 6103 else if (!arm_arch4)
f7fbdd4a 6104 {
0438d37f 6105 if (MEM_P (operands[1]))
cffb2a26 6106 {
c1a66faf 6107 rtx base;
6108 rtx offset = const0_rtx;
6109 rtx reg = gen_reg_rtx (SImode);
6110
0438d37f 6111 if ((REG_P (base = XEXP (operands[1], 0))
c1a66faf 6112 || (GET_CODE (base) == PLUS
0438d37f 6113 && (CONST_INT_P (offset = XEXP (base, 1)))
c1a66faf 6114 && ((INTVAL(offset) & 1) != 1)
0438d37f 6115 && REG_P (base = XEXP (base, 0))))
c1a66faf 6116 && REGNO_POINTER_ALIGN (REGNO (base)) >= 32)
206ee9a2 6117 {
8deb3959 6118 rtx new_rtx;
c1a66faf 6119
8deb3959 6120 new_rtx = widen_memory_access (operands[1], SImode,
6121 ((INTVAL (offset) & ~3)
6122 - INTVAL (offset)));
6123 emit_insn (gen_movsi (reg, new_rtx));
c1a66faf 6124 if (((INTVAL (offset) & 2) != 0)
6125 ^ (BYTES_BIG_ENDIAN ? 1 : 0))
6126 {
6127 rtx reg2 = gen_reg_rtx (SImode);
6128
6129 emit_insn (gen_lshrsi3 (reg2, reg, GEN_INT (16)));
6130 reg = reg2;
6131 }
206ee9a2 6132 }
c1a66faf 6133 else
6134 emit_insn (gen_movhi_bytes (reg, operands[1]));
6135
6136 operands[1] = gen_lowpart (HImode, reg);
cffb2a26 6137 }
6138 }
6139 }
674a8f0b 6140 /* Handle loading a large integer during reload. */
0438d37f 6141 else if (CONST_INT_P (operands[1])
215b30b3 6142 && !const_ok_for_arm (INTVAL (operands[1]))
6143 && !const_ok_for_arm (~INTVAL (operands[1])))
cffb2a26 6144 {
6145 /* Writing a constant to memory needs a scratch, which should
6146 be handled with SECONDARY_RELOADs. */
0438d37f 6147 gcc_assert (REG_P (operands[0]));
cffb2a26 6148
6149 operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
6150 emit_insn (gen_movsi (operands[0], operands[1]));
6151 DONE;
6152 }
6153 }
25f905c2 6154 else if (TARGET_THUMB2)
6155 {
6156 /* Thumb-2 can do everything except mem=mem and mem=const easily. */
e1ba4a27 6157 if (can_create_pseudo_p ())
25f905c2 6158 {
0438d37f 6159 if (!REG_P (operands[0]))
25f905c2 6160 operands[1] = force_reg (HImode, operands[1]);
6161 /* Zero extend a constant, and keep it in an SImode reg. */
0438d37f 6162 else if (CONST_INT_P (operands[1]))
25f905c2 6163 {
6164 rtx reg = gen_reg_rtx (SImode);
6165 HOST_WIDE_INT val = INTVAL (operands[1]) & 0xffff;
6166
6167 emit_insn (gen_movsi (reg, GEN_INT (val)));
6168 operands[1] = gen_lowpart (HImode, reg);
6169 }
6170 }
6171 }
6172 else /* TARGET_THUMB1 */
cffb2a26 6173 {
e1ba4a27 6174 if (can_create_pseudo_p ())
cffb2a26 6175 {
0438d37f 6176 if (CONST_INT_P (operands[1]))
6cffc037 6177 {
6178 rtx reg = gen_reg_rtx (SImode);
6179
6180 emit_insn (gen_movsi (reg, operands[1]));
6181 operands[1] = gen_lowpart (HImode, reg);
6182 }
cffb2a26 6183
6184 /* ??? We shouldn't really get invalid addresses here, but this can
215b30b3 6185 happen if we are passed a SP (never OK for HImode/QImode) or
bc409cb4 6186 virtual register (also rejected as illegitimate for HImode/QImode)
6187 relative address. */
cffb2a26 6188 /* ??? This should perhaps be fixed elsewhere, for instance, in
6189 fixup_stack_1, by checking for other kinds of invalid addresses,
6190 e.g. a bare reference to a virtual register. This may confuse the
6191 alpha though, which must handle this case differently. */
0438d37f 6192 if (MEM_P (operands[0])
215b30b3 6193 && !memory_address_p (GET_MODE (operands[0]),
6194 XEXP (operands[0], 0)))
537ffcfc 6195 operands[0]
6196 = replace_equiv_address (operands[0],
6197 copy_to_reg (XEXP (operands[0], 0)));
cffb2a26 6198
0438d37f 6199 if (MEM_P (operands[1])
215b30b3 6200 && !memory_address_p (GET_MODE (operands[1]),
6201 XEXP (operands[1], 0)))
537ffcfc 6202 operands[1]
6203 = replace_equiv_address (operands[1],
6204 copy_to_reg (XEXP (operands[1], 0)));
6cffc037 6205
0438d37f 6206 if (MEM_P (operands[1]) && optimize > 0)
6cffc037 6207 {
6208 rtx reg = gen_reg_rtx (SImode);
6209
6210 emit_insn (gen_zero_extendhisi2 (reg, operands[1]));
6211 operands[1] = gen_lowpart (HImode, reg);
6212 }
6213
0438d37f 6214 if (MEM_P (operands[0]))
6cffc037 6215 operands[1] = force_reg (HImode, operands[1]);
cffb2a26 6216 }
0438d37f 6217 else if (CONST_INT_P (operands[1])
234f6557 6218 && !satisfies_constraint_I (operands[1]))
cffb2a26 6219 {
6cffc037 6220 /* Handle loading a large integer during reload. */
6221
cffb2a26 6222 /* Writing a constant to memory needs a scratch, which should
6223 be handled with SECONDARY_RELOADs. */
0438d37f 6224 gcc_assert (REG_P (operands[0]));
cffb2a26 6225
1a83b3ff 6226 operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
cffb2a26 6227 emit_insn (gen_movsi (operands[0], operands[1]));
6228 DONE;
6229 }
b11cae9e 6230 }
cffb2a26 6231 "
6232)
6233
25f7a26e 6234(define_expand "movhi_bytes"
eab14235 6235 [(set (match_dup 2) (zero_extend:SI (match_operand:HI 1 "" "")))
25f7a26e 6236 (set (match_dup 3)
eab14235 6237 (zero_extend:SI (match_dup 6)))
25f7a26e 6238 (set (match_operand:SI 0 "" "")
6239 (ior:SI (ashift:SI (match_dup 4) (const_int 8)) (match_dup 5)))]
cffb2a26 6240 "TARGET_ARM"
25f7a26e 6241 "
215b30b3 6242 {
6243 rtx mem1, mem2;
6244 rtx addr = copy_to_mode_reg (SImode, XEXP (operands[1], 0));
6245
788fcce0 6246 mem1 = change_address (operands[1], QImode, addr);
29c05e22 6247 mem2 = change_address (operands[1], QImode,
6248 plus_constant (Pmode, addr, 1));
215b30b3 6249 operands[0] = gen_lowpart (SImode, operands[0]);
6250 operands[1] = mem1;
6251 operands[2] = gen_reg_rtx (SImode);
6252 operands[3] = gen_reg_rtx (SImode);
6253 operands[6] = mem2;
25f7a26e 6254
215b30b3 6255 if (BYTES_BIG_ENDIAN)
6256 {
6257 operands[4] = operands[2];
6258 operands[5] = operands[3];
6259 }
6260 else
6261 {
6262 operands[4] = operands[3];
6263 operands[5] = operands[2];
6264 }
6265 }"
6266)
25f7a26e 6267
c7597b5d 6268(define_expand "movhi_bigend"
6269 [(set (match_dup 2)
6270 (rotate:SI (subreg:SI (match_operand:HI 1 "memory_operand" "") 0)
6271 (const_int 16)))
6272 (set (match_dup 3)
6273 (ashiftrt:SI (match_dup 2) (const_int 16)))
6274 (set (match_operand:HI 0 "s_register_operand" "")
787f8210 6275 (match_dup 4))]
cffb2a26 6276 "TARGET_ARM"
c7597b5d 6277 "
6278 operands[2] = gen_reg_rtx (SImode);
6279 operands[3] = gen_reg_rtx (SImode);
787f8210 6280 operands[4] = gen_lowpart (HImode, operands[3]);
215b30b3 6281 "
6282)
b11cae9e 6283
a2f10574 6284;; Pattern to recognize insn generated default case above
f7fbdd4a 6285(define_insn "*movhi_insn_arch4"
e4585731 6286 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m,r")
6287 (match_operand:HI 1 "general_operand" "rIk,K,n,r,mi"))]
cffb2a26 6288 "TARGET_ARM
6289 && arm_arch4
85e02ccb 6290 && (register_operand (operands[0], HImode)
6291 || register_operand (operands[1], HImode))"
f7fbdd4a 6292 "@
6293 mov%?\\t%0, %1\\t%@ movhi
6294 mvn%?\\t%0, #%B1\\t%@ movhi
b1c1a101 6295 movw%?\\t%0, %L1\\t%@ movhi
25f905c2 6296 str%(h%)\\t%1, %0\\t%@ movhi
6297 ldr%(h%)\\t%0, %1\\t%@ movhi"
65f68e55 6298 [(set_attr "predicable" "yes")
e4585731 6299 (set_attr "pool_range" "*,*,*,*,256")
6300 (set_attr "neg_pool_range" "*,*,*,*,244")
6301 (set_attr "arch" "*,*,v6t2,*,*")
65f68e55 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")
e4585731 6307 (const_string "mov_imm")
65f68e55 6308 (const_string "store1")
6309 (const_string "load1")])]
cffb2a26 6310)
f7fbdd4a 6311
f7fbdd4a 6312(define_insn "*movhi_bytes"
65f68e55 6313 [(set (match_operand:HI 0 "s_register_operand" "=r,r,r")
5fd254ed 6314 (match_operand:HI 1 "arm_rhs_operand" "I,rk,K"))]
c1a66faf 6315 "TARGET_ARM"
25f7a26e 6316 "@
65f68e55 6317 mov%?\\t%0, %1\\t%@ movhi
25f7a26e 6318 mov%?\\t%0, %1\\t%@ movhi
0d66636f 6319 mvn%?\\t%0, #%B1\\t%@ movhi"
d2a518d1 6320 [(set_attr "predicable" "yes")
1aed5204 6321 (set_attr "type" "mov_imm,mov_reg,mvn_imm")]
0d66636f 6322)
cffb2a26 6323
bc5c7e08 6324;; We use a DImode scratch because we may occasionally need an additional
6325;; temporary if the address isn't offsettable -- push_reload doesn't seem
6326;; to take any notice of the "o" constraints on reload_memory_operand operand.
d3373b54 6327(define_expand "reload_outhi"
cffb2a26 6328 [(parallel [(match_operand:HI 0 "arm_reload_memory_operand" "=o")
215b30b3 6329 (match_operand:HI 1 "s_register_operand" "r")
6330 (match_operand:DI 2 "s_register_operand" "=&l")])]
cffb2a26 6331 "TARGET_EITHER"
6332 "if (TARGET_ARM)
6333 arm_reload_out_hi (operands);
6334 else
6335 thumb_reload_out_hi (operands);
d3373b54 6336 DONE;
cffb2a26 6337 "
6338)
d3373b54 6339
25f7a26e 6340(define_expand "reload_inhi"
6341 [(parallel [(match_operand:HI 0 "s_register_operand" "=r")
cffb2a26 6342 (match_operand:HI 1 "arm_reload_memory_operand" "o")
bc5c7e08 6343 (match_operand:DI 2 "s_register_operand" "=&r")])]
c1a66faf 6344 "TARGET_EITHER"
25f7a26e 6345 "
cffb2a26 6346 if (TARGET_ARM)
6347 arm_reload_in_hi (operands);
6348 else
6349 thumb_reload_out_hi (operands);
25f7a26e 6350 DONE;
6351")
6352
9c08d1fa 6353(define_expand "movqi"
6354 [(set (match_operand:QI 0 "general_operand" "")
6355 (match_operand:QI 1 "general_operand" ""))]
cffb2a26 6356 "TARGET_EITHER"
9c08d1fa 6357 "
6cffc037 6358 /* Everything except mem = const or mem = mem can be done easily */
0045890a 6359
e1ba4a27 6360 if (can_create_pseudo_p ())
cffb2a26 6361 {
0438d37f 6362 if (CONST_INT_P (operands[1]))
6cffc037 6363 {
6364 rtx reg = gen_reg_rtx (SImode);
6365
03770691 6366 /* For thumb we want an unsigned immediate, then we are more likely
6367 to be able to use a movs insn. */
6368 if (TARGET_THUMB)
6369 operands[1] = GEN_INT (INTVAL (operands[1]) & 255);
6370
6cffc037 6371 emit_insn (gen_movsi (reg, operands[1]));
6372 operands[1] = gen_lowpart (QImode, reg);
6373 }
cffb2a26 6374
6cffc037 6375 if (TARGET_THUMB)
6376 {
cffb2a26 6377 /* ??? We shouldn't really get invalid addresses here, but this can
215b30b3 6378 happen if we are passed a SP (never OK for HImode/QImode) or
bc409cb4 6379 virtual register (also rejected as illegitimate for HImode/QImode)
6380 relative address. */
cffb2a26 6381 /* ??? This should perhaps be fixed elsewhere, for instance, in
6382 fixup_stack_1, by checking for other kinds of invalid addresses,
6383 e.g. a bare reference to a virtual register. This may confuse the
6384 alpha though, which must handle this case differently. */
0438d37f 6385 if (MEM_P (operands[0])
215b30b3 6386 && !memory_address_p (GET_MODE (operands[0]),
cffb2a26 6387 XEXP (operands[0], 0)))
537ffcfc 6388 operands[0]
6389 = replace_equiv_address (operands[0],
6390 copy_to_reg (XEXP (operands[0], 0)));
0438d37f 6391 if (MEM_P (operands[1])
215b30b3 6392 && !memory_address_p (GET_MODE (operands[1]),
cffb2a26 6393 XEXP (operands[1], 0)))
537ffcfc 6394 operands[1]
6395 = replace_equiv_address (operands[1],
6396 copy_to_reg (XEXP (operands[1], 0)));
6cffc037 6397 }
6398
0438d37f 6399 if (MEM_P (operands[1]) && optimize > 0)
6cffc037 6400 {
6401 rtx reg = gen_reg_rtx (SImode);
6402
6403 emit_insn (gen_zero_extendqisi2 (reg, operands[1]));
6404 operands[1] = gen_lowpart (QImode, reg);
6405 }
6406
0438d37f 6407 if (MEM_P (operands[0]))
6cffc037 6408 operands[1] = force_reg (QImode, operands[1]);
6409 }
6410 else if (TARGET_THUMB
0438d37f 6411 && CONST_INT_P (operands[1])
234f6557 6412 && !satisfies_constraint_I (operands[1]))
6cffc037 6413 {
674a8f0b 6414 /* Handle loading a large integer during reload. */
cffb2a26 6415
6cffc037 6416 /* Writing a constant to memory needs a scratch, which should
6417 be handled with SECONDARY_RELOADs. */
0438d37f 6418 gcc_assert (REG_P (operands[0]));
6cffc037 6419
6420 operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
6421 emit_insn (gen_movsi (operands[0], operands[1]));
6422 DONE;
cffb2a26 6423 }
6424 "
6425)
b11cae9e 6426
cffb2a26 6427(define_insn "*arm_movqi_insn"
fd711051 6428 [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,r,l,r,l,Uu,r,m")
490f62ca 6429 (match_operand:QI 1 "general_operand" "rk,rk,I,Py,K,Uu,l,Uh,r"))]
25f905c2 6430 "TARGET_32BIT
cffb2a26 6431 && ( register_operand (operands[0], QImode)
6432 || register_operand (operands[1], QImode))"
5565501b 6433 "@
fd711051 6434 mov%?\\t%0, %1
6435 mov%?\\t%0, %1
65f68e55 6436 mov%?\\t%0, %1
5565501b 6437 mov%?\\t%0, %1
6438 mvn%?\\t%0, #%B1
25f905c2 6439 ldr%(b%)\\t%0, %1
a54e3e7b 6440 str%(b%)\\t%1, %0
6441 ldr%(b%)\\t%0, %1
25f905c2 6442 str%(b%)\\t%1, %0"
1aed5204 6443 [(set_attr "type" "mov_reg,mov_reg,mov_imm,mov_imm,mvn_imm,load1,store1,load1,store1")
a54e3e7b 6444 (set_attr "predicable" "yes")
fd711051 6445 (set_attr "predicable_short_it" "yes,yes,yes,no,no,no,no,no,no")
6446 (set_attr "arch" "t2,any,any,t2,any,t2,t2,any,any")
6447 (set_attr "length" "2,4,4,2,4,2,2,4,4")]
cffb2a26 6448)
6449
9b8516be 6450;; HFmode moves
6451(define_expand "movhf"
6452 [(set (match_operand:HF 0 "general_operand" "")
6453 (match_operand:HF 1 "general_operand" ""))]
6454 "TARGET_EITHER"
6455 "
6456 if (TARGET_32BIT)
6457 {
0438d37f 6458 if (MEM_P (operands[0]))
9b8516be 6459 operands[1] = force_reg (HFmode, operands[1]);
6460 }
6461 else /* TARGET_THUMB1 */
6462 {
6463 if (can_create_pseudo_p ())
6464 {
0438d37f 6465 if (!REG_P (operands[0]))
9b8516be 6466 operands[1] = force_reg (HFmode, operands[1]);
6467 }
6468 }
6469 "
6470)
6471
6472(define_insn "*arm32_movhf"
6473 [(set (match_operand:HF 0 "nonimmediate_operand" "=r,m,r,r")
6474 (match_operand:HF 1 "general_operand" " m,r,r,F"))]
7c36fe71 6475 "TARGET_32BIT && !(TARGET_HARD_FLOAT && TARGET_FP16) && !arm_restrict_it
9b8516be 6476 && ( s_register_operand (operands[0], HFmode)
6477 || s_register_operand (operands[1], HFmode))"
6478 "*
6479 switch (which_alternative)
6480 {
6481 case 0: /* ARM register from memory */
6482 return \"ldr%(h%)\\t%0, %1\\t%@ __fp16\";
6483 case 1: /* memory from ARM register */
6484 return \"str%(h%)\\t%1, %0\\t%@ __fp16\";
6485 case 2: /* ARM register from ARM register */
6486 return \"mov%?\\t%0, %1\\t%@ __fp16\";
6487 case 3: /* ARM register from constant */
6488 {
6489 REAL_VALUE_TYPE r;
6490 long bits;
6491 rtx ops[4];
6492
6493 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
6494 bits = real_to_target (NULL, &r, HFmode);
6495 ops[0] = operands[0];
6496 ops[1] = GEN_INT (bits);
6497 ops[2] = GEN_INT (bits & 0xff00);
6498 ops[3] = GEN_INT (bits & 0x00ff);
6499
6500 if (arm_arch_thumb2)
6501 output_asm_insn (\"movw%?\\t%0, %1\", ops);
6502 else
6503 output_asm_insn (\"mov%?\\t%0, %2\;orr%?\\t%0, %0, %3\", ops);
6504 return \"\";
6505 }
6506 default:
6507 gcc_unreachable ();
6508 }
6509 "
6510 [(set_attr "conds" "unconditional")
ad4fc3c0 6511 (set_attr "type" "load1,store1,mov_reg,multiple")
9b8516be 6512 (set_attr "length" "4,4,4,8")
d2a518d1 6513 (set_attr "predicable" "yes")]
9b8516be 6514)
6515
87b22bf7 6516(define_expand "movsf"
6517 [(set (match_operand:SF 0 "general_operand" "")
6518 (match_operand:SF 1 "general_operand" ""))]
cffb2a26 6519 "TARGET_EITHER"
87b22bf7 6520 "
25f905c2 6521 if (TARGET_32BIT)
cffb2a26 6522 {
0438d37f 6523 if (MEM_P (operands[0]))
cffb2a26 6524 operands[1] = force_reg (SFmode, operands[1]);
6525 }
25f905c2 6526 else /* TARGET_THUMB1 */
cffb2a26 6527 {
e1ba4a27 6528 if (can_create_pseudo_p ())
cffb2a26 6529 {
0438d37f 6530 if (!REG_P (operands[0]))
cffb2a26 6531 operands[1] = force_reg (SFmode, operands[1]);
6532 }
6533 }
6534 "
6535)
6536
03d440a6 6537;; Transform a floating-point move of a constant into a core register into
6538;; an SImode operation.
cffb2a26 6539(define_split
03d440a6 6540 [(set (match_operand:SF 0 "arm_general_register_operand" "")
cffb2a26 6541 (match_operand:SF 1 "immediate_operand" ""))]
339034d0 6542 "TARGET_EITHER
cffb2a26 6543 && reload_completed
0438d37f 6544 && CONST_DOUBLE_P (operands[1])"
cffb2a26 6545 [(set (match_dup 2) (match_dup 3))]
6546 "
6547 operands[2] = gen_lowpart (SImode, operands[0]);
6548 operands[3] = gen_lowpart (SImode, operands[1]);
6549 if (operands[2] == 0 || operands[3] == 0)
6550 FAIL;
215b30b3 6551 "
6552)
87b22bf7 6553
cffb2a26 6554(define_insn "*arm_movsf_soft_insn"
6555 [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,m")
6556 (match_operand:SF 1 "general_operand" "r,mE,r"))]
cde1623a 6557 "TARGET_32BIT
cffb2a26 6558 && TARGET_SOFT_FLOAT
0438d37f 6559 && (!MEM_P (operands[0])
215b30b3 6560 || register_operand (operands[1], SFmode))"
9a1112d7 6561 "@
6562 mov%?\\t%0, %1
6563 ldr%?\\t%0, %1\\t%@ float
6564 str%?\\t%1, %0\\t%@ float"
cde1623a 6565 [(set_attr "predicable" "yes")
7c36fe71 6566 (set_attr "predicable_short_it" "no")
1aed5204 6567 (set_attr "type" "mov_reg,load1,store1")
42e1de19 6568 (set_attr "arm_pool_range" "*,4096,*")
6569 (set_attr "thumb2_pool_range" "*,4094,*")
cde1623a 6570 (set_attr "arm_neg_pool_range" "*,4084,*")
6571 (set_attr "thumb2_neg_pool_range" "*,0,*")]
cffb2a26 6572)
6573
9c08d1fa 6574(define_expand "movdf"
87b22bf7 6575 [(set (match_operand:DF 0 "general_operand" "")
6576 (match_operand:DF 1 "general_operand" ""))]
cffb2a26 6577 "TARGET_EITHER"
9c08d1fa 6578 "
25f905c2 6579 if (TARGET_32BIT)
cffb2a26 6580 {
0438d37f 6581 if (MEM_P (operands[0]))
cffb2a26 6582 operands[1] = force_reg (DFmode, operands[1]);
6583 }
6584 else /* TARGET_THUMB */
6585 {
e1ba4a27 6586 if (can_create_pseudo_p ())
cffb2a26 6587 {
0438d37f 6588 if (!REG_P (operands[0]))
cffb2a26 6589 operands[1] = force_reg (DFmode, operands[1]);
6590 }
6591 }
6592 "
6593)
b11cae9e 6594
9c08d1fa 6595;; Reloading a df mode value stored in integer regs to memory can require a
6596;; scratch reg.
6597(define_expand "reload_outdf"
cffb2a26 6598 [(match_operand:DF 0 "arm_reload_memory_operand" "=o")
87b22bf7 6599 (match_operand:DF 1 "s_register_operand" "r")
6600 (match_operand:SI 2 "s_register_operand" "=&r")]
06adefdc 6601 "TARGET_THUMB2"
87b22bf7 6602 "
215b30b3 6603 {
6604 enum rtx_code code = GET_CODE (XEXP (operands[0], 0));
f7fbdd4a 6605
215b30b3 6606 if (code == REG)
6607 operands[2] = XEXP (operands[0], 0);
6608 else if (code == POST_INC || code == PRE_DEC)
6609 {
6610 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
6611 operands[1] = gen_rtx_SUBREG (DImode, operands[1], 0);
6612 emit_insn (gen_movdi (operands[0], operands[1]));
6613 DONE;
6614 }
6615 else if (code == PRE_INC)
6616 {
6617 rtx reg = XEXP (XEXP (operands[0], 0), 0);
f7fbdd4a 6618
215b30b3 6619 emit_insn (gen_addsi3 (reg, reg, GEN_INT (8)));
6620 operands[2] = reg;
6621 }
6622 else if (code == POST_DEC)
6623 operands[2] = XEXP (XEXP (operands[0], 0), 0);
6624 else
6625 emit_insn (gen_addsi3 (operands[2], XEXP (XEXP (operands[0], 0), 0),
6626 XEXP (XEXP (operands[0], 0), 1)));
f7fbdd4a 6627
788fcce0 6628 emit_insn (gen_rtx_SET (VOIDmode,
6629 replace_equiv_address (operands[0], operands[2]),
215b30b3 6630 operands[1]));
f7fbdd4a 6631
215b30b3 6632 if (code == POST_DEC)
6633 emit_insn (gen_addsi3 (operands[2], operands[2], GEN_INT (-8)));
6634
6635 DONE;
6636 }"
6637)
9c08d1fa 6638
9a1112d7 6639(define_insn "*movdf_soft_insn"
353cf59a 6640 [(set (match_operand:DF 0 "nonimmediate_soft_df_operand" "=r,r,r,q,m")
6641 (match_operand:DF 1 "soft_df_operand" "rDa,Db,Dc,mF,q"))]
cde1623a 6642 "TARGET_32BIT && TARGET_SOFT_FLOAT
b2778788 6643 && ( register_operand (operands[0], DFmode)
6644 || register_operand (operands[1], DFmode))"
d51f92df 6645 "*
6646 switch (which_alternative)
6647 {
6648 case 0:
6649 case 1:
6650 case 2:
6651 return \"#\";
6652 default:
26ff80c0 6653 return output_move_double (operands, true, NULL);
d51f92df 6654 }
6655 "
359a6e9f 6656 [(set_attr "length" "8,12,16,8,8")
1b7da4ac 6657 (set_attr "type" "multiple,multiple,multiple,load2,store2")
42e1de19 6658 (set_attr "arm_pool_range" "*,*,*,1020,*")
6659 (set_attr "thumb2_pool_range" "*,*,*,1018,*")
8848d797 6660 (set_attr "arm_neg_pool_range" "*,*,*,1004,*")
cde1623a 6661 (set_attr "thumb2_neg_pool_range" "*,*,*,0,*")]
cffb2a26 6662)
b11cae9e 6663\f
b11cae9e 6664
9c08d1fa 6665;; load- and store-multiple insns
6666;; The arm can load/store any set of registers, provided that they are in
320ea44d 6667;; ascending order, but these expanders assume a contiguous set.
b11cae9e 6668
9c08d1fa 6669(define_expand "load_multiple"
6670 [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
6671 (match_operand:SI 1 "" ""))
6672 (use (match_operand:SI 2 "" ""))])]
25f905c2 6673 "TARGET_32BIT"
9580c25f 6674{
6675 HOST_WIDE_INT offset = 0;
6676
bd5b4116 6677 /* Support only fixed point registers. */
0438d37f 6678 if (!CONST_INT_P (operands[2])
6e628811 6679 || INTVAL (operands[2]) > MAX_LDM_STM_OPS
9c08d1fa 6680 || INTVAL (operands[2]) < 2
0438d37f 6681 || !MEM_P (operands[1])
6682 || !REG_P (operands[0])
bd5b4116 6683 || REGNO (operands[0]) > (LAST_ARM_REGNUM - 1)
6684 || REGNO (operands[0]) + INTVAL (operands[2]) > LAST_ARM_REGNUM)
9c08d1fa 6685 FAIL;
6686
6687 operands[3]
320ea44d 6688 = arm_gen_load_multiple (arm_regs_in_sequence + REGNO (operands[0]),
6689 INTVAL (operands[2]),
f082f1c4 6690 force_reg (SImode, XEXP (operands[1], 0)),
320ea44d 6691 FALSE, operands[1], &offset);
9580c25f 6692})
b11cae9e 6693
9c08d1fa 6694(define_expand "store_multiple"
6695 [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
6696 (match_operand:SI 1 "" ""))
6697 (use (match_operand:SI 2 "" ""))])]
25f905c2 6698 "TARGET_32BIT"
9580c25f 6699{
6700 HOST_WIDE_INT offset = 0;
6701
674a8f0b 6702 /* Support only fixed point registers. */
0438d37f 6703 if (!CONST_INT_P (operands[2])
6e628811 6704 || INTVAL (operands[2]) > MAX_LDM_STM_OPS
9c08d1fa 6705 || INTVAL (operands[2]) < 2
0438d37f 6706 || !REG_P (operands[1])
6707 || !MEM_P (operands[0])
bd5b4116 6708 || REGNO (operands[1]) > (LAST_ARM_REGNUM - 1)
6709 || REGNO (operands[1]) + INTVAL (operands[2]) > LAST_ARM_REGNUM)
9c08d1fa 6710 FAIL;
6711
6712 operands[3]
320ea44d 6713 = arm_gen_store_multiple (arm_regs_in_sequence + REGNO (operands[1]),
6714 INTVAL (operands[2]),
f082f1c4 6715 force_reg (SImode, XEXP (operands[0], 0)),
320ea44d 6716 FALSE, operands[0], &offset);
9580c25f 6717})
b11cae9e 6718
9c08d1fa 6719
e34ebfca 6720(define_expand "setmemsi"
6721 [(match_operand:BLK 0 "general_operand" "")
6722 (match_operand:SI 1 "const_int_operand" "")
6723 (match_operand:SI 2 "const_int_operand" "")
6724 (match_operand:SI 3 "const_int_operand" "")]
6725 "TARGET_32BIT"
6726{
6727 if (arm_gen_setmem (operands))
6728 DONE;
6729
6730 FAIL;
6731})
6732
6733
9c08d1fa 6734;; Move a block of memory if it is word aligned and MORE than 2 words long.
6735;; We could let this apply for blocks of less than this, but it clobbers so
6736;; many registers that there is then probably a better way.
6737
008c057d 6738(define_expand "movmemqi"
34191dd1 6739 [(match_operand:BLK 0 "general_operand" "")
6740 (match_operand:BLK 1 "general_operand" "")
6741 (match_operand:SI 2 "const_int_operand" "")
6742 (match_operand:SI 3 "const_int_operand" "")]
ae51a965 6743 ""
9c08d1fa 6744 "
25f905c2 6745 if (TARGET_32BIT)
cffb2a26 6746 {
ae51a965 6747 if (TARGET_LDRD && current_tune->prefer_ldrd_strd
6748 && !optimize_function_for_size_p (cfun))
6749 {
6750 if (gen_movmem_ldrd_strd (operands))
6751 DONE;
6752 FAIL;
6753 }
6754
008c057d 6755 if (arm_gen_movmemqi (operands))
cffb2a26 6756 DONE;
6757 FAIL;
6758 }
25f905c2 6759 else /* TARGET_THUMB1 */
cffb2a26 6760 {
6761 if ( INTVAL (operands[3]) != 4
6762 || INTVAL (operands[2]) > 48)
6763 FAIL;
6764
008c057d 6765 thumb_expand_movmemqi (operands);
cffb2a26 6766 DONE;
6767 }
6768 "
6769)
9c08d1fa 6770\f
b11cae9e 6771
341940e8 6772;; Compare & branch insns
8d232dc7 6773;; The range calculations are based as follows:
341940e8 6774;; For forward branches, the address calculation returns the address of
6775;; the next instruction. This is 2 beyond the branch instruction.
6776;; For backward branches, the address calculation returns the address of
6777;; the first instruction in this pattern (cmp). This is 2 before the branch
6778;; instruction for the shortest sequence, and 4 before the branch instruction
6779;; if we have to jump around an unconditional branch.
6780;; To the basic branch range the PC offset must be added (this is +4).
6781;; So for forward branches we have
6782;; (pos_range - pos_base_offs + pc_offs) = (pos_range - 2 + 4).
6783;; And for backward branches we have
6784;; (neg_range - neg_base_offs + pc_offs) = (neg_range - (-2 or -4) + 4).
6785;;
6786;; For a 'b' pos_range = 2046, neg_range = -2048 giving (-2040->2048).
6787;; For a 'b<cond>' pos_range = 254, neg_range = -256 giving (-250 ->256).
cffb2a26 6788
aeac46d4 6789(define_expand "cbranchsi4"
6790 [(set (pc) (if_then_else
aa06947a 6791 (match_operator 0 "expandable_comparison_operator"
aeac46d4 6792 [(match_operand:SI 1 "s_register_operand" "")
6793 (match_operand:SI 2 "nonmemory_operand" "")])
6794 (label_ref (match_operand 3 "" ""))
6795 (pc)))]
f9aa4160 6796 "TARGET_EITHER"
aeac46d4 6797 "
74f4459c 6798 if (!TARGET_THUMB1)
6799 {
f9aa4160 6800 if (!arm_validize_comparison (&operands[0], &operands[1], &operands[2]))
6801 FAIL;
74f4459c 6802 emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
6803 operands[3]));
6804 DONE;
6805 }
25f905c2 6806 if (thumb1_cmpneg_operand (operands[2], SImode))
aeac46d4 6807 {
6808 emit_jump_insn (gen_cbranchsi4_scratch (NULL, operands[1], operands[2],
6809 operands[3], operands[0]));
6810 DONE;
6811 }
25f905c2 6812 if (!thumb1_cmp_operand (operands[2], SImode))
aeac46d4 6813 operands[2] = force_reg (SImode, operands[2]);
6814 ")
6815
74f4459c 6816(define_expand "cbranchsf4"
6817 [(set (pc) (if_then_else
aa06947a 6818 (match_operator 0 "expandable_comparison_operator"
74f4459c 6819 [(match_operand:SF 1 "s_register_operand" "")
6820 (match_operand:SF 2 "arm_float_compare_operand" "")])
6821 (label_ref (match_operand 3 "" ""))
6822 (pc)))]
6823 "TARGET_32BIT && TARGET_HARD_FLOAT"
6824 "emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
6825 operands[3])); DONE;"
6826)
6827
6828(define_expand "cbranchdf4"
6829 [(set (pc) (if_then_else
aa06947a 6830 (match_operator 0 "expandable_comparison_operator"
74f4459c 6831 [(match_operand:DF 1 "s_register_operand" "")
6832 (match_operand:DF 2 "arm_float_compare_operand" "")])
6833 (label_ref (match_operand 3 "" ""))
6834 (pc)))]
a50d7267 6835 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
74f4459c 6836 "emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
6837 operands[3])); DONE;"
6838)
6839
74f4459c 6840(define_expand "cbranchdi4"
6841 [(set (pc) (if_then_else
aa06947a 6842 (match_operator 0 "expandable_comparison_operator"
b8eae306 6843 [(match_operand:DI 1 "s_register_operand" "")
a8045a4f 6844 (match_operand:DI 2 "cmpdi_operand" "")])
74f4459c 6845 (label_ref (match_operand 3 "" ""))
6846 (pc)))]
a8045a4f 6847 "TARGET_32BIT"
6848 "{
0438d37f 6849 if (!arm_validize_comparison (&operands[0], &operands[1], &operands[2]))
f9aa4160 6850 FAIL;
6851 emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
a8045a4f 6852 operands[3]));
6853 DONE;
6854 }"
74f4459c 6855)
6856
9c08d1fa 6857;; Comparison and test insns
6858
cffb2a26 6859(define_insn "*arm_cmpsi_insn"
bd5b4116 6860 [(set (reg:CC CC_REGNUM)
f9f234ec 6861 (compare:CC (match_operand:SI 0 "s_register_operand" "l,r,r,r,r")
6862 (match_operand:SI 1 "arm_add_operand" "Py,r,r,I,L")))]
25f905c2 6863 "TARGET_32BIT"
5565501b 6864 "@
a6864a24 6865 cmp%?\\t%0, %1
6866 cmp%?\\t%0, %1
aea4c774 6867 cmp%?\\t%0, %1
f9f234ec 6868 cmp%?\\t%0, %1
aea4c774 6869 cmn%?\\t%0, #%n1"
a6864a24 6870 [(set_attr "conds" "set")
f9f234ec 6871 (set_attr "arch" "t2,t2,any,any,any")
6872 (set_attr "length" "2,2,4,4,4")
65f68e55 6873 (set_attr "predicable" "yes")
f9f234ec 6874 (set_attr "predicable_short_it" "yes,yes,yes,no,no")
112eda6f 6875 (set_attr "type" "alus_imm,alus_sreg,alus_sreg,alus_imm,alus_imm")]
cffb2a26 6876)
b11cae9e 6877
d5d4dc8d 6878(define_insn "*cmpsi_shiftsi"
bd5b4116 6879 [(set (reg:CC CC_REGNUM)
d82e788e 6880 (compare:CC (match_operand:SI 0 "s_register_operand" "r,r,r")
cffb2a26 6881 (match_operator:SI 3 "shift_operator"
d82e788e 6882 [(match_operand:SI 1 "s_register_operand" "r,r,r")
6883 (match_operand:SI 2 "shift_amount_operand" "M,r,M")])))]
d5d4dc8d 6884 "TARGET_32BIT"
f9f234ec 6885 "cmp\\t%0, %1%S3"
344495ea 6886 [(set_attr "conds" "set")
331beb1a 6887 (set_attr "shift" "1")
d82e788e 6888 (set_attr "arch" "32,a,a")
6889 (set_attr "type" "alus_shift_imm,alu_shift_reg,alus_shift_imm")])
b11cae9e 6890
d5d4dc8d 6891(define_insn "*cmpsi_shiftsi_swp"
bd5b4116 6892 [(set (reg:CC_SWP CC_REGNUM)
aea4c774 6893 (compare:CC_SWP (match_operator:SI 3 "shift_operator"
d82e788e 6894 [(match_operand:SI 1 "s_register_operand" "r,r,r")
6895 (match_operand:SI 2 "shift_amount_operand" "M,r,M")])
6896 (match_operand:SI 0 "s_register_operand" "r,r,r")))]
d5d4dc8d 6897 "TARGET_32BIT"
aea4c774 6898 "cmp%?\\t%0, %1%S3"
344495ea 6899 [(set_attr "conds" "set")
331beb1a 6900 (set_attr "shift" "1")
d82e788e 6901 (set_attr "arch" "32,a,a")
6902 (set_attr "type" "alus_shift_imm,alu_shift_reg,alus_shift_imm")])
b11cae9e 6903
25f905c2 6904(define_insn "*arm_cmpsi_negshiftsi_si"
aed179ae 6905 [(set (reg:CC_Z CC_REGNUM)
6906 (compare:CC_Z
6907 (neg:SI (match_operator:SI 1 "shift_operator"
6908 [(match_operand:SI 2 "s_register_operand" "r")
6909 (match_operand:SI 3 "reg_or_int_operand" "rM")]))
6910 (match_operand:SI 0 "s_register_operand" "r")))]
cffb2a26 6911 "TARGET_ARM"
aed179ae 6912 "cmn%?\\t%0, %2%S1"
344495ea 6913 [(set_attr "conds" "set")
aed179ae 6914 (set (attr "type") (if_then_else (match_operand 3 "const_int_operand" "")
d82e788e 6915 (const_string "alus_shift_imm")
6916 (const_string "alus_shift_reg")))
596e5e8f 6917 (set_attr "predicable" "yes")]
0d66636f 6918)
b11cae9e 6919
a8045a4f 6920;; DImode comparisons. The generic code generates branches that
6921;; if-conversion can not reduce to a conditional compare, so we do
6922;; that directly.
6923
ba6a3b2f 6924(define_insn_and_split "*arm_cmpdi_insn"
a8045a4f 6925 [(set (reg:CC_NCV CC_REGNUM)
6926 (compare:CC_NCV (match_operand:DI 0 "s_register_operand" "r")
6927 (match_operand:DI 1 "arm_di_operand" "rDi")))
6928 (clobber (match_scratch:SI 2 "=r"))]
b805622c 6929 "TARGET_32BIT"
ba6a3b2f 6930 "#" ; "cmp\\t%Q0, %Q1\;sbcs\\t%2, %R0, %R1"
6931 "&& reload_completed"
6932 [(set (reg:CC CC_REGNUM)
6933 (compare:CC (match_dup 0) (match_dup 1)))
6934 (parallel [(set (reg:CC CC_REGNUM)
6935 (compare:CC (match_dup 3) (match_dup 4)))
6936 (set (match_dup 2)
6937 (minus:SI (match_dup 5)
6938 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))])]
6939 {
6940 operands[3] = gen_highpart (SImode, operands[0]);
6941 operands[0] = gen_lowpart (SImode, operands[0]);
6942 if (CONST_INT_P (operands[1]))
6943 {
6944 operands[4] = GEN_INT (~INTVAL (gen_highpart_mode (SImode,
6945 DImode,
6946 operands[1])));
6947 operands[5] = gen_rtx_PLUS (SImode, operands[3], operands[4]);
6948 }
6949 else
6950 {
6951 operands[4] = gen_highpart (SImode, operands[1]);
6952 operands[5] = gen_rtx_MINUS (SImode, operands[3], operands[4]);
6953 }
6954 operands[1] = gen_lowpart (SImode, operands[1]);
6955 operands[2] = gen_lowpart (SImode, operands[2]);
6956 }
a8045a4f 6957 [(set_attr "conds" "set")
1b7da4ac 6958 (set_attr "length" "8")
6959 (set_attr "type" "multiple")]
a8045a4f 6960)
6961
ba6a3b2f 6962(define_insn_and_split "*arm_cmpdi_unsigned"
a8045a4f 6963 [(set (reg:CC_CZ CC_REGNUM)
1a86364b 6964 (compare:CC_CZ (match_operand:DI 0 "s_register_operand" "l,r,r,r")
6965 (match_operand:DI 1 "arm_di_operand" "Py,r,Di,rDi")))]
7c36fe71 6966
48a98053 6967 "TARGET_32BIT"
ba6a3b2f 6968 "#" ; "cmp\\t%R0, %R1\;it eq\;cmpeq\\t%Q0, %Q1"
6969 "&& reload_completed"
6970 [(set (reg:CC CC_REGNUM)
6971 (compare:CC (match_dup 2) (match_dup 3)))
6972 (cond_exec (eq:SI (reg:CC CC_REGNUM) (const_int 0))
6973 (set (reg:CC CC_REGNUM)
6974 (compare:CC (match_dup 0) (match_dup 1))))]
6975 {
6976 operands[2] = gen_highpart (SImode, operands[0]);
6977 operands[0] = gen_lowpart (SImode, operands[0]);
6978 if (CONST_INT_P (operands[1]))
6979 operands[3] = gen_highpart_mode (SImode, DImode, operands[1]);
6980 else
6981 operands[3] = gen_highpart (SImode, operands[1]);
6982 operands[1] = gen_lowpart (SImode, operands[1]);
6983 }
a8045a4f 6984 [(set_attr "conds" "set")
1a86364b 6985 (set_attr "enabled_for_depr_it" "yes,yes,no,*")
6986 (set_attr "arch" "t2,t2,t2,a")
6987 (set_attr "length" "6,6,10,8")
1b7da4ac 6988 (set_attr "type" "multiple")]
a8045a4f 6989)
6990
6991(define_insn "*arm_cmpdi_zero"
6992 [(set (reg:CC_Z CC_REGNUM)
6993 (compare:CC_Z (match_operand:DI 0 "s_register_operand" "r")
6994 (const_int 0)))
6995 (clobber (match_scratch:SI 1 "=r"))]
6996 "TARGET_32BIT"
6997 "orr%.\\t%1, %Q0, %R0"
1b7da4ac 6998 [(set_attr "conds" "set")
6999 (set_attr "type" "logics_reg")]
a8045a4f 7000)
7001
9c08d1fa 7002; This insn allows redundant compares to be removed by cse, nothing should
7003; ever appear in the output file since (set (reg x) (reg x)) is a no-op that
7004; is deleted later on. The match_dup will match the mode here, so that
7005; mode changes of the condition codes aren't lost by this even though we don't
7006; specify what they are.
7007
8a18b90c 7008(define_insn "*deleted_compare"
9c08d1fa 7009 [(set (match_operand 0 "cc_register" "") (match_dup 0))]
25f905c2 7010 "TARGET_32BIT"
40dbec34 7011 "\\t%@ deleted compare"
cffb2a26 7012 [(set_attr "conds" "set")
1b7da4ac 7013 (set_attr "length" "0")
7014 (set_attr "type" "no_insn")]
cffb2a26 7015)
9c08d1fa 7016
7017\f
7018;; Conditional branch insns
7019
74f4459c 7020(define_expand "cbranch_cc"
9c08d1fa 7021 [(set (pc)
74f4459c 7022 (if_then_else (match_operator 0 "" [(match_operand 1 "" "")
7023 (match_operand 2 "" "")])
7024 (label_ref (match_operand 3 "" ""))
9c08d1fa 7025 (pc)))]
25f905c2 7026 "TARGET_32BIT"
74f4459c 7027 "operands[1] = arm_gen_compare_reg (GET_CODE (operands[0]),
e1b93706 7028 operands[1], operands[2], NULL_RTX);
74f4459c 7029 operands[2] = const0_rtx;"
8fa3ba89 7030)
7031
7032;;
7033;; Patterns to match conditional branch insns.
7034;;
7035
ffcc986d 7036(define_insn "arm_cond_branch"
9c08d1fa 7037 [(set (pc)
8fa3ba89 7038 (if_then_else (match_operator 1 "arm_comparison_operator"
8a18b90c 7039 [(match_operand 2 "cc_register" "") (const_int 0)])
9c08d1fa 7040 (label_ref (match_operand 0 "" ""))
7041 (pc)))]
25f905c2 7042 "TARGET_32BIT"
d75350ce 7043 "*
9c08d1fa 7044 if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
cffb2a26 7045 {
7046 arm_ccfsm_state += 2;
7047 return \"\";
7048 }
e2348bcb 7049 return \"b%d1\\t%l0\";
cffb2a26 7050 "
a2cd141b 7051 [(set_attr "conds" "use")
a6864a24 7052 (set_attr "type" "branch")
7053 (set (attr "length")
7054 (if_then_else
0bf497f5 7055 (and (match_test "TARGET_THUMB2")
a6864a24 7056 (and (ge (minus (match_dup 0) (pc)) (const_int -250))
7057 (le (minus (match_dup 0) (pc)) (const_int 256))))
7058 (const_int 2)
7059 (const_int 4)))]
cffb2a26 7060)
d75350ce 7061
cffb2a26 7062(define_insn "*arm_cond_branch_reversed"
9c08d1fa 7063 [(set (pc)
8fa3ba89 7064 (if_then_else (match_operator 1 "arm_comparison_operator"
8a18b90c 7065 [(match_operand 2 "cc_register" "") (const_int 0)])
9c08d1fa 7066 (pc)
7067 (label_ref (match_operand 0 "" ""))))]
25f905c2 7068 "TARGET_32BIT"
d75350ce 7069 "*
9c08d1fa 7070 if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
cffb2a26 7071 {
7072 arm_ccfsm_state += 2;
7073 return \"\";
7074 }
e2348bcb 7075 return \"b%D1\\t%l0\";
cffb2a26 7076 "
a2cd141b 7077 [(set_attr "conds" "use")
a6864a24 7078 (set_attr "type" "branch")
7079 (set (attr "length")
7080 (if_then_else
0bf497f5 7081 (and (match_test "TARGET_THUMB2")
a6864a24 7082 (and (ge (minus (match_dup 0) (pc)) (const_int -250))
7083 (le (minus (match_dup 0) (pc)) (const_int 256))))
7084 (const_int 2)
7085 (const_int 4)))]
cffb2a26 7086)
7087
b11cae9e 7088\f
9c08d1fa 7089
7090; scc insns
7091
74f4459c 7092(define_expand "cstore_cc"
7db9af5d 7093 [(set (match_operand:SI 0 "s_register_operand" "")
74f4459c 7094 (match_operator:SI 1 "" [(match_operand 2 "" "")
7095 (match_operand 3 "" "")]))]
25f905c2 7096 "TARGET_32BIT"
74f4459c 7097 "operands[2] = arm_gen_compare_reg (GET_CODE (operands[1]),
e1b93706 7098 operands[2], operands[3], NULL_RTX);
74f4459c 7099 operands[3] = const0_rtx;"
8fa3ba89 7100)
7101
a3b84066 7102(define_insn_and_split "*mov_scc"
9c08d1fa 7103 [(set (match_operand:SI 0 "s_register_operand" "=r")
8fa3ba89 7104 (match_operator:SI 1 "arm_comparison_operator"
8a18b90c 7105 [(match_operand 2 "cc_register" "") (const_int 0)]))]
cffb2a26 7106 "TARGET_ARM"
a3b84066 7107 "#" ; "mov%D1\\t%0, #0\;mov%d1\\t%0, #1"
7108 "TARGET_ARM"
7109 [(set (match_dup 0)
7110 (if_then_else:SI (match_dup 1)
7111 (const_int 1)
7112 (const_int 0)))]
7113 ""
cffb2a26 7114 [(set_attr "conds" "use")
1b7da4ac 7115 (set_attr "length" "8")
7116 (set_attr "type" "multiple")]
cffb2a26 7117)
9c08d1fa 7118
a3b84066 7119(define_insn_and_split "*mov_negscc"
9c08d1fa 7120 [(set (match_operand:SI 0 "s_register_operand" "=r")
8fa3ba89 7121 (neg:SI (match_operator:SI 1 "arm_comparison_operator"
8a18b90c 7122 [(match_operand 2 "cc_register" "") (const_int 0)])))]
cffb2a26 7123 "TARGET_ARM"
a3b84066 7124 "#" ; "mov%D1\\t%0, #0\;mvn%d1\\t%0, #0"
7125 "TARGET_ARM"
7126 [(set (match_dup 0)
7127 (if_then_else:SI (match_dup 1)
7128 (match_dup 3)
7129 (const_int 0)))]
7130 {
7131 operands[3] = GEN_INT (~0);
7132 }
cffb2a26 7133 [(set_attr "conds" "use")
1b7da4ac 7134 (set_attr "length" "8")
7135 (set_attr "type" "multiple")]
cffb2a26 7136)
9c08d1fa 7137
a3b84066 7138(define_insn_and_split "*mov_notscc"
9c08d1fa 7139 [(set (match_operand:SI 0 "s_register_operand" "=r")
8fa3ba89 7140 (not:SI (match_operator:SI 1 "arm_comparison_operator"
8a18b90c 7141 [(match_operand 2 "cc_register" "") (const_int 0)])))]
cffb2a26 7142 "TARGET_ARM"
a3b84066 7143 "#" ; "mvn%D1\\t%0, #0\;mvn%d1\\t%0, #1"
7144 "TARGET_ARM"
7145 [(set (match_dup 0)
7146 (if_then_else:SI (match_dup 1)
7147 (match_dup 3)
7148 (match_dup 4)))]
7149 {
7150 operands[3] = GEN_INT (~1);
7151 operands[4] = GEN_INT (~0);
7152 }
cffb2a26 7153 [(set_attr "conds" "use")
1b7da4ac 7154 (set_attr "length" "8")
7155 (set_attr "type" "multiple")]
cffb2a26 7156)
9c08d1fa 7157
595d88b5 7158(define_expand "cstoresi4"
7159 [(set (match_operand:SI 0 "s_register_operand" "")
aa06947a 7160 (match_operator:SI 1 "expandable_comparison_operator"
595d88b5 7161 [(match_operand:SI 2 "s_register_operand" "")
7162 (match_operand:SI 3 "reg_or_int_operand" "")]))]
74f4459c 7163 "TARGET_32BIT || TARGET_THUMB1"
595d88b5 7164 "{
7165 rtx op3, scratch, scratch2;
7166
74f4459c 7167 if (!TARGET_THUMB1)
7168 {
7169 if (!arm_add_operand (operands[3], SImode))
7170 operands[3] = force_reg (SImode, operands[3]);
7171 emit_insn (gen_cstore_cc (operands[0], operands[1],
7172 operands[2], operands[3]));
7173 DONE;
7174 }
7175
595d88b5 7176 if (operands[3] == const0_rtx)
7177 {
7178 switch (GET_CODE (operands[1]))
7179 {
7180 case EQ:
25f905c2 7181 emit_insn (gen_cstoresi_eq0_thumb1 (operands[0], operands[2]));
595d88b5 7182 break;
7183
7184 case NE:
25f905c2 7185 emit_insn (gen_cstoresi_ne0_thumb1 (operands[0], operands[2]));
595d88b5 7186 break;
7187
7188 case LE:
7189 scratch = expand_binop (SImode, add_optab, operands[2], constm1_rtx,
7190 NULL_RTX, 0, OPTAB_WIDEN);
7191 scratch = expand_binop (SImode, ior_optab, operands[2], scratch,
7192 NULL_RTX, 0, OPTAB_WIDEN);
7193 expand_binop (SImode, lshr_optab, scratch, GEN_INT (31),
7194 operands[0], 1, OPTAB_WIDEN);
7195 break;
7196
7197 case GE:
7198 scratch = expand_unop (SImode, one_cmpl_optab, operands[2],
7199 NULL_RTX, 1);
7200 expand_binop (SImode, lshr_optab, scratch, GEN_INT (31),
7201 NULL_RTX, 1, OPTAB_WIDEN);
7202 break;
7203
7204 case GT:
7205 scratch = expand_binop (SImode, ashr_optab, operands[2],
7206 GEN_INT (31), NULL_RTX, 0, OPTAB_WIDEN);
7207 scratch = expand_binop (SImode, sub_optab, scratch, operands[2],
7208 NULL_RTX, 0, OPTAB_WIDEN);
7209 expand_binop (SImode, lshr_optab, scratch, GEN_INT (31), operands[0],
7210 0, OPTAB_WIDEN);
7211 break;
7212
7213 /* LT is handled by generic code. No need for unsigned with 0. */
7214 default:
7215 FAIL;
7216 }
7217 DONE;
7218 }
7219
7220 switch (GET_CODE (operands[1]))
7221 {
7222 case EQ:
7223 scratch = expand_binop (SImode, sub_optab, operands[2], operands[3],
7224 NULL_RTX, 0, OPTAB_WIDEN);
25f905c2 7225 emit_insn (gen_cstoresi_eq0_thumb1 (operands[0], scratch));
595d88b5 7226 break;
7227
7228 case NE:
7229 scratch = expand_binop (SImode, sub_optab, operands[2], operands[3],
7230 NULL_RTX, 0, OPTAB_WIDEN);
25f905c2 7231 emit_insn (gen_cstoresi_ne0_thumb1 (operands[0], scratch));
595d88b5 7232 break;
7233
7234 case LE:
7235 op3 = force_reg (SImode, operands[3]);
7236
7237 scratch = expand_binop (SImode, lshr_optab, operands[2], GEN_INT (31),
7238 NULL_RTX, 1, OPTAB_WIDEN);
7239 scratch2 = expand_binop (SImode, ashr_optab, op3, GEN_INT (31),
7240 NULL_RTX, 0, OPTAB_WIDEN);
25f905c2 7241 emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch2,
595d88b5 7242 op3, operands[2]));
7243 break;
7244
7245 case GE:
7246 op3 = operands[3];
25f905c2 7247 if (!thumb1_cmp_operand (op3, SImode))
595d88b5 7248 op3 = force_reg (SImode, op3);
7249 scratch = expand_binop (SImode, ashr_optab, operands[2], GEN_INT (31),
7250 NULL_RTX, 0, OPTAB_WIDEN);
7251 scratch2 = expand_binop (SImode, lshr_optab, op3, GEN_INT (31),
7252 NULL_RTX, 1, OPTAB_WIDEN);
25f905c2 7253 emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch2,
595d88b5 7254 operands[2], op3));
7255 break;
7256
7257 case LEU:
7258 op3 = force_reg (SImode, operands[3]);
7259 scratch = force_reg (SImode, const0_rtx);
25f905c2 7260 emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch,
595d88b5 7261 op3, operands[2]));
7262 break;
7263
7264 case GEU:
7265 op3 = operands[3];
25f905c2 7266 if (!thumb1_cmp_operand (op3, SImode))
595d88b5 7267 op3 = force_reg (SImode, op3);
7268 scratch = force_reg (SImode, const0_rtx);
25f905c2 7269 emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch,
595d88b5 7270 operands[2], op3));
7271 break;
7272
7273 case LTU:
7274 op3 = operands[3];
25f905c2 7275 if (!thumb1_cmp_operand (op3, SImode))
595d88b5 7276 op3 = force_reg (SImode, op3);
7277 scratch = gen_reg_rtx (SImode);
408b7ae5 7278 emit_insn (gen_cstoresi_ltu_thumb1 (operands[0], operands[2], op3));
595d88b5 7279 break;
7280
7281 case GTU:
7282 op3 = force_reg (SImode, operands[3]);
7283 scratch = gen_reg_rtx (SImode);
408b7ae5 7284 emit_insn (gen_cstoresi_ltu_thumb1 (operands[0], op3, operands[2]));
595d88b5 7285 break;
7286
7287 /* No good sequences for GT, LT. */
7288 default:
7289 FAIL;
7290 }
7291 DONE;
7292}")
7293
74f4459c 7294(define_expand "cstoresf4"
7295 [(set (match_operand:SI 0 "s_register_operand" "")
aa06947a 7296 (match_operator:SI 1 "expandable_comparison_operator"
74f4459c 7297 [(match_operand:SF 2 "s_register_operand" "")
7298 (match_operand:SF 3 "arm_float_compare_operand" "")]))]
7299 "TARGET_32BIT && TARGET_HARD_FLOAT"
7300 "emit_insn (gen_cstore_cc (operands[0], operands[1],
7301 operands[2], operands[3])); DONE;"
7302)
7303
7304(define_expand "cstoredf4"
7305 [(set (match_operand:SI 0 "s_register_operand" "")
aa06947a 7306 (match_operator:SI 1 "expandable_comparison_operator"
74f4459c 7307 [(match_operand:DF 2 "s_register_operand" "")
7308 (match_operand:DF 3 "arm_float_compare_operand" "")]))]
d63ed457 7309 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
74f4459c 7310 "emit_insn (gen_cstore_cc (operands[0], operands[1],
7311 operands[2], operands[3])); DONE;"
7312)
7313
74f4459c 7314(define_expand "cstoredi4"
7315 [(set (match_operand:SI 0 "s_register_operand" "")
aa06947a 7316 (match_operator:SI 1 "expandable_comparison_operator"
b8eae306 7317 [(match_operand:DI 2 "s_register_operand" "")
a8045a4f 7318 (match_operand:DI 3 "cmpdi_operand" "")]))]
7319 "TARGET_32BIT"
7320 "{
f9aa4160 7321 if (!arm_validize_comparison (&operands[1],
7322 &operands[2],
7323 &operands[3]))
7324 FAIL;
7325 emit_insn (gen_cstore_cc (operands[0], operands[1], operands[2],
a8045a4f 7326 operands[3]));
7327 DONE;
7328 }"
74f4459c 7329)
7330
9c08d1fa 7331\f
39b5e676 7332;; Conditional move insns
7333
7334(define_expand "movsicc"
8a18b90c 7335 [(set (match_operand:SI 0 "s_register_operand" "")
aa06947a 7336 (if_then_else:SI (match_operand 1 "expandable_comparison_operator" "")
aea4c774 7337 (match_operand:SI 2 "arm_not_operand" "")
8a18b90c 7338 (match_operand:SI 3 "arm_not_operand" "")))]
25f905c2 7339 "TARGET_32BIT"
39b5e676 7340 "
215b30b3 7341 {
f9aa4160 7342 enum rtx_code code;
278b301d 7343 rtx ccreg;
7344
f9aa4160 7345 if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0),
7346 &XEXP (operands[1], 1)))
278b301d 7347 FAIL;
f9aa4160 7348
7349 code = GET_CODE (operands[1]);
74f4459c 7350 ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
e1b93706 7351 XEXP (operands[1], 1), NULL_RTX);
29bb088d 7352 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
215b30b3 7353 }"
7354)
39b5e676 7355
7356(define_expand "movsfcc"
8a18b90c 7357 [(set (match_operand:SF 0 "s_register_operand" "")
4df97ffc 7358 (if_then_else:SF (match_operand 1 "arm_cond_move_operator" "")
8a18b90c 7359 (match_operand:SF 2 "s_register_operand" "")
d86c91f6 7360 (match_operand:SF 3 "s_register_operand" "")))]
19f6bf8d 7361 "TARGET_32BIT && TARGET_HARD_FLOAT"
39b5e676 7362 "
215b30b3 7363 {
7364 enum rtx_code code = GET_CODE (operands[1]);
7365 rtx ccreg;
f082f1c4 7366
f9aa4160 7367 if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0),
7368 &XEXP (operands[1], 1)))
7369 FAIL;
39b5e676 7370
f9aa4160 7371 code = GET_CODE (operands[1]);
74f4459c 7372 ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
e1b93706 7373 XEXP (operands[1], 1), NULL_RTX);
29bb088d 7374 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
215b30b3 7375 }"
7376)
39b5e676 7377
7378(define_expand "movdfcc"
8a18b90c 7379 [(set (match_operand:DF 0 "s_register_operand" "")
4df97ffc 7380 (if_then_else:DF (match_operand 1 "arm_cond_move_operator" "")
8a18b90c 7381 (match_operand:DF 2 "s_register_operand" "")
d86c91f6 7382 (match_operand:DF 3 "s_register_operand" "")))]
994606f8 7383 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
39b5e676 7384 "
215b30b3 7385 {
7386 enum rtx_code code = GET_CODE (operands[1]);
278b301d 7387 rtx ccreg;
39b5e676 7388
f9aa4160 7389 if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0),
7390 &XEXP (operands[1], 1)))
7391 FAIL;
7392 code = GET_CODE (operands[1]);
74f4459c 7393 ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
e1b93706 7394 XEXP (operands[1], 1), NULL_RTX);
29bb088d 7395 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
215b30b3 7396 }"
7397)
39b5e676 7398
91cb50d2 7399(define_insn "*cmov<mode>"
7400 [(set (match_operand:SDF 0 "s_register_operand" "=<F_constraint>")
7401 (if_then_else:SDF (match_operator 1 "arm_vsel_comparison_operator"
7402 [(match_operand 2 "cc_register" "") (const_int 0)])
7403 (match_operand:SDF 3 "s_register_operand"
7404 "<F_constraint>")
7405 (match_operand:SDF 4 "s_register_operand"
7406 "<F_constraint>")))]
7407 "TARGET_HARD_FLOAT && TARGET_FPU_ARMV8 <vfp_double_cond>"
7408 "*
7409 {
7410 enum arm_cond_code code = maybe_get_arm_condition_code (operands[1]);
7411 switch (code)
7412 {
7413 case ARM_GE:
7414 case ARM_GT:
7415 case ARM_EQ:
7416 case ARM_VS:
7417 return \"vsel%d1.<V_if_elem>\\t%<V_reg>0, %<V_reg>3, %<V_reg>4\";
7418 case ARM_LT:
7419 case ARM_LE:
7420 case ARM_NE:
7421 case ARM_VC:
7422 return \"vsel%D1.<V_if_elem>\\t%<V_reg>0, %<V_reg>4, %<V_reg>3\";
7423 default:
7424 gcc_unreachable ();
7425 }
7426 return \"\";
7427 }"
7428 [(set_attr "conds" "use")
6664d308 7429 (set_attr "type" "fcsel")]
91cb50d2 7430)
7431
190efb17 7432(define_insn_and_split "*movsicc_insn"
f082f1c4 7433 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r,r,r,r,r")
8a18b90c 7434 (if_then_else:SI
8fa3ba89 7435 (match_operator 3 "arm_comparison_operator"
8a18b90c 7436 [(match_operand 4 "cc_register" "") (const_int 0)])
f082f1c4 7437 (match_operand:SI 1 "arm_not_operand" "0,0,rI,K,rI,rI,K,K")
7438 (match_operand:SI 2 "arm_not_operand" "rI,K,0,0,rI,K,rI,K")))]
cffb2a26 7439 "TARGET_ARM"
39b5e676 7440 "@
8a18b90c 7441 mov%D3\\t%0, %2
7442 mvn%D3\\t%0, #%B2
f082f1c4 7443 mov%d3\\t%0, %1
7444 mvn%d3\\t%0, #%B1
190efb17 7445 #
7446 #
7447 #
7448 #"
7449 ; alt4: mov%d3\\t%0, %1\;mov%D3\\t%0, %2
7450 ; alt5: mov%d3\\t%0, %1\;mvn%D3\\t%0, #%B2
7451 ; alt6: mvn%d3\\t%0, #%B1\;mov%D3\\t%0, %2
7452 ; alt7: mvn%d3\\t%0, #%B1\;mvn%D3\\t%0, #%B2"
7453 "&& reload_completed"
7454 [(const_int 0)]
7455 {
7456 enum rtx_code rev_code;
3754d046 7457 machine_mode mode;
190efb17 7458 rtx rev_cond;
7459
7460 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
7461 operands[3],
7462 gen_rtx_SET (VOIDmode,
7463 operands[0],
7464 operands[1])));
7465
7466 rev_code = GET_CODE (operands[3]);
7467 mode = GET_MODE (operands[4]);
7468 if (mode == CCFPmode || mode == CCFPEmode)
7469 rev_code = reverse_condition_maybe_unordered (rev_code);
7470 else
7471 rev_code = reverse_condition (rev_code);
7472
7473 rev_cond = gen_rtx_fmt_ee (rev_code,
7474 VOIDmode,
7475 operands[4],
7476 const0_rtx);
7477 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
7478 rev_cond,
7479 gen_rtx_SET (VOIDmode,
7480 operands[0],
7481 operands[2])));
7482 DONE;
7483 }
f082f1c4 7484 [(set_attr "length" "4,4,4,4,8,8,8,8")
d2a518d1 7485 (set_attr "conds" "use")
65f68e55 7486 (set_attr_alternative "type"
7487 [(if_then_else (match_operand 2 "const_int_operand" "")
1aed5204 7488 (const_string "mov_imm")
7489 (const_string "mov_reg"))
7490 (const_string "mvn_imm")
65f68e55 7491 (if_then_else (match_operand 1 "const_int_operand" "")
1aed5204 7492 (const_string "mov_imm")
7493 (const_string "mov_reg"))
7494 (const_string "mvn_imm")
7495 (const_string "mov_reg")
7496 (const_string "mov_reg")
7497 (const_string "mov_reg")
7498 (const_string "mov_reg")])]
215b30b3 7499)
39b5e676 7500
39b5e676 7501(define_insn "*movsfcc_soft_insn"
f082f1c4 7502 [(set (match_operand:SF 0 "s_register_operand" "=r,r")
8fa3ba89 7503 (if_then_else:SF (match_operator 3 "arm_comparison_operator"
8a18b90c 7504 [(match_operand 4 "cc_register" "") (const_int 0)])
f082f1c4 7505 (match_operand:SF 1 "s_register_operand" "0,r")
7506 (match_operand:SF 2 "s_register_operand" "r,0")))]
cffb2a26 7507 "TARGET_ARM && TARGET_SOFT_FLOAT"
f082f1c4 7508 "@
7509 mov%D3\\t%0, %2
7510 mov%d3\\t%0, %1"
d2a518d1 7511 [(set_attr "conds" "use")
1aed5204 7512 (set_attr "type" "mov_reg")]
8fa3ba89 7513)
39b5e676 7514
39b5e676 7515\f
9c08d1fa 7516;; Jump and linkage insns
7517
cffb2a26 7518(define_expand "jump"
9c08d1fa 7519 [(set (pc)
7520 (label_ref (match_operand 0 "" "")))]
cffb2a26 7521 "TARGET_EITHER"
9c08d1fa 7522 ""
cffb2a26 7523)
7524
7525(define_insn "*arm_jump"
7526 [(set (pc)
7527 (label_ref (match_operand 0 "" "")))]
25f905c2 7528 "TARGET_32BIT"
9c08d1fa 7529 "*
0d66636f 7530 {
7531 if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
7532 {
7533 arm_ccfsm_state += 2;
7534 return \"\";
7535 }
7536 return \"b%?\\t%l0\";
7537 }
7538 "
a6864a24 7539 [(set_attr "predicable" "yes")
7540 (set (attr "length")
7541 (if_then_else
0bf497f5 7542 (and (match_test "TARGET_THUMB2")
a6864a24 7543 (and (ge (minus (match_dup 0) (pc)) (const_int -2044))
7544 (le (minus (match_dup 0) (pc)) (const_int 2048))))
7545 (const_int 2)
1b7da4ac 7546 (const_int 4)))
7547 (set_attr "type" "branch")]
0d66636f 7548)
9c08d1fa 7549
d3373b54 7550(define_expand "call"
7551 [(parallel [(call (match_operand 0 "memory_operand" "")
7552 (match_operand 1 "general_operand" ""))
cffb2a26 7553 (use (match_operand 2 "" ""))
bd5b4116 7554 (clobber (reg:SI LR_REGNUM))])]
cffb2a26 7555 "TARGET_EITHER"
6c4c2133 7556 "
7557 {
bac7fc85 7558 rtx callee, pat;
bbe777ea 7559
bbe777ea 7560 /* In an untyped call, we can get NULL for operand 2. */
7561 if (operands[2] == NULL_RTX)
7562 operands[2] = const0_rtx;
7563
de55252a 7564 /* Decide if we should generate indirect calls by loading the
85c36fd1 7565 32-bit address of the callee into a register before performing the
de55252a 7566 branch and link. */
7567 callee = XEXP (operands[0], 0);
7568 if (GET_CODE (callee) == SYMBOL_REF
7569 ? arm_is_long_call_p (SYMBOL_REF_DECL (callee))
7570 : !REG_P (callee))
bbe777ea 7571 XEXP (operands[0], 0) = force_reg (Pmode, callee);
bac7fc85 7572
7573 pat = gen_call_internal (operands[0], operands[1], operands[2]);
ca373797 7574 arm_emit_call_insn (pat, XEXP (operands[0], 0), false);
bac7fc85 7575 DONE;
6c4c2133 7576 }"
7577)
d3373b54 7578
bac7fc85 7579(define_expand "call_internal"
7580 [(parallel [(call (match_operand 0 "memory_operand" "")
7581 (match_operand 1 "general_operand" ""))
7582 (use (match_operand 2 "" ""))
7583 (clobber (reg:SI LR_REGNUM))])])
7584
f1039640 7585(define_insn "*call_reg_armv5"
d3373b54 7586 [(call (mem:SI (match_operand:SI 0 "s_register_operand" "r"))
cffb2a26 7587 (match_operand 1 "" ""))
7588 (use (match_operand 2 "" ""))
bd5b4116 7589 (clobber (reg:SI LR_REGNUM))]
33ae7c4b 7590 "TARGET_ARM && arm_arch5 && !SIBLING_CALL_P (insn)"
f1039640 7591 "blx%?\\t%0"
7592 [(set_attr "type" "call")]
7593)
7594
7595(define_insn "*call_reg_arm"
7596 [(call (mem:SI (match_operand:SI 0 "s_register_operand" "r"))
7597 (match_operand 1 "" ""))
7598 (use (match_operand 2 "" ""))
7599 (clobber (reg:SI LR_REGNUM))]
33ae7c4b 7600 "TARGET_ARM && !arm_arch5 && !SIBLING_CALL_P (insn)"
9c08d1fa 7601 "*
5565501b 7602 return output_call (operands);
cffb2a26 7603 "
7604 ;; length is worst case, normally it is only two
7605 [(set_attr "length" "12")
7606 (set_attr "type" "call")]
7607)
9c08d1fa 7608
89504fc1 7609
7610;; Note: not used for armv5+ because the sequence used (ldr pc, ...) is not
7611;; considered a function call by the branch predictor of some cores (PR40887).
7612;; Falls back to blx rN (*call_reg_armv5).
7613
f7fbdd4a 7614(define_insn "*call_mem"
a3c63a9d 7615 [(call (mem:SI (match_operand:SI 0 "call_memory_operand" "m"))
cffb2a26 7616 (match_operand 1 "" ""))
7617 (use (match_operand 2 "" ""))
bd5b4116 7618 (clobber (reg:SI LR_REGNUM))]
33ae7c4b 7619 "TARGET_ARM && !arm_arch5 && !SIBLING_CALL_P (insn)"
9c08d1fa 7620 "*
5565501b 7621 return output_call_mem (operands);
cffb2a26 7622 "
7623 [(set_attr "length" "12")
7624 (set_attr "type" "call")]
7625)
7626
d3373b54 7627(define_expand "call_value"
e0698af7 7628 [(parallel [(set (match_operand 0 "" "")
7629 (call (match_operand 1 "memory_operand" "")
7630 (match_operand 2 "general_operand" "")))
cffb2a26 7631 (use (match_operand 3 "" ""))
bd5b4116 7632 (clobber (reg:SI LR_REGNUM))])]
cffb2a26 7633 "TARGET_EITHER"
6c4c2133 7634 "
7635 {
bac7fc85 7636 rtx pat, callee;
bbe777ea 7637
7638 /* In an untyped call, we can get NULL for operand 2. */
7639 if (operands[3] == 0)
7640 operands[3] = const0_rtx;
7641
de55252a 7642 /* Decide if we should generate indirect calls by loading the
7643 32-bit address of the callee into a register before performing the
7644 branch and link. */
7645 callee = XEXP (operands[1], 0);
7646 if (GET_CODE (callee) == SYMBOL_REF
7647 ? arm_is_long_call_p (SYMBOL_REF_DECL (callee))
7648 : !REG_P (callee))
78fe751b 7649 XEXP (operands[1], 0) = force_reg (Pmode, callee);
bac7fc85 7650
7651 pat = gen_call_value_internal (operands[0], operands[1],
7652 operands[2], operands[3]);
ca373797 7653 arm_emit_call_insn (pat, XEXP (operands[1], 0), false);
bac7fc85 7654 DONE;
6c4c2133 7655 }"
7656)
d3373b54 7657
bac7fc85 7658(define_expand "call_value_internal"
7659 [(parallel [(set (match_operand 0 "" "")
7660 (call (match_operand 1 "memory_operand" "")
7661 (match_operand 2 "general_operand" "")))
7662 (use (match_operand 3 "" ""))
7663 (clobber (reg:SI LR_REGNUM))])])
7664
f1039640 7665(define_insn "*call_value_reg_armv5"
27ed6835 7666 [(set (match_operand 0 "" "")
755eb2b4 7667 (call (mem:SI (match_operand:SI 1 "s_register_operand" "r"))
cffb2a26 7668 (match_operand 2 "" "")))
bbe777ea 7669 (use (match_operand 3 "" ""))
bd5b4116 7670 (clobber (reg:SI LR_REGNUM))]
33ae7c4b 7671 "TARGET_ARM && arm_arch5 && !SIBLING_CALL_P (insn)"
f1039640 7672 "blx%?\\t%1"
7673 [(set_attr "type" "call")]
7674)
7675
7676(define_insn "*call_value_reg_arm"
7677 [(set (match_operand 0 "" "")
7678 (call (mem:SI (match_operand:SI 1 "s_register_operand" "r"))
7679 (match_operand 2 "" "")))
7680 (use (match_operand 3 "" ""))
7681 (clobber (reg:SI LR_REGNUM))]
33ae7c4b 7682 "TARGET_ARM && !arm_arch5 && !SIBLING_CALL_P (insn)"
9c08d1fa 7683 "*
215b30b3 7684 return output_call (&operands[1]);
cffb2a26 7685 "
7686 [(set_attr "length" "12")
7687 (set_attr "type" "call")]
7688)
9c08d1fa 7689
89504fc1 7690;; Note: see *call_mem
7691
f7fbdd4a 7692(define_insn "*call_value_mem"
27ed6835 7693 [(set (match_operand 0 "" "")
a3c63a9d 7694 (call (mem:SI (match_operand:SI 1 "call_memory_operand" "m"))
cffb2a26 7695 (match_operand 2 "" "")))
bbe777ea 7696 (use (match_operand 3 "" ""))
bd5b4116 7697 (clobber (reg:SI LR_REGNUM))]
33ae7c4b 7698 "TARGET_ARM && !arm_arch5 && (!CONSTANT_ADDRESS_P (XEXP (operands[1], 0)))
7699 && !SIBLING_CALL_P (insn)"
9c08d1fa 7700 "*
215b30b3 7701 return output_call_mem (&operands[1]);
cffb2a26 7702 "
7703 [(set_attr "length" "12")
7704 (set_attr "type" "call")]
7705)
9c08d1fa 7706
7707;; Allow calls to SYMBOL_REFs specially as they are not valid general addresses
7708;; The 'a' causes the operand to be treated as an address, i.e. no '#' output.
7709
f7fbdd4a 7710(define_insn "*call_symbol"
27ed6835 7711 [(call (mem:SI (match_operand:SI 0 "" ""))
cffb2a26 7712 (match_operand 1 "" ""))
bbe777ea 7713 (use (match_operand 2 "" ""))
bd5b4116 7714 (clobber (reg:SI LR_REGNUM))]
d68c2c10 7715 "TARGET_32BIT
33ae7c4b 7716 && !SIBLING_CALL_P (insn)
cffb2a26 7717 && (GET_CODE (operands[0]) == SYMBOL_REF)
de55252a 7718 && !arm_is_long_call_p (SYMBOL_REF_DECL (operands[0]))"
6ebaa29d 7719 "*
7720 {
55c1e470 7721 return NEED_PLT_RELOC ? \"bl%?\\t%a0(PLT)\" : \"bl%?\\t%a0\";
6ebaa29d 7722 }"
cffb2a26 7723 [(set_attr "type" "call")]
7724)
9c08d1fa 7725
f7fbdd4a 7726(define_insn "*call_value_symbol"
ccd90aaa 7727 [(set (match_operand 0 "" "")
27ed6835 7728 (call (mem:SI (match_operand:SI 1 "" ""))
dd6d7504 7729 (match_operand:SI 2 "" "")))
bbe777ea 7730 (use (match_operand 3 "" ""))
bd5b4116 7731 (clobber (reg:SI LR_REGNUM))]
d68c2c10 7732 "TARGET_32BIT
33ae7c4b 7733 && !SIBLING_CALL_P (insn)
cffb2a26 7734 && (GET_CODE (operands[1]) == SYMBOL_REF)
de55252a 7735 && !arm_is_long_call_p (SYMBOL_REF_DECL (operands[1]))"
6ebaa29d 7736 "*
7737 {
55c1e470 7738 return NEED_PLT_RELOC ? \"bl%?\\t%a1(PLT)\" : \"bl%?\\t%a1\";
6ebaa29d 7739 }"
cffb2a26 7740 [(set_attr "type" "call")]
7741)
7742
ca373797 7743(define_expand "sibcall_internal"
7744 [(parallel [(call (match_operand 0 "memory_operand" "")
7745 (match_operand 1 "general_operand" ""))
7746 (return)
7747 (use (match_operand 2 "" ""))])])
7748
1c494086 7749;; We may also be able to do sibcalls for Thumb, but it's much harder...
7750(define_expand "sibcall"
7751 [(parallel [(call (match_operand 0 "memory_operand" "")
7752 (match_operand 1 "general_operand" ""))
2ba80634 7753 (return)
7754 (use (match_operand 2 "" ""))])]
d68c2c10 7755 "TARGET_32BIT"
1c494086 7756 "
7757 {
ca373797 7758 rtx pat;
7759
3112c3f7 7760 if ((!REG_P (XEXP (operands[0], 0))
7761 && GET_CODE (XEXP (operands[0], 0)) != SYMBOL_REF)
7762 || (GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
7763 && arm_is_long_call_p (SYMBOL_REF_DECL (XEXP (operands[0], 0)))))
33ae7c4b 7764 XEXP (operands[0], 0) = force_reg (SImode, XEXP (operands[0], 0));
7765
1c494086 7766 if (operands[2] == NULL_RTX)
7767 operands[2] = const0_rtx;
ca373797 7768
7769 pat = gen_sibcall_internal (operands[0], operands[1], operands[2]);
7770 arm_emit_call_insn (pat, operands[0], true);
7771 DONE;
1c494086 7772 }"
7773)
7774
ca373797 7775(define_expand "sibcall_value_internal"
7776 [(parallel [(set (match_operand 0 "" "")
7777 (call (match_operand 1 "memory_operand" "")
7778 (match_operand 2 "general_operand" "")))
7779 (return)
7780 (use (match_operand 3 "" ""))])])
7781
1c494086 7782(define_expand "sibcall_value"
ccd90aaa 7783 [(parallel [(set (match_operand 0 "" "")
1c494086 7784 (call (match_operand 1 "memory_operand" "")
7785 (match_operand 2 "general_operand" "")))
2ba80634 7786 (return)
7787 (use (match_operand 3 "" ""))])]
d68c2c10 7788 "TARGET_32BIT"
1c494086 7789 "
7790 {
ca373797 7791 rtx pat;
7792
3112c3f7 7793 if ((!REG_P (XEXP (operands[1], 0))
7794 && GET_CODE (XEXP (operands[1], 0)) != SYMBOL_REF)
7795 || (GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
7796 && arm_is_long_call_p (SYMBOL_REF_DECL (XEXP (operands[1], 0)))))
33ae7c4b 7797 XEXP (operands[1], 0) = force_reg (SImode, XEXP (operands[1], 0));
7798
1c494086 7799 if (operands[3] == NULL_RTX)
7800 operands[3] = const0_rtx;
ca373797 7801
7802 pat = gen_sibcall_value_internal (operands[0], operands[1],
7803 operands[2], operands[3]);
7804 arm_emit_call_insn (pat, operands[1], true);
7805 DONE;
1c494086 7806 }"
7807)
7808
7809(define_insn "*sibcall_insn"
84ce8e5c 7810 [(call (mem:SI (match_operand:SI 0 "call_insn_operand" "Cs, US"))
1c494086 7811 (match_operand 1 "" ""))
2ba80634 7812 (return)
7813 (use (match_operand 2 "" ""))]
33ae7c4b 7814 "TARGET_32BIT && SIBLING_CALL_P (insn)"
1c494086 7815 "*
33ae7c4b 7816 if (which_alternative == 1)
7817 return NEED_PLT_RELOC ? \"b%?\\t%a0(PLT)\" : \"b%?\\t%a0\";
7818 else
7819 {
7820 if (arm_arch5 || arm_arch4t)
947d113e 7821 return \"bx%?\\t%0\\t%@ indirect register sibling call\";
33ae7c4b 7822 else
7823 return \"mov%?\\t%|pc, %0\\t%@ indirect register sibling call\";
7824 }
1c494086 7825 "
7826 [(set_attr "type" "call")]
7827)
7828
7829(define_insn "*sibcall_value_insn"
84ce8e5c 7830 [(set (match_operand 0 "" "")
7831 (call (mem:SI (match_operand:SI 1 "call_insn_operand" "Cs,US"))
1c494086 7832 (match_operand 2 "" "")))
2ba80634 7833 (return)
7834 (use (match_operand 3 "" ""))]
33ae7c4b 7835 "TARGET_32BIT && SIBLING_CALL_P (insn)"
1c494086 7836 "*
33ae7c4b 7837 if (which_alternative == 1)
7838 return NEED_PLT_RELOC ? \"b%?\\t%a1(PLT)\" : \"b%?\\t%a1\";
7839 else
7840 {
7841 if (arm_arch5 || arm_arch4t)
84ce8e5c 7842 return \"bx%?\\t%1\";
33ae7c4b 7843 else
7844 return \"mov%?\\t%|pc, %1\\t@ indirect sibling call \";
7845 }
1c494086 7846 "
7847 [(set_attr "type" "call")]
7848)
7849
0686440e 7850(define_expand "<return_str>return"
7851 [(returns)]
8cba51a5 7852 "(TARGET_ARM || (TARGET_THUMB2
7853 && ARM_FUNC_TYPE (arm_current_func_type ()) == ARM_FT_NORMAL
7854 && !IS_STACKALIGN (arm_current_func_type ())))
0686440e 7855 <return_cond_false>"
8cba51a5 7856 "
7857 {
7858 if (TARGET_THUMB2)
7859 {
0686440e 7860 thumb2_expand_return (<return_simple_p>);
8cba51a5 7861 DONE;
7862 }
7863 }
7864 "
7865)
d68c2c10 7866
9c08d1fa 7867;; Often the return insn will be the same as loading from memory, so set attr
d68c2c10 7868(define_insn "*arm_return"
9c08d1fa 7869 [(return)]
cffb2a26 7870 "TARGET_ARM && USE_RETURN_INSN (FALSE)"
9c08d1fa 7871 "*
9c08d1fa 7872 {
cffb2a26 7873 if (arm_ccfsm_state == 2)
7874 {
7875 arm_ccfsm_state += 2;
7876 return \"\";
7877 }
e2549f81 7878 return output_return_instruction (const_true_rtx, true, false, false);
cffb2a26 7879 }"
a2cd141b 7880 [(set_attr "type" "load1")
755eb2b4 7881 (set_attr "length" "12")
0d66636f 7882 (set_attr "predicable" "yes")]
cffb2a26 7883)
9c08d1fa 7884
0686440e 7885(define_insn "*cond_<return_str>return"
9c08d1fa 7886 [(set (pc)
8fa3ba89 7887 (if_then_else (match_operator 0 "arm_comparison_operator"
8a18b90c 7888 [(match_operand 1 "cc_register" "") (const_int 0)])
0686440e 7889 (returns)
9c08d1fa 7890 (pc)))]
0686440e 7891 "TARGET_ARM <return_cond_true>"
9c08d1fa 7892 "*
8fa3ba89 7893 {
7894 if (arm_ccfsm_state == 2)
7895 {
7896 arm_ccfsm_state += 2;
7897 return \"\";
7898 }
0686440e 7899 return output_return_instruction (operands[0], true, false,
7900 <return_simple_p>);
8fa3ba89 7901 }"
7902 [(set_attr "conds" "use")
755eb2b4 7903 (set_attr "length" "12")
a2cd141b 7904 (set_attr "type" "load1")]
8fa3ba89 7905)
9c08d1fa 7906
0686440e 7907(define_insn "*cond_<return_str>return_inverted"
9c08d1fa 7908 [(set (pc)
8fa3ba89 7909 (if_then_else (match_operator 0 "arm_comparison_operator"
8a18b90c 7910 [(match_operand 1 "cc_register" "") (const_int 0)])
9c08d1fa 7911 (pc)
0686440e 7912 (returns)))]
7913 "TARGET_ARM <return_cond_true>"
9c08d1fa 7914 "*
8fa3ba89 7915 {
7916 if (arm_ccfsm_state == 2)
7917 {
7918 arm_ccfsm_state += 2;
7919 return \"\";
7920 }
0686440e 7921 return output_return_instruction (operands[0], true, true,
7922 <return_simple_p>);
8fa3ba89 7923 }"
7924 [(set_attr "conds" "use")
37a1317b 7925 (set_attr "length" "12")
a2cd141b 7926 (set_attr "type" "load1")]
8fa3ba89 7927)
9c08d1fa 7928
e2549f81 7929(define_insn "*arm_simple_return"
7930 [(simple_return)]
7931 "TARGET_ARM"
7932 "*
7933 {
7934 if (arm_ccfsm_state == 2)
7935 {
7936 arm_ccfsm_state += 2;
7937 return \"\";
7938 }
7939 return output_return_instruction (const_true_rtx, true, false, true);
7940 }"
7941 [(set_attr "type" "branch")
7942 (set_attr "length" "4")
7943 (set_attr "predicable" "yes")]
7944)
7945
68121397 7946;; Generate a sequence of instructions to determine if the processor is
7947;; in 26-bit or 32-bit mode, and return the appropriate return address
7948;; mask.
7949
7950(define_expand "return_addr_mask"
7951 [(set (match_dup 1)
7952 (compare:CC_NOOV (unspec [(const_int 0)] UNSPEC_CHECK_ARCH)
7953 (const_int 0)))
7954 (set (match_operand:SI 0 "s_register_operand" "")
7955 (if_then_else:SI (eq (match_dup 1) (const_int 0))
7956 (const_int -1)
7957 (const_int 67108860)))] ; 0x03fffffc
7958 "TARGET_ARM"
7959 "
62eddbd4 7960 operands[1] = gen_rtx_REG (CC_NOOVmode, CC_REGNUM);
68121397 7961 ")
7962
7963(define_insn "*check_arch2"
7964 [(set (match_operand:CC_NOOV 0 "cc_register" "")
7965 (compare:CC_NOOV (unspec [(const_int 0)] UNSPEC_CHECK_ARCH)
7966 (const_int 0)))]
7967 "TARGET_ARM"
7968 "teq\\t%|r0, %|r0\;teq\\t%|pc, %|pc"
7969 [(set_attr "length" "8")
1b7da4ac 7970 (set_attr "conds" "set")
7971 (set_attr "type" "multiple")]
68121397 7972)
7973
9c08d1fa 7974;; Call subroutine returning any type.
7975
7976(define_expand "untyped_call"
7977 [(parallel [(call (match_operand 0 "" "")
7978 (const_int 0))
7979 (match_operand 1 "" "")
7980 (match_operand 2 "" "")])]
ccd90aaa 7981 "TARGET_EITHER"
9c08d1fa 7982 "
215b30b3 7983 {
7984 int i;
ccd90aaa 7985 rtx par = gen_rtx_PARALLEL (VOIDmode,
7986 rtvec_alloc (XVECLEN (operands[2], 0)));
7987 rtx addr = gen_reg_rtx (Pmode);
7988 rtx mem;
7989 int size = 0;
9c08d1fa 7990
ccd90aaa 7991 emit_move_insn (addr, XEXP (operands[1], 0));
7992 mem = change_address (operands[1], BLKmode, addr);
9c08d1fa 7993
215b30b3 7994 for (i = 0; i < XVECLEN (operands[2], 0); i++)
7995 {
ccd90aaa 7996 rtx src = SET_SRC (XVECEXP (operands[2], 0, i));
9c08d1fa 7997
ccd90aaa 7998 /* Default code only uses r0 as a return value, but we could
7999 be using anything up to 4 registers. */
8000 if (REGNO (src) == R0_REGNUM)
8001 src = gen_rtx_REG (TImode, R0_REGNUM);
8002
8003 XVECEXP (par, 0, i) = gen_rtx_EXPR_LIST (VOIDmode, src,
8004 GEN_INT (size));
8005 size += GET_MODE_SIZE (GET_MODE (src));
8006 }
8007
8008 emit_call_insn (GEN_CALL_VALUE (par, operands[0], const0_rtx, NULL,
8009 const0_rtx));
8010
8011 size = 0;
8012
8013 for (i = 0; i < XVECLEN (par, 0); i++)
8014 {
8015 HOST_WIDE_INT offset = 0;
8016 rtx reg = XEXP (XVECEXP (par, 0, i), 0);
8017
8018 if (size != 0)
29c05e22 8019 emit_move_insn (addr, plus_constant (Pmode, addr, size));
ccd90aaa 8020
8021 mem = change_address (mem, GET_MODE (reg), NULL);
8022 if (REGNO (reg) == R0_REGNUM)
8023 {
8024 /* On thumb we have to use a write-back instruction. */
320ea44d 8025 emit_insn (arm_gen_store_multiple (arm_regs_in_sequence, 4, addr,
8026 TARGET_THUMB ? TRUE : FALSE, mem, &offset));
ccd90aaa 8027 size = TARGET_ARM ? 16 : 0;
8028 }
8029 else
8030 {
8031 emit_move_insn (mem, reg);
8032 size = GET_MODE_SIZE (GET_MODE (reg));
8033 }
215b30b3 8034 }
9c08d1fa 8035
215b30b3 8036 /* The optimizer does not know that the call sets the function value
8037 registers we stored in the result block. We avoid problems by
8038 claiming that all hard registers are used and clobbered at this
8039 point. */
8040 emit_insn (gen_blockage ());
8041
8042 DONE;
8043 }"
8044)
9c08d1fa 8045
ccd90aaa 8046(define_expand "untyped_return"
8047 [(match_operand:BLK 0 "memory_operand" "")
8048 (match_operand 1 "" "")]
8049 "TARGET_EITHER"
8050 "
8051 {
8052 int i;
8053 rtx addr = gen_reg_rtx (Pmode);
8054 rtx mem;
8055 int size = 0;
8056
8057 emit_move_insn (addr, XEXP (operands[0], 0));
8058 mem = change_address (operands[0], BLKmode, addr);
8059
8060 for (i = 0; i < XVECLEN (operands[1], 0); i++)
8061 {
8062 HOST_WIDE_INT offset = 0;
8063 rtx reg = SET_DEST (XVECEXP (operands[1], 0, i));
8064
8065 if (size != 0)
29c05e22 8066 emit_move_insn (addr, plus_constant (Pmode, addr, size));
ccd90aaa 8067
8068 mem = change_address (mem, GET_MODE (reg), NULL);
8069 if (REGNO (reg) == R0_REGNUM)
8070 {
8071 /* On thumb we have to use a write-back instruction. */
320ea44d 8072 emit_insn (arm_gen_load_multiple (arm_regs_in_sequence, 4, addr,
8073 TARGET_THUMB ? TRUE : FALSE, mem, &offset));
ccd90aaa 8074 size = TARGET_ARM ? 16 : 0;
8075 }
8076 else
8077 {
8078 emit_move_insn (reg, mem);
8079 size = GET_MODE_SIZE (GET_MODE (reg));
8080 }
8081 }
8082
8083 /* Emit USE insns before the return. */
8084 for (i = 0; i < XVECLEN (operands[1], 0); i++)
18b42941 8085 emit_use (SET_DEST (XVECEXP (operands[1], 0, i)));
ccd90aaa 8086
8087 /* Construct the return. */
8088 expand_naked_return ();
8089
8090 DONE;
8091 }"
8092)
8093
9c08d1fa 8094;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
8095;; all of memory. This blocks insns from being moved across this point.
8096
8097(define_insn "blockage"
e1159bbe 8098 [(unspec_volatile [(const_int 0)] VUNSPEC_BLOCKAGE)]
cffb2a26 8099 "TARGET_EITHER"
9c08d1fa 8100 ""
cffb2a26 8101 [(set_attr "length" "0")
8102 (set_attr "type" "block")]
8103)
9c08d1fa 8104
f7fbdd4a 8105(define_expand "casesi"
8106 [(match_operand:SI 0 "s_register_operand" "") ; index to jump on
aea4c774 8107 (match_operand:SI 1 "const_int_operand" "") ; lower bound
8108 (match_operand:SI 2 "const_int_operand" "") ; total range
f7fbdd4a 8109 (match_operand:SI 3 "" "") ; table label
8110 (match_operand:SI 4 "" "")] ; Out of range label
e6ac8414 8111 "TARGET_32BIT || optimize_size || flag_pic"
f7fbdd4a 8112 "
215b30b3 8113 {
e6ac8414 8114 enum insn_code code;
215b30b3 8115 if (operands[1] != const0_rtx)
8116 {
e6ac8414 8117 rtx reg = gen_reg_rtx (SImode);
f7fbdd4a 8118
215b30b3 8119 emit_insn (gen_addsi3 (reg, operands[0],
d022fa24 8120 gen_int_mode (-INTVAL (operands[1]),
8121 SImode)));
215b30b3 8122 operands[0] = reg;
8123 }
9c08d1fa 8124
25f905c2 8125 if (TARGET_ARM)
e6ac8414 8126 code = CODE_FOR_arm_casesi_internal;
3db2019b 8127 else if (TARGET_THUMB1)
e6ac8414 8128 code = CODE_FOR_thumb1_casesi_internal_pic;
25f905c2 8129 else if (flag_pic)
e6ac8414 8130 code = CODE_FOR_thumb2_casesi_internal_pic;
25f905c2 8131 else
e6ac8414 8132 code = CODE_FOR_thumb2_casesi_internal;
8133
8134 if (!insn_data[(int) code].operand[1].predicate(operands[2], SImode))
8135 operands[2] = force_reg (SImode, operands[2]);
8136
8137 emit_jump_insn (GEN_FCN ((int) code) (operands[0], operands[2],
8138 operands[3], operands[4]));
215b30b3 8139 DONE;
8140 }"
8141)
f7fbdd4a 8142
f082f1c4 8143;; The USE in this pattern is needed to tell flow analysis that this is
8144;; a CASESI insn. It has no other purpose.
25f905c2 8145(define_insn "arm_casesi_internal"
f082f1c4 8146 [(parallel [(set (pc)
8147 (if_then_else
8148 (leu (match_operand:SI 0 "s_register_operand" "r")
8149 (match_operand:SI 1 "arm_rhs_operand" "rI"))
8150 (mem:SI (plus:SI (mult:SI (match_dup 0) (const_int 4))
8151 (label_ref (match_operand 2 "" ""))))
8152 (label_ref (match_operand 3 "" ""))))
bd5b4116 8153 (clobber (reg:CC CC_REGNUM))
f082f1c4 8154 (use (label_ref (match_dup 2)))])]
cffb2a26 8155 "TARGET_ARM"
f7fbdd4a 8156 "*
0d66636f 8157 if (flag_pic)
8158 return \"cmp\\t%0, %1\;addls\\t%|pc, %|pc, %0, asl #2\;b\\t%l3\";
8159 return \"cmp\\t%0, %1\;ldrls\\t%|pc, [%|pc, %0, asl #2]\;b\\t%l3\";
8160 "
8161 [(set_attr "conds" "clob")
1b7da4ac 8162 (set_attr "length" "12")
8163 (set_attr "type" "multiple")]
0d66636f 8164)
9c08d1fa 8165
cffb2a26 8166(define_expand "indirect_jump"
9c08d1fa 8167 [(set (pc)
cffb2a26 8168 (match_operand:SI 0 "s_register_operand" ""))]
8169 "TARGET_EITHER"
25f905c2 8170 "
8171 /* Thumb-2 doesn't have mov pc, reg. Explicitly set the low bit of the
8172 address and use bx. */
8173 if (TARGET_THUMB2)
8174 {
8175 rtx tmp;
8176 tmp = gen_reg_rtx (SImode);
8177 emit_insn (gen_iorsi3 (tmp, operands[0], GEN_INT(1)));
8178 operands[0] = tmp;
8179 }
8180 "
cffb2a26 8181)
8182
f1039640 8183;; NB Never uses BX.
cffb2a26 8184(define_insn "*arm_indirect_jump"
8185 [(set (pc)
8186 (match_operand:SI 0 "s_register_operand" "r"))]
8187 "TARGET_ARM"
8188 "mov%?\\t%|pc, %0\\t%@ indirect register jump"
1b7da4ac 8189 [(set_attr "predicable" "yes")
8190 (set_attr "type" "branch")]
cffb2a26 8191)
9c08d1fa 8192
f7fbdd4a 8193(define_insn "*load_indirect_jump"
9c08d1fa 8194 [(set (pc)
8195 (match_operand:SI 0 "memory_operand" "m"))]
cffb2a26 8196 "TARGET_ARM"
8197 "ldr%?\\t%|pc, %0\\t%@ indirect memory jump"
a2cd141b 8198 [(set_attr "type" "load1")
61a2d04c 8199 (set_attr "pool_range" "4096")
8200 (set_attr "neg_pool_range" "4084")
0d66636f 8201 (set_attr "predicable" "yes")]
cffb2a26 8202)
8203
9c08d1fa 8204\f
8205;; Misc insns
8206
8207(define_insn "nop"
8208 [(const_int 0)]
cffb2a26 8209 "TARGET_EITHER"
8210 "*
25f905c2 8211 if (TARGET_UNIFIED_ASM)
8212 return \"nop\";
cffb2a26 8213 if (TARGET_ARM)
8214 return \"mov%?\\t%|r0, %|r0\\t%@ nop\";
8215 return \"mov\\tr8, r8\";
8216 "
8217 [(set (attr "length")
8218 (if_then_else (eq_attr "is_thumb" "yes")
8219 (const_int 2)
1b7da4ac 8220 (const_int 4)))
8221 (set_attr "type" "mov_reg")]
cffb2a26 8222)
8223
ad9d4399 8224(define_insn "trap"
8225 [(trap_if (const_int 1) (const_int 0))]
8226 ""
8227 "*
8228 if (TARGET_ARM)
8229 return \".inst\\t0xe7f000f0\";
8230 else
8231 return \".inst\\t0xdeff\";
8232 "
8233 [(set (attr "length")
8234 (if_then_else (eq_attr "is_thumb" "yes")
8235 (const_int 2)
8236 (const_int 4)))
8237 (set_attr "type" "trap")
8238 (set_attr "conds" "unconditional")]
8239)
8240
9c08d1fa 8241\f
8242;; Patterns to allow combination of arithmetic, cond code and shifts
8243
0abea32c 8244(define_insn "*<arith_shift_insn>_multsi"
8245 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8246 (shiftable_ops:SI
8247 (mult:SI (match_operand:SI 2 "s_register_operand" "r,r")
8248 (match_operand:SI 3 "power_of_two_operand" ""))
8249 (match_operand:SI 1 "s_register_operand" "rk,<t2_binop0>")))]
d5d4dc8d 8250 "TARGET_32BIT"
0abea32c 8251 "<arith_shift_insn>%?\\t%0, %1, %2, lsl %b3"
8252 [(set_attr "predicable" "yes")
8253 (set_attr "predicable_short_it" "no")
753d9835 8254 (set_attr "shift" "2")
0abea32c 8255 (set_attr "arch" "a,t2")
8256 (set_attr "type" "alu_shift_imm")])
8257
8258(define_insn "*<arith_shift_insn>_shiftsi"
8259 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
8260 (shiftable_ops:SI
8261 (match_operator:SI 2 "shift_nomul_operator"
8262 [(match_operand:SI 3 "s_register_operand" "r,r,r")
8263 (match_operand:SI 4 "shift_amount_operand" "M,M,r")])
8264 (match_operand:SI 1 "s_register_operand" "rk,<t2_binop0>,rk")))]
a021b821 8265 "TARGET_32BIT && GET_CODE (operands[2]) != MULT"
0abea32c 8266 "<arith_shift_insn>%?\\t%0, %1, %3%S2"
344495ea 8267 [(set_attr "predicable" "yes")
74ef923b 8268 (set_attr "predicable_short_it" "no")
753d9835 8269 (set_attr "shift" "3")
0abea32c 8270 (set_attr "arch" "a,t2,a")
8271 (set_attr "type" "alu_shift_imm,alu_shift_imm,alu_shift_reg")])
9c08d1fa 8272
d7863cfe 8273(define_split
8274 [(set (match_operand:SI 0 "s_register_operand" "")
8275 (match_operator:SI 1 "shiftable_operator"
8276 [(match_operator:SI 2 "shiftable_operator"
8277 [(match_operator:SI 3 "shift_operator"
8278 [(match_operand:SI 4 "s_register_operand" "")
8279 (match_operand:SI 5 "reg_or_int_operand" "")])
8280 (match_operand:SI 6 "s_register_operand" "")])
8281 (match_operand:SI 7 "arm_rhs_operand" "")]))
8282 (clobber (match_operand:SI 8 "s_register_operand" ""))]
d5d4dc8d 8283 "TARGET_32BIT"
d7863cfe 8284 [(set (match_dup 8)
8285 (match_op_dup 2 [(match_op_dup 3 [(match_dup 4) (match_dup 5)])
8286 (match_dup 6)]))
8287 (set (match_dup 0)
8288 (match_op_dup 1 [(match_dup 8) (match_dup 7)]))]
8289 "")
8290
f7fbdd4a 8291(define_insn "*arith_shiftsi_compare0"
bd5b4116 8292 [(set (reg:CC_NOOV CC_REGNUM)
d5d4dc8d 8293 (compare:CC_NOOV
8294 (match_operator:SI 1 "shiftable_operator"
8295 [(match_operator:SI 3 "shift_operator"
8296 [(match_operand:SI 4 "s_register_operand" "r,r")
8297 (match_operand:SI 5 "shift_amount_operand" "M,r")])
8298 (match_operand:SI 2 "s_register_operand" "r,r")])
8299 (const_int 0)))
8300 (set (match_operand:SI 0 "s_register_operand" "=r,r")
9c08d1fa 8301 (match_op_dup 1 [(match_op_dup 3 [(match_dup 4) (match_dup 5)])
8302 (match_dup 2)]))]
d5d4dc8d 8303 "TARGET_32BIT"
25f905c2 8304 "%i1%.\\t%0, %2, %4%S3"
344495ea 8305 [(set_attr "conds" "set")
331beb1a 8306 (set_attr "shift" "4")
d5d4dc8d 8307 (set_attr "arch" "32,a")
d82e788e 8308 (set_attr "type" "alus_shift_imm,alus_shift_reg")])
9c08d1fa 8309
f7fbdd4a 8310(define_insn "*arith_shiftsi_compare0_scratch"
bd5b4116 8311 [(set (reg:CC_NOOV CC_REGNUM)
d5d4dc8d 8312 (compare:CC_NOOV
8313 (match_operator:SI 1 "shiftable_operator"
8314 [(match_operator:SI 3 "shift_operator"
8315 [(match_operand:SI 4 "s_register_operand" "r,r")
8316 (match_operand:SI 5 "shift_amount_operand" "M,r")])
8317 (match_operand:SI 2 "s_register_operand" "r,r")])
8318 (const_int 0)))
8319 (clobber (match_scratch:SI 0 "=r,r"))]
8320 "TARGET_32BIT"
25f905c2 8321 "%i1%.\\t%0, %2, %4%S3"
344495ea 8322 [(set_attr "conds" "set")
331beb1a 8323 (set_attr "shift" "4")
d5d4dc8d 8324 (set_attr "arch" "32,a")
d82e788e 8325 (set_attr "type" "alus_shift_imm,alus_shift_reg")])
9c08d1fa 8326
f7fbdd4a 8327(define_insn "*sub_shiftsi"
d5d4dc8d 8328 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8329 (minus:SI (match_operand:SI 1 "s_register_operand" "r,r")
9c08d1fa 8330 (match_operator:SI 2 "shift_operator"
d5d4dc8d 8331 [(match_operand:SI 3 "s_register_operand" "r,r")
8332 (match_operand:SI 4 "shift_amount_operand" "M,r")])))]
8333 "TARGET_32BIT"
6c4c2133 8334 "sub%?\\t%0, %1, %3%S2"
344495ea 8335 [(set_attr "predicable" "yes")
331beb1a 8336 (set_attr "shift" "3")
d5d4dc8d 8337 (set_attr "arch" "32,a")
d82e788e 8338 (set_attr "type" "alus_shift_imm,alus_shift_reg")])
9c08d1fa 8339
f7fbdd4a 8340(define_insn "*sub_shiftsi_compare0"
bd5b4116 8341 [(set (reg:CC_NOOV CC_REGNUM)
40dbec34 8342 (compare:CC_NOOV
d82e788e 8343 (minus:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
40dbec34 8344 (match_operator:SI 2 "shift_operator"
d82e788e 8345 [(match_operand:SI 3 "s_register_operand" "r,r,r")
8346 (match_operand:SI 4 "shift_amount_operand" "M,r,M")]))
40dbec34 8347 (const_int 0)))
d82e788e 8348 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
d5d4dc8d 8349 (minus:SI (match_dup 1)
8350 (match_op_dup 2 [(match_dup 3) (match_dup 4)])))]
8351 "TARGET_32BIT"
25f905c2 8352 "sub%.\\t%0, %1, %3%S2"
344495ea 8353 [(set_attr "conds" "set")
a2cd141b 8354 (set_attr "shift" "3")
d82e788e 8355 (set_attr "arch" "32,a,a")
8356 (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")])
9c08d1fa 8357
f7fbdd4a 8358(define_insn "*sub_shiftsi_compare0_scratch"
bd5b4116 8359 [(set (reg:CC_NOOV CC_REGNUM)
40dbec34 8360 (compare:CC_NOOV
d82e788e 8361 (minus:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
40dbec34 8362 (match_operator:SI 2 "shift_operator"
d82e788e 8363 [(match_operand:SI 3 "s_register_operand" "r,r,r")
8364 (match_operand:SI 4 "shift_amount_operand" "M,r,M")]))
40dbec34 8365 (const_int 0)))
d82e788e 8366 (clobber (match_scratch:SI 0 "=r,r,r"))]
d5d4dc8d 8367 "TARGET_32BIT"
25f905c2 8368 "sub%.\\t%0, %1, %3%S2"
344495ea 8369 [(set_attr "conds" "set")
a2cd141b 8370 (set_attr "shift" "3")
d82e788e 8371 (set_attr "arch" "32,a,a")
8372 (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")])
9c08d1fa 8373\f
8374
190efb17 8375(define_insn_and_split "*and_scc"
9c08d1fa 8376 [(set (match_operand:SI 0 "s_register_operand" "=r")
8fa3ba89 8377 (and:SI (match_operator:SI 1 "arm_comparison_operator"
190efb17 8378 [(match_operand 2 "cc_register" "") (const_int 0)])
8379 (match_operand:SI 3 "s_register_operand" "r")))]
cffb2a26 8380 "TARGET_ARM"
190efb17 8381 "#" ; "mov%D1\\t%0, #0\;and%d1\\t%0, %3, #1"
8382 "&& reload_completed"
8383 [(cond_exec (match_dup 5) (set (match_dup 0) (const_int 0)))
8384 (cond_exec (match_dup 4) (set (match_dup 0)
8385 (and:SI (match_dup 3) (const_int 1))))]
8386 {
3754d046 8387 machine_mode mode = GET_MODE (operands[2]);
190efb17 8388 enum rtx_code rc = GET_CODE (operands[1]);
8389
8390 /* Note that operands[4] is the same as operands[1],
8391 but with VOIDmode as the result. */
8392 operands[4] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
8393 if (mode == CCFPmode || mode == CCFPEmode)
8394 rc = reverse_condition_maybe_unordered (rc);
8395 else
8396 rc = reverse_condition (rc);
8397 operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
8398 }
8fa3ba89 8399 [(set_attr "conds" "use")
1b7da4ac 8400 (set_attr "type" "multiple")
8fa3ba89 8401 (set_attr "length" "8")]
8402)
9c08d1fa 8403
190efb17 8404(define_insn_and_split "*ior_scc"
9c08d1fa 8405 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
190efb17 8406 (ior:SI (match_operator:SI 1 "arm_comparison_operator"
8407 [(match_operand 2 "cc_register" "") (const_int 0)])
8408 (match_operand:SI 3 "s_register_operand" "0,?r")))]
cffb2a26 8409 "TARGET_ARM"
e2348bcb 8410 "@
190efb17 8411 orr%d1\\t%0, %3, #1
8412 #"
8413 "&& reload_completed
8414 && REGNO (operands [0]) != REGNO (operands[3])"
8415 ;; && which_alternative == 1
8416 ; mov%D1\\t%0, %3\;orr%d1\\t%0, %3, #1
8417 [(cond_exec (match_dup 5) (set (match_dup 0) (match_dup 3)))
8418 (cond_exec (match_dup 4) (set (match_dup 0)
8419 (ior:SI (match_dup 3) (const_int 1))))]
8420 {
3754d046 8421 machine_mode mode = GET_MODE (operands[2]);
190efb17 8422 enum rtx_code rc = GET_CODE (operands[1]);
8423
8424 /* Note that operands[4] is the same as operands[1],
8425 but with VOIDmode as the result. */
8426 operands[4] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
8427 if (mode == CCFPmode || mode == CCFPEmode)
8428 rc = reverse_condition_maybe_unordered (rc);
8429 else
8430 rc = reverse_condition (rc);
8431 operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
8432 }
8fa3ba89 8433 [(set_attr "conds" "use")
1b7da4ac 8434 (set_attr "length" "4,8")
8435 (set_attr "type" "logic_imm,multiple")]
8fa3ba89 8436)
9c08d1fa 8437
2df9477b 8438; A series of splitters for the compare_scc pattern below. Note that
8439; order is important.
8440(define_split
8441 [(set (match_operand:SI 0 "s_register_operand" "")
8442 (lt:SI (match_operand:SI 1 "s_register_operand" "")
8443 (const_int 0)))
8444 (clobber (reg:CC CC_REGNUM))]
8445 "TARGET_32BIT && reload_completed"
8446 [(set (match_dup 0) (lshiftrt:SI (match_dup 1) (const_int 31)))])
8447
8448(define_split
8449 [(set (match_operand:SI 0 "s_register_operand" "")
8450 (ge:SI (match_operand:SI 1 "s_register_operand" "")
8451 (const_int 0)))
8452 (clobber (reg:CC CC_REGNUM))]
8453 "TARGET_32BIT && reload_completed"
8454 [(set (match_dup 0) (not:SI (match_dup 1)))
8455 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 31)))])
8456
98562479 8457(define_split
8458 [(set (match_operand:SI 0 "s_register_operand" "")
8459 (eq:SI (match_operand:SI 1 "s_register_operand" "")
8460 (const_int 0)))
8461 (clobber (reg:CC CC_REGNUM))]
8462 "arm_arch5 && TARGET_32BIT"
8463 [(set (match_dup 0) (clz:SI (match_dup 1)))
8464 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 5)))]
8465)
8466
2df9477b 8467(define_split
8468 [(set (match_operand:SI 0 "s_register_operand" "")
8469 (eq:SI (match_operand:SI 1 "s_register_operand" "")
8470 (const_int 0)))
8471 (clobber (reg:CC CC_REGNUM))]
8472 "TARGET_32BIT && reload_completed"
8473 [(parallel
080c0b9a 8474 [(set (reg:CC CC_REGNUM)
8475 (compare:CC (const_int 1) (match_dup 1)))
2df9477b 8476 (set (match_dup 0)
8477 (minus:SI (const_int 1) (match_dup 1)))])
080c0b9a 8478 (cond_exec (ltu:CC (reg:CC CC_REGNUM) (const_int 0))
2df9477b 8479 (set (match_dup 0) (const_int 0)))])
8480
8481(define_split
8482 [(set (match_operand:SI 0 "s_register_operand" "")
8483 (ne:SI (match_operand:SI 1 "s_register_operand" "")
8484 (match_operand:SI 2 "const_int_operand" "")))
8485 (clobber (reg:CC CC_REGNUM))]
8486 "TARGET_32BIT && reload_completed"
8487 [(parallel
8488 [(set (reg:CC CC_REGNUM)
8489 (compare:CC (match_dup 1) (match_dup 2)))
8490 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 3)))])
8491 (cond_exec (ne:CC (reg:CC CC_REGNUM) (const_int 0))
8492 (set (match_dup 0) (const_int 1)))]
8493{
8494 operands[3] = GEN_INT (-INTVAL (operands[2]));
8495})
8496
8497(define_split
8498 [(set (match_operand:SI 0 "s_register_operand" "")
8499 (ne:SI (match_operand:SI 1 "s_register_operand" "")
8500 (match_operand:SI 2 "arm_add_operand" "")))
8501 (clobber (reg:CC CC_REGNUM))]
8502 "TARGET_32BIT && reload_completed"
8503 [(parallel
8504 [(set (reg:CC_NOOV CC_REGNUM)
8505 (compare:CC_NOOV (minus:SI (match_dup 1) (match_dup 2))
8506 (const_int 0)))
8507 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
8508 (cond_exec (ne:CC_NOOV (reg:CC_NOOV CC_REGNUM) (const_int 0))
8509 (set (match_dup 0) (const_int 1)))])
8510
8511(define_insn_and_split "*compare_scc"
fd711051 8512 [(set (match_operand:SI 0 "s_register_operand" "=Ts,Ts")
8fa3ba89 8513 (match_operator:SI 1 "arm_comparison_operator"
5565501b 8514 [(match_operand:SI 2 "s_register_operand" "r,r")
8515 (match_operand:SI 3 "arm_add_operand" "rI,L")]))
bd5b4116 8516 (clobber (reg:CC CC_REGNUM))]
2df9477b 8517 "TARGET_32BIT"
8518 "#"
8519 "&& reload_completed"
8520 [(set (reg:CC CC_REGNUM) (compare:CC (match_dup 2) (match_dup 3)))
8521 (cond_exec (match_dup 4) (set (match_dup 0) (const_int 0)))
8522 (cond_exec (match_dup 5) (set (match_dup 0) (const_int 1)))]
8523{
8524 rtx tmp1;
3754d046 8525 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
2df9477b 8526 operands[2], operands[3]);
8527 enum rtx_code rc = GET_CODE (operands[1]);
e2348bcb 8528
2df9477b 8529 tmp1 = gen_rtx_REG (mode, CC_REGNUM);
080c0b9a 8530
2df9477b 8531 operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, tmp1, const0_rtx);
8532 if (mode == CCFPmode || mode == CCFPEmode)
8533 rc = reverse_condition_maybe_unordered (rc);
8534 else
8535 rc = reverse_condition (rc);
8536 operands[4] = gen_rtx_fmt_ee (rc, VOIDmode, tmp1, const0_rtx);
1b7da4ac 8537}
8538 [(set_attr "type" "multiple")]
8539)
9c08d1fa 8540
080c0b9a 8541;; Attempt to improve the sequence generated by the compare_scc splitters
8542;; not to use conditional execution.
98562479 8543
8544;; Rd = (eq (reg1) (const_int0)) // ARMv5
8545;; clz Rd, reg1
8546;; lsr Rd, Rd, #5
080c0b9a 8547(define_peephole2
8548 [(set (reg:CC CC_REGNUM)
8549 (compare:CC (match_operand:SI 1 "register_operand" "")
98562479 8550 (const_int 0)))
8551 (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
8552 (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
8553 (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
8554 (set (match_dup 0) (const_int 1)))]
8555 "arm_arch5 && TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)"
8556 [(set (match_dup 0) (clz:SI (match_dup 1)))
8557 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 5)))]
8558)
8559
8560;; Rd = (eq (reg1) (const_int0)) // !ARMv5
8561;; negs Rd, reg1
8562;; adc Rd, Rd, reg1
8563(define_peephole2
8564 [(set (reg:CC CC_REGNUM)
8565 (compare:CC (match_operand:SI 1 "register_operand" "")
8566 (const_int 0)))
080c0b9a 8567 (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
8568 (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
8569 (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
8570 (set (match_dup 0) (const_int 1)))
98562479 8571 (match_scratch:SI 2 "r")]
8572 "TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)"
922b6913 8573 [(parallel
8574 [(set (reg:CC CC_REGNUM)
98562479 8575 (compare:CC (const_int 0) (match_dup 1)))
8576 (set (match_dup 2) (minus:SI (const_int 0) (match_dup 1)))])
8577 (set (match_dup 0)
8578 (plus:SI (plus:SI (match_dup 1) (match_dup 2))
8579 (geu:SI (reg:CC CC_REGNUM) (const_int 0))))]
8580)
8581
31991287 8582;; Rd = (eq (reg1) (reg2/imm)) // ARMv5 and optimising for speed.
98562479 8583;; sub Rd, Reg1, reg2
8584;; clz Rd, Rd
8585;; lsr Rd, Rd, #5
8586(define_peephole2
8587 [(set (reg:CC CC_REGNUM)
8588 (compare:CC (match_operand:SI 1 "register_operand" "")
8589 (match_operand:SI 2 "arm_rhs_operand" "")))
8590 (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
8591 (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
8592 (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
8593 (set (match_dup 0) (const_int 1)))]
31991287 8594 "arm_arch5 && TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)
8595 && !(TARGET_THUMB2 && optimize_insn_for_size_p ())"
98562479 8596 [(set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))
8597 (set (match_dup 0) (clz:SI (match_dup 0)))
8598 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 5)))]
8599)
8600
8601
31991287 8602;; Rd = (eq (reg1) (reg2)) // ! ARMv5 or optimising for size.
98562479 8603;; sub T1, Reg1, reg2
8604;; negs Rd, T1
8605;; adc Rd, Rd, T1
8606(define_peephole2
8607 [(set (reg:CC CC_REGNUM)
8608 (compare:CC (match_operand:SI 1 "register_operand" "")
8609 (match_operand:SI 2 "arm_rhs_operand" "")))
8610 (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
8611 (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
8612 (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
8613 (set (match_dup 0) (const_int 1)))
8614 (match_scratch:SI 3 "r")]
8615 "TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)"
31991287 8616 [(set (match_dup 3) (match_dup 4))
080c0b9a 8617 (parallel
8618 [(set (reg:CC CC_REGNUM)
8619 (compare:CC (const_int 0) (match_dup 3)))
8620 (set (match_dup 0) (minus:SI (const_int 0) (match_dup 3)))])
98562479 8621 (set (match_dup 0)
8622 (plus:SI (plus:SI (match_dup 0) (match_dup 3))
8623 (geu:SI (reg:CC CC_REGNUM) (const_int 0))))]
31991287 8624 "
8625 if (CONST_INT_P (operands[2]))
8626 operands[4] = plus_constant (SImode, operands[1], -INTVAL (operands[2]));
8627 else
8628 operands[4] = gen_rtx_MINUS (SImode, operands[1], operands[2]);
8629 ")
080c0b9a 8630
f7fbdd4a 8631(define_insn "*cond_move"
9c08d1fa 8632 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
aea4c774 8633 (if_then_else:SI (match_operator 3 "equality_operator"
8fa3ba89 8634 [(match_operator 4 "arm_comparison_operator"
8a18b90c 8635 [(match_operand 5 "cc_register" "") (const_int 0)])
aea4c774 8636 (const_int 0)])
8637 (match_operand:SI 1 "arm_rhs_operand" "0,rI,?rI")
8638 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))]
cffb2a26 8639 "TARGET_ARM"
9c08d1fa 8640 "*
8fa3ba89 8641 if (GET_CODE (operands[3]) == NE)
8642 {
8643 if (which_alternative != 1)
8644 output_asm_insn (\"mov%D4\\t%0, %2\", operands);
8645 if (which_alternative != 0)
8646 output_asm_insn (\"mov%d4\\t%0, %1\", operands);
8647 return \"\";
8648 }
8649 if (which_alternative != 0)
8650 output_asm_insn (\"mov%D4\\t%0, %1\", operands);
8651 if (which_alternative != 1)
8652 output_asm_insn (\"mov%d4\\t%0, %2\", operands);
8653 return \"\";
8654 "
8655 [(set_attr "conds" "use")
1b7da4ac 8656 (set_attr "type" "mov_reg,mov_reg,multiple")
8fa3ba89 8657 (set_attr "length" "4,4,8")]
8658)
9c08d1fa 8659
f7fbdd4a 8660(define_insn "*cond_arith"
9c08d1fa 8661 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8662 (match_operator:SI 5 "shiftable_operator"
8fa3ba89 8663 [(match_operator:SI 4 "arm_comparison_operator"
9c08d1fa 8664 [(match_operand:SI 2 "s_register_operand" "r,r")
8665 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
8666 (match_operand:SI 1 "s_register_operand" "0,?r")]))
bd5b4116 8667 (clobber (reg:CC CC_REGNUM))]
cffb2a26 8668 "TARGET_ARM"
9c08d1fa 8669 "*
8fa3ba89 8670 if (GET_CODE (operands[4]) == LT && operands[3] == const0_rtx)
8671 return \"%i5\\t%0, %1, %2, lsr #31\";
40dbec34 8672
8fa3ba89 8673 output_asm_insn (\"cmp\\t%2, %3\", operands);
8674 if (GET_CODE (operands[5]) == AND)
8675 output_asm_insn (\"mov%D4\\t%0, #0\", operands);
8676 else if (GET_CODE (operands[5]) == MINUS)
8677 output_asm_insn (\"rsb%D4\\t%0, %1, #0\", operands);
8678 else if (which_alternative != 0)
8679 output_asm_insn (\"mov%D4\\t%0, %1\", operands);
8680 return \"%i5%d4\\t%0, %1, #1\";
8681 "
8682 [(set_attr "conds" "clob")
1b7da4ac 8683 (set_attr "length" "12")
8684 (set_attr "type" "multiple")]
8fa3ba89 8685)
9c08d1fa 8686
f7fbdd4a 8687(define_insn "*cond_sub"
9c08d1fa 8688 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8689 (minus:SI (match_operand:SI 1 "s_register_operand" "0,?r")
8fa3ba89 8690 (match_operator:SI 4 "arm_comparison_operator"
9c08d1fa 8691 [(match_operand:SI 2 "s_register_operand" "r,r")
8692 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))
bd5b4116 8693 (clobber (reg:CC CC_REGNUM))]
cffb2a26 8694 "TARGET_ARM"
9c08d1fa 8695 "*
8fa3ba89 8696 output_asm_insn (\"cmp\\t%2, %3\", operands);
8697 if (which_alternative != 0)
8698 output_asm_insn (\"mov%D4\\t%0, %1\", operands);
8699 return \"sub%d4\\t%0, %1, #1\";
8700 "
8701 [(set_attr "conds" "clob")
1b7da4ac 8702 (set_attr "length" "8,12")
8703 (set_attr "type" "multiple")]
8fa3ba89 8704)
9c08d1fa 8705
aea4c774 8706(define_insn "*cmp_ite0"
cffb2a26 8707 [(set (match_operand 6 "dominant_cc_register" "")
aea4c774 8708 (compare
8709 (if_then_else:SI
8fa3ba89 8710 (match_operator 4 "arm_comparison_operator"
2ff91fec 8711 [(match_operand:SI 0 "s_register_operand"
8712 "l,l,l,r,r,r,r,r,r")
8713 (match_operand:SI 1 "arm_add_operand"
8714 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
8fa3ba89 8715 (match_operator:SI 5 "arm_comparison_operator"
2ff91fec 8716 [(match_operand:SI 2 "s_register_operand"
8717 "l,r,r,l,l,r,r,r,r")
8718 (match_operand:SI 3 "arm_add_operand"
8719 "lPy,rI,L,lPy,lPy,rI,rI,L,L")])
aea4c774 8720 (const_int 0))
8721 (const_int 0)))]
2ff91fec 8722 "TARGET_32BIT"
9c08d1fa 8723 "*
aea4c774 8724 {
2ff91fec 8725 static const char * const cmp1[NUM_OF_COND_CMP][2] =
8726 {
8727 {\"cmp%d5\\t%0, %1\",
8728 \"cmp%d4\\t%2, %3\"},
8729 {\"cmn%d5\\t%0, #%n1\",
8730 \"cmp%d4\\t%2, %3\"},
8731 {\"cmp%d5\\t%0, %1\",
8732 \"cmn%d4\\t%2, #%n3\"},
8733 {\"cmn%d5\\t%0, #%n1\",
8734 \"cmn%d4\\t%2, #%n3\"}
8735 };
8736 static const char * const cmp2[NUM_OF_COND_CMP][2] =
8737 {
8738 {\"cmp\\t%2, %3\",
8739 \"cmp\\t%0, %1\"},
8740 {\"cmp\\t%2, %3\",
8741 \"cmn\\t%0, #%n1\"},
8742 {\"cmn\\t%2, #%n3\",
8743 \"cmp\\t%0, %1\"},
8744 {\"cmn\\t%2, #%n3\",
8745 \"cmn\\t%0, #%n1\"}
8746 };
8747 static const char * const ite[2] =
8fa3ba89 8748 {
2ff91fec 8749 \"it\\t%d5\",
8750 \"it\\t%d4\"
8fa3ba89 8751 };
2ff91fec 8752 static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
8753 CMP_CMP, CMN_CMP, CMP_CMP,
8754 CMN_CMP, CMP_CMN, CMN_CMN};
8fa3ba89 8755 int swap =
8756 comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4]));
8757
2ff91fec 8758 output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
8759 if (TARGET_THUMB2) {
8760 output_asm_insn (ite[swap], operands);
8761 }
8762 output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
8763 return \"\";
8fa3ba89 8764 }"
8765 [(set_attr "conds" "set")
2ff91fec 8766 (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
1b7da4ac 8767 (set_attr "type" "multiple")
2ff91fec 8768 (set_attr_alternative "length"
8769 [(const_int 6)
8770 (const_int 8)
8771 (const_int 8)
8772 (const_int 8)
8773 (const_int 8)
8774 (if_then_else (eq_attr "is_thumb" "no")
8775 (const_int 8)
8776 (const_int 10))
8777 (if_then_else (eq_attr "is_thumb" "no")
8778 (const_int 8)
8779 (const_int 10))
8780 (if_then_else (eq_attr "is_thumb" "no")
8781 (const_int 8)
8782 (const_int 10))
8783 (if_then_else (eq_attr "is_thumb" "no")
8784 (const_int 8)
8785 (const_int 10))])]
8fa3ba89 8786)
9c08d1fa 8787
aea4c774 8788(define_insn "*cmp_ite1"
cffb2a26 8789 [(set (match_operand 6 "dominant_cc_register" "")
aea4c774 8790 (compare
8791 (if_then_else:SI
8fa3ba89 8792 (match_operator 4 "arm_comparison_operator"
2ff91fec 8793 [(match_operand:SI 0 "s_register_operand"
8794 "l,l,l,r,r,r,r,r,r")
8795 (match_operand:SI 1 "arm_add_operand"
8796 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
8fa3ba89 8797 (match_operator:SI 5 "arm_comparison_operator"
2ff91fec 8798 [(match_operand:SI 2 "s_register_operand"
8799 "l,r,r,l,l,r,r,r,r")
8800 (match_operand:SI 3 "arm_add_operand"
8801 "lPy,rI,L,lPy,lPy,rI,rI,L,L")])
aea4c774 8802 (const_int 1))
8803 (const_int 0)))]
2ff91fec 8804 "TARGET_32BIT"
9c08d1fa 8805 "*
9c08d1fa 8806 {
2ff91fec 8807 static const char * const cmp1[NUM_OF_COND_CMP][2] =
8808 {
8809 {\"cmp\\t%0, %1\",
8810 \"cmp\\t%2, %3\"},
8811 {\"cmn\\t%0, #%n1\",
8812 \"cmp\\t%2, %3\"},
8813 {\"cmp\\t%0, %1\",
8814 \"cmn\\t%2, #%n3\"},
8815 {\"cmn\\t%0, #%n1\",
8816 \"cmn\\t%2, #%n3\"}
8817 };
8818 static const char * const cmp2[NUM_OF_COND_CMP][2] =
215b30b3 8819 {
2ff91fec 8820 {\"cmp%d4\\t%2, %3\",
8821 \"cmp%D5\\t%0, %1\"},
8822 {\"cmp%d4\\t%2, %3\",
8823 \"cmn%D5\\t%0, #%n1\"},
8824 {\"cmn%d4\\t%2, #%n3\",
8825 \"cmp%D5\\t%0, %1\"},
8826 {\"cmn%d4\\t%2, #%n3\",
8827 \"cmn%D5\\t%0, #%n1\"}
215b30b3 8828 };
2ff91fec 8829 static const char * const ite[2] =
8830 {
8831 \"it\\t%d4\",
8832 \"it\\t%D5\"
8833 };
8834 static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
8835 CMP_CMP, CMN_CMP, CMP_CMP,
8836 CMN_CMP, CMP_CMN, CMN_CMN};
215b30b3 8837 int swap =
8838 comparison_dominates_p (GET_CODE (operands[5]),
8839 reverse_condition (GET_CODE (operands[4])));
8840
2ff91fec 8841 output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
8842 if (TARGET_THUMB2) {
8843 output_asm_insn (ite[swap], operands);
8844 }
8845 output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
8846 return \"\";
215b30b3 8847 }"
8fa3ba89 8848 [(set_attr "conds" "set")
2ff91fec 8849 (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
8850 (set_attr_alternative "length"
8851 [(const_int 6)
8852 (const_int 8)
8853 (const_int 8)
8854 (const_int 8)
8855 (const_int 8)
8856 (if_then_else (eq_attr "is_thumb" "no")
8857 (const_int 8)
8858 (const_int 10))
8859 (if_then_else (eq_attr "is_thumb" "no")
8860 (const_int 8)
8861 (const_int 10))
8862 (if_then_else (eq_attr "is_thumb" "no")
8863 (const_int 8)
8864 (const_int 10))
8865 (if_then_else (eq_attr "is_thumb" "no")
8866 (const_int 8)
1b7da4ac 8867 (const_int 10))])
8868 (set_attr "type" "multiple")]
8fa3ba89 8869)
9c08d1fa 8870
f6c53574 8871(define_insn "*cmp_and"
8872 [(set (match_operand 6 "dominant_cc_register" "")
8873 (compare
8874 (and:SI
8875 (match_operator 4 "arm_comparison_operator"
2ff91fec 8876 [(match_operand:SI 0 "s_register_operand"
8877 "l,l,l,r,r,r,r,r,r")
8878 (match_operand:SI 1 "arm_add_operand"
8879 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
f6c53574 8880 (match_operator:SI 5 "arm_comparison_operator"
2ff91fec 8881 [(match_operand:SI 2 "s_register_operand"
8882 "l,r,r,l,l,r,r,r,r")
8883 (match_operand:SI 3 "arm_add_operand"
8884 "lPy,rI,L,lPy,lPy,rI,rI,L,L")]))
f6c53574 8885 (const_int 0)))]
2ff91fec 8886 "TARGET_32BIT"
f6c53574 8887 "*
8888 {
2ff91fec 8889 static const char *const cmp1[NUM_OF_COND_CMP][2] =
f6c53574 8890 {
2ff91fec 8891 {\"cmp%d5\\t%0, %1\",
8892 \"cmp%d4\\t%2, %3\"},
8893 {\"cmn%d5\\t%0, #%n1\",
8894 \"cmp%d4\\t%2, %3\"},
8895 {\"cmp%d5\\t%0, %1\",
8896 \"cmn%d4\\t%2, #%n3\"},
8897 {\"cmn%d5\\t%0, #%n1\",
8898 \"cmn%d4\\t%2, #%n3\"}
f6c53574 8899 };
2ff91fec 8900 static const char *const cmp2[NUM_OF_COND_CMP][2] =
8901 {
8902 {\"cmp\\t%2, %3\",
8903 \"cmp\\t%0, %1\"},
8904 {\"cmp\\t%2, %3\",
8905 \"cmn\\t%0, #%n1\"},
8906 {\"cmn\\t%2, #%n3\",
8907 \"cmp\\t%0, %1\"},
8908 {\"cmn\\t%2, #%n3\",
8909 \"cmn\\t%0, #%n1\"}
8910 };
8911 static const char *const ite[2] =
8912 {
8913 \"it\\t%d5\",
8914 \"it\\t%d4\"
8915 };
8916 static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
8917 CMP_CMP, CMN_CMP, CMP_CMP,
8918 CMN_CMP, CMP_CMN, CMN_CMN};
f6c53574 8919 int swap =
8920 comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4]));
8921
2ff91fec 8922 output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
8923 if (TARGET_THUMB2) {
8924 output_asm_insn (ite[swap], operands);
8925 }
8926 output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
8927 return \"\";
f6c53574 8928 }"
8929 [(set_attr "conds" "set")
8930 (set_attr "predicable" "no")
2ff91fec 8931 (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
8932 (set_attr_alternative "length"
8933 [(const_int 6)
8934 (const_int 8)
8935 (const_int 8)
8936 (const_int 8)
8937 (const_int 8)
8938 (if_then_else (eq_attr "is_thumb" "no")
8939 (const_int 8)
8940 (const_int 10))
8941 (if_then_else (eq_attr "is_thumb" "no")
8942 (const_int 8)
8943 (const_int 10))
8944 (if_then_else (eq_attr "is_thumb" "no")
8945 (const_int 8)
8946 (const_int 10))
8947 (if_then_else (eq_attr "is_thumb" "no")
8948 (const_int 8)
1b7da4ac 8949 (const_int 10))])
8950 (set_attr "type" "multiple")]
f6c53574 8951)
8952
8953(define_insn "*cmp_ior"
8954 [(set (match_operand 6 "dominant_cc_register" "")
8955 (compare
8956 (ior:SI
8957 (match_operator 4 "arm_comparison_operator"
2ff91fec 8958 [(match_operand:SI 0 "s_register_operand"
8959 "l,l,l,r,r,r,r,r,r")
8960 (match_operand:SI 1 "arm_add_operand"
8961 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
f6c53574 8962 (match_operator:SI 5 "arm_comparison_operator"
2ff91fec 8963 [(match_operand:SI 2 "s_register_operand"
8964 "l,r,r,l,l,r,r,r,r")
8965 (match_operand:SI 3 "arm_add_operand"
8966 "lPy,rI,L,lPy,lPy,rI,rI,L,L")]))
f6c53574 8967 (const_int 0)))]
2ff91fec 8968 "TARGET_32BIT"
f6c53574 8969 "*
f6c53574 8970 {
2ff91fec 8971 static const char *const cmp1[NUM_OF_COND_CMP][2] =
8972 {
8973 {\"cmp\\t%0, %1\",
8974 \"cmp\\t%2, %3\"},
8975 {\"cmn\\t%0, #%n1\",
8976 \"cmp\\t%2, %3\"},
8977 {\"cmp\\t%0, %1\",
8978 \"cmn\\t%2, #%n3\"},
8979 {\"cmn\\t%0, #%n1\",
8980 \"cmn\\t%2, #%n3\"}
8981 };
8982 static const char *const cmp2[NUM_OF_COND_CMP][2] =
8983 {
8984 {\"cmp%D4\\t%2, %3\",
8985 \"cmp%D5\\t%0, %1\"},
8986 {\"cmp%D4\\t%2, %3\",
8987 \"cmn%D5\\t%0, #%n1\"},
8988 {\"cmn%D4\\t%2, #%n3\",
8989 \"cmp%D5\\t%0, %1\"},
8990 {\"cmn%D4\\t%2, #%n3\",
8991 \"cmn%D5\\t%0, #%n1\"}
8992 };
8993 static const char *const ite[2] =
8994 {
8995 \"it\\t%D4\",
8996 \"it\\t%D5\"
8997 };
8998 static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
8999 CMP_CMP, CMN_CMP, CMP_CMP,
9000 CMN_CMP, CMP_CMN, CMN_CMN};
9001 int swap =
9002 comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4]));
9003
9004 output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
9005 if (TARGET_THUMB2) {
9006 output_asm_insn (ite[swap], operands);
9007 }
9008 output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
9009 return \"\";
9010 }
9011 "
f6c53574 9012 [(set_attr "conds" "set")
2ff91fec 9013 (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
9014 (set_attr_alternative "length"
9015 [(const_int 6)
9016 (const_int 8)
9017 (const_int 8)
9018 (const_int 8)
9019 (const_int 8)
9020 (if_then_else (eq_attr "is_thumb" "no")
9021 (const_int 8)
9022 (const_int 10))
9023 (if_then_else (eq_attr "is_thumb" "no")
9024 (const_int 8)
9025 (const_int 10))
9026 (if_then_else (eq_attr "is_thumb" "no")
9027 (const_int 8)
9028 (const_int 10))
9029 (if_then_else (eq_attr "is_thumb" "no")
9030 (const_int 8)
1b7da4ac 9031 (const_int 10))])
9032 (set_attr "type" "multiple")]
f6c53574 9033)
9034
3c5afce6 9035(define_insn_and_split "*ior_scc_scc"
fd711051 9036 [(set (match_operand:SI 0 "s_register_operand" "=Ts")
3c5afce6 9037 (ior:SI (match_operator:SI 3 "arm_comparison_operator"
9038 [(match_operand:SI 1 "s_register_operand" "r")
9039 (match_operand:SI 2 "arm_add_operand" "rIL")])
9040 (match_operator:SI 6 "arm_comparison_operator"
9041 [(match_operand:SI 4 "s_register_operand" "r")
9042 (match_operand:SI 5 "arm_add_operand" "rIL")])))
9043 (clobber (reg:CC CC_REGNUM))]
2ff91fec 9044 "TARGET_32BIT
3c5afce6 9045 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_OR_Y)
9046 != CCmode)"
9047 "#"
2ff91fec 9048 "TARGET_32BIT && reload_completed"
3c5afce6 9049 [(set (match_dup 7)
9050 (compare
9051 (ior:SI
9052 (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9053 (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9054 (const_int 0)))
9055 (set (match_dup 0) (ne:SI (match_dup 7) (const_int 0)))]
9056 "operands[7]
9057 = gen_rtx_REG (arm_select_dominance_cc_mode (operands[3], operands[6],
9058 DOM_CC_X_OR_Y),
601f584c 9059 CC_REGNUM);"
9060 [(set_attr "conds" "clob")
1b7da4ac 9061 (set_attr "length" "16")
9062 (set_attr "type" "multiple")]
9063)
601f584c 9064
9065; If the above pattern is followed by a CMP insn, then the compare is
9066; redundant, since we can rework the conditional instruction that follows.
9067(define_insn_and_split "*ior_scc_scc_cmp"
9068 [(set (match_operand 0 "dominant_cc_register" "")
9069 (compare (ior:SI (match_operator:SI 3 "arm_comparison_operator"
9070 [(match_operand:SI 1 "s_register_operand" "r")
9071 (match_operand:SI 2 "arm_add_operand" "rIL")])
9072 (match_operator:SI 6 "arm_comparison_operator"
9073 [(match_operand:SI 4 "s_register_operand" "r")
9074 (match_operand:SI 5 "arm_add_operand" "rIL")]))
9075 (const_int 0)))
fd711051 9076 (set (match_operand:SI 7 "s_register_operand" "=Ts")
601f584c 9077 (ior:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9078 (match_op_dup 6 [(match_dup 4) (match_dup 5)])))]
2ff91fec 9079 "TARGET_32BIT"
601f584c 9080 "#"
2ff91fec 9081 "TARGET_32BIT && reload_completed"
601f584c 9082 [(set (match_dup 0)
9083 (compare
9084 (ior:SI
9085 (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9086 (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9087 (const_int 0)))
9088 (set (match_dup 7) (ne:SI (match_dup 0) (const_int 0)))]
9089 ""
9090 [(set_attr "conds" "set")
1b7da4ac 9091 (set_attr "length" "16")
9092 (set_attr "type" "multiple")]
9093)
3c5afce6 9094
9095(define_insn_and_split "*and_scc_scc"
fd711051 9096 [(set (match_operand:SI 0 "s_register_operand" "=Ts")
3c5afce6 9097 (and:SI (match_operator:SI 3 "arm_comparison_operator"
9098 [(match_operand:SI 1 "s_register_operand" "r")
9099 (match_operand:SI 2 "arm_add_operand" "rIL")])
9100 (match_operator:SI 6 "arm_comparison_operator"
9101 [(match_operand:SI 4 "s_register_operand" "r")
9102 (match_operand:SI 5 "arm_add_operand" "rIL")])))
9103 (clobber (reg:CC CC_REGNUM))]
2ff91fec 9104 "TARGET_32BIT
3c5afce6 9105 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y)
9106 != CCmode)"
9107 "#"
2ff91fec 9108 "TARGET_32BIT && reload_completed
601f584c 9109 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y)
9110 != CCmode)"
3c5afce6 9111 [(set (match_dup 7)
9112 (compare
9113 (and:SI
9114 (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9115 (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9116 (const_int 0)))
9117 (set (match_dup 0) (ne:SI (match_dup 7) (const_int 0)))]
9118 "operands[7]
9119 = gen_rtx_REG (arm_select_dominance_cc_mode (operands[3], operands[6],
9120 DOM_CC_X_AND_Y),
601f584c 9121 CC_REGNUM);"
9122 [(set_attr "conds" "clob")
1b7da4ac 9123 (set_attr "length" "16")
9124 (set_attr "type" "multiple")]
9125)
601f584c 9126
9127; If the above pattern is followed by a CMP insn, then the compare is
9128; redundant, since we can rework the conditional instruction that follows.
9129(define_insn_and_split "*and_scc_scc_cmp"
9130 [(set (match_operand 0 "dominant_cc_register" "")
9131 (compare (and:SI (match_operator:SI 3 "arm_comparison_operator"
9132 [(match_operand:SI 1 "s_register_operand" "r")
9133 (match_operand:SI 2 "arm_add_operand" "rIL")])
9134 (match_operator:SI 6 "arm_comparison_operator"
9135 [(match_operand:SI 4 "s_register_operand" "r")
9136 (match_operand:SI 5 "arm_add_operand" "rIL")]))
9137 (const_int 0)))
fd711051 9138 (set (match_operand:SI 7 "s_register_operand" "=Ts")
601f584c 9139 (and:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9140 (match_op_dup 6 [(match_dup 4) (match_dup 5)])))]
2ff91fec 9141 "TARGET_32BIT"
601f584c 9142 "#"
2ff91fec 9143 "TARGET_32BIT && reload_completed"
601f584c 9144 [(set (match_dup 0)
9145 (compare
9146 (and:SI
9147 (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9148 (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9149 (const_int 0)))
9150 (set (match_dup 7) (ne:SI (match_dup 0) (const_int 0)))]
9151 ""
9152 [(set_attr "conds" "set")
1b7da4ac 9153 (set_attr "length" "16")
9154 (set_attr "type" "multiple")]
9155)
601f584c 9156
9157;; If there is no dominance in the comparison, then we can still save an
9158;; instruction in the AND case, since we can know that the second compare
9159;; need only zero the value if false (if true, then the value is already
9160;; correct).
9161(define_insn_and_split "*and_scc_scc_nodom"
fd711051 9162 [(set (match_operand:SI 0 "s_register_operand" "=&Ts,&Ts,&Ts")
601f584c 9163 (and:SI (match_operator:SI 3 "arm_comparison_operator"
9164 [(match_operand:SI 1 "s_register_operand" "r,r,0")
9165 (match_operand:SI 2 "arm_add_operand" "rIL,0,rIL")])
9166 (match_operator:SI 6 "arm_comparison_operator"
9167 [(match_operand:SI 4 "s_register_operand" "r,r,r")
9168 (match_operand:SI 5 "arm_add_operand" "rIL,rIL,rIL")])))
9169 (clobber (reg:CC CC_REGNUM))]
2ff91fec 9170 "TARGET_32BIT
601f584c 9171 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y)
9172 == CCmode)"
9173 "#"
2ff91fec 9174 "TARGET_32BIT && reload_completed"
601f584c 9175 [(parallel [(set (match_dup 0)
9176 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
9177 (clobber (reg:CC CC_REGNUM))])
9178 (set (match_dup 7) (match_op_dup 8 [(match_dup 4) (match_dup 5)]))
9179 (set (match_dup 0)
9180 (if_then_else:SI (match_op_dup 6 [(match_dup 7) (const_int 0)])
9181 (match_dup 0)
9182 (const_int 0)))]
9183 "operands[7] = gen_rtx_REG (SELECT_CC_MODE (GET_CODE (operands[6]),
9184 operands[4], operands[5]),
9185 CC_REGNUM);
9186 operands[8] = gen_rtx_COMPARE (GET_MODE (operands[7]), operands[4],
9187 operands[5]);"
9188 [(set_attr "conds" "clob")
1b7da4ac 9189 (set_attr "length" "20")
9190 (set_attr "type" "multiple")]
9191)
3c5afce6 9192
3a0bdee0 9193(define_split
9194 [(set (reg:CC_NOOV CC_REGNUM)
9195 (compare:CC_NOOV (ior:SI
9196 (and:SI (match_operand:SI 0 "s_register_operand" "")
9197 (const_int 1))
b0694be0 9198 (match_operator:SI 1 "arm_comparison_operator"
3a0bdee0 9199 [(match_operand:SI 2 "s_register_operand" "")
9200 (match_operand:SI 3 "arm_add_operand" "")]))
9201 (const_int 0)))
9202 (clobber (match_operand:SI 4 "s_register_operand" ""))]
9203 "TARGET_ARM"
9204 [(set (match_dup 4)
9205 (ior:SI (match_op_dup 1 [(match_dup 2) (match_dup 3)])
9206 (match_dup 0)))
9207 (set (reg:CC_NOOV CC_REGNUM)
9208 (compare:CC_NOOV (and:SI (match_dup 4) (const_int 1))
9209 (const_int 0)))]
9210 "")
9211
9212(define_split
9213 [(set (reg:CC_NOOV CC_REGNUM)
9214 (compare:CC_NOOV (ior:SI
b0694be0 9215 (match_operator:SI 1 "arm_comparison_operator"
3a0bdee0 9216 [(match_operand:SI 2 "s_register_operand" "")
9217 (match_operand:SI 3 "arm_add_operand" "")])
9218 (and:SI (match_operand:SI 0 "s_register_operand" "")
9219 (const_int 1)))
9220 (const_int 0)))
9221 (clobber (match_operand:SI 4 "s_register_operand" ""))]
9222 "TARGET_ARM"
9223 [(set (match_dup 4)
9224 (ior:SI (match_op_dup 1 [(match_dup 2) (match_dup 3)])
9225 (match_dup 0)))
9226 (set (reg:CC_NOOV CC_REGNUM)
9227 (compare:CC_NOOV (and:SI (match_dup 4) (const_int 1))
9228 (const_int 0)))]
9229 "")
25f905c2 9230;; ??? The conditional patterns above need checking for Thumb-2 usefulness
3a0bdee0 9231
190efb17 9232(define_insn_and_split "*negscc"
9c08d1fa 9233 [(set (match_operand:SI 0 "s_register_operand" "=r")
8fa3ba89 9234 (neg:SI (match_operator 3 "arm_comparison_operator"
9c08d1fa 9235 [(match_operand:SI 1 "s_register_operand" "r")
9236 (match_operand:SI 2 "arm_rhs_operand" "rI")])))
bd5b4116 9237 (clobber (reg:CC CC_REGNUM))]
cffb2a26 9238 "TARGET_ARM"
190efb17 9239 "#"
9240 "&& reload_completed"
9241 [(const_int 0)]
9242 {
9243 rtx cc_reg = gen_rtx_REG (CCmode, CC_REGNUM);
e2348bcb 9244
190efb17 9245 if (GET_CODE (operands[3]) == LT && operands[2] == const0_rtx)
9246 {
9247 /* Emit mov\\t%0, %1, asr #31 */
9248 emit_insn (gen_rtx_SET (VOIDmode,
9249 operands[0],
9250 gen_rtx_ASHIFTRT (SImode,
9251 operands[1],
9252 GEN_INT (31))));
9253 DONE;
9254 }
9255 else if (GET_CODE (operands[3]) == NE)
9256 {
9257 /* Emit subs\\t%0, %1, %2\;mvnne\\t%0, #0 */
9258 if (CONST_INT_P (operands[2]))
9259 emit_insn (gen_cmpsi2_addneg (operands[0], operands[1], operands[2],
9260 GEN_INT (- INTVAL (operands[2]))));
9261 else
9262 emit_insn (gen_subsi3_compare (operands[0], operands[1], operands[2]));
9263
9264 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
9265 gen_rtx_NE (SImode,
9266 cc_reg,
9267 const0_rtx),
9268 gen_rtx_SET (SImode,
9269 operands[0],
9270 GEN_INT (~0))));
9271 DONE;
9272 }
9273 else
9274 {
9275 /* Emit: cmp\\t%1, %2\;mov%D3\\t%0, #0\;mvn%d3\\t%0, #0 */
9276 emit_insn (gen_rtx_SET (VOIDmode,
9277 cc_reg,
9278 gen_rtx_COMPARE (CCmode, operands[1], operands[2])));
9279 enum rtx_code rc = GET_CODE (operands[3]);
9280
9281 rc = reverse_condition (rc);
9282 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
9283 gen_rtx_fmt_ee (rc,
9284 VOIDmode,
9285 cc_reg,
9286 const0_rtx),
9287 gen_rtx_SET (VOIDmode, operands[0], const0_rtx)));
9288 rc = GET_CODE (operands[3]);
9289 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
9290 gen_rtx_fmt_ee (rc,
9291 VOIDmode,
9292 cc_reg,
9293 const0_rtx),
9294 gen_rtx_SET (VOIDmode,
9295 operands[0],
9296 GEN_INT (~0))));
9297 DONE;
9298 }
9299 FAIL;
9300 }
8fa3ba89 9301 [(set_attr "conds" "clob")
1b7da4ac 9302 (set_attr "length" "12")
9303 (set_attr "type" "multiple")]
8fa3ba89 9304)
9c08d1fa 9305
90404b57 9306(define_insn_and_split "movcond_addsi"
9307 [(set (match_operand:SI 0 "s_register_operand" "=r,l,r")
9308 (if_then_else:SI
9309 (match_operator 5 "comparison_operator"
9310 [(plus:SI (match_operand:SI 3 "s_register_operand" "r,r,r")
9311 (match_operand:SI 4 "arm_add_operand" "rIL,rIL,rIL"))
9312 (const_int 0)])
9313 (match_operand:SI 1 "arm_rhs_operand" "rI,rPy,r")
9314 (match_operand:SI 2 "arm_rhs_operand" "rI,rPy,r")))
9315 (clobber (reg:CC CC_REGNUM))]
9316 "TARGET_32BIT"
9317 "#"
9318 "&& reload_completed"
9319 [(set (reg:CC_NOOV CC_REGNUM)
9320 (compare:CC_NOOV
9321 (plus:SI (match_dup 3)
9322 (match_dup 4))
9323 (const_int 0)))
9324 (set (match_dup 0) (match_dup 1))
9325 (cond_exec (match_dup 6)
9326 (set (match_dup 0) (match_dup 2)))]
9327 "
9328 {
3754d046 9329 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[5]),
90404b57 9330 operands[3], operands[4]);
9331 enum rtx_code rc = GET_CODE (operands[5]);
90404b57 9332 operands[6] = gen_rtx_REG (mode, CC_REGNUM);
9333 gcc_assert (!(mode == CCFPmode || mode == CCFPEmode));
4d01ce2f 9334 if (REGNO (operands[2]) != REGNO (operands[0]))
9335 rc = reverse_condition (rc);
f145bcba 9336 else
9337 std::swap (operands[1], operands[2]);
90404b57 9338
9339 operands[6] = gen_rtx_fmt_ee (rc, VOIDmode, operands[6], const0_rtx);
9340 }
9341 "
9342 [(set_attr "conds" "clob")
1b7da4ac 9343 (set_attr "enabled_for_depr_it" "no,yes,yes")
9344 (set_attr "type" "multiple")]
90404b57 9345)
9346
9c08d1fa 9347(define_insn "movcond"
9348 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
5565501b 9349 (if_then_else:SI
8fa3ba89 9350 (match_operator 5 "arm_comparison_operator"
5565501b 9351 [(match_operand:SI 3 "s_register_operand" "r,r,r")
9352 (match_operand:SI 4 "arm_add_operand" "rIL,rIL,rIL")])
9353 (match_operand:SI 1 "arm_rhs_operand" "0,rI,?rI")
9354 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
bd5b4116 9355 (clobber (reg:CC CC_REGNUM))]
cffb2a26 9356 "TARGET_ARM"
9c08d1fa 9357 "*
9358 if (GET_CODE (operands[5]) == LT
9359 && (operands[4] == const0_rtx))
9360 {
0438d37f 9361 if (which_alternative != 1 && REG_P (operands[1]))
9c08d1fa 9362 {
9c08d1fa 9363 if (operands[2] == const0_rtx)
e2348bcb 9364 return \"and\\t%0, %1, %3, asr #31\";
9365 return \"ands\\t%0, %1, %3, asr #32\;movcc\\t%0, %2\";
9c08d1fa 9366 }
0438d37f 9367 else if (which_alternative != 0 && REG_P (operands[2]))
9c08d1fa 9368 {
9c08d1fa 9369 if (operands[1] == const0_rtx)
e2348bcb 9370 return \"bic\\t%0, %2, %3, asr #31\";
9371 return \"bics\\t%0, %2, %3, asr #32\;movcs\\t%0, %1\";
9c08d1fa 9372 }
9373 /* The only case that falls through to here is when both ops 1 & 2
674a8f0b 9374 are constants. */
9c08d1fa 9375 }
e2348bcb 9376
9c08d1fa 9377 if (GET_CODE (operands[5]) == GE
9378 && (operands[4] == const0_rtx))
9379 {
0438d37f 9380 if (which_alternative != 1 && REG_P (operands[1]))
9c08d1fa 9381 {
9c08d1fa 9382 if (operands[2] == const0_rtx)
e2348bcb 9383 return \"bic\\t%0, %1, %3, asr #31\";
9384 return \"bics\\t%0, %1, %3, asr #32\;movcs\\t%0, %2\";
9c08d1fa 9385 }
0438d37f 9386 else if (which_alternative != 0 && REG_P (operands[2]))
9c08d1fa 9387 {
9c08d1fa 9388 if (operands[1] == const0_rtx)
e2348bcb 9389 return \"and\\t%0, %2, %3, asr #31\";
9390 return \"ands\\t%0, %2, %3, asr #32\;movcc\\t%0, %1\";
9c08d1fa 9391 }
9392 /* The only case that falls through to here is when both ops 1 & 2
674a8f0b 9393 are constants. */
9c08d1fa 9394 }
0438d37f 9395 if (CONST_INT_P (operands[4])
9c08d1fa 9396 && !const_ok_for_arm (INTVAL (operands[4])))
e2348bcb 9397 output_asm_insn (\"cmn\\t%3, #%n4\", operands);
9c08d1fa 9398 else
e2348bcb 9399 output_asm_insn (\"cmp\\t%3, %4\", operands);
9c08d1fa 9400 if (which_alternative != 0)
e2348bcb 9401 output_asm_insn (\"mov%d5\\t%0, %1\", operands);
9c08d1fa 9402 if (which_alternative != 1)
e2348bcb 9403 output_asm_insn (\"mov%D5\\t%0, %2\", operands);
9c08d1fa 9404 return \"\";
215b30b3 9405 "
8fa3ba89 9406 [(set_attr "conds" "clob")
1b7da4ac 9407 (set_attr "length" "8,8,12")
9408 (set_attr "type" "multiple")]
8fa3ba89 9409)
9c08d1fa 9410
25f905c2 9411;; ??? The patterns below need checking for Thumb-2 usefulness.
9412
8a18b90c 9413(define_insn "*ifcompare_plus_move"
9414 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8fa3ba89 9415 (if_then_else:SI (match_operator 6 "arm_comparison_operator"
8a18b90c 9416 [(match_operand:SI 4 "s_register_operand" "r,r")
9417 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
9418 (plus:SI
9419 (match_operand:SI 2 "s_register_operand" "r,r")
9420 (match_operand:SI 3 "arm_add_operand" "rIL,rIL"))
129a2fe4 9421 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))
bd5b4116 9422 (clobber (reg:CC CC_REGNUM))]
cffb2a26 9423 "TARGET_ARM"
8a18b90c 9424 "#"
8fa3ba89 9425 [(set_attr "conds" "clob")
1b7da4ac 9426 (set_attr "length" "8,12")
9427 (set_attr "type" "multiple")]
8fa3ba89 9428)
8a18b90c 9429
9430(define_insn "*if_plus_move"
129a2fe4 9431 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r")
8a18b90c 9432 (if_then_else:SI
8fa3ba89 9433 (match_operator 4 "arm_comparison_operator"
8a18b90c 9434 [(match_operand 5 "cc_register" "") (const_int 0)])
9435 (plus:SI
129a2fe4 9436 (match_operand:SI 2 "s_register_operand" "r,r,r,r")
9437 (match_operand:SI 3 "arm_add_operand" "rI,L,rI,L"))
9438 (match_operand:SI 1 "arm_rhs_operand" "0,0,?rI,?rI")))]
cffb2a26 9439 "TARGET_ARM"
8a18b90c 9440 "@
9441 add%d4\\t%0, %2, %3
9442 sub%d4\\t%0, %2, #%n3
9443 add%d4\\t%0, %2, %3\;mov%D4\\t%0, %1
129a2fe4 9444 sub%d4\\t%0, %2, #%n3\;mov%D4\\t%0, %1"
8fa3ba89 9445 [(set_attr "conds" "use")
9446 (set_attr "length" "4,4,8,8")
65f68e55 9447 (set_attr_alternative "type"
9448 [(if_then_else (match_operand 3 "const_int_operand" "")
d82e788e 9449 (const_string "alu_imm" )
112eda6f 9450 (const_string "alu_sreg"))
d82e788e 9451 (const_string "alu_imm")
112eda6f 9452 (const_string "alu_sreg")
9453 (const_string "alu_sreg")])]
8fa3ba89 9454)
8a18b90c 9455
9456(define_insn "*ifcompare_move_plus"
5565501b 9457 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8fa3ba89 9458 (if_then_else:SI (match_operator 6 "arm_comparison_operator"
8a18b90c 9459 [(match_operand:SI 4 "s_register_operand" "r,r")
9460 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
129a2fe4 9461 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
8a18b90c 9462 (plus:SI
9463 (match_operand:SI 2 "s_register_operand" "r,r")
9464 (match_operand:SI 3 "arm_add_operand" "rIL,rIL"))))
bd5b4116 9465 (clobber (reg:CC CC_REGNUM))]
cffb2a26 9466 "TARGET_ARM"
8a18b90c 9467 "#"
8fa3ba89 9468 [(set_attr "conds" "clob")
1b7da4ac 9469 (set_attr "length" "8,12")
9470 (set_attr "type" "multiple")]
8fa3ba89 9471)
8a18b90c 9472
9473(define_insn "*if_move_plus"
129a2fe4 9474 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r")
8a18b90c 9475 (if_then_else:SI
8fa3ba89 9476 (match_operator 4 "arm_comparison_operator"
8a18b90c 9477 [(match_operand 5 "cc_register" "") (const_int 0)])
129a2fe4 9478 (match_operand:SI 1 "arm_rhs_operand" "0,0,?rI,?rI")
8a18b90c 9479 (plus:SI
129a2fe4 9480 (match_operand:SI 2 "s_register_operand" "r,r,r,r")
9481 (match_operand:SI 3 "arm_add_operand" "rI,L,rI,L"))))]
cffb2a26 9482 "TARGET_ARM"
8a18b90c 9483 "@
9484 add%D4\\t%0, %2, %3
9485 sub%D4\\t%0, %2, #%n3
9486 add%D4\\t%0, %2, %3\;mov%d4\\t%0, %1
129a2fe4 9487 sub%D4\\t%0, %2, #%n3\;mov%d4\\t%0, %1"
8fa3ba89 9488 [(set_attr "conds" "use")
9489 (set_attr "length" "4,4,8,8")
112eda6f 9490 (set_attr "type" "alu_sreg,alu_imm,multiple,multiple")]
8fa3ba89 9491)
8a18b90c 9492
9493(define_insn "*ifcompare_arith_arith"
9494 [(set (match_operand:SI 0 "s_register_operand" "=r")
8fa3ba89 9495 (if_then_else:SI (match_operator 9 "arm_comparison_operator"
8a18b90c 9496 [(match_operand:SI 5 "s_register_operand" "r")
9497 (match_operand:SI 6 "arm_add_operand" "rIL")])
9c08d1fa 9498 (match_operator:SI 8 "shiftable_operator"
8a18b90c 9499 [(match_operand:SI 1 "s_register_operand" "r")
9500 (match_operand:SI 2 "arm_rhs_operand" "rI")])
9c08d1fa 9501 (match_operator:SI 7 "shiftable_operator"
8a18b90c 9502 [(match_operand:SI 3 "s_register_operand" "r")
9503 (match_operand:SI 4 "arm_rhs_operand" "rI")])))
bd5b4116 9504 (clobber (reg:CC CC_REGNUM))]
cffb2a26 9505 "TARGET_ARM"
8a18b90c 9506 "#"
8fa3ba89 9507 [(set_attr "conds" "clob")
1b7da4ac 9508 (set_attr "length" "12")
9509 (set_attr "type" "multiple")]
8fa3ba89 9510)
9c08d1fa 9511
8a18b90c 9512(define_insn "*if_arith_arith"
9513 [(set (match_operand:SI 0 "s_register_operand" "=r")
8fa3ba89 9514 (if_then_else:SI (match_operator 5 "arm_comparison_operator"
8a18b90c 9515 [(match_operand 8 "cc_register" "") (const_int 0)])
9516 (match_operator:SI 6 "shiftable_operator"
9517 [(match_operand:SI 1 "s_register_operand" "r")
9518 (match_operand:SI 2 "arm_rhs_operand" "rI")])
9519 (match_operator:SI 7 "shiftable_operator"
9520 [(match_operand:SI 3 "s_register_operand" "r")
9521 (match_operand:SI 4 "arm_rhs_operand" "rI")])))]
cffb2a26 9522 "TARGET_ARM"
8a18b90c 9523 "%I6%d5\\t%0, %1, %2\;%I7%D5\\t%0, %3, %4"
8fa3ba89 9524 [(set_attr "conds" "use")
1b7da4ac 9525 (set_attr "length" "8")
9526 (set_attr "type" "multiple")]
8fa3ba89 9527)
8a18b90c 9528
f7fbdd4a 9529(define_insn "*ifcompare_arith_move"
9c08d1fa 9530 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8fa3ba89 9531 (if_then_else:SI (match_operator 6 "arm_comparison_operator"
9c08d1fa 9532 [(match_operand:SI 2 "s_register_operand" "r,r")
5565501b 9533 (match_operand:SI 3 "arm_add_operand" "rIL,rIL")])
9c08d1fa 9534 (match_operator:SI 7 "shiftable_operator"
9535 [(match_operand:SI 4 "s_register_operand" "r,r")
9536 (match_operand:SI 5 "arm_rhs_operand" "rI,rI")])
129a2fe4 9537 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))
bd5b4116 9538 (clobber (reg:CC CC_REGNUM))]
cffb2a26 9539 "TARGET_ARM"
9c08d1fa 9540 "*
9c08d1fa 9541 /* If we have an operation where (op x 0) is the identity operation and
01cc3b75 9542 the conditional operator is LT or GE and we are comparing against zero and
674a8f0b 9543 everything is in registers then we can do this in two instructions. */
9c08d1fa 9544 if (operands[3] == const0_rtx
9545 && GET_CODE (operands[7]) != AND
0438d37f 9546 && REG_P (operands[5])
9547 && REG_P (operands[1])
9c08d1fa 9548 && REGNO (operands[1]) == REGNO (operands[4])
9549 && REGNO (operands[4]) != REGNO (operands[0]))
9550 {
9551 if (GET_CODE (operands[6]) == LT)
40dbec34 9552 return \"and\\t%0, %5, %2, asr #31\;%I7\\t%0, %4, %0\";
9c08d1fa 9553 else if (GET_CODE (operands[6]) == GE)
40dbec34 9554 return \"bic\\t%0, %5, %2, asr #31\;%I7\\t%0, %4, %0\";
9c08d1fa 9555 }
0438d37f 9556 if (CONST_INT_P (operands[3])
9c08d1fa 9557 && !const_ok_for_arm (INTVAL (operands[3])))
e2348bcb 9558 output_asm_insn (\"cmn\\t%2, #%n3\", operands);
9c08d1fa 9559 else
e2348bcb 9560 output_asm_insn (\"cmp\\t%2, %3\", operands);
40dbec34 9561 output_asm_insn (\"%I7%d6\\t%0, %4, %5\", operands);
9c08d1fa 9562 if (which_alternative != 0)
129a2fe4 9563 return \"mov%D6\\t%0, %1\";
9c08d1fa 9564 return \"\";
215b30b3 9565 "
8fa3ba89 9566 [(set_attr "conds" "clob")
1b7da4ac 9567 (set_attr "length" "8,12")
9568 (set_attr "type" "multiple")]
8fa3ba89 9569)
9c08d1fa 9570
8a18b90c 9571(define_insn "*if_arith_move"
129a2fe4 9572 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8fa3ba89 9573 (if_then_else:SI (match_operator 4 "arm_comparison_operator"
8a18b90c 9574 [(match_operand 6 "cc_register" "") (const_int 0)])
9575 (match_operator:SI 5 "shiftable_operator"
129a2fe4 9576 [(match_operand:SI 2 "s_register_operand" "r,r")
9577 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
9578 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))]
cffb2a26 9579 "TARGET_ARM"
8a18b90c 9580 "@
9581 %I5%d4\\t%0, %2, %3
129a2fe4 9582 %I5%d4\\t%0, %2, %3\;mov%D4\\t%0, %1"
8fa3ba89 9583 [(set_attr "conds" "use")
9584 (set_attr "length" "4,8")
1b7da4ac 9585 (set_attr "type" "alu_shift_reg,multiple")]
8fa3ba89 9586)
8a18b90c 9587
f7fbdd4a 9588(define_insn "*ifcompare_move_arith"
9c08d1fa 9589 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8fa3ba89 9590 (if_then_else:SI (match_operator 6 "arm_comparison_operator"
9c08d1fa 9591 [(match_operand:SI 4 "s_register_operand" "r,r")
5565501b 9592 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
129a2fe4 9593 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
9c08d1fa 9594 (match_operator:SI 7 "shiftable_operator"
9595 [(match_operand:SI 2 "s_register_operand" "r,r")
9596 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))
bd5b4116 9597 (clobber (reg:CC CC_REGNUM))]
cffb2a26 9598 "TARGET_ARM"
9c08d1fa 9599 "*
9c08d1fa 9600 /* If we have an operation where (op x 0) is the identity operation and
01cc3b75 9601 the conditional operator is LT or GE and we are comparing against zero and
9c08d1fa 9602 everything is in registers then we can do this in two instructions */
9603 if (operands[5] == const0_rtx
9604 && GET_CODE (operands[7]) != AND
0438d37f 9605 && REG_P (operands[3])
9606 && REG_P (operands[1])
9c08d1fa 9607 && REGNO (operands[1]) == REGNO (operands[2])
9608 && REGNO (operands[2]) != REGNO (operands[0]))
9609 {
9610 if (GET_CODE (operands[6]) == GE)
40dbec34 9611 return \"and\\t%0, %3, %4, asr #31\;%I7\\t%0, %2, %0\";
9c08d1fa 9612 else if (GET_CODE (operands[6]) == LT)
40dbec34 9613 return \"bic\\t%0, %3, %4, asr #31\;%I7\\t%0, %2, %0\";
9c08d1fa 9614 }
40dbec34 9615
0438d37f 9616 if (CONST_INT_P (operands[5])
9c08d1fa 9617 && !const_ok_for_arm (INTVAL (operands[5])))
e2348bcb 9618 output_asm_insn (\"cmn\\t%4, #%n5\", operands);
9c08d1fa 9619 else
e2348bcb 9620 output_asm_insn (\"cmp\\t%4, %5\", operands);
40dbec34 9621
9c08d1fa 9622 if (which_alternative != 0)
129a2fe4 9623 output_asm_insn (\"mov%d6\\t%0, %1\", operands);
40dbec34 9624 return \"%I7%D6\\t%0, %2, %3\";
215b30b3 9625 "
8fa3ba89 9626 [(set_attr "conds" "clob")
1b7da4ac 9627 (set_attr "length" "8,12")
9628 (set_attr "type" "multiple")]
8fa3ba89 9629)
9c08d1fa 9630
8a18b90c 9631(define_insn "*if_move_arith"
129a2fe4 9632 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8a18b90c 9633 (if_then_else:SI
8fa3ba89 9634 (match_operator 4 "arm_comparison_operator"
8a18b90c 9635 [(match_operand 6 "cc_register" "") (const_int 0)])
129a2fe4 9636 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
8a18b90c 9637 (match_operator:SI 5 "shiftable_operator"
129a2fe4 9638 [(match_operand:SI 2 "s_register_operand" "r,r")
9639 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))]
cffb2a26 9640 "TARGET_ARM"
8a18b90c 9641 "@
9642 %I5%D4\\t%0, %2, %3
129a2fe4 9643 %I5%D4\\t%0, %2, %3\;mov%d4\\t%0, %1"
8fa3ba89 9644 [(set_attr "conds" "use")
9645 (set_attr "length" "4,8")
1b7da4ac 9646 (set_attr "type" "alu_shift_reg,multiple")]
8fa3ba89 9647)
8a18b90c 9648
9649(define_insn "*ifcompare_move_not"
9c08d1fa 9650 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8a18b90c 9651 (if_then_else:SI
8fa3ba89 9652 (match_operator 5 "arm_comparison_operator"
8a18b90c 9653 [(match_operand:SI 3 "s_register_operand" "r,r")
9654 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
9655 (match_operand:SI 1 "arm_not_operand" "0,?rIK")
9656 (not:SI
9657 (match_operand:SI 2 "s_register_operand" "r,r"))))
bd5b4116 9658 (clobber (reg:CC CC_REGNUM))]
cffb2a26 9659 "TARGET_ARM"
8a18b90c 9660 "#"
8fa3ba89 9661 [(set_attr "conds" "clob")
1b7da4ac 9662 (set_attr "length" "8,12")
9663 (set_attr "type" "multiple")]
8fa3ba89 9664)
9c08d1fa 9665
8a18b90c 9666(define_insn "*if_move_not"
9667 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9668 (if_then_else:SI
8fa3ba89 9669 (match_operator 4 "arm_comparison_operator"
8a18b90c 9670 [(match_operand 3 "cc_register" "") (const_int 0)])
9671 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")
9672 (not:SI (match_operand:SI 2 "s_register_operand" "r,r,r"))))]
cffb2a26 9673 "TARGET_ARM"
8a18b90c 9674 "@
9675 mvn%D4\\t%0, %2
9676 mov%d4\\t%0, %1\;mvn%D4\\t%0, %2
9677 mvn%d4\\t%0, #%B1\;mvn%D4\\t%0, %2"
8fa3ba89 9678 [(set_attr "conds" "use")
1aed5204 9679 (set_attr "type" "mvn_reg")
1b7da4ac 9680 (set_attr "length" "4,8,8")
9681 (set_attr "type" "mvn_reg,multiple,multiple")]
8fa3ba89 9682)
8a18b90c 9683
9684(define_insn "*ifcompare_not_move"
9c08d1fa 9685 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8a18b90c 9686 (if_then_else:SI
8fa3ba89 9687 (match_operator 5 "arm_comparison_operator"
8a18b90c 9688 [(match_operand:SI 3 "s_register_operand" "r,r")
9689 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
9690 (not:SI
9691 (match_operand:SI 2 "s_register_operand" "r,r"))
9692 (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
bd5b4116 9693 (clobber (reg:CC CC_REGNUM))]
cffb2a26 9694 "TARGET_ARM"
8a18b90c 9695 "#"
8fa3ba89 9696 [(set_attr "conds" "clob")
1b7da4ac 9697 (set_attr "length" "8,12")
9698 (set_attr "type" "multiple")]
8fa3ba89 9699)
9c08d1fa 9700
8a18b90c 9701(define_insn "*if_not_move"
9702 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9703 (if_then_else:SI
8fa3ba89 9704 (match_operator 4 "arm_comparison_operator"
8a18b90c 9705 [(match_operand 3 "cc_register" "") (const_int 0)])
9706 (not:SI (match_operand:SI 2 "s_register_operand" "r,r,r"))
9707 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")))]
cffb2a26 9708 "TARGET_ARM"
8a18b90c 9709 "@
9710 mvn%d4\\t%0, %2
9711 mov%D4\\t%0, %1\;mvn%d4\\t%0, %2
9712 mvn%D4\\t%0, #%B1\;mvn%d4\\t%0, %2"
8fa3ba89 9713 [(set_attr "conds" "use")
1b7da4ac 9714 (set_attr "type" "mvn_reg,multiple,multiple")
8fa3ba89 9715 (set_attr "length" "4,8,8")]
9716)
8a18b90c 9717
9718(define_insn "*ifcompare_shift_move"
9c08d1fa 9719 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8a18b90c 9720 (if_then_else:SI
8fa3ba89 9721 (match_operator 6 "arm_comparison_operator"
8a18b90c 9722 [(match_operand:SI 4 "s_register_operand" "r,r")
9723 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
9724 (match_operator:SI 7 "shift_operator"
9725 [(match_operand:SI 2 "s_register_operand" "r,r")
9726 (match_operand:SI 3 "arm_rhs_operand" "rM,rM")])
9727 (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
bd5b4116 9728 (clobber (reg:CC CC_REGNUM))]
cffb2a26 9729 "TARGET_ARM"
9c08d1fa 9730 "#"
8fa3ba89 9731 [(set_attr "conds" "clob")
1b7da4ac 9732 (set_attr "length" "8,12")
9733 (set_attr "type" "multiple")]
8fa3ba89 9734)
9c08d1fa 9735
8a18b90c 9736(define_insn "*if_shift_move"
9737 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9738 (if_then_else:SI
8fa3ba89 9739 (match_operator 5 "arm_comparison_operator"
8a18b90c 9740 [(match_operand 6 "cc_register" "") (const_int 0)])
9741 (match_operator:SI 4 "shift_operator"
9742 [(match_operand:SI 2 "s_register_operand" "r,r,r")
9743 (match_operand:SI 3 "arm_rhs_operand" "rM,rM,rM")])
9744 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")))]
cffb2a26 9745 "TARGET_ARM"
5565501b 9746 "@
8a18b90c 9747 mov%d5\\t%0, %2%S4
9748 mov%D5\\t%0, %1\;mov%d5\\t%0, %2%S4
9749 mvn%D5\\t%0, #%B1\;mov%d5\\t%0, %2%S4"
8fa3ba89 9750 [(set_attr "conds" "use")
331beb1a 9751 (set_attr "shift" "2")
a2cd141b 9752 (set_attr "length" "4,8,8")
1b7da4ac 9753 (set_attr "type" "mov_shift_reg,multiple,multiple")]
8fa3ba89 9754)
5565501b 9755
8a18b90c 9756(define_insn "*ifcompare_move_shift"
9757 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5565501b 9758 (if_then_else:SI
8fa3ba89 9759 (match_operator 6 "arm_comparison_operator"
8a18b90c 9760 [(match_operand:SI 4 "s_register_operand" "r,r")
9761 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
9762 (match_operand:SI 1 "arm_not_operand" "0,?rIK")
5565501b 9763 (match_operator:SI 7 "shift_operator"
8a18b90c 9764 [(match_operand:SI 2 "s_register_operand" "r,r")
9765 (match_operand:SI 3 "arm_rhs_operand" "rM,rM")])))
bd5b4116 9766 (clobber (reg:CC CC_REGNUM))]
cffb2a26 9767 "TARGET_ARM"
8a18b90c 9768 "#"
8fa3ba89 9769 [(set_attr "conds" "clob")
1b7da4ac 9770 (set_attr "length" "8,12")
9771 (set_attr "type" "multiple")]
8fa3ba89 9772)
5565501b 9773
8a18b90c 9774(define_insn "*if_move_shift"
9775 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
5565501b 9776 (if_then_else:SI
8fa3ba89 9777 (match_operator 5 "arm_comparison_operator"
8a18b90c 9778 [(match_operand 6 "cc_register" "") (const_int 0)])
9779 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")
9780 (match_operator:SI 4 "shift_operator"
9781 [(match_operand:SI 2 "s_register_operand" "r,r,r")
9782 (match_operand:SI 3 "arm_rhs_operand" "rM,rM,rM")])))]
cffb2a26 9783 "TARGET_ARM"
5565501b 9784 "@
8a18b90c 9785 mov%D5\\t%0, %2%S4
9786 mov%d5\\t%0, %1\;mov%D5\\t%0, %2%S4
9787 mvn%d5\\t%0, #%B1\;mov%D5\\t%0, %2%S4"
8fa3ba89 9788 [(set_attr "conds" "use")
331beb1a 9789 (set_attr "shift" "2")
a2cd141b 9790 (set_attr "length" "4,8,8")
1b7da4ac 9791 (set_attr "type" "mov_shift_reg,multiple,multiple")]
8fa3ba89 9792)
9c08d1fa 9793
f7fbdd4a 9794(define_insn "*ifcompare_shift_shift"
8a18b90c 9795 [(set (match_operand:SI 0 "s_register_operand" "=r")
5565501b 9796 (if_then_else:SI
8fa3ba89 9797 (match_operator 7 "arm_comparison_operator"
8a18b90c 9798 [(match_operand:SI 5 "s_register_operand" "r")
9799 (match_operand:SI 6 "arm_add_operand" "rIL")])
5565501b 9800 (match_operator:SI 8 "shift_operator"
8a18b90c 9801 [(match_operand:SI 1 "s_register_operand" "r")
9802 (match_operand:SI 2 "arm_rhs_operand" "rM")])
5565501b 9803 (match_operator:SI 9 "shift_operator"
8a18b90c 9804 [(match_operand:SI 3 "s_register_operand" "r")
9805 (match_operand:SI 4 "arm_rhs_operand" "rM")])))
bd5b4116 9806 (clobber (reg:CC CC_REGNUM))]
cffb2a26 9807 "TARGET_ARM"
8a18b90c 9808 "#"
8fa3ba89 9809 [(set_attr "conds" "clob")
1b7da4ac 9810 (set_attr "length" "12")
9811 (set_attr "type" "multiple")]
8fa3ba89 9812)
9c08d1fa 9813
8a18b90c 9814(define_insn "*if_shift_shift"
9815 [(set (match_operand:SI 0 "s_register_operand" "=r")
9816 (if_then_else:SI
8fa3ba89 9817 (match_operator 5 "arm_comparison_operator"
8a18b90c 9818 [(match_operand 8 "cc_register" "") (const_int 0)])
9819 (match_operator:SI 6 "shift_operator"
9820 [(match_operand:SI 1 "s_register_operand" "r")
9821 (match_operand:SI 2 "arm_rhs_operand" "rM")])
9822 (match_operator:SI 7 "shift_operator"
9823 [(match_operand:SI 3 "s_register_operand" "r")
9824 (match_operand:SI 4 "arm_rhs_operand" "rM")])))]
cffb2a26 9825 "TARGET_ARM"
8a18b90c 9826 "mov%d5\\t%0, %1%S6\;mov%D5\\t%0, %3%S7"
8fa3ba89 9827 [(set_attr "conds" "use")
331beb1a 9828 (set_attr "shift" "1")
a2cd141b 9829 (set_attr "length" "8")
9830 (set (attr "type") (if_then_else
9831 (and (match_operand 2 "const_int_operand" "")
9832 (match_operand 4 "const_int_operand" ""))
1aed5204 9833 (const_string "mov_shift")
9834 (const_string "mov_shift_reg")))]
8fa3ba89 9835)
8a18b90c 9836
f7fbdd4a 9837(define_insn "*ifcompare_not_arith"
8a18b90c 9838 [(set (match_operand:SI 0 "s_register_operand" "=r")
5565501b 9839 (if_then_else:SI
8fa3ba89 9840 (match_operator 6 "arm_comparison_operator"
8a18b90c 9841 [(match_operand:SI 4 "s_register_operand" "r")
9842 (match_operand:SI 5 "arm_add_operand" "rIL")])
9843 (not:SI (match_operand:SI 1 "s_register_operand" "r"))
5565501b 9844 (match_operator:SI 7 "shiftable_operator"
8a18b90c 9845 [(match_operand:SI 2 "s_register_operand" "r")
9846 (match_operand:SI 3 "arm_rhs_operand" "rI")])))
bd5b4116 9847 (clobber (reg:CC CC_REGNUM))]
cffb2a26 9848 "TARGET_ARM"
8a18b90c 9849 "#"
8fa3ba89 9850 [(set_attr "conds" "clob")
1b7da4ac 9851 (set_attr "length" "12")
9852 (set_attr "type" "multiple")]
8fa3ba89 9853)
9c08d1fa 9854
8a18b90c 9855(define_insn "*if_not_arith"
9856 [(set (match_operand:SI 0 "s_register_operand" "=r")
9857 (if_then_else:SI
8fa3ba89 9858 (match_operator 5 "arm_comparison_operator"
8a18b90c 9859 [(match_operand 4 "cc_register" "") (const_int 0)])
9860 (not:SI (match_operand:SI 1 "s_register_operand" "r"))
9861 (match_operator:SI 6 "shiftable_operator"
9862 [(match_operand:SI 2 "s_register_operand" "r")
9863 (match_operand:SI 3 "arm_rhs_operand" "rI")])))]
cffb2a26 9864 "TARGET_ARM"
8a18b90c 9865 "mvn%d5\\t%0, %1\;%I6%D5\\t%0, %2, %3"
8fa3ba89 9866 [(set_attr "conds" "use")
1aed5204 9867 (set_attr "type" "mvn_reg")
8fa3ba89 9868 (set_attr "length" "8")]
9869)
8a18b90c 9870
9871(define_insn "*ifcompare_arith_not"
9872 [(set (match_operand:SI 0 "s_register_operand" "=r")
5565501b 9873 (if_then_else:SI
8fa3ba89 9874 (match_operator 6 "arm_comparison_operator"
8a18b90c 9875 [(match_operand:SI 4 "s_register_operand" "r")
9876 (match_operand:SI 5 "arm_add_operand" "rIL")])
5565501b 9877 (match_operator:SI 7 "shiftable_operator"
8a18b90c 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"))))
bd5b4116 9881 (clobber (reg:CC CC_REGNUM))]
cffb2a26 9882 "TARGET_ARM"
8a18b90c 9883 "#"
8fa3ba89 9884 [(set_attr "conds" "clob")
1b7da4ac 9885 (set_attr "length" "12")
9886 (set_attr "type" "multiple")]
8fa3ba89 9887)
9c08d1fa 9888
8a18b90c 9889(define_insn "*if_arith_not"
9890 [(set (match_operand:SI 0 "s_register_operand" "=r")
9891 (if_then_else:SI
8fa3ba89 9892 (match_operator 5 "arm_comparison_operator"
8a18b90c 9893 [(match_operand 4 "cc_register" "") (const_int 0)])
9894 (match_operator:SI 6 "shiftable_operator"
9895 [(match_operand:SI 2 "s_register_operand" "r")
9896 (match_operand:SI 3 "arm_rhs_operand" "rI")])
9897 (not:SI (match_operand:SI 1 "s_register_operand" "r"))))]
cffb2a26 9898 "TARGET_ARM"
8a18b90c 9899 "mvn%D5\\t%0, %1\;%I6%d5\\t%0, %2, %3"
8fa3ba89 9900 [(set_attr "conds" "use")
1b7da4ac 9901 (set_attr "type" "multiple")
8fa3ba89 9902 (set_attr "length" "8")]
9903)
8a18b90c 9904
f7fbdd4a 9905(define_insn "*ifcompare_neg_move"
8a18b90c 9906 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5565501b 9907 (if_then_else:SI
8fa3ba89 9908 (match_operator 5 "arm_comparison_operator"
8a18b90c 9909 [(match_operand:SI 3 "s_register_operand" "r,r")
9910 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
9911 (neg:SI (match_operand:SI 2 "s_register_operand" "r,r"))
9912 (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
bd5b4116 9913 (clobber (reg:CC CC_REGNUM))]
cffb2a26 9914 "TARGET_ARM"
8a18b90c 9915 "#"
8fa3ba89 9916 [(set_attr "conds" "clob")
1b7da4ac 9917 (set_attr "length" "8,12")
9918 (set_attr "type" "multiple")]
8fa3ba89 9919)
8a18b90c 9920
9921(define_insn "*if_neg_move"
9922 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9923 (if_then_else:SI
8fa3ba89 9924 (match_operator 4 "arm_comparison_operator"
8a18b90c 9925 [(match_operand 3 "cc_register" "") (const_int 0)])
9926 (neg:SI (match_operand:SI 2 "s_register_operand" "r,r,r"))
9927 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")))]
cffb2a26 9928 "TARGET_ARM"
8a18b90c 9929 "@
9930 rsb%d4\\t%0, %2, #0
9931 mov%D4\\t%0, %1\;rsb%d4\\t%0, %2, #0
9932 mvn%D4\\t%0, #%B1\;rsb%d4\\t%0, %2, #0"
8fa3ba89 9933 [(set_attr "conds" "use")
1b7da4ac 9934 (set_attr "length" "4,8,8")
9935 (set_attr "type" "logic_shift_imm,multiple,multiple")]
8fa3ba89 9936)
9c08d1fa 9937
f7fbdd4a 9938(define_insn "*ifcompare_move_neg"
8a18b90c 9939 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5565501b 9940 (if_then_else:SI
8fa3ba89 9941 (match_operator 5 "arm_comparison_operator"
8a18b90c 9942 [(match_operand:SI 3 "s_register_operand" "r,r")
9943 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
9944 (match_operand:SI 1 "arm_not_operand" "0,?rIK")
9945 (neg:SI (match_operand:SI 2 "s_register_operand" "r,r"))))
bd5b4116 9946 (clobber (reg:CC CC_REGNUM))]
cffb2a26 9947 "TARGET_ARM"
8a18b90c 9948 "#"
8fa3ba89 9949 [(set_attr "conds" "clob")
1b7da4ac 9950 (set_attr "length" "8,12")
9951 (set_attr "type" "multiple")]
8fa3ba89 9952)
8a18b90c 9953
9954(define_insn "*if_move_neg"
9955 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9956 (if_then_else:SI
8fa3ba89 9957 (match_operator 4 "arm_comparison_operator"
8a18b90c 9958 [(match_operand 3 "cc_register" "") (const_int 0)])
9959 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")
9960 (neg:SI (match_operand:SI 2 "s_register_operand" "r,r,r"))))]
cffb2a26 9961 "TARGET_ARM"
8a18b90c 9962 "@
9963 rsb%D4\\t%0, %2, #0
9964 mov%d4\\t%0, %1\;rsb%D4\\t%0, %2, #0
9965 mvn%d4\\t%0, #%B1\;rsb%D4\\t%0, %2, #0"
0d66636f 9966 [(set_attr "conds" "use")
1b7da4ac 9967 (set_attr "length" "4,8,8")
9968 (set_attr "type" "logic_shift_imm,multiple,multiple")]
0d66636f 9969)
9c08d1fa 9970
f7fbdd4a 9971(define_insn "*arith_adjacentmem"
9c08d1fa 9972 [(set (match_operand:SI 0 "s_register_operand" "=r")
9973 (match_operator:SI 1 "shiftable_operator"
9974 [(match_operand:SI 2 "memory_operand" "m")
9975 (match_operand:SI 3 "memory_operand" "m")]))
9976 (clobber (match_scratch:SI 4 "=r"))]
cffb2a26 9977 "TARGET_ARM && adjacent_mem_locations (operands[2], operands[3])"
9c08d1fa 9978 "*
215b30b3 9979 {
9980 rtx ldm[3];
9981 rtx arith[4];
94dee231 9982 rtx base_reg;
9983 HOST_WIDE_INT val1 = 0, val2 = 0;
9c08d1fa 9984
215b30b3 9985 if (REGNO (operands[0]) > REGNO (operands[4]))
9986 {
9987 ldm[1] = operands[4];
9988 ldm[2] = operands[0];
9989 }
9990 else
9991 {
9992 ldm[1] = operands[0];
9993 ldm[2] = operands[4];
9994 }
94dee231 9995
9996 base_reg = XEXP (operands[2], 0);
9997
9998 if (!REG_P (base_reg))
9999 {
10000 val1 = INTVAL (XEXP (base_reg, 1));
10001 base_reg = XEXP (base_reg, 0);
10002 }
10003
10004 if (!REG_P (XEXP (operands[3], 0)))
215b30b3 10005 val2 = INTVAL (XEXP (XEXP (operands[3], 0), 1));
94dee231 10006
215b30b3 10007 arith[0] = operands[0];
10008 arith[3] = operands[1];
94dee231 10009
215b30b3 10010 if (val1 < val2)
10011 {
10012 arith[1] = ldm[1];
10013 arith[2] = ldm[2];
10014 }
10015 else
10016 {
10017 arith[1] = ldm[2];
10018 arith[2] = ldm[1];
10019 }
94dee231 10020
10021 ldm[0] = base_reg;
10022 if (val1 !=0 && val2 != 0)
215b30b3 10023 {
cdb1295a 10024 rtx ops[3];
10025
94dee231 10026 if (val1 == 4 || val2 == 4)
10027 /* Other val must be 8, since we know they are adjacent and neither
10028 is zero. */
25f905c2 10029 output_asm_insn (\"ldm%(ib%)\\t%0, {%1, %2}\", ldm);
cdb1295a 10030 else if (const_ok_for_arm (val1) || const_ok_for_arm (-val1))
94dee231 10031 {
94dee231 10032 ldm[0] = ops[0] = operands[4];
10033 ops[1] = base_reg;
10034 ops[2] = GEN_INT (val1);
10035 output_add_immediate (ops);
10036 if (val1 < val2)
25f905c2 10037 output_asm_insn (\"ldm%(ia%)\\t%0, {%1, %2}\", ldm);
94dee231 10038 else
25f905c2 10039 output_asm_insn (\"ldm%(da%)\\t%0, {%1, %2}\", ldm);
94dee231 10040 }
cdb1295a 10041 else
10042 {
10043 /* Offset is out of range for a single add, so use two ldr. */
10044 ops[0] = ldm[1];
10045 ops[1] = base_reg;
10046 ops[2] = GEN_INT (val1);
10047 output_asm_insn (\"ldr%?\\t%0, [%1, %2]\", ops);
10048 ops[0] = ldm[2];
10049 ops[2] = GEN_INT (val2);
10050 output_asm_insn (\"ldr%?\\t%0, [%1, %2]\", ops);
10051 }
215b30b3 10052 }
94dee231 10053 else if (val1 != 0)
215b30b3 10054 {
215b30b3 10055 if (val1 < val2)
25f905c2 10056 output_asm_insn (\"ldm%(da%)\\t%0, {%1, %2}\", ldm);
215b30b3 10057 else
25f905c2 10058 output_asm_insn (\"ldm%(ia%)\\t%0, {%1, %2}\", ldm);
215b30b3 10059 }
10060 else
10061 {
215b30b3 10062 if (val1 < val2)
25f905c2 10063 output_asm_insn (\"ldm%(ia%)\\t%0, {%1, %2}\", ldm);
215b30b3 10064 else
25f905c2 10065 output_asm_insn (\"ldm%(da%)\\t%0, {%1, %2}\", ldm);
215b30b3 10066 }
10067 output_asm_insn (\"%I3%?\\t%0, %1, %2\", arith);
10068 return \"\";
10069 }"
10070 [(set_attr "length" "12")
10071 (set_attr "predicable" "yes")
a2cd141b 10072 (set_attr "type" "load1")]
215b30b3 10073)
9c08d1fa 10074
9c08d1fa 10075; This pattern is never tried by combine, so do it as a peephole
10076
a0f94409 10077(define_peephole2
372575c7 10078 [(set (match_operand:SI 0 "arm_general_register_operand" "")
10079 (match_operand:SI 1 "arm_general_register_operand" ""))
bd5b4116 10080 (set (reg:CC CC_REGNUM)
aea4c774 10081 (compare:CC (match_dup 1) (const_int 0)))]
372575c7 10082 "TARGET_ARM"
a0f94409 10083 [(parallel [(set (reg:CC CC_REGNUM) (compare:CC (match_dup 1) (const_int 0)))
10084 (set (match_dup 0) (match_dup 1))])]
10085 ""
0d66636f 10086)
9c08d1fa 10087
9c08d1fa 10088(define_split
10089 [(set (match_operand:SI 0 "s_register_operand" "")
10090 (and:SI (ge:SI (match_operand:SI 1 "s_register_operand" "")
10091 (const_int 0))
8fa3ba89 10092 (neg:SI (match_operator:SI 2 "arm_comparison_operator"
9c08d1fa 10093 [(match_operand:SI 3 "s_register_operand" "")
10094 (match_operand:SI 4 "arm_rhs_operand" "")]))))
10095 (clobber (match_operand:SI 5 "s_register_operand" ""))]
cffb2a26 10096 "TARGET_ARM"
9c08d1fa 10097 [(set (match_dup 5) (not:SI (ashiftrt:SI (match_dup 1) (const_int 31))))
10098 (set (match_dup 0) (and:SI (match_op_dup 2 [(match_dup 3) (match_dup 4)])
10099 (match_dup 5)))]
215b30b3 10100 ""
10101)
9c08d1fa 10102
aea4c774 10103;; This split can be used because CC_Z mode implies that the following
10104;; branch will be an equality, or an unsigned inequality, so the sign
10105;; extension is not needed.
9c08d1fa 10106
aea4c774 10107(define_split
bd5b4116 10108 [(set (reg:CC_Z CC_REGNUM)
aea4c774 10109 (compare:CC_Z
10110 (ashift:SI (subreg:SI (match_operand:QI 0 "memory_operand" "") 0)
9c08d1fa 10111 (const_int 24))
aea4c774 10112 (match_operand 1 "const_int_operand" "")))
10113 (clobber (match_scratch:SI 2 ""))]
cffb2a26 10114 "TARGET_ARM
10115 && (((unsigned HOST_WIDE_INT) INTVAL (operands[1]))
10116 == (((unsigned HOST_WIDE_INT) INTVAL (operands[1])) >> 24) << 24)"
aea4c774 10117 [(set (match_dup 2) (zero_extend:SI (match_dup 0)))
bd5b4116 10118 (set (reg:CC CC_REGNUM) (compare:CC (match_dup 2) (match_dup 1)))]
aea4c774 10119 "
9c08d1fa 10120 operands[1] = GEN_INT (((unsigned long) INTVAL (operands[1])) >> 24);
215b30b3 10121 "
10122)
25f905c2 10123;; ??? Check the patterns above for Thumb-2 usefulness
9c08d1fa 10124
87b22bf7 10125(define_expand "prologue"
10126 [(clobber (const_int 0))]
cffb2a26 10127 "TARGET_EITHER"
25f905c2 10128 "if (TARGET_32BIT)
cffb2a26 10129 arm_expand_prologue ();
10130 else
25f905c2 10131 thumb1_expand_prologue ();
87b22bf7 10132 DONE;
cffb2a26 10133 "
10134)
87b22bf7 10135
56d27660 10136(define_expand "epilogue"
4c44712e 10137 [(clobber (const_int 0))]
cffb2a26 10138 "TARGET_EITHER"
56d27660 10139 "
18d50ae6 10140 if (crtl->calls_eh_return)
fb94f18b 10141 emit_insn (gen_force_register_use (gen_rtx_REG (Pmode, 2)));
25f905c2 10142 if (TARGET_THUMB1)
c3635784 10143 {
10144 thumb1_expand_epilogue ();
10145 emit_jump_insn (gen_rtx_UNSPEC_VOLATILE (VOIDmode,
10146 gen_rtvec (1, ret_rtx), VUNSPEC_EPILOGUE));
10147 }
10148 else if (HAVE_return)
10149 {
10150 /* HAVE_return is testing for USE_RETURN_INSN (FALSE). Hence,
10151 no need for explicit testing again. */
10152 emit_jump_insn (gen_return ());
10153 }
10154 else if (TARGET_32BIT)
10155 {
10156 arm_expand_epilogue (true);
10157 }
cffb2a26 10158 DONE;
10159 "
10160)
56d27660 10161
ef5651d0 10162;; Note - although unspec_volatile's USE all hard registers,
10163;; USEs are ignored after relaod has completed. Thus we need
10164;; to add an unspec of the link register to ensure that flow
10165;; does not think that it is unused by the sibcall branch that
10166;; will replace the standard function epilogue.
c3635784 10167(define_expand "sibcall_epilogue"
fb94f18b 10168 [(parallel [(unspec:SI [(reg:SI LR_REGNUM)] UNSPEC_REGISTER_USE)
c3635784 10169 (unspec_volatile [(return)] VUNSPEC_EPILOGUE)])]
10170 "TARGET_32BIT"
10171 "
10172 arm_expand_epilogue (false);
10173 DONE;
10174 "
1c494086 10175)
10176
cffb2a26 10177(define_expand "eh_epilogue"
7db9af5d 10178 [(use (match_operand:SI 0 "register_operand" ""))
10179 (use (match_operand:SI 1 "register_operand" ""))
10180 (use (match_operand:SI 2 "register_operand" ""))]
cffb2a26 10181 "TARGET_EITHER"
10182 "
215b30b3 10183 {
10184 cfun->machine->eh_epilogue_sp_ofs = operands[1];
0438d37f 10185 if (!REG_P (operands[2]) || REGNO (operands[2]) != 2)
215b30b3 10186 {
10187 rtx ra = gen_rtx_REG (Pmode, 2);
10188
10189 emit_move_insn (ra, operands[2]);
10190 operands[2] = ra;
10191 }
5cf3595a 10192 /* This is a hack -- we may have crystalized the function type too
10193 early. */
10194 cfun->machine->func_type = 0;
215b30b3 10195 }"
10196)
56d27660 10197
9c08d1fa 10198;; This split is only used during output to reduce the number of patterns
10199;; that need assembler instructions adding to them. We allowed the setting
10200;; of the conditions to be implicit during rtl generation so that
10201;; the conditional compare patterns would work. However this conflicts to
8a18b90c 10202;; some extent with the conditional data operations, so we have to split them
9c08d1fa 10203;; up again here.
10204
25f905c2 10205;; ??? Need to audit these splitters for Thumb-2. Why isn't normal
10206;; conditional execution sufficient?
10207
9c08d1fa 10208(define_split
10209 [(set (match_operand:SI 0 "s_register_operand" "")
8fa3ba89 10210 (if_then_else:SI (match_operator 1 "arm_comparison_operator"
10211 [(match_operand 2 "" "") (match_operand 3 "" "")])
10212 (match_dup 0)
10213 (match_operand 4 "" "")))
bd5b4116 10214 (clobber (reg:CC CC_REGNUM))]
ac8b093b 10215 "TARGET_ARM && reload_completed"
8fa3ba89 10216 [(set (match_dup 5) (match_dup 6))
10217 (cond_exec (match_dup 7)
10218 (set (match_dup 0) (match_dup 4)))]
10219 "
10220 {
3754d046 10221 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
8fa3ba89 10222 operands[2], operands[3]);
10223 enum rtx_code rc = GET_CODE (operands[1]);
10224
bd5b4116 10225 operands[5] = gen_rtx_REG (mode, CC_REGNUM);
8fa3ba89 10226 operands[6] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
10227 if (mode == CCFPmode || mode == CCFPEmode)
10228 rc = reverse_condition_maybe_unordered (rc);
10229 else
10230 rc = reverse_condition (rc);
10231
10232 operands[7] = gen_rtx_fmt_ee (rc, VOIDmode, operands[5], const0_rtx);
10233 }"
10234)
10235
10236(define_split
10237 [(set (match_operand:SI 0 "s_register_operand" "")
10238 (if_then_else:SI (match_operator 1 "arm_comparison_operator"
10239 [(match_operand 2 "" "") (match_operand 3 "" "")])
10240 (match_operand 4 "" "")
10241 (match_dup 0)))
bd5b4116 10242 (clobber (reg:CC CC_REGNUM))]
ac8b093b 10243 "TARGET_ARM && reload_completed"
8fa3ba89 10244 [(set (match_dup 5) (match_dup 6))
10245 (cond_exec (match_op_dup 1 [(match_dup 5) (const_int 0)])
10246 (set (match_dup 0) (match_dup 4)))]
10247 "
10248 {
3754d046 10249 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
8fa3ba89 10250 operands[2], operands[3]);
10251
bd5b4116 10252 operands[5] = gen_rtx_REG (mode, CC_REGNUM);
8fa3ba89 10253 operands[6] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
10254 }"
10255)
10256
10257(define_split
10258 [(set (match_operand:SI 0 "s_register_operand" "")
10259 (if_then_else:SI (match_operator 1 "arm_comparison_operator"
9c08d1fa 10260 [(match_operand 2 "" "") (match_operand 3 "" "")])
10261 (match_operand 4 "" "")
10262 (match_operand 5 "" "")))
bd5b4116 10263 (clobber (reg:CC CC_REGNUM))]
ac8b093b 10264 "TARGET_ARM && reload_completed"
8fa3ba89 10265 [(set (match_dup 6) (match_dup 7))
10266 (cond_exec (match_op_dup 1 [(match_dup 6) (const_int 0)])
10267 (set (match_dup 0) (match_dup 4)))
10268 (cond_exec (match_dup 8)
10269 (set (match_dup 0) (match_dup 5)))]
10270 "
10271 {
3754d046 10272 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
8fa3ba89 10273 operands[2], operands[3]);
10274 enum rtx_code rc = GET_CODE (operands[1]);
10275
bd5b4116 10276 operands[6] = gen_rtx_REG (mode, CC_REGNUM);
8fa3ba89 10277 operands[7] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
10278 if (mode == CCFPmode || mode == CCFPEmode)
10279 rc = reverse_condition_maybe_unordered (rc);
10280 else
10281 rc = reverse_condition (rc);
10282
10283 operands[8] = gen_rtx_fmt_ee (rc, VOIDmode, operands[6], const0_rtx);
10284 }"
10285)
10286
cffb2a26 10287(define_split
10288 [(set (match_operand:SI 0 "s_register_operand" "")
8fa3ba89 10289 (if_then_else:SI (match_operator 1 "arm_comparison_operator"
cffb2a26 10290 [(match_operand:SI 2 "s_register_operand" "")
10291 (match_operand:SI 3 "arm_add_operand" "")])
10292 (match_operand:SI 4 "arm_rhs_operand" "")
10293 (not:SI
10294 (match_operand:SI 5 "s_register_operand" ""))))
bd5b4116 10295 (clobber (reg:CC CC_REGNUM))]
ac8b093b 10296 "TARGET_ARM && reload_completed"
cffb2a26 10297 [(set (match_dup 6) (match_dup 7))
f6c53574 10298 (cond_exec (match_op_dup 1 [(match_dup 6) (const_int 0)])
10299 (set (match_dup 0) (match_dup 4)))
10300 (cond_exec (match_dup 8)
10301 (set (match_dup 0) (not:SI (match_dup 5))))]
cffb2a26 10302 "
215b30b3 10303 {
3754d046 10304 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
215b30b3 10305 operands[2], operands[3]);
f6c53574 10306 enum rtx_code rc = GET_CODE (operands[1]);
cffb2a26 10307
bd5b4116 10308 operands[6] = gen_rtx_REG (mode, CC_REGNUM);
1a83b3ff 10309 operands[7] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
f6c53574 10310 if (mode == CCFPmode || mode == CCFPEmode)
10311 rc = reverse_condition_maybe_unordered (rc);
10312 else
10313 rc = reverse_condition (rc);
10314
10315 operands[8] = gen_rtx_fmt_ee (rc, VOIDmode, operands[6], const0_rtx);
215b30b3 10316 }"
10317)
cffb2a26 10318
10319(define_insn "*cond_move_not"
10320 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8fa3ba89 10321 (if_then_else:SI (match_operator 4 "arm_comparison_operator"
cffb2a26 10322 [(match_operand 3 "cc_register" "") (const_int 0)])
10323 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
10324 (not:SI
10325 (match_operand:SI 2 "s_register_operand" "r,r"))))]
10326 "TARGET_ARM"
10327 "@
10328 mvn%D4\\t%0, %2
10329 mov%d4\\t%0, %1\;mvn%D4\\t%0, %2"
0d66636f 10330 [(set_attr "conds" "use")
1b7da4ac 10331 (set_attr "type" "mvn_reg,multiple")
0d66636f 10332 (set_attr "length" "4,8")]
10333)
cffb2a26 10334
9c08d1fa 10335;; The next two patterns occur when an AND operation is followed by a
10336;; scc insn sequence
10337
f7fbdd4a 10338(define_insn "*sign_extract_onebit"
9c08d1fa 10339 [(set (match_operand:SI 0 "s_register_operand" "=r")
10340 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
10341 (const_int 1)
ed750274 10342 (match_operand:SI 2 "const_int_operand" "n")))
10343 (clobber (reg:CC CC_REGNUM))]
cffb2a26 10344 "TARGET_ARM"
9c08d1fa 10345 "*
0d66636f 10346 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
10347 output_asm_insn (\"ands\\t%0, %1, %2\", operands);
10348 return \"mvnne\\t%0, #0\";
10349 "
10350 [(set_attr "conds" "clob")
1b7da4ac 10351 (set_attr "length" "8")
10352 (set_attr "type" "multiple")]
0d66636f 10353)
9c08d1fa 10354
f7fbdd4a 10355(define_insn "*not_signextract_onebit"
9c08d1fa 10356 [(set (match_operand:SI 0 "s_register_operand" "=r")
10357 (not:SI
10358 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
10359 (const_int 1)
ed750274 10360 (match_operand:SI 2 "const_int_operand" "n"))))
10361 (clobber (reg:CC CC_REGNUM))]
cffb2a26 10362 "TARGET_ARM"
9c08d1fa 10363 "*
0d66636f 10364 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
10365 output_asm_insn (\"tst\\t%1, %2\", operands);
10366 output_asm_insn (\"mvneq\\t%0, #0\", operands);
10367 return \"movne\\t%0, #0\";
10368 "
10369 [(set_attr "conds" "clob")
1b7da4ac 10370 (set_attr "length" "12")
10371 (set_attr "type" "multiple")]
0d66636f 10372)
25f905c2 10373;; ??? The above patterns need auditing for Thumb-2
87b22bf7 10374
0d66636f 10375;; Push multiple registers to the stack. Registers are in parallel (use ...)
10376;; expressions. For simplicity, the first register is also in the unspec
10377;; part.
08508cbf 10378;; To avoid the usage of GNU extension, the length attribute is computed
10379;; in a C function arm_attr_length_push_multi.
f7fbdd4a 10380(define_insn "*push_multi"
87b22bf7 10381 [(match_parallel 2 "multi_register_push"
7571d3f7 10382 [(set (match_operand:BLK 0 "push_mult_memory_operand" "")
3cc80a30 10383 (unspec:BLK [(match_operand:SI 1 "s_register_operand" "")]
e1159bbe 10384 UNSPEC_PUSH_MULT))])]
7571d3f7 10385 ""
87b22bf7 10386 "*
215b30b3 10387 {
10388 int num_saves = XVECLEN (operands[2], 0);
ed593f11 10389
215b30b3 10390 /* For the StrongARM at least it is faster to
25f905c2 10391 use STR to store only a single register.
542d5028 10392 In Thumb mode always use push, and the assembler will pick
10393 something appropriate. */
25f905c2 10394 if (num_saves == 1 && TARGET_ARM)
61309563 10395 output_asm_insn (\"str%?\\t%1, [%m0, #-4]!\", operands);
215b30b3 10396 else
10397 {
10398 int i;
10399 char pattern[100];
ed593f11 10400
25f905c2 10401 if (TARGET_ARM)
61309563 10402 strcpy (pattern, \"stm%(fd%)\\t%m0!, {%1\");
10403 else if (TARGET_THUMB2)
10404 strcpy (pattern, \"push%?\\t{%1\");
25f905c2 10405 else
10406 strcpy (pattern, \"push\\t{%1\");
215b30b3 10407
6079f055 10408 for (i = 1; i < num_saves; i++)
215b30b3 10409 {
10410 strcat (pattern, \", %|\");
10411 strcat (pattern,
10412 reg_names[REGNO (XEXP (XVECEXP (operands[2], 0, i), 0))]);
10413 }
10414
10415 strcat (pattern, \"}\");
10416 output_asm_insn (pattern, operands);
10417 }
10418
10419 return \"\";
10420 }"
a6864a24 10421 [(set_attr "type" "store4")
10422 (set (attr "length")
08508cbf 10423 (symbol_ref "arm_attr_length_push_multi (operands[2], operands[1])"))]
215b30b3 10424)
f7fbdd4a 10425
4c58c898 10426(define_insn "stack_tie"
10427 [(set (mem:BLK (scratch))
aaa37ad6 10428 (unspec:BLK [(match_operand:SI 0 "s_register_operand" "rk")
10429 (match_operand:SI 1 "s_register_operand" "rk")]
4c58c898 10430 UNSPEC_PRLG_STK))]
10431 ""
10432 ""
1b7da4ac 10433 [(set_attr "length" "0")
10434 (set_attr "type" "block")]
4c58c898 10435)
10436
426be8c5 10437;; Pop (as used in epilogue RTL)
10438;;
10439(define_insn "*load_multiple_with_writeback"
10440 [(match_parallel 0 "load_multiple_operation"
10441 [(set (match_operand:SI 1 "s_register_operand" "+rk")
10442 (plus:SI (match_dup 1)
809003b3 10443 (match_operand:SI 2 "const_int_I_operand" "I")))
426be8c5 10444 (set (match_operand:SI 3 "s_register_operand" "=rk")
10445 (mem:SI (match_dup 1)))
10446 ])]
10447 "TARGET_32BIT && (reload_in_progress || reload_completed)"
10448 "*
10449 {
10450 arm_output_multireg_pop (operands, /*return_pc=*/false,
10451 /*cond=*/const_true_rtx,
10452 /*reverse=*/false,
10453 /*update=*/true);
10454 return \"\";
10455 }
10456 "
10457 [(set_attr "type" "load4")
10458 (set_attr "predicable" "yes")]
10459)
10460
10461;; Pop with return (as used in epilogue RTL)
10462;;
10463;; This instruction is generated when the registers are popped at the end of
10464;; epilogue. Here, instead of popping the value into LR and then generating
10465;; jump to LR, value is popped into PC directly. Hence, the pattern is combined
10466;; with (return).
10467(define_insn "*pop_multiple_with_writeback_and_return"
10468 [(match_parallel 0 "pop_multiple_return"
10469 [(return)
10470 (set (match_operand:SI 1 "s_register_operand" "+rk")
10471 (plus:SI (match_dup 1)
809003b3 10472 (match_operand:SI 2 "const_int_I_operand" "I")))
426be8c5 10473 (set (match_operand:SI 3 "s_register_operand" "=rk")
10474 (mem:SI (match_dup 1)))
10475 ])]
10476 "TARGET_32BIT && (reload_in_progress || reload_completed)"
10477 "*
10478 {
10479 arm_output_multireg_pop (operands, /*return_pc=*/true,
10480 /*cond=*/const_true_rtx,
10481 /*reverse=*/false,
10482 /*update=*/true);
10483 return \"\";
10484 }
10485 "
10486 [(set_attr "type" "load4")
10487 (set_attr "predicable" "yes")]
10488)
10489
10490(define_insn "*pop_multiple_with_return"
10491 [(match_parallel 0 "pop_multiple_return"
10492 [(return)
10493 (set (match_operand:SI 2 "s_register_operand" "=rk")
10494 (mem:SI (match_operand:SI 1 "s_register_operand" "rk")))
10495 ])]
10496 "TARGET_32BIT && (reload_in_progress || reload_completed)"
10497 "*
10498 {
10499 arm_output_multireg_pop (operands, /*return_pc=*/true,
10500 /*cond=*/const_true_rtx,
10501 /*reverse=*/false,
10502 /*update=*/false);
10503 return \"\";
10504 }
10505 "
10506 [(set_attr "type" "load4")
10507 (set_attr "predicable" "yes")]
10508)
10509
10510;; Load into PC and return
10511(define_insn "*ldr_with_return"
10512 [(return)
10513 (set (reg:SI PC_REGNUM)
10514 (mem:SI (post_inc:SI (match_operand:SI 0 "s_register_operand" "+rk"))))]
10515 "TARGET_32BIT && (reload_in_progress || reload_completed)"
10516 "ldr%?\t%|pc, [%0], #4"
10517 [(set_attr "type" "load1")
10518 (set_attr "predicable" "yes")]
10519)
1a0b0f12 10520;; Pop for floating point registers (as used in epilogue RTL)
10521(define_insn "*vfp_pop_multiple_with_writeback"
10522 [(match_parallel 0 "pop_multiple_fp"
10523 [(set (match_operand:SI 1 "s_register_operand" "+rk")
10524 (plus:SI (match_dup 1)
809003b3 10525 (match_operand:SI 2 "const_int_I_operand" "I")))
2f2163a4 10526 (set (match_operand:DF 3 "vfp_hard_register_operand" "")
1a0b0f12 10527 (mem:DF (match_dup 1)))])]
10528 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
10529 "*
10530 {
10531 int num_regs = XVECLEN (operands[0], 0);
10532 char pattern[100];
10533 rtx op_list[2];
b34d8dac 10534 strcpy (pattern, \"vldm\\t\");
1a0b0f12 10535 strcat (pattern, reg_names[REGNO (SET_DEST (XVECEXP (operands[0], 0, 0)))]);
10536 strcat (pattern, \"!, {\");
10537 op_list[0] = XEXP (XVECEXP (operands[0], 0, 1), 0);
10538 strcat (pattern, \"%P0\");
10539 if ((num_regs - 1) > 1)
10540 {
10541 strcat (pattern, \"-%P1\");
10542 op_list [1] = XEXP (XVECEXP (operands[0], 0, num_regs - 1), 0);
10543 }
10544
10545 strcat (pattern, \"}\");
10546 output_asm_insn (pattern, op_list);
10547 return \"\";
10548 }
10549 "
10550 [(set_attr "type" "load4")
10551 (set_attr "conds" "unconditional")
10552 (set_attr "predicable" "no")]
10553)
10554
f7fbdd4a 10555;; Special patterns for dealing with the constant pool
10556
cffb2a26 10557(define_insn "align_4"
e1159bbe 10558 [(unspec_volatile [(const_int 0)] VUNSPEC_ALIGN)]
cffb2a26 10559 "TARGET_EITHER"
f7fbdd4a 10560 "*
cffb2a26 10561 assemble_align (32);
f7fbdd4a 10562 return \"\";
cffb2a26 10563 "
1b7da4ac 10564 [(set_attr "type" "no_insn")]
cffb2a26 10565)
f7fbdd4a 10566
755eb2b4 10567(define_insn "align_8"
10568 [(unspec_volatile [(const_int 0)] VUNSPEC_ALIGN8)]
f9273c43 10569 "TARGET_EITHER"
755eb2b4 10570 "*
10571 assemble_align (64);
10572 return \"\";
10573 "
1b7da4ac 10574 [(set_attr "type" "no_insn")]
755eb2b4 10575)
10576
cffb2a26 10577(define_insn "consttable_end"
e1159bbe 10578 [(unspec_volatile [(const_int 0)] VUNSPEC_POOL_END)]
cffb2a26 10579 "TARGET_EITHER"
f7fbdd4a 10580 "*
cffb2a26 10581 making_const_table = FALSE;
f7fbdd4a 10582 return \"\";
cffb2a26 10583 "
1b7da4ac 10584 [(set_attr "type" "no_insn")]
cffb2a26 10585)
f7fbdd4a 10586
0e207eb8 10587(define_insn "consttable_1"
10588 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_1)]
10589 "TARGET_EITHER"
10590 "*
10591 making_const_table = TRUE;
10592 assemble_integer (operands[0], 1, BITS_PER_WORD, 1);
10593 assemble_zeros (3);
10594 return \"\";
10595 "
10596 [(set_attr "length" "4")
10597 (set_attr "type" "no_insn")]
10598)
10599
10600(define_insn "consttable_2"
10601 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_2)]
10602 "TARGET_EITHER"
10603 "*
10604 {
10605 rtx x = operands[0];
10606 making_const_table = TRUE;
10607 switch (GET_MODE_CLASS (GET_MODE (x)))
10608 {
10609 case MODE_FLOAT:
10610 arm_emit_fp16_const (x);
10611 break;
10612 default:
10613 assemble_integer (operands[0], 2, BITS_PER_WORD, 1);
10614 assemble_zeros (2);
10615 break;
10616 }
10617 return \"\";
10618 }"
10619 [(set_attr "length" "4")
10620 (set_attr "type" "no_insn")]
10621)
10622
cffb2a26 10623(define_insn "consttable_4"
e1159bbe 10624 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_4)]
cffb2a26 10625 "TARGET_EITHER"
10626 "*
10627 {
9b8516be 10628 rtx x = operands[0];
cffb2a26 10629 making_const_table = TRUE;
9b8516be 10630 switch (GET_MODE_CLASS (GET_MODE (x)))
cffb2a26 10631 {
10632 case MODE_FLOAT:
0e207eb8 10633 {
10634 REAL_VALUE_TYPE r;
10635 REAL_VALUE_FROM_CONST_DOUBLE (r, x);
10636 assemble_real (r, GET_MODE (x), BITS_PER_WORD);
10637 break;
10638 }
cffb2a26 10639 default:
7b04c5d5 10640 /* XXX: Sometimes gcc does something really dumb and ends up with
10641 a HIGH in a constant pool entry, usually because it's trying to
10642 load into a VFP register. We know this will always be used in
10643 combination with a LO_SUM which ignores the high bits, so just
10644 strip off the HIGH. */
10645 if (GET_CODE (x) == HIGH)
10646 x = XEXP (x, 0);
9b8516be 10647 assemble_integer (x, 4, BITS_PER_WORD, 1);
10648 mark_symbol_refs_as_used (x);
cffb2a26 10649 break;
10650 }
10651 return \"\";
10652 }"
1b7da4ac 10653 [(set_attr "length" "4")
10654 (set_attr "type" "no_insn")]
cffb2a26 10655)
10656
10657(define_insn "consttable_8"
e1159bbe 10658 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_8)]
cffb2a26 10659 "TARGET_EITHER"
10660 "*
10661 {
10662 making_const_table = TRUE;
10663 switch (GET_MODE_CLASS (GET_MODE (operands[0])))
10664 {
10665 case MODE_FLOAT:
10666 {
badfe841 10667 REAL_VALUE_TYPE r;
10668 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[0]);
10669 assemble_real (r, GET_MODE (operands[0]), BITS_PER_WORD);
cffb2a26 10670 break;
10671 }
10672 default:
09d688ff 10673 assemble_integer (operands[0], 8, BITS_PER_WORD, 1);
cffb2a26 10674 break;
10675 }
10676 return \"\";
10677 }"
1b7da4ac 10678 [(set_attr "length" "8")
10679 (set_attr "type" "no_insn")]
cffb2a26 10680)
10681
d98a3884 10682(define_insn "consttable_16"
10683 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_16)]
10684 "TARGET_EITHER"
10685 "*
10686 {
10687 making_const_table = TRUE;
10688 switch (GET_MODE_CLASS (GET_MODE (operands[0])))
10689 {
10690 case MODE_FLOAT:
10691 {
10692 REAL_VALUE_TYPE r;
10693 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[0]);
10694 assemble_real (r, GET_MODE (operands[0]), BITS_PER_WORD);
10695 break;
10696 }
10697 default:
10698 assemble_integer (operands[0], 16, BITS_PER_WORD, 1);
10699 break;
10700 }
10701 return \"\";
10702 }"
1b7da4ac 10703 [(set_attr "length" "16")
10704 (set_attr "type" "no_insn")]
d98a3884 10705)
10706
331beb1a 10707;; V5 Instructions,
10708
8f4be2be 10709(define_insn "clzsi2"
10710 [(set (match_operand:SI 0 "s_register_operand" "=r")
10711 (clz:SI (match_operand:SI 1 "s_register_operand" "r")))]
25f905c2 10712 "TARGET_32BIT && arm_arch5"
ee7cbe0e 10713 "clz%?\\t%0, %1"
bcaec148 10714 [(set_attr "predicable" "yes")
4a510717 10715 (set_attr "predicable_short_it" "no")
bebe9bbb 10716 (set_attr "type" "clz")])
331beb1a 10717
099ad98b 10718(define_insn "rbitsi2"
10719 [(set (match_operand:SI 0 "s_register_operand" "=r")
10720 (unspec:SI [(match_operand:SI 1 "s_register_operand" "r")] UNSPEC_RBIT))]
10721 "TARGET_32BIT && arm_arch_thumb2"
10722 "rbit%?\\t%0, %1"
10723 [(set_attr "predicable" "yes")
4a510717 10724 (set_attr "predicable_short_it" "no")
bebe9bbb 10725 (set_attr "type" "clz")])
099ad98b 10726
10727(define_expand "ctzsi2"
10728 [(set (match_operand:SI 0 "s_register_operand" "")
10729 (ctz:SI (match_operand:SI 1 "s_register_operand" "")))]
10730 "TARGET_32BIT && arm_arch_thumb2"
10731 "
30191172 10732 {
10733 rtx tmp = gen_reg_rtx (SImode);
10734 emit_insn (gen_rbitsi2 (tmp, operands[1]));
10735 emit_insn (gen_clzsi2 (operands[0], tmp));
10736 }
099ad98b 10737 DONE;
10738 "
10739)
10740
e1159bbe 10741;; V5E instructions.
331beb1a 10742
10743(define_insn "prefetch"
f4e79814 10744 [(prefetch (match_operand:SI 0 "address_operand" "p")
10745 (match_operand:SI 1 "" "")
10746 (match_operand:SI 2 "" ""))]
25f905c2 10747 "TARGET_32BIT && arm_arch5e"
1b7da4ac 10748 "pld\\t%a0"
10749 [(set_attr "type" "load1")]
10750)
331beb1a 10751
0d66636f 10752;; General predication pattern
10753
10754(define_cond_exec
10755 [(match_operator 0 "arm_comparison_operator"
10756 [(match_operand 1 "cc_register" "")
10757 (const_int 0)])]
580f4c48 10758 "TARGET_32BIT
10759 && (!TARGET_NO_VOLATILE_CE || !volatile_refs_p (PATTERN (insn)))"
0d66636f 10760 ""
c7a58118 10761[(set_attr "predicated" "yes")]
0d66636f 10762)
10763
fb94f18b 10764(define_insn "force_register_use"
10765 [(unspec:SI [(match_operand:SI 0 "register_operand" "")] UNSPEC_REGISTER_USE)]
063a05c7 10766 ""
fb94f18b 10767 "%@ %0 needed"
1b7da4ac 10768 [(set_attr "length" "0")
10769 (set_attr "type" "no_insn")]
063a05c7 10770)
7db9af5d 10771
4c44712e 10772
10773;; Patterns for exception handling
10774
10775(define_expand "eh_return"
10776 [(use (match_operand 0 "general_operand" ""))]
10777 "TARGET_EITHER"
10778 "
10779 {
25f905c2 10780 if (TARGET_32BIT)
4c44712e 10781 emit_insn (gen_arm_eh_return (operands[0]));
10782 else
10783 emit_insn (gen_thumb_eh_return (operands[0]));
10784 DONE;
10785 }"
10786)
10787
10788;; We can't expand this before we know where the link register is stored.
10789(define_insn_and_split "arm_eh_return"
10790 [(unspec_volatile [(match_operand:SI 0 "s_register_operand" "r")]
10791 VUNSPEC_EH_RETURN)
10792 (clobber (match_scratch:SI 1 "=&r"))]
10793 "TARGET_ARM"
10794 "#"
10795 "&& reload_completed"
10796 [(const_int 0)]
10797 "
10798 {
10799 arm_set_return_address (operands[0], operands[1]);
10800 DONE;
10801 }"
10802)
10803
f655717d 10804\f
10805;; TLS support
10806
10807(define_insn "load_tp_hard"
10808 [(set (match_operand:SI 0 "register_operand" "=r")
10809 (unspec:SI [(const_int 0)] UNSPEC_TLS))]
10810 "TARGET_HARD_TP"
10811 "mrc%?\\tp15, 0, %0, c13, c0, 3\\t@ load_tp_hard"
1b7da4ac 10812 [(set_attr "predicable" "yes")
4b5d7374 10813 (set_attr "type" "mrs")]
f655717d 10814)
10815
10816;; Doesn't clobber R1-R3. Must use r0 for the first operand.
10817(define_insn "load_tp_soft"
10818 [(set (reg:SI 0) (unspec:SI [(const_int 0)] UNSPEC_TLS))
10819 (clobber (reg:SI LR_REGNUM))
10820 (clobber (reg:SI IP_REGNUM))
10821 (clobber (reg:CC CC_REGNUM))]
10822 "TARGET_SOFT_TP"
10823 "bl\\t__aeabi_read_tp\\t@ load_tp_soft"
1b7da4ac 10824 [(set_attr "conds" "clob")
10825 (set_attr "type" "branch")]
f655717d 10826)
10827
f41e4452 10828;; tls descriptor call
10829(define_insn "tlscall"
10830 [(set (reg:SI R0_REGNUM)
10831 (unspec:SI [(reg:SI R0_REGNUM)
10832 (match_operand:SI 0 "" "X")
10833 (match_operand 1 "" "")] UNSPEC_TLS))
10834 (clobber (reg:SI R1_REGNUM))
10835 (clobber (reg:SI LR_REGNUM))
10836 (clobber (reg:SI CC_REGNUM))]
10837 "TARGET_GNU2_TLS"
10838 {
10839 targetm.asm_out.internal_label (asm_out_file, "LPIC",
10840 INTVAL (operands[1]));
10841 return "bl\\t%c0(tlscall)";
10842 }
10843 [(set_attr "conds" "clob")
1b7da4ac 10844 (set_attr "length" "4")
10845 (set_attr "type" "branch")]
f41e4452 10846)
10847
1fe0edab 10848;; For thread pointer builtin
10849(define_expand "get_thread_pointersi"
10850 [(match_operand:SI 0 "s_register_operand" "=r")]
10851 ""
10852 "
10853 {
10854 arm_load_tp (operands[0]);
10855 DONE;
10856 }")
10857
f41e4452 10858;;
10859
aabe09ac 10860;; We only care about the lower 16 bits of the constant
10861;; being inserted into the upper 16 bits of the register.
eca5c984 10862(define_insn "*arm_movtas_ze"
10863 [(set (zero_extract:SI (match_operand:SI 0 "s_register_operand" "+r")
10864 (const_int 16)
10865 (const_int 16))
10866 (match_operand:SI 1 "const_int_operand" ""))]
181ab277 10867 "arm_arch_thumb2"
aabe09ac 10868 "movt%?\t%0, %L1"
eca5c984 10869 [(set_attr "predicable" "yes")
7c36fe71 10870 (set_attr "predicable_short_it" "no")
1b7da4ac 10871 (set_attr "length" "4")
10872 (set_attr "type" "mov_imm")]
eca5c984 10873)
10874
c0fc3696 10875(define_insn "*arm_rev"
a486b499 10876 [(set (match_operand:SI 0 "s_register_operand" "=l,l,r")
10877 (bswap:SI (match_operand:SI 1 "s_register_operand" "l,l,r")))]
10878 "arm_arch6"
10879 "@
10880 rev\t%0, %1
10881 rev%?\t%0, %1
10882 rev%?\t%0, %1"
10883 [(set_attr "arch" "t1,t2,32")
1b7da4ac 10884 (set_attr "length" "2,2,4")
4a510717 10885 (set_attr "predicable" "no,yes,yes")
10886 (set_attr "predicable_short_it" "no")
1b7da4ac 10887 (set_attr "type" "rev")]
ff82f757 10888)
10889
10890(define_expand "arm_legacy_rev"
10891 [(set (match_operand:SI 2 "s_register_operand" "")
10892 (xor:SI (rotatert:SI (match_operand:SI 1 "s_register_operand" "")
10893 (const_int 16))
10894 (match_dup 1)))
10895 (set (match_dup 2)
10896 (lshiftrt:SI (match_dup 2)
10897 (const_int 8)))
10898 (set (match_operand:SI 3 "s_register_operand" "")
10899 (rotatert:SI (match_dup 1)
10900 (const_int 8)))
10901 (set (match_dup 2)
10902 (and:SI (match_dup 2)
10903 (const_int -65281)))
10904 (set (match_operand:SI 0 "s_register_operand" "")
10905 (xor:SI (match_dup 3)
10906 (match_dup 2)))]
10907 "TARGET_32BIT"
10908 ""
10909)
10910
10911;; Reuse temporaries to keep register pressure down.
10912(define_expand "thumb_legacy_rev"
10913 [(set (match_operand:SI 2 "s_register_operand" "")
10914 (ashift:SI (match_operand:SI 1 "s_register_operand" "")
10915 (const_int 24)))
10916 (set (match_operand:SI 3 "s_register_operand" "")
10917 (lshiftrt:SI (match_dup 1)
10918 (const_int 24)))
10919 (set (match_dup 3)
10920 (ior:SI (match_dup 3)
10921 (match_dup 2)))
10922 (set (match_operand:SI 4 "s_register_operand" "")
10923 (const_int 16))
10924 (set (match_operand:SI 5 "s_register_operand" "")
10925 (rotatert:SI (match_dup 1)
10926 (match_dup 4)))
10927 (set (match_dup 2)
10928 (ashift:SI (match_dup 5)
10929 (const_int 24)))
10930 (set (match_dup 5)
10931 (lshiftrt:SI (match_dup 5)
10932 (const_int 24)))
10933 (set (match_dup 5)
10934 (ior:SI (match_dup 5)
10935 (match_dup 2)))
10936 (set (match_dup 5)
10937 (rotatert:SI (match_dup 5)
10938 (match_dup 4)))
10939 (set (match_operand:SI 0 "s_register_operand" "")
10940 (ior:SI (match_dup 5)
10941 (match_dup 3)))]
10942 "TARGET_THUMB"
10943 ""
10944)
10945
10946(define_expand "bswapsi2"
10947 [(set (match_operand:SI 0 "s_register_operand" "=r")
10948 (bswap:SI (match_operand:SI 1 "s_register_operand" "r")))]
8d1af482 10949"TARGET_EITHER && (arm_arch6 || !optimize_size)"
ff82f757 10950"
8d1af482 10951 if (!arm_arch6)
10952 {
10953 rtx op2 = gen_reg_rtx (SImode);
10954 rtx op3 = gen_reg_rtx (SImode);
ff82f757 10955
8d1af482 10956 if (TARGET_THUMB)
10957 {
10958 rtx op4 = gen_reg_rtx (SImode);
10959 rtx op5 = gen_reg_rtx (SImode);
ff82f757 10960
8d1af482 10961 emit_insn (gen_thumb_legacy_rev (operands[0], operands[1],
10962 op2, op3, op4, op5));
10963 }
10964 else
10965 {
10966 emit_insn (gen_arm_legacy_rev (operands[0], operands[1],
10967 op2, op3));
10968 }
ff82f757 10969
8d1af482 10970 DONE;
10971 }
ff82f757 10972 "
10973)
10974
a486b499 10975;; bswap16 patterns: use revsh and rev16 instructions for the signed
10976;; and unsigned variants, respectively. For rev16, expose
10977;; byte-swapping in the lower 16 bits only.
10978(define_insn "*arm_revsh"
10979 [(set (match_operand:SI 0 "s_register_operand" "=l,l,r")
10980 (sign_extend:SI (bswap:HI (match_operand:HI 1 "s_register_operand" "l,l,r"))))]
10981 "arm_arch6"
10982 "@
10983 revsh\t%0, %1
10984 revsh%?\t%0, %1
10985 revsh%?\t%0, %1"
10986 [(set_attr "arch" "t1,t2,32")
1b7da4ac 10987 (set_attr "length" "2,2,4")
10988 (set_attr "type" "rev")]
a486b499 10989)
10990
10991(define_insn "*arm_rev16"
10992 [(set (match_operand:HI 0 "s_register_operand" "=l,l,r")
10993 (bswap:HI (match_operand:HI 1 "s_register_operand" "l,l,r")))]
10994 "arm_arch6"
10995 "@
10996 rev16\t%0, %1
10997 rev16%?\t%0, %1
10998 rev16%?\t%0, %1"
10999 [(set_attr "arch" "t1,t2,32")
1b7da4ac 11000 (set_attr "length" "2,2,4")
11001 (set_attr "type" "rev")]
09f69e55 11002)
11003
11004;; There are no canonicalisation rules for the position of the lshiftrt, ashift
11005;; operations within an IOR/AND RTX, therefore we have two patterns matching
11006;; each valid permutation.
11007
11008(define_insn "arm_rev16si2"
11009 [(set (match_operand:SI 0 "register_operand" "=l,l,r")
11010 (ior:SI (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "l,l,r")
11011 (const_int 8))
11012 (match_operand:SI 3 "const_int_operand" "n,n,n"))
11013 (and:SI (lshiftrt:SI (match_dup 1)
11014 (const_int 8))
11015 (match_operand:SI 2 "const_int_operand" "n,n,n"))))]
11016 "arm_arch6
11017 && aarch_rev16_shleft_mask_imm_p (operands[3], SImode)
11018 && aarch_rev16_shright_mask_imm_p (operands[2], SImode)"
11019 "rev16\\t%0, %1"
11020 [(set_attr "arch" "t1,t2,32")
11021 (set_attr "length" "2,2,4")
11022 (set_attr "type" "rev")]
11023)
11024
11025(define_insn "arm_rev16si2_alt"
11026 [(set (match_operand:SI 0 "register_operand" "=l,l,r")
11027 (ior:SI (and:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" "l,l,r")
11028 (const_int 8))
11029 (match_operand:SI 2 "const_int_operand" "n,n,n"))
11030 (and:SI (ashift:SI (match_dup 1)
11031 (const_int 8))
11032 (match_operand:SI 3 "const_int_operand" "n,n,n"))))]
11033 "arm_arch6
11034 && aarch_rev16_shleft_mask_imm_p (operands[3], SImode)
11035 && aarch_rev16_shright_mask_imm_p (operands[2], SImode)"
11036 "rev16\\t%0, %1"
11037 [(set_attr "arch" "t1,t2,32")
11038 (set_attr "length" "2,2,4")
11039 (set_attr "type" "rev")]
a486b499 11040)
11041
11042(define_expand "bswaphi2"
11043 [(set (match_operand:HI 0 "s_register_operand" "=r")
11044 (bswap:HI (match_operand:HI 1 "s_register_operand" "r")))]
11045"arm_arch6"
11046""
11047)
11048
1653cf17 11049;; Patterns for LDRD/STRD in Thumb2 mode
11050
11051(define_insn "*thumb2_ldrd"
11052 [(set (match_operand:SI 0 "s_register_operand" "=r")
11053 (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "rk")
11054 (match_operand:SI 2 "ldrd_strd_offset_operand" "Do"))))
11055 (set (match_operand:SI 3 "s_register_operand" "=r")
11056 (mem:SI (plus:SI (match_dup 1)
11057 (match_operand:SI 4 "const_int_operand" ""))))]
11058 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11059 && current_tune->prefer_ldrd_strd
11060 && ((INTVAL (operands[2]) + 4) == INTVAL (operands[4]))
11061 && (operands_ok_ldrd_strd (operands[0], operands[3],
11062 operands[1], INTVAL (operands[2]),
11063 false, true))"
11064 "ldrd%?\t%0, %3, [%1, %2]"
11065 [(set_attr "type" "load2")
d952d547 11066 (set_attr "predicable" "yes")
11067 (set_attr "predicable_short_it" "no")])
1653cf17 11068
11069(define_insn "*thumb2_ldrd_base"
11070 [(set (match_operand:SI 0 "s_register_operand" "=r")
11071 (mem:SI (match_operand:SI 1 "s_register_operand" "rk")))
11072 (set (match_operand:SI 2 "s_register_operand" "=r")
11073 (mem:SI (plus:SI (match_dup 1)
11074 (const_int 4))))]
11075 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11076 && current_tune->prefer_ldrd_strd
11077 && (operands_ok_ldrd_strd (operands[0], operands[2],
11078 operands[1], 0, false, true))"
11079 "ldrd%?\t%0, %2, [%1]"
11080 [(set_attr "type" "load2")
d952d547 11081 (set_attr "predicable" "yes")
11082 (set_attr "predicable_short_it" "no")])
1653cf17 11083
11084(define_insn "*thumb2_ldrd_base_neg"
11085 [(set (match_operand:SI 0 "s_register_operand" "=r")
11086 (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "rk")
11087 (const_int -4))))
11088 (set (match_operand:SI 2 "s_register_operand" "=r")
11089 (mem:SI (match_dup 1)))]
11090 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11091 && current_tune->prefer_ldrd_strd
11092 && (operands_ok_ldrd_strd (operands[0], operands[2],
11093 operands[1], -4, false, true))"
11094 "ldrd%?\t%0, %2, [%1, #-4]"
11095 [(set_attr "type" "load2")
d952d547 11096 (set_attr "predicable" "yes")
11097 (set_attr "predicable_short_it" "no")])
1653cf17 11098
11099(define_insn "*thumb2_strd"
11100 [(set (mem:SI (plus:SI (match_operand:SI 0 "s_register_operand" "rk")
11101 (match_operand:SI 1 "ldrd_strd_offset_operand" "Do")))
11102 (match_operand:SI 2 "s_register_operand" "r"))
11103 (set (mem:SI (plus:SI (match_dup 0)
11104 (match_operand:SI 3 "const_int_operand" "")))
11105 (match_operand:SI 4 "s_register_operand" "r"))]
11106 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11107 && current_tune->prefer_ldrd_strd
11108 && ((INTVAL (operands[1]) + 4) == INTVAL (operands[3]))
11109 && (operands_ok_ldrd_strd (operands[2], operands[4],
11110 operands[0], INTVAL (operands[1]),
11111 false, false))"
11112 "strd%?\t%2, %4, [%0, %1]"
11113 [(set_attr "type" "store2")
d952d547 11114 (set_attr "predicable" "yes")
11115 (set_attr "predicable_short_it" "no")])
1653cf17 11116
11117(define_insn "*thumb2_strd_base"
11118 [(set (mem:SI (match_operand:SI 0 "s_register_operand" "rk"))
11119 (match_operand:SI 1 "s_register_operand" "r"))
11120 (set (mem:SI (plus:SI (match_dup 0)
11121 (const_int 4)))
11122 (match_operand:SI 2 "s_register_operand" "r"))]
11123 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11124 && current_tune->prefer_ldrd_strd
11125 && (operands_ok_ldrd_strd (operands[1], operands[2],
11126 operands[0], 0, false, false))"
11127 "strd%?\t%1, %2, [%0]"
11128 [(set_attr "type" "store2")
d952d547 11129 (set_attr "predicable" "yes")
11130 (set_attr "predicable_short_it" "no")])
1653cf17 11131
11132(define_insn "*thumb2_strd_base_neg"
11133 [(set (mem:SI (plus:SI (match_operand:SI 0 "s_register_operand" "rk")
11134 (const_int -4)))
11135 (match_operand:SI 1 "s_register_operand" "r"))
11136 (set (mem:SI (match_dup 0))
11137 (match_operand:SI 2 "s_register_operand" "r"))]
11138 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11139 && current_tune->prefer_ldrd_strd
11140 && (operands_ok_ldrd_strd (operands[1], operands[2],
11141 operands[0], -4, false, false))"
11142 "strd%?\t%1, %2, [%0, #-4]"
11143 [(set_attr "type" "store2")
d952d547 11144 (set_attr "predicable" "yes")
11145 (set_attr "predicable_short_it" "no")])
1653cf17 11146
2a0c73f2 11147;; ARMv8 CRC32 instructions.
11148(define_insn "<crc_variant>"
11149 [(set (match_operand:SI 0 "s_register_operand" "=r")
11150 (unspec:SI [(match_operand:SI 1 "s_register_operand" "r")
11151 (match_operand:<crc_mode> 2 "s_register_operand" "r")]
11152 CRC))]
11153 "TARGET_CRC32"
11154 "<crc_variant>\\t%0, %1, %2"
11155 [(set_attr "type" "crc")
11156 (set_attr "conds" "unconditional")]
11157)
1653cf17 11158
353cf59a 11159;; Load the load/store double peephole optimizations.
11160(include "ldrdstrd.md")
11161
320ea44d 11162;; Load the load/store multiple patterns
11163(include "ldmstm.md")
426be8c5 11164
11165;; Patterns in ldmstm.md don't cover more than 4 registers. This pattern covers
11166;; large lists without explicit writeback generated for APCS_FRAME epilogue.
11167(define_insn "*load_multiple"
11168 [(match_parallel 0 "load_multiple_operation"
11169 [(set (match_operand:SI 2 "s_register_operand" "=rk")
11170 (mem:SI (match_operand:SI 1 "s_register_operand" "rk")))
11171 ])]
11172 "TARGET_32BIT"
11173 "*
11174 {
11175 arm_output_multireg_pop (operands, /*return_pc=*/false,
11176 /*cond=*/const_true_rtx,
11177 /*reverse=*/false,
11178 /*update=*/false);
11179 return \"\";
11180 }
11181 "
11182 [(set_attr "predicable" "yes")]
11183)
11184
84450ddc 11185(define_expand "copysignsf3"
11186 [(match_operand:SF 0 "register_operand")
11187 (match_operand:SF 1 "register_operand")
11188 (match_operand:SF 2 "register_operand")]
11189 "TARGET_SOFT_FLOAT && arm_arch_thumb2"
11190 "{
11191 emit_move_insn (operands[0], operands[2]);
11192 emit_insn (gen_insv_t2 (simplify_gen_subreg (SImode, operands[0], SFmode, 0),
11193 GEN_INT (31), GEN_INT (0),
11194 simplify_gen_subreg (SImode, operands[1], SFmode, 0)));
11195 DONE;
11196 }"
11197)
11198
11199(define_expand "copysigndf3"
11200 [(match_operand:DF 0 "register_operand")
11201 (match_operand:DF 1 "register_operand")
11202 (match_operand:DF 2 "register_operand")]
11203 "TARGET_SOFT_FLOAT && arm_arch_thumb2"
11204 "{
11205 rtx op0_low = gen_lowpart (SImode, operands[0]);
11206 rtx op0_high = gen_highpart (SImode, operands[0]);
11207 rtx op1_low = gen_lowpart (SImode, operands[1]);
11208 rtx op1_high = gen_highpart (SImode, operands[1]);
11209 rtx op2_high = gen_highpart (SImode, operands[2]);
11210
11211 rtx scratch1 = gen_reg_rtx (SImode);
11212 rtx scratch2 = gen_reg_rtx (SImode);
11213 emit_move_insn (scratch1, op2_high);
11214 emit_move_insn (scratch2, op1_high);
11215
11216 emit_insn(gen_rtx_SET(SImode, scratch1,
11217 gen_rtx_LSHIFTRT (SImode, op2_high, GEN_INT(31))));
11218 emit_insn(gen_insv_t2(scratch2, GEN_INT(1), GEN_INT(31), scratch1));
11219 emit_move_insn (op0_low, op1_low);
11220 emit_move_insn (op0_high, scratch2);
11221
11222 DONE;
11223 }"
11224)
11225
d98a3884 11226;; Vector bits common to IWMMXT and Neon
11227(include "vec-common.md")
755eb2b4 11228;; Load the Intel Wireless Multimedia Extension patterns
11229(include "iwmmxt.md")
a2cd141b 11230;; Load the VFP co-processor patterns
11231(include "vfp.md")
bc360af8 11232;; Thumb-1 patterns
11233(include "thumb1.md")
25f905c2 11234;; Thumb-2 patterns
11235(include "thumb2.md")
d98a3884 11236;; Neon patterns
11237(include "neon.md")
e84fdf6e 11238;; Crypto patterns
11239(include "crypto.md")
06df6b17 11240;; Synchronization Primitives
11241(include "sync.md")
bbbe4599 11242;; Fixed-point patterns
11243(include "arm-fixed.md")