]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/config/arm/arm.md
2015-05-12 Ed Schonberg <schonberg@adacore.com>
[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.
8724f216 72(define_attr "is_thumb" "yes,no"
73 (const (if_then_else (symbol_ref "TARGET_THUMB")
74 (const_string "yes") (const_string "no"))))
cffb2a26 75
ef51b8e1 76; IS_ARCH6 is set to 'yes' when we are generating code form ARMv6.
77(define_attr "is_arch6" "no,yes" (const (symbol_ref "arm_arch6")))
78
747b7458 79; IS_THUMB1 is set to 'yes' iff we are generating Thumb-1 code.
8724f216 80(define_attr "is_thumb1" "yes,no"
81 (const (if_then_else (symbol_ref "TARGET_THUMB1")
82 (const_string "yes") (const_string "no"))))
747b7458 83
c7a58118 84; We use this attribute to disable alternatives that can produce 32-bit
85; instructions inside an IT-block in Thumb2 state. ARMv8 deprecates IT blocks
86; that contain 32-bit instructions.
87(define_attr "enabled_for_depr_it" "no,yes" (const_string "yes"))
88
89; This attribute is used to disable a predicated alternative when we have
90; arm_restrict_it.
91(define_attr "predicable_short_it" "no,yes" (const_string "yes"))
92
331beb1a 93;; Operand number of an input operand that is shifted. Zero if the
94;; given instruction does not shift one of its input operands.
331beb1a 95(define_attr "shift" "" (const_int 0))
96
55a94dda 97;; [For compatibility with AArch64 in pipeline models]
98;; Attribute that specifies whether or not the instruction touches fp
99;; registers.
100(define_attr "fp" "no,yes" (const_string "no"))
101
3d91c5d6 102; Floating Point Unit. If we only have floating point emulation, then there
103; is no point in scheduling the floating point insns. (Well, for best
104; performance we should try and group them together).
bffbb863 105(define_attr "fpu" "none,vfp"
c7f506fd 106 (const (symbol_ref "arm_fpu_attr")))
3d91c5d6 107
c7a58118 108(define_attr "predicated" "yes,no" (const_string "no"))
109
094e994f 110; LENGTH of an instruction (in bytes)
06df6b17 111(define_attr "length" ""
e1b93706 112 (const_int 4))
9c08d1fa 113
d5d4dc8d 114; The architecture which supports the instruction (or alternative).
115; This can be "a" for ARM, "t" for either of the Thumbs, "32" for
116; TARGET_32BIT, "t1" or "t2" to specify a specific Thumb mode. "v6"
117; for ARM or Thumb-2 with arm_arch6, and nov6 for ARM without
e4585731 118; arm_arch6. "v6t2" for Thumb-2 with arm_arch6. This attribute is
119; used to compute attribute "enabled", use type "any" to enable an
120; alternative in all cases.
121(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 122 (const_string "any"))
123
124(define_attr "arch_enabled" "no,yes"
125 (cond [(eq_attr "arch" "any")
126 (const_string "yes")
127
128 (and (eq_attr "arch" "a")
0bf497f5 129 (match_test "TARGET_ARM"))
d5d4dc8d 130 (const_string "yes")
131
132 (and (eq_attr "arch" "t")
0bf497f5 133 (match_test "TARGET_THUMB"))
d5d4dc8d 134 (const_string "yes")
135
136 (and (eq_attr "arch" "t1")
0bf497f5 137 (match_test "TARGET_THUMB1"))
d5d4dc8d 138 (const_string "yes")
139
140 (and (eq_attr "arch" "t2")
0bf497f5 141 (match_test "TARGET_THUMB2"))
d5d4dc8d 142 (const_string "yes")
143
144 (and (eq_attr "arch" "32")
0bf497f5 145 (match_test "TARGET_32BIT"))
d5d4dc8d 146 (const_string "yes")
147
148 (and (eq_attr "arch" "v6")
0bf497f5 149 (match_test "TARGET_32BIT && arm_arch6"))
d5d4dc8d 150 (const_string "yes")
151
152 (and (eq_attr "arch" "nov6")
0bf497f5 153 (match_test "TARGET_32BIT && !arm_arch6"))
a651f34d 154 (const_string "yes")
155
e4585731 156 (and (eq_attr "arch" "v6t2")
157 (match_test "TARGET_32BIT && arm_arch6 && arm_arch_thumb2"))
158 (const_string "yes")
159
b6779ddc 160 (and (eq_attr "arch" "avoid_neon_for_64bits")
161 (match_test "TARGET_NEON")
162 (not (match_test "TARGET_PREFER_NEON_64BITS")))
a651f34d 163 (const_string "yes")
164
b6779ddc 165 (and (eq_attr "arch" "neon_for_64bits")
166 (match_test "TARGET_NEON")
167 (match_test "TARGET_PREFER_NEON_64BITS"))
6b8f7c28 168 (const_string "yes")
169
170 (and (eq_attr "arch" "iwmmxt2")
171 (match_test "TARGET_REALLY_IWMMXT2"))
21cc9773 172 (const_string "yes")
173
174 (and (eq_attr "arch" "armv6_or_vfpv3")
175 (match_test "arm_arch6 || TARGET_VFP3"))
176 (const_string "yes")
177 ]
6b8f7c28 178
d5d4dc8d 179 (const_string "no")))
180
aa06c51c 181(define_attr "opt" "any,speed,size"
182 (const_string "any"))
183
184(define_attr "opt_enabled" "no,yes"
185 (cond [(eq_attr "opt" "any")
186 (const_string "yes")
187
188 (and (eq_attr "opt" "speed")
189 (match_test "optimize_function_for_speed_p (cfun)"))
190 (const_string "yes")
191
192 (and (eq_attr "opt" "size")
193 (match_test "optimize_function_for_size_p (cfun)"))
194 (const_string "yes")]
195 (const_string "no")))
196
861033d5 197(define_attr "use_literal_pool" "no,yes"
198 (cond [(and (eq_attr "type" "f_loads,f_loadd")
199 (match_test "CONSTANT_P (operands[1])"))
200 (const_string "yes")]
201 (const_string "no")))
202
d5d4dc8d 203; Enable all alternatives that are both arch_enabled and insn_enabled.
951a3f72 204; FIXME:: opt_enabled has been temporarily removed till the time we have
205; an attribute that allows the use of such alternatives.
206; This depends on caching of speed_p, size_p on a per
207; alternative basis. The problem is that the enabled attribute
208; cannot depend on any state that is not cached or is not constant
209; for a compilation unit. We probably need a generic "hot/cold"
210; alternative which if implemented can help with this. We disable this
211; until such a time as this is implemented and / or the improvements or
212; regressions with removing this attribute are double checked.
213; See ashldi3_neon and <shift>di3_neon in neon.md.
214
93b431d9 215 (define_attr "enabled" "no,yes"
0abea32c 216 (cond [(and (eq_attr "predicable_short_it" "no")
c7a58118 217 (and (eq_attr "predicated" "yes")
218 (match_test "arm_restrict_it")))
219 (const_string "no")
220
221 (and (eq_attr "enabled_for_depr_it" "no")
222 (match_test "arm_restrict_it"))
223 (const_string "no")
224
861033d5 225 (and (eq_attr "use_literal_pool" "yes")
226 (match_test "arm_disable_literal_pool"))
227 (const_string "no")
228
aa06c51c 229 (eq_attr "arch_enabled" "no")
aa06c51c 230 (const_string "no")]
231 (const_string "yes")))
d5d4dc8d 232
56d27660 233; POOL_RANGE is how far away from a constant pool entry that this insn
234; can be placed. If the distance is zero, then this insn will never
235; reference the pool.
42e1de19 236; Note that for Thumb constant pools the PC value is rounded down to the
237; nearest multiple of four. Therefore, THUMB2_POOL_RANGE (and POOL_RANGE for
238; Thumb insns) should be set to <max_range> - 2.
cffb2a26 239; NEG_POOL_RANGE is nonzero for insns that can reference a constant pool entry
8848d797 240; before its address. It is set to <max_range> - (8 + <data_size>).
cde1623a 241(define_attr "arm_pool_range" "" (const_int 0))
242(define_attr "thumb2_pool_range" "" (const_int 0))
243(define_attr "arm_neg_pool_range" "" (const_int 0))
244(define_attr "thumb2_neg_pool_range" "" (const_int 0))
245
246(define_attr "pool_range" ""
247 (cond [(eq_attr "is_thumb" "yes") (attr "thumb2_pool_range")]
248 (attr "arm_pool_range")))
249(define_attr "neg_pool_range" ""
250 (cond [(eq_attr "is_thumb" "yes") (attr "thumb2_neg_pool_range")]
251 (attr "arm_neg_pool_range")))
56d27660 252
215b30b3 253; An assembler sequence may clobber the condition codes without us knowing.
4d7a8451 254; If such an insn references the pool, then we have no way of knowing how,
255; so use the most conservative value for pool_range.
9c08d1fa 256(define_asm_attributes
4d7a8451 257 [(set_attr "conds" "clob")
258 (set_attr "length" "4")
259 (set_attr "pool_range" "250")])
9c08d1fa 260
9888ad6d 261; Load scheduling, set from the arm_ld_sched variable
4c834714 262; initialized by arm_option_override()
9888ad6d 263(define_attr "ldsched" "no,yes" (const (symbol_ref "arm_ld_sched")))
849170fd 264
f7fbdd4a 265; condition codes: this one is used by final_prescan_insn to speed up
266; conditionalizing instructions. It saves having to scan the rtl to see if
267; it uses or alters the condition codes.
215b30b3 268;
f7fbdd4a 269; USE means that the condition codes are used by the insn in the process of
215b30b3 270; outputting code, this means (at present) that we can't use the insn in
271; inlined branches
272;
f7fbdd4a 273; SET means that the purpose of the insn is to set the condition codes in a
215b30b3 274; well defined manner.
275;
f7fbdd4a 276; CLOB means that the condition codes are altered in an undefined manner, if
215b30b3 277; they are altered at all
278;
ad6d3e2a 279; UNCONDITIONAL means the instruction can not be conditionally executed and
280; that the instruction does not use or alter the condition codes.
c52acdd2 281;
ad6d3e2a 282; NOCOND means that the instruction does not use or alter the condition
283; codes but can be converted into a conditionally exectuted instruction.
f7fbdd4a 284
b0694be0 285(define_attr "conds" "use,set,clob,unconditional,nocond"
747b7458 286 (if_then_else
287 (ior (eq_attr "is_thumb1" "yes")
288 (eq_attr "type" "call"))
c1a66faf 289 (const_string "clob")
32093010 290 (if_then_else (eq_attr "is_neon_type" "no")
52432540 291 (const_string "nocond")
292 (const_string "unconditional"))))
f7fbdd4a 293
215b30b3 294; Predicable means that the insn can be conditionally executed based on
295; an automatically added predicate (additional patterns are generated by
296; gen...). We default to 'no' because no Thumb patterns match this rule
297; and not all ARM patterns do.
0d66636f 298(define_attr "predicable" "no,yes" (const_string "no"))
299
129a2fe4 300; Only model the write buffer for ARM6 and ARM7. Earlier processors don't
301; have one. Later ones, such as StrongARM, have write-back caches, so don't
8d232dc7 302; suffer blockages enough to warrant modelling this (and it can adversely
129a2fe4 303; affect the schedule).
74a71f7d 304(define_attr "model_wbuf" "no,yes" (const (symbol_ref "arm_tune_wbuf")))
129a2fe4 305
215b30b3 306; WRITE_CONFLICT implies that a read following an unrelated write is likely
307; to stall the processor. Used with model_wbuf above.
9c08d1fa 308(define_attr "write_conflict" "no,yes"
309 (if_then_else (eq_attr "type"
96854199 310 "block,call,load1")
9c08d1fa 311 (const_string "yes")
312 (const_string "no")))
313
215b30b3 314; Classify the insns into those that take one cycle and those that take more
315; than one on the main cpu execution unit.
f7fbdd4a 316(define_attr "core_cycles" "single,multi"
317 (if_then_else (eq_attr "type"
112eda6f 318 "adc_imm, adc_reg, adcs_imm, adcs_reg, adr, alu_ext, alu_imm, alu_sreg,\
319 alu_shift_imm, alu_shift_reg, alu_dsp_reg, alus_ext, alus_imm, alus_sreg,\
d82e788e 320 alus_shift_imm, alus_shift_reg, bfm, csel, rev, logic_imm, logic_reg,\
321 logic_shift_imm, logic_shift_reg, logics_imm, logics_reg,\
322 logics_shift_imm, logics_shift_reg, extend, shift_imm, float, fcsel,\
7cb6c048 323 wmmx_wor, wmmx_wxor, wmmx_wand, wmmx_wandn, wmmx_wmov, wmmx_tmcrr,\
324 wmmx_tmrrc, wmmx_wldr, wmmx_wstr, wmmx_tmcr, wmmx_tmrc, wmmx_wadd,\
325 wmmx_wsub, wmmx_wmul, wmmx_wmac, wmmx_wavg2, wmmx_tinsr, wmmx_textrm,\
326 wmmx_wshufh, wmmx_wcmpeq, wmmx_wcmpgt, wmmx_wmax, wmmx_wmin, wmmx_wpack,\
327 wmmx_wunpckih, wmmx_wunpckil, wmmx_wunpckeh, wmmx_wunpckel, wmmx_wror,\
328 wmmx_wsra, wmmx_wsrl, wmmx_wsll, wmmx_wmadd, wmmx_tmia, wmmx_tmiaph,\
329 wmmx_tmiaxy, wmmx_tbcst, wmmx_tmovmsk, wmmx_wacc, wmmx_waligni,\
330 wmmx_walignr, wmmx_tandc, wmmx_textrc, wmmx_torc, wmmx_torvsc, wmmx_wsad,\
331 wmmx_wabs, wmmx_wabsdiff, wmmx_waddsubhx, wmmx_wsubaddhx, wmmx_wavg4,\
332 wmmx_wmulw, wmmx_wqmulm, wmmx_wqmulwm, wmmx_waddbhus, wmmx_wqmiaxy,\
333 wmmx_wmiaxy, wmmx_wmiawxy, wmmx_wmerge")
f7fbdd4a 334 (const_string "single")
335 (const_string "multi")))
336
cffb2a26 337;; FAR_JUMP is "yes" if a BL instruction is used to generate a branch to a
215b30b3 338;; distant label. Only applicable to Thumb code.
cffb2a26 339(define_attr "far_jump" "yes,no" (const_string "no"))
340
d51f92df 341
25f905c2 342;; The number of machine instructions this pattern expands to.
343;; Used for Thumb-2 conditional execution.
344(define_attr "ce_count" "" (const_int 1))
345
4182b724 346;;---------------------------------------------------------------------------
347;; Unspecs
348
349(include "unspecs.md")
350
d51f92df 351;;---------------------------------------------------------------------------
fd781bb2 352;; Mode iterators
d51f92df 353
3de0dec6 354(include "iterators.md")
03770691 355
d51f92df 356;;---------------------------------------------------------------------------
357;; Predicates
358
9c9db025 359(include "predicates.md")
234f6557 360(include "constraints.md")
9c9db025 361
a2cd141b 362;;---------------------------------------------------------------------------
363;; Pipeline descriptions
215b30b3 364
e3879fd0 365(define_attr "tune_cortexr4" "yes,no"
366 (const (if_then_else
7d3cda8c 367 (eq_attr "tune" "cortexr4,cortexr4f,cortexr5")
e3879fd0 368 (const_string "yes")
369 (const_string "no"))))
370
a2cd141b 371;; True if the generic scheduling description should be used.
372
373(define_attr "generic_sched" "yes,no"
2546d93a 374 (const (if_then_else
e18862f3 375 (ior (eq_attr "tune" "fa526,fa626,fa606te,fa626te,fmp626,fa726te,\
376 arm926ejs,arm1020e,arm1026ejs,arm1136js,\
377 arm1136jfs,cortexa5,cortexa7,cortexa8,\
42e7b263 378 cortexa9,cortexa12,cortexa15,cortexa17,\
b1099bfd 379 cortexa53,cortexa57,cortexm4,cortexm7,\
380 marvell_pj4,xgene1")
2546d93a 381 (eq_attr "tune_cortexr4" "yes"))
4d5cb40d 382 (const_string "no")
383 (const_string "yes"))))
384
c0e1af52 385(define_attr "generic_vfp" "yes,no"
386 (const (if_then_else
387 (and (eq_attr "fpu" "vfp")
e18862f3 388 (eq_attr "tune" "!arm1020e,arm1022e,cortexa5,cortexa7,\
389 cortexa8,cortexa9,cortexa53,cortexm4,\
55a94dda 390 cortexm7,marvell_pj4,xgene1")
e3879fd0 391 (eq_attr "tune_cortexr4" "no"))
c0e1af52 392 (const_string "yes")
393 (const_string "no"))))
394
6b8f7c28 395(include "marvell-f-iwmmxt.md")
a2cd141b 396(include "arm-generic.md")
397(include "arm926ejs.md")
c0e1af52 398(include "arm1020e.md")
a2cd141b 399(include "arm1026ejs.md")
400(include "arm1136jfs.md")
0e266d06 401(include "fa526.md")
402(include "fa606te.md")
403(include "fa626te.md")
404(include "fmp626.md")
405(include "fa726te.md")
3f1e069f 406(include "cortex-a5.md")
d6b7f019 407(include "cortex-a7.md")
bcaec148 408(include "cortex-a8.md")
036068af 409(include "cortex-a9.md")
65f2f758 410(include "cortex-a15.md")
42e7b263 411(include "cortex-a17.md")
da10bc87 412(include "cortex-a53.md")
b1099bfd 413(include "cortex-a57.md")
934a1e72 414(include "cortex-r4.md")
e3879fd0 415(include "cortex-r4f.md")
e18862f3 416(include "cortex-m7.md")
2546d93a 417(include "cortex-m4.md")
418(include "cortex-m4-fpu.md")
55e3ada8 419(include "vfp11.md")
ea7d210b 420(include "marvell-pj4.md")
55a94dda 421(include "xgene1.md")
3586df96 422
9c08d1fa 423\f
215b30b3 424;;---------------------------------------------------------------------------
e1159bbe 425;; Insn patterns
426;;
a0f94409 427;; Addition insns.
215b30b3 428
9c08d1fa 429;; Note: For DImode insns, there is normally no reason why operands should
430;; not be in the same register, what we don't want is for something being
431;; written to partially overlap something that is an input.
432
cffb2a26 433(define_expand "adddi3"
434 [(parallel
215b30b3 435 [(set (match_operand:DI 0 "s_register_operand" "")
cffb2a26 436 (plus:DI (match_operand:DI 1 "s_register_operand" "")
10e5ccd5 437 (match_operand:DI 2 "arm_adddi_operand" "")))
bd5b4116 438 (clobber (reg:CC CC_REGNUM))])]
cffb2a26 439 "TARGET_EITHER"
440 "
25f905c2 441 if (TARGET_THUMB1)
cffb2a26 442 {
0438d37f 443 if (!REG_P (operands[1]))
bc5a93af 444 operands[1] = force_reg (DImode, operands[1]);
0438d37f 445 if (!REG_P (operands[2]))
bc5a93af 446 operands[2] = force_reg (DImode, operands[2]);
cffb2a26 447 }
448 "
449)
450
a0f94409 451(define_insn_and_split "*arm_adddi3"
10e5ccd5 452 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r,&r,&r,&r")
453 (plus:DI (match_operand:DI 1 "s_register_operand" "%0, 0, r, 0, r")
454 (match_operand:DI 2 "arm_adddi_operand" "r, 0, r, Dd, Dd")))
bd5b4116 455 (clobber (reg:CC CC_REGNUM))]
b805622c 456 "TARGET_32BIT && !TARGET_NEON"
33782ec7 457 "#"
94829feb 458 "TARGET_32BIT && reload_completed
459 && ! (TARGET_NEON && IS_VFP_REGNUM (REGNO (operands[0])))"
a0f94409 460 [(parallel [(set (reg:CC_C CC_REGNUM)
461 (compare:CC_C (plus:SI (match_dup 1) (match_dup 2))
462 (match_dup 1)))
463 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
080c0b9a 464 (set (match_dup 3) (plus:SI (plus:SI (match_dup 4) (match_dup 5))
465 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
a0f94409 466 "
467 {
468 operands[3] = gen_highpart (SImode, operands[0]);
469 operands[0] = gen_lowpart (SImode, operands[0]);
470 operands[4] = gen_highpart (SImode, operands[1]);
471 operands[1] = gen_lowpart (SImode, operands[1]);
10e5ccd5 472 operands[5] = gen_highpart_mode (SImode, DImode, operands[2]);
a0f94409 473 operands[2] = gen_lowpart (SImode, operands[2]);
474 }"
cffb2a26 475 [(set_attr "conds" "clob")
1b7da4ac 476 (set_attr "length" "8")
477 (set_attr "type" "multiple")]
cffb2a26 478)
9c08d1fa 479
a0f94409 480(define_insn_and_split "*adddi_sesidi_di"
9c08d1fa 481 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
482 (plus:DI (sign_extend:DI
97499065 483 (match_operand:SI 2 "s_register_operand" "r,r"))
e5fea38e 484 (match_operand:DI 1 "s_register_operand" "0,r")))
bd5b4116 485 (clobber (reg:CC CC_REGNUM))]
b805622c 486 "TARGET_32BIT"
33782ec7 487 "#"
25f905c2 488 "TARGET_32BIT && reload_completed"
a0f94409 489 [(parallel [(set (reg:CC_C CC_REGNUM)
490 (compare:CC_C (plus:SI (match_dup 1) (match_dup 2))
491 (match_dup 1)))
492 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
080c0b9a 493 (set (match_dup 3) (plus:SI (plus:SI (ashiftrt:SI (match_dup 2)
a0f94409 494 (const_int 31))
080c0b9a 495 (match_dup 4))
496 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
a0f94409 497 "
498 {
499 operands[3] = gen_highpart (SImode, operands[0]);
500 operands[0] = gen_lowpart (SImode, operands[0]);
501 operands[4] = gen_highpart (SImode, operands[1]);
502 operands[1] = gen_lowpart (SImode, operands[1]);
503 operands[2] = gen_lowpart (SImode, operands[2]);
504 }"
215b30b3 505 [(set_attr "conds" "clob")
1b7da4ac 506 (set_attr "length" "8")
507 (set_attr "type" "multiple")]
215b30b3 508)
9c08d1fa 509
a0f94409 510(define_insn_and_split "*adddi_zesidi_di"
9c08d1fa 511 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
512 (plus:DI (zero_extend:DI
97499065 513 (match_operand:SI 2 "s_register_operand" "r,r"))
e5fea38e 514 (match_operand:DI 1 "s_register_operand" "0,r")))
a0f94409 515 (clobber (reg:CC CC_REGNUM))]
b805622c 516 "TARGET_32BIT"
33782ec7 517 "#"
25f905c2 518 "TARGET_32BIT && reload_completed"
a0f94409 519 [(parallel [(set (reg:CC_C CC_REGNUM)
520 (compare:CC_C (plus:SI (match_dup 1) (match_dup 2))
521 (match_dup 1)))
522 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
080c0b9a 523 (set (match_dup 3) (plus:SI (plus:SI (match_dup 4) (const_int 0))
524 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
a0f94409 525 "
526 {
527 operands[3] = gen_highpart (SImode, operands[0]);
528 operands[0] = gen_lowpart (SImode, operands[0]);
529 operands[4] = gen_highpart (SImode, operands[1]);
530 operands[1] = gen_lowpart (SImode, operands[1]);
531 operands[2] = gen_lowpart (SImode, operands[2]);
532 }"
cffb2a26 533 [(set_attr "conds" "clob")
1b7da4ac 534 (set_attr "length" "8")
535 (set_attr "type" "multiple")]
cffb2a26 536)
b11cae9e 537
87b22bf7 538(define_expand "addsi3"
cffb2a26 539 [(set (match_operand:SI 0 "s_register_operand" "")
87b22bf7 540 (plus:SI (match_operand:SI 1 "s_register_operand" "")
541 (match_operand:SI 2 "reg_or_int_operand" "")))]
cffb2a26 542 "TARGET_EITHER"
87b22bf7 543 "
0438d37f 544 if (TARGET_32BIT && CONST_INT_P (operands[2]))
87b22bf7 545 {
96f57e36 546 arm_split_constant (PLUS, SImode, NULL_RTX,
547 INTVAL (operands[2]), operands[0], operands[1],
e1ba4a27 548 optimize && can_create_pseudo_p ());
87b22bf7 549 DONE;
550 }
cffb2a26 551 "
552)
87b22bf7 553
5bd751ff 554; If there is a scratch available, this will be faster than synthesizing the
a0f94409 555; addition.
556(define_peephole2
557 [(match_scratch:SI 3 "r")
372575c7 558 (set (match_operand:SI 0 "arm_general_register_operand" "")
559 (plus:SI (match_operand:SI 1 "arm_general_register_operand" "")
cffb2a26 560 (match_operand:SI 2 "const_int_operand" "")))]
25f905c2 561 "TARGET_32BIT &&
a0f94409 562 !(const_ok_for_arm (INTVAL (operands[2]))
563 || const_ok_for_arm (-INTVAL (operands[2])))
564 && const_ok_for_arm (~INTVAL (operands[2]))"
565 [(set (match_dup 3) (match_dup 2))
566 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 3)))]
567 ""
568)
87b22bf7 569
2f02c19f 570;; The r/r/k alternative is required when reloading the address
571;; (plus (reg rN) (reg sp)) into (reg rN). In this case reload will
572;; put the duplicated register first, and not try the commutative version.
a0f94409 573(define_insn_and_split "*arm_addsi3"
7c36fe71 574 [(set (match_operand:SI 0 "s_register_operand" "=rk,l,l ,l ,r ,k ,r,r ,k ,r ,k,k,r ,k ,r")
575 (plus:SI (match_operand:SI 1 "s_register_operand" "%0 ,l,0 ,l ,rk,k ,r,rk,k ,rk,k,r,rk,k ,rk")
576 (match_operand:SI 2 "reg_or_int_operand" "rk ,l,Py,Pd,rI,rI,k,Pj,Pj,L ,L,L,PJ,PJ,?n")))]
25f905c2 577 "TARGET_32BIT"
5565501b 578 "@
c24d855d 579 add%?\\t%0, %0, %2
5565501b 580 add%?\\t%0, %1, %2
a0b3420a 581 add%?\\t%0, %1, %2
7c36fe71 582 add%?\\t%0, %1, %2
583 add%?\\t%0, %1, %2
aaa37ad6 584 add%?\\t%0, %1, %2
2f02c19f 585 add%?\\t%0, %2, %1
d5cbae34 586 addw%?\\t%0, %1, %2
587 addw%?\\t%0, %1, %2
aaa37ad6 588 sub%?\\t%0, %1, #%n2
87b22bf7 589 sub%?\\t%0, %1, #%n2
d7757711 590 sub%?\\t%0, %1, #%n2
d5cbae34 591 subw%?\\t%0, %1, #%n2
592 subw%?\\t%0, %1, #%n2
87b22bf7 593 #"
a3ffc315 594 "TARGET_32BIT
0438d37f 595 && CONST_INT_P (operands[2])
d5cbae34 596 && !const_ok_for_op (INTVAL (operands[2]), PLUS)
a3ffc315 597 && (reload_completed || !arm_eliminable_register (operands[1]))"
a0f94409 598 [(clobber (const_int 0))]
599 "
96f57e36 600 arm_split_constant (PLUS, SImode, curr_insn,
601 INTVAL (operands[2]), operands[0],
a0f94409 602 operands[1], 0);
603 DONE;
604 "
7c36fe71 605 [(set_attr "length" "2,4,4,4,4,4,4,4,4,4,4,4,4,4,16")
d5cbae34 606 (set_attr "predicable" "yes")
7c36fe71 607 (set_attr "predicable_short_it" "yes,yes,yes,yes,no,no,no,no,no,no,no,no,no,no,no")
608 (set_attr "arch" "t2,t2,t2,t2,*,*,*,t2,t2,*,*,a,t2,t2,*")
65f68e55 609 (set (attr "type") (if_then_else (match_operand 2 "const_int_operand" "")
d82e788e 610 (const_string "alu_imm")
112eda6f 611 (const_string "alu_sreg")))
65f68e55 612 ]
cffb2a26 613)
614
90c2bcf0 615(define_insn "addsi3_compare0"
bd5b4116 616 [(set (reg:CC_NOOV CC_REGNUM)
5565501b 617 (compare:CC_NOOV
65f68e55 618 (plus:SI (match_operand:SI 1 "s_register_operand" "r, r,r")
619 (match_operand:SI 2 "arm_add_operand" "I,L,r"))
5565501b 620 (const_int 0)))
65f68e55 621 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9c08d1fa 622 (plus:SI (match_dup 1) (match_dup 2)))]
ec792a7b 623 "TARGET_ARM"
5565501b 624 "@
25f905c2 625 add%.\\t%0, %1, %2
65f68e55 626 sub%.\\t%0, %1, #%n2
627 add%.\\t%0, %1, %2"
628 [(set_attr "conds" "set")
112eda6f 629 (set_attr "type" "alus_imm,alus_imm,alus_sreg")]
cffb2a26 630)
9c08d1fa 631
aea4c774 632(define_insn "*addsi3_compare0_scratch"
bd5b4116 633 [(set (reg:CC_NOOV CC_REGNUM)
aea4c774 634 (compare:CC_NOOV
65f68e55 635 (plus:SI (match_operand:SI 0 "s_register_operand" "r, r, r")
636 (match_operand:SI 1 "arm_add_operand" "I,L, r"))
aea4c774 637 (const_int 0)))]
ec792a7b 638 "TARGET_ARM"
cffb2a26 639 "@
640 cmn%?\\t%0, %1
65f68e55 641 cmp%?\\t%0, #%n1
642 cmn%?\\t%0, %1"
596e5e8f 643 [(set_attr "conds" "set")
65f68e55 644 (set_attr "predicable" "yes")
112eda6f 645 (set_attr "type" "alus_imm,alus_imm,alus_sreg")]
0d66636f 646)
cffb2a26 647
aed179ae 648(define_insn "*compare_negsi_si"
649 [(set (reg:CC_Z CC_REGNUM)
650 (compare:CC_Z
7c36fe71 651 (neg:SI (match_operand:SI 0 "s_register_operand" "l,r"))
652 (match_operand:SI 1 "s_register_operand" "l,r")))]
25f905c2 653 "TARGET_32BIT"
aed179ae 654 "cmn%?\\t%1, %0"
596e5e8f 655 [(set_attr "conds" "set")
7c36fe71 656 (set_attr "predicable" "yes")
657 (set_attr "arch" "t2,*")
658 (set_attr "length" "2,4")
1b7da4ac 659 (set_attr "predicable_short_it" "yes,no")
112eda6f 660 (set_attr "type" "alus_sreg")]
0d66636f 661)
aea4c774 662
203c488f 663;; This is the canonicalization of addsi3_compare0_for_combiner when the
664;; addend is a constant.
190efb17 665(define_insn "cmpsi2_addneg"
203c488f 666 [(set (reg:CC CC_REGNUM)
667 (compare:CC
668 (match_operand:SI 1 "s_register_operand" "r,r")
2a977b78 669 (match_operand:SI 2 "arm_addimm_operand" "L,I")))
203c488f 670 (set (match_operand:SI 0 "s_register_operand" "=r,r")
671 (plus:SI (match_dup 1)
2a977b78 672 (match_operand:SI 3 "arm_addimm_operand" "I,L")))]
25f905c2 673 "TARGET_32BIT && INTVAL (operands[2]) == -INTVAL (operands[3])"
203c488f 674 "@
2a977b78 675 add%.\\t%0, %1, %3
676 sub%.\\t%0, %1, #%n3"
1b7da4ac 677 [(set_attr "conds" "set")
112eda6f 678 (set_attr "type" "alus_sreg")]
203c488f 679)
680
681;; Convert the sequence
682;; sub rd, rn, #1
683;; cmn rd, #1 (equivalent to cmp rd, #-1)
684;; bne dest
685;; into
686;; subs rd, rn, #1
687;; bcs dest ((unsigned)rn >= 1)
688;; similarly for the beq variant using bcc.
689;; This is a common looping idiom (while (n--))
690(define_peephole2
372575c7 691 [(set (match_operand:SI 0 "arm_general_register_operand" "")
692 (plus:SI (match_operand:SI 1 "arm_general_register_operand" "")
203c488f 693 (const_int -1)))
694 (set (match_operand 2 "cc_register" "")
695 (compare (match_dup 0) (const_int -1)))
696 (set (pc)
697 (if_then_else (match_operator 3 "equality_operator"
698 [(match_dup 2) (const_int 0)])
699 (match_operand 4 "" "")
700 (match_operand 5 "" "")))]
25f905c2 701 "TARGET_32BIT && peep2_reg_dead_p (3, operands[2])"
203c488f 702 [(parallel[
703 (set (match_dup 2)
704 (compare:CC
705 (match_dup 1) (const_int 1)))
706 (set (match_dup 0) (plus:SI (match_dup 1) (const_int -1)))])
707 (set (pc)
708 (if_then_else (match_op_dup 3 [(match_dup 2) (const_int 0)])
709 (match_dup 4)
710 (match_dup 5)))]
711 "operands[2] = gen_rtx_REG (CCmode, CC_REGNUM);
712 operands[3] = gen_rtx_fmt_ee ((GET_CODE (operands[3]) == NE
713 ? GEU : LTU),
714 VOIDmode,
715 operands[2], const0_rtx);"
716)
717
ebcc79bc 718;; The next four insns work because they compare the result with one of
719;; the operands, and we know that the use of the condition code is
720;; either GEU or LTU, so we can use the carry flag from the addition
721;; instead of doing the compare a second time.
722(define_insn "*addsi3_compare_op1"
bd5b4116 723 [(set (reg:CC_C CC_REGNUM)
ebcc79bc 724 (compare:CC_C
65f68e55 725 (plus:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
726 (match_operand:SI 2 "arm_add_operand" "I,L,r"))
ebcc79bc 727 (match_dup 1)))
65f68e55 728 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
ebcc79bc 729 (plus:SI (match_dup 1) (match_dup 2)))]
25f905c2 730 "TARGET_32BIT"
ebcc79bc 731 "@
25f905c2 732 add%.\\t%0, %1, %2
65f68e55 733 sub%.\\t%0, %1, #%n2
734 add%.\\t%0, %1, %2"
735 [(set_attr "conds" "set")
112eda6f 736 (set_attr "type" "alus_imm,alus_imm,alus_sreg")]
0d66636f 737)
ebcc79bc 738
739(define_insn "*addsi3_compare_op2"
bd5b4116 740 [(set (reg:CC_C CC_REGNUM)
ebcc79bc 741 (compare:CC_C
65f68e55 742 (plus:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
743 (match_operand:SI 2 "arm_add_operand" "I,L,r"))
ebcc79bc 744 (match_dup 2)))
65f68e55 745 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9c08d1fa 746 (plus:SI (match_dup 1) (match_dup 2)))]
25f905c2 747 "TARGET_32BIT"
5565501b 748 "@
65f68e55 749 add%.\\t%0, %1, %2
25f905c2 750 add%.\\t%0, %1, %2
751 sub%.\\t%0, %1, #%n2"
65f68e55 752 [(set_attr "conds" "set")
112eda6f 753 (set_attr "type" "alus_imm,alus_imm,alus_sreg")]
0d66636f 754)
9c08d1fa 755
ebcc79bc 756(define_insn "*compare_addsi2_op0"
bd5b4116 757 [(set (reg:CC_C CC_REGNUM)
7c36fe71 758 (compare:CC_C
759 (plus:SI (match_operand:SI 0 "s_register_operand" "l,l,r,r,r")
760 (match_operand:SI 1 "arm_add_operand" "Pv,l,I,L,r"))
761 (match_dup 0)))]
25f905c2 762 "TARGET_32BIT"
ebcc79bc 763 "@
7c36fe71 764 cmp%?\\t%0, #%n1
765 cmn%?\\t%0, %1
ebcc79bc 766 cmn%?\\t%0, %1
65f68e55 767 cmp%?\\t%0, #%n1
768 cmn%?\\t%0, %1"
596e5e8f 769 [(set_attr "conds" "set")
65f68e55 770 (set_attr "predicable" "yes")
7c36fe71 771 (set_attr "arch" "t2,t2,*,*,*")
772 (set_attr "predicable_short_it" "yes,yes,no,no,no")
773 (set_attr "length" "2,2,4,4,4")
112eda6f 774 (set_attr "type" "alus_imm,alus_sreg,alus_imm,alus_imm,alus_sreg")]
0d66636f 775)
ebcc79bc 776
777(define_insn "*compare_addsi2_op1"
bd5b4116 778 [(set (reg:CC_C CC_REGNUM)
7c36fe71 779 (compare:CC_C
780 (plus:SI (match_operand:SI 0 "s_register_operand" "l,l,r,r,r")
781 (match_operand:SI 1 "arm_add_operand" "Pv,l,I,L,r"))
782 (match_dup 1)))]
25f905c2 783 "TARGET_32BIT"
ebcc79bc 784 "@
7c36fe71 785 cmp%?\\t%0, #%n1
786 cmn%?\\t%0, %1
ebcc79bc 787 cmn%?\\t%0, %1
65f68e55 788 cmp%?\\t%0, #%n1
789 cmn%?\\t%0, %1"
596e5e8f 790 [(set_attr "conds" "set")
65f68e55 791 (set_attr "predicable" "yes")
7c36fe71 792 (set_attr "arch" "t2,t2,*,*,*")
793 (set_attr "predicable_short_it" "yes,yes,no,no,no")
794 (set_attr "length" "2,2,4,4,4")
112eda6f 795 (set_attr "type" "alus_imm,alus_sreg,alus_imm,alus_imm,alus_sreg")]
7c36fe71 796 )
ebcc79bc 797
080c0b9a 798(define_insn "*addsi3_carryin_<optab>"
7c36fe71 799 [(set (match_operand:SI 0 "s_register_operand" "=l,r,r")
800 (plus:SI (plus:SI (match_operand:SI 1 "s_register_operand" "%l,r,r")
801 (match_operand:SI 2 "arm_not_operand" "0,rI,K"))
802 (LTUGEU:SI (reg:<cnb> CC_REGNUM) (const_int 0))))]
25f905c2 803 "TARGET_32BIT"
10e5ccd5 804 "@
a0b3420a 805 adc%?\\t%0, %1, %2
10e5ccd5 806 adc%?\\t%0, %1, %2
807 sbc%?\\t%0, %1, #%B2"
a7de272d 808 [(set_attr "conds" "use")
7c36fe71 809 (set_attr "predicable" "yes")
810 (set_attr "arch" "t2,*,*")
811 (set_attr "length" "4")
1b7da4ac 812 (set_attr "predicable_short_it" "yes,no,no")
813 (set_attr "type" "adc_reg,adc_reg,adc_imm")]
cffb2a26 814)
ebcc79bc 815
080c0b9a 816(define_insn "*addsi3_carryin_alt2_<optab>"
7c36fe71 817 [(set (match_operand:SI 0 "s_register_operand" "=l,r,r")
818 (plus:SI (plus:SI (LTUGEU:SI (reg:<cnb> CC_REGNUM) (const_int 0))
819 (match_operand:SI 1 "s_register_operand" "%l,r,r"))
820 (match_operand:SI 2 "arm_rhs_operand" "l,rI,K")))]
25f905c2 821 "TARGET_32BIT"
10e5ccd5 822 "@
a0b3420a 823 adc%?\\t%0, %1, %2
10e5ccd5 824 adc%?\\t%0, %1, %2
825 sbc%?\\t%0, %1, #%B2"
a7de272d 826 [(set_attr "conds" "use")
7c36fe71 827 (set_attr "predicable" "yes")
828 (set_attr "arch" "t2,*,*")
829 (set_attr "length" "4")
1b7da4ac 830 (set_attr "predicable_short_it" "yes,no,no")
831 (set_attr "type" "adc_reg,adc_reg,adc_imm")]
0d66636f 832)
ebcc79bc 833
080c0b9a 834(define_insn "*addsi3_carryin_shift_<optab>"
ebcc79bc 835 [(set (match_operand:SI 0 "s_register_operand" "=r")
080c0b9a 836 (plus:SI (plus:SI
837 (match_operator:SI 2 "shift_operator"
838 [(match_operand:SI 3 "s_register_operand" "r")
839 (match_operand:SI 4 "reg_or_int_operand" "rM")])
840 (match_operand:SI 1 "s_register_operand" "r"))
841 (LTUGEU:SI (reg:<cnb> CC_REGNUM) (const_int 0))))]
25f905c2 842 "TARGET_32BIT"
080c0b9a 843 "adc%?\\t%0, %1, %3%S2"
844 [(set_attr "conds" "use")
a7de272d 845 (set_attr "predicable" "yes")
7c36fe71 846 (set_attr "predicable_short_it" "no")
080c0b9a 847 (set (attr "type") (if_then_else (match_operand 4 "const_int_operand" "")
d82e788e 848 (const_string "alu_shift_imm")
849 (const_string "alu_shift_reg")))]
cffb2a26 850)
ebcc79bc 851
922b6913 852(define_insn "*addsi3_carryin_clobercc_<optab>"
853 [(set (match_operand:SI 0 "s_register_operand" "=r")
854 (plus:SI (plus:SI (match_operand:SI 1 "s_register_operand" "%r")
855 (match_operand:SI 2 "arm_rhs_operand" "rI"))
856 (LTUGEU:SI (reg:<cnb> CC_REGNUM) (const_int 0))))
857 (clobber (reg:CC CC_REGNUM))]
858 "TARGET_32BIT"
859 "adc%.\\t%0, %1, %2"
1b7da4ac 860 [(set_attr "conds" "set")
861 (set_attr "type" "adcs_reg")]
922b6913 862)
863
9154bd82 864(define_insn "*subsi3_carryin"
865 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
866 (minus:SI (minus:SI (match_operand:SI 1 "reg_or_int_operand" "r,I")
867 (match_operand:SI 2 "s_register_operand" "r,r"))
868 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
869 "TARGET_32BIT"
870 "@
871 sbc%?\\t%0, %1, %2
872 rsc%?\\t%0, %2, %1"
873 [(set_attr "conds" "use")
874 (set_attr "arch" "*,a")
7c36fe71 875 (set_attr "predicable" "yes")
1b7da4ac 876 (set_attr "predicable_short_it" "no")
877 (set_attr "type" "adc_reg,adc_imm")]
9154bd82 878)
879
880(define_insn "*subsi3_carryin_const"
881 [(set (match_operand:SI 0 "s_register_operand" "=r")
882 (minus:SI (plus:SI (match_operand:SI 1 "reg_or_int_operand" "r")
883 (match_operand:SI 2 "arm_not_operand" "K"))
884 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
885 "TARGET_32BIT"
886 "sbc\\t%0, %1, #%B2"
1b7da4ac 887 [(set_attr "conds" "use")
888 (set_attr "type" "adc_imm")]
9154bd82 889)
890
891(define_insn "*subsi3_carryin_compare"
892 [(set (reg:CC CC_REGNUM)
893 (compare:CC (match_operand:SI 1 "s_register_operand" "r")
894 (match_operand:SI 2 "s_register_operand" "r")))
895 (set (match_operand:SI 0 "s_register_operand" "=r")
896 (minus:SI (minus:SI (match_dup 1)
897 (match_dup 2))
898 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
899 "TARGET_32BIT"
900 "sbcs\\t%0, %1, %2"
1b7da4ac 901 [(set_attr "conds" "set")
902 (set_attr "type" "adcs_reg")]
9154bd82 903)
904
905(define_insn "*subsi3_carryin_compare_const"
906 [(set (reg:CC CC_REGNUM)
907 (compare:CC (match_operand:SI 1 "reg_or_int_operand" "r")
908 (match_operand:SI 2 "arm_not_operand" "K")))
909 (set (match_operand:SI 0 "s_register_operand" "=r")
910 (minus:SI (plus:SI (match_dup 1)
911 (match_dup 2))
912 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
913 "TARGET_32BIT"
914 "sbcs\\t%0, %1, #%B2"
1b7da4ac 915 [(set_attr "conds" "set")
916 (set_attr "type" "adcs_imm")]
9154bd82 917)
918
919(define_insn "*subsi3_carryin_shift"
920 [(set (match_operand:SI 0 "s_register_operand" "=r")
921 (minus:SI (minus:SI
922 (match_operand:SI 1 "s_register_operand" "r")
923 (match_operator:SI 2 "shift_operator"
924 [(match_operand:SI 3 "s_register_operand" "r")
925 (match_operand:SI 4 "reg_or_int_operand" "rM")]))
926 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
927 "TARGET_32BIT"
928 "sbc%?\\t%0, %1, %3%S2"
929 [(set_attr "conds" "use")
930 (set_attr "predicable" "yes")
931 (set (attr "type") (if_then_else (match_operand 4 "const_int_operand" "")
d82e788e 932 (const_string "alu_shift_imm")
933 (const_string "alu_shift_reg")))]
9154bd82 934)
935
936(define_insn "*rsbsi3_carryin_shift"
937 [(set (match_operand:SI 0 "s_register_operand" "=r")
938 (minus:SI (minus:SI
939 (match_operator:SI 2 "shift_operator"
940 [(match_operand:SI 3 "s_register_operand" "r")
941 (match_operand:SI 4 "reg_or_int_operand" "rM")])
942 (match_operand:SI 1 "s_register_operand" "r"))
943 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
944 "TARGET_ARM"
945 "rsc%?\\t%0, %1, %3%S2"
946 [(set_attr "conds" "use")
947 (set_attr "predicable" "yes")
948 (set (attr "type") (if_then_else (match_operand 4 "const_int_operand" "")
d82e788e 949 (const_string "alu_shift_imm")
950 (const_string "alu_shift_reg")))]
9154bd82 951)
952
d795fb69 953; transform ((x << y) - 1) to ~(~(x-1) << y) Where X is a constant.
954(define_split
955 [(set (match_operand:SI 0 "s_register_operand" "")
956 (plus:SI (ashift:SI (match_operand:SI 1 "const_int_operand" "")
957 (match_operand:SI 2 "s_register_operand" ""))
958 (const_int -1)))
959 (clobber (match_operand:SI 3 "s_register_operand" ""))]
25f905c2 960 "TARGET_32BIT"
d795fb69 961 [(set (match_dup 3) (match_dup 1))
962 (set (match_dup 0) (not:SI (ashift:SI (match_dup 3) (match_dup 2))))]
963 "
964 operands[1] = GEN_INT (~(INTVAL (operands[1]) - 1));
965")
966
604f3a0a 967(define_expand "addsf3"
968 [(set (match_operand:SF 0 "s_register_operand" "")
969 (plus:SF (match_operand:SF 1 "s_register_operand" "")
d86c91f6 970 (match_operand:SF 2 "s_register_operand" "")))]
25f905c2 971 "TARGET_32BIT && TARGET_HARD_FLOAT"
604f3a0a 972 "
604f3a0a 973")
974
604f3a0a 975(define_expand "adddf3"
976 [(set (match_operand:DF 0 "s_register_operand" "")
977 (plus:DF (match_operand:DF 1 "s_register_operand" "")
d86c91f6 978 (match_operand:DF 2 "s_register_operand" "")))]
a50d7267 979 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
604f3a0a 980 "
604f3a0a 981")
982
cffb2a26 983(define_expand "subdi3"
984 [(parallel
985 [(set (match_operand:DI 0 "s_register_operand" "")
986 (minus:DI (match_operand:DI 1 "s_register_operand" "")
987 (match_operand:DI 2 "s_register_operand" "")))
bd5b4116 988 (clobber (reg:CC CC_REGNUM))])]
cffb2a26 989 "TARGET_EITHER"
990 "
25f905c2 991 if (TARGET_THUMB1)
cffb2a26 992 {
0438d37f 993 if (!REG_P (operands[1]))
5aa8c5f0 994 operands[1] = force_reg (DImode, operands[1]);
0438d37f 995 if (!REG_P (operands[2]))
5aa8c5f0 996 operands[2] = force_reg (DImode, operands[2]);
cffb2a26 997 }
998 "
999)
1000
2f9b23e3 1001(define_insn_and_split "*arm_subdi3"
cffb2a26 1002 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r,&r")
9c08d1fa 1003 (minus:DI (match_operand:DI 1 "s_register_operand" "0,r,0")
1004 (match_operand:DI 2 "s_register_operand" "r,0,0")))
bd5b4116 1005 (clobber (reg:CC CC_REGNUM))]
94829feb 1006 "TARGET_32BIT && !TARGET_NEON"
2f9b23e3 1007 "#" ; "subs\\t%Q0, %Q1, %Q2\;sbc\\t%R0, %R1, %R2"
1008 "&& reload_completed"
1009 [(parallel [(set (reg:CC CC_REGNUM)
1010 (compare:CC (match_dup 1) (match_dup 2)))
1011 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
1012 (set (match_dup 3) (minus:SI (minus:SI (match_dup 4) (match_dup 5))
1013 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1014 {
1015 operands[3] = gen_highpart (SImode, operands[0]);
1016 operands[0] = gen_lowpart (SImode, operands[0]);
1017 operands[4] = gen_highpart (SImode, operands[1]);
1018 operands[1] = gen_lowpart (SImode, operands[1]);
1019 operands[5] = gen_highpart (SImode, operands[2]);
1020 operands[2] = gen_lowpart (SImode, operands[2]);
1021 }
cffb2a26 1022 [(set_attr "conds" "clob")
1b7da4ac 1023 (set_attr "length" "8")
1024 (set_attr "type" "multiple")]
cffb2a26 1025)
1026
2f9b23e3 1027(define_insn_and_split "*subdi_di_zesidi"
cffb2a26 1028 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
e5fea38e 1029 (minus:DI (match_operand:DI 1 "s_register_operand" "0,r")
9c08d1fa 1030 (zero_extend:DI
cffb2a26 1031 (match_operand:SI 2 "s_register_operand" "r,r"))))
bd5b4116 1032 (clobber (reg:CC CC_REGNUM))]
25f905c2 1033 "TARGET_32BIT"
2f9b23e3 1034 "#" ; "subs\\t%Q0, %Q1, %2\;sbc\\t%R0, %R1, #0"
1035 "&& reload_completed"
1036 [(parallel [(set (reg:CC CC_REGNUM)
1037 (compare:CC (match_dup 1) (match_dup 2)))
1038 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
1039 (set (match_dup 3) (minus:SI (plus:SI (match_dup 4) (match_dup 5))
1040 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1041 {
1042 operands[3] = gen_highpart (SImode, operands[0]);
1043 operands[0] = gen_lowpart (SImode, operands[0]);
1044 operands[4] = gen_highpart (SImode, operands[1]);
1045 operands[1] = gen_lowpart (SImode, operands[1]);
1046 operands[5] = GEN_INT (~0);
1047 }
cffb2a26 1048 [(set_attr "conds" "clob")
1b7da4ac 1049 (set_attr "length" "8")
1050 (set_attr "type" "multiple")]
cffb2a26 1051)
9c08d1fa 1052
2f9b23e3 1053(define_insn_and_split "*subdi_di_sesidi"
cffb2a26 1054 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
e5fea38e 1055 (minus:DI (match_operand:DI 1 "s_register_operand" "0,r")
9c08d1fa 1056 (sign_extend:DI
cffb2a26 1057 (match_operand:SI 2 "s_register_operand" "r,r"))))
bd5b4116 1058 (clobber (reg:CC CC_REGNUM))]
25f905c2 1059 "TARGET_32BIT"
2f9b23e3 1060 "#" ; "subs\\t%Q0, %Q1, %2\;sbc\\t%R0, %R1, %2, asr #31"
1061 "&& reload_completed"
1062 [(parallel [(set (reg:CC CC_REGNUM)
1063 (compare:CC (match_dup 1) (match_dup 2)))
1064 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
1065 (set (match_dup 3) (minus:SI (minus:SI (match_dup 4)
1066 (ashiftrt:SI (match_dup 2)
1067 (const_int 31)))
1068 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1069 {
1070 operands[3] = gen_highpart (SImode, operands[0]);
1071 operands[0] = gen_lowpart (SImode, operands[0]);
1072 operands[4] = gen_highpart (SImode, operands[1]);
1073 operands[1] = gen_lowpart (SImode, operands[1]);
1074 }
cffb2a26 1075 [(set_attr "conds" "clob")
1b7da4ac 1076 (set_attr "length" "8")
1077 (set_attr "type" "multiple")]
cffb2a26 1078)
9c08d1fa 1079
2f9b23e3 1080(define_insn_and_split "*subdi_zesidi_di"
cffb2a26 1081 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
9c08d1fa 1082 (minus:DI (zero_extend:DI
cffb2a26 1083 (match_operand:SI 2 "s_register_operand" "r,r"))
e5fea38e 1084 (match_operand:DI 1 "s_register_operand" "0,r")))
bd5b4116 1085 (clobber (reg:CC CC_REGNUM))]
cffb2a26 1086 "TARGET_ARM"
2f9b23e3 1087 "#" ; "rsbs\\t%Q0, %Q1, %2\;rsc\\t%R0, %R1, #0"
1088 ; is equivalent to:
1089 ; "subs\\t%Q0, %2, %Q1\;rsc\\t%R0, %R1, #0"
1090 "&& reload_completed"
1091 [(parallel [(set (reg:CC CC_REGNUM)
1092 (compare:CC (match_dup 2) (match_dup 1)))
1093 (set (match_dup 0) (minus:SI (match_dup 2) (match_dup 1)))])
1094 (set (match_dup 3) (minus:SI (minus:SI (const_int 0) (match_dup 4))
1095 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1096 {
1097 operands[3] = gen_highpart (SImode, operands[0]);
1098 operands[0] = gen_lowpart (SImode, operands[0]);
1099 operands[4] = gen_highpart (SImode, operands[1]);
1100 operands[1] = gen_lowpart (SImode, operands[1]);
1101 }
cffb2a26 1102 [(set_attr "conds" "clob")
1b7da4ac 1103 (set_attr "length" "8")
1104 (set_attr "type" "multiple")]
cffb2a26 1105)
9c08d1fa 1106
2f9b23e3 1107(define_insn_and_split "*subdi_sesidi_di"
cffb2a26 1108 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
9c08d1fa 1109 (minus:DI (sign_extend:DI
cffb2a26 1110 (match_operand:SI 2 "s_register_operand" "r,r"))
e5fea38e 1111 (match_operand:DI 1 "s_register_operand" "0,r")))
bd5b4116 1112 (clobber (reg:CC CC_REGNUM))]
cffb2a26 1113 "TARGET_ARM"
2f9b23e3 1114 "#" ; "rsbs\\t%Q0, %Q1, %2\;rsc\\t%R0, %R1, %2, asr #31"
1115 ; is equivalent to:
1116 ; "subs\\t%Q0, %2, %Q1\;rsc\\t%R0, %R1, %2, asr #31"
1117 "&& reload_completed"
1118 [(parallel [(set (reg:CC CC_REGNUM)
1119 (compare:CC (match_dup 2) (match_dup 1)))
1120 (set (match_dup 0) (minus:SI (match_dup 2) (match_dup 1)))])
1121 (set (match_dup 3) (minus:SI (minus:SI
1122 (ashiftrt:SI (match_dup 2)
1123 (const_int 31))
1124 (match_dup 4))
1125 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1126 {
1127 operands[3] = gen_highpart (SImode, operands[0]);
1128 operands[0] = gen_lowpart (SImode, operands[0]);
1129 operands[4] = gen_highpart (SImode, operands[1]);
1130 operands[1] = gen_lowpart (SImode, operands[1]);
1131 }
cffb2a26 1132 [(set_attr "conds" "clob")
1b7da4ac 1133 (set_attr "length" "8")
1134 (set_attr "type" "multiple")]
cffb2a26 1135)
9c08d1fa 1136
2f9b23e3 1137(define_insn_and_split "*subdi_zesidi_zesidi"
cffb2a26 1138 [(set (match_operand:DI 0 "s_register_operand" "=r")
9c08d1fa 1139 (minus:DI (zero_extend:DI
cffb2a26 1140 (match_operand:SI 1 "s_register_operand" "r"))
9c08d1fa 1141 (zero_extend:DI
cffb2a26 1142 (match_operand:SI 2 "s_register_operand" "r"))))
bd5b4116 1143 (clobber (reg:CC CC_REGNUM))]
25f905c2 1144 "TARGET_32BIT"
2f9b23e3 1145 "#" ; "subs\\t%Q0, %1, %2\;sbc\\t%R0, %1, %1"
1146 "&& reload_completed"
1147 [(parallel [(set (reg:CC CC_REGNUM)
1148 (compare:CC (match_dup 1) (match_dup 2)))
1149 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
1150 (set (match_dup 3) (minus:SI (minus:SI (match_dup 1) (match_dup 1))
1151 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1152 {
1153 operands[3] = gen_highpart (SImode, operands[0]);
1154 operands[0] = gen_lowpart (SImode, operands[0]);
1155 }
cffb2a26 1156 [(set_attr "conds" "clob")
1b7da4ac 1157 (set_attr "length" "8")
1158 (set_attr "type" "multiple")]
cffb2a26 1159)
b11cae9e 1160
87b22bf7 1161(define_expand "subsi3"
cffb2a26 1162 [(set (match_operand:SI 0 "s_register_operand" "")
87b22bf7 1163 (minus:SI (match_operand:SI 1 "reg_or_int_operand" "")
1164 (match_operand:SI 2 "s_register_operand" "")))]
cffb2a26 1165 "TARGET_EITHER"
87b22bf7 1166 "
0438d37f 1167 if (CONST_INT_P (operands[1]))
87b22bf7 1168 {
25f905c2 1169 if (TARGET_32BIT)
cffb2a26 1170 {
96f57e36 1171 arm_split_constant (MINUS, SImode, NULL_RTX,
1172 INTVAL (operands[1]), operands[0],
e1ba4a27 1173 operands[2], optimize && can_create_pseudo_p ());
cffb2a26 1174 DONE;
1175 }
25f905c2 1176 else /* TARGET_THUMB1 */
cffb2a26 1177 operands[1] = force_reg (SImode, operands[1]);
87b22bf7 1178 }
cffb2a26 1179 "
1180)
87b22bf7 1181
25f905c2 1182; ??? Check Thumb-2 split length
a0f94409 1183(define_insn_and_split "*arm_subsi3_insn"
3a44c5a9 1184 [(set (match_operand:SI 0 "s_register_operand" "=l,l ,l ,l ,r,r,r,rk,r")
1185 (minus:SI (match_operand:SI 1 "reg_or_int_operand" "l ,0 ,l ,Pz,I,r,r,k ,?n")
1186 (match_operand:SI 2 "reg_or_int_operand" "l ,Py,Pd,l ,r,I,r,r ,r")))]
25f905c2 1187 "TARGET_32BIT"
e2348bcb 1188 "@
7c36fe71 1189 sub%?\\t%0, %1, %2
1190 sub%?\\t%0, %2
1191 sub%?\\t%0, %1, %2
1192 rsb%?\\t%0, %2, %1
87b22bf7 1193 rsb%?\\t%0, %2, %1
aaa37ad6 1194 sub%?\\t%0, %1, %2
080c0b9a 1195 sub%?\\t%0, %1, %2
65f68e55 1196 sub%?\\t%0, %1, %2
87b22bf7 1197 #"
0438d37f 1198 "&& (CONST_INT_P (operands[1])
91a5e339 1199 && !const_ok_for_arm (INTVAL (operands[1])))"
87b22bf7 1200 [(clobber (const_int 0))]
1201 "
96f57e36 1202 arm_split_constant (MINUS, SImode, curr_insn,
1203 INTVAL (operands[1]), operands[0], operands[2], 0);
87b22bf7 1204 DONE;
cffb2a26 1205 "
7c36fe71 1206 [(set_attr "length" "4,4,4,4,4,4,4,4,16")
1207 (set_attr "arch" "t2,t2,t2,t2,*,*,*,*,*")
65f68e55 1208 (set_attr "predicable" "yes")
7c36fe71 1209 (set_attr "predicable_short_it" "yes,yes,yes,yes,no,no,no,no,no")
112eda6f 1210 (set_attr "type" "alu_sreg,alu_sreg,alu_sreg,alu_sreg,alu_imm,alu_imm,alu_sreg,alu_sreg,multiple")]
a0f94409 1211)
1212
1213(define_peephole2
1214 [(match_scratch:SI 3 "r")
372575c7 1215 (set (match_operand:SI 0 "arm_general_register_operand" "")
a0f94409 1216 (minus:SI (match_operand:SI 1 "const_int_operand" "")
372575c7 1217 (match_operand:SI 2 "arm_general_register_operand" "")))]
25f905c2 1218 "TARGET_32BIT
a0f94409 1219 && !const_ok_for_arm (INTVAL (operands[1]))
1220 && const_ok_for_arm (~INTVAL (operands[1]))"
1221 [(set (match_dup 3) (match_dup 1))
1222 (set (match_dup 0) (minus:SI (match_dup 3) (match_dup 2)))]
1223 ""
cffb2a26 1224)
b11cae9e 1225
f7fbdd4a 1226(define_insn "*subsi3_compare0"
bd5b4116 1227 [(set (reg:CC_NOOV CC_REGNUM)
215b30b3 1228 (compare:CC_NOOV
65f68e55 1229 (minus:SI (match_operand:SI 1 "arm_rhs_operand" "r,r,I")
1230 (match_operand:SI 2 "arm_rhs_operand" "I,r,r"))
215b30b3 1231 (const_int 0)))
65f68e55 1232 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9c08d1fa 1233 (minus:SI (match_dup 1) (match_dup 2)))]
25f905c2 1234 "TARGET_32BIT"
e2348bcb 1235 "@
65f68e55 1236 sub%.\\t%0, %1, %2
25f905c2 1237 sub%.\\t%0, %1, %2
1238 rsb%.\\t%0, %2, %1"
65f68e55 1239 [(set_attr "conds" "set")
112eda6f 1240 (set_attr "type" "alus_imm,alus_sreg,alus_sreg")]
cffb2a26 1241)
9c08d1fa 1242
190efb17 1243(define_insn "subsi3_compare"
080c0b9a 1244 [(set (reg:CC CC_REGNUM)
65f68e55 1245 (compare:CC (match_operand:SI 1 "arm_rhs_operand" "r,r,I")
1246 (match_operand:SI 2 "arm_rhs_operand" "I,r,r")))
1247 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
2df9477b 1248 (minus:SI (match_dup 1) (match_dup 2)))]
1249 "TARGET_32BIT"
1250 "@
65f68e55 1251 sub%.\\t%0, %1, %2
2df9477b 1252 sub%.\\t%0, %1, %2
1253 rsb%.\\t%0, %2, %1"
65f68e55 1254 [(set_attr "conds" "set")
112eda6f 1255 (set_attr "type" "alus_imm,alus_sreg,alus_sreg")]
2df9477b 1256)
1257
604f3a0a 1258(define_expand "subsf3"
1259 [(set (match_operand:SF 0 "s_register_operand" "")
d86c91f6 1260 (minus:SF (match_operand:SF 1 "s_register_operand" "")
1261 (match_operand:SF 2 "s_register_operand" "")))]
25f905c2 1262 "TARGET_32BIT && TARGET_HARD_FLOAT"
604f3a0a 1263 "
604f3a0a 1264")
1265
604f3a0a 1266(define_expand "subdf3"
1267 [(set (match_operand:DF 0 "s_register_operand" "")
d86c91f6 1268 (minus:DF (match_operand:DF 1 "s_register_operand" "")
1269 (match_operand:DF 2 "s_register_operand" "")))]
a50d7267 1270 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
604f3a0a 1271 "
604f3a0a 1272")
1273
b11cae9e 1274\f
1275;; Multiplication insns
1276
4422d91f 1277(define_expand "mulhi3"
1278 [(set (match_operand:HI 0 "s_register_operand" "")
1279 (mult:HI (match_operand:HI 1 "s_register_operand" "")
1280 (match_operand:HI 2 "s_register_operand" "")))]
1281 "TARGET_DSP_MULTIPLY"
1282 "
1283 {
1284 rtx result = gen_reg_rtx (SImode);
1285 emit_insn (gen_mulhisi3 (result, operands[1], operands[2]));
1286 emit_move_insn (operands[0], gen_lowpart (HImode, result));
1287 DONE;
1288 }"
1289)
1290
cffb2a26 1291(define_expand "mulsi3"
1292 [(set (match_operand:SI 0 "s_register_operand" "")
1293 (mult:SI (match_operand:SI 2 "s_register_operand" "")
1294 (match_operand:SI 1 "s_register_operand" "")))]
1295 "TARGET_EITHER"
1296 ""
1297)
1298
9c08d1fa 1299;; Use `&' and then `0' to prevent the operands 0 and 1 being the same
cffb2a26 1300(define_insn "*arm_mulsi3"
1301 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r")
9c08d1fa 1302 (mult:SI (match_operand:SI 2 "s_register_operand" "r,r")
e5fea38e 1303 (match_operand:SI 1 "s_register_operand" "%0,r")))]
58d7d654 1304 "TARGET_32BIT && !arm_arch6"
f7fbdd4a 1305 "mul%?\\t%0, %2, %1"
9da0ec36 1306 [(set_attr "type" "mul")
0d66636f 1307 (set_attr "predicable" "yes")]
cffb2a26 1308)
1309
58d7d654 1310(define_insn "*arm_mulsi3_v6"
d952d547 1311 [(set (match_operand:SI 0 "s_register_operand" "=l,l,r")
1312 (mult:SI (match_operand:SI 1 "s_register_operand" "0,l,r")
1313 (match_operand:SI 2 "s_register_operand" "l,0,r")))]
58d7d654 1314 "TARGET_32BIT && arm_arch6"
1315 "mul%?\\t%0, %1, %2"
9da0ec36 1316 [(set_attr "type" "mul")
d952d547 1317 (set_attr "predicable" "yes")
1318 (set_attr "arch" "t2,t2,*")
1319 (set_attr "length" "4")
1320 (set_attr "predicable_short_it" "yes,yes,no")]
58d7d654 1321)
1322
f7fbdd4a 1323(define_insn "*mulsi3_compare0"
bd5b4116 1324 [(set (reg:CC_NOOV CC_REGNUM)
9c08d1fa 1325 (compare:CC_NOOV (mult:SI
1326 (match_operand:SI 2 "s_register_operand" "r,r")
e5fea38e 1327 (match_operand:SI 1 "s_register_operand" "%0,r"))
9c08d1fa 1328 (const_int 0)))
1329 (set (match_operand:SI 0 "s_register_operand" "=&r,&r")
1330 (mult:SI (match_dup 2) (match_dup 1)))]
58d7d654 1331 "TARGET_ARM && !arm_arch6"
1332 "mul%.\\t%0, %2, %1"
1333 [(set_attr "conds" "set")
9da0ec36 1334 (set_attr "type" "muls")]
58d7d654 1335)
1336
1337(define_insn "*mulsi3_compare0_v6"
1338 [(set (reg:CC_NOOV CC_REGNUM)
1339 (compare:CC_NOOV (mult:SI
1340 (match_operand:SI 2 "s_register_operand" "r")
1341 (match_operand:SI 1 "s_register_operand" "r"))
1342 (const_int 0)))
1343 (set (match_operand:SI 0 "s_register_operand" "=r")
1344 (mult:SI (match_dup 2) (match_dup 1)))]
1345 "TARGET_ARM && arm_arch6 && optimize_size"
25f905c2 1346 "mul%.\\t%0, %2, %1"
cffb2a26 1347 [(set_attr "conds" "set")
9da0ec36 1348 (set_attr "type" "muls")]
cffb2a26 1349)
9c08d1fa 1350
f7fbdd4a 1351(define_insn "*mulsi_compare0_scratch"
bd5b4116 1352 [(set (reg:CC_NOOV CC_REGNUM)
9c08d1fa 1353 (compare:CC_NOOV (mult:SI
1354 (match_operand:SI 2 "s_register_operand" "r,r")
e5fea38e 1355 (match_operand:SI 1 "s_register_operand" "%0,r"))
9c08d1fa 1356 (const_int 0)))
1357 (clobber (match_scratch:SI 0 "=&r,&r"))]
58d7d654 1358 "TARGET_ARM && !arm_arch6"
1359 "mul%.\\t%0, %2, %1"
1360 [(set_attr "conds" "set")
9da0ec36 1361 (set_attr "type" "muls")]
58d7d654 1362)
1363
1364(define_insn "*mulsi_compare0_scratch_v6"
1365 [(set (reg:CC_NOOV CC_REGNUM)
1366 (compare:CC_NOOV (mult:SI
1367 (match_operand:SI 2 "s_register_operand" "r")
1368 (match_operand:SI 1 "s_register_operand" "r"))
1369 (const_int 0)))
1370 (clobber (match_scratch:SI 0 "=r"))]
1371 "TARGET_ARM && arm_arch6 && optimize_size"
25f905c2 1372 "mul%.\\t%0, %2, %1"
cffb2a26 1373 [(set_attr "conds" "set")
9da0ec36 1374 (set_attr "type" "muls")]
cffb2a26 1375)
9c08d1fa 1376
b11cae9e 1377;; Unnamed templates to match MLA instruction.
1378
f7fbdd4a 1379(define_insn "*mulsi3addsi"
9c08d1fa 1380 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r,&r")
c8f69309 1381 (plus:SI
9c08d1fa 1382 (mult:SI (match_operand:SI 2 "s_register_operand" "r,r,r,r")
e5fea38e 1383 (match_operand:SI 1 "s_register_operand" "%0,r,0,r"))
1384 (match_operand:SI 3 "s_register_operand" "r,r,0,0")))]
58d7d654 1385 "TARGET_32BIT && !arm_arch6"
1386 "mla%?\\t%0, %2, %1, %3"
9da0ec36 1387 [(set_attr "type" "mla")
58d7d654 1388 (set_attr "predicable" "yes")]
1389)
1390
1391(define_insn "*mulsi3addsi_v6"
1392 [(set (match_operand:SI 0 "s_register_operand" "=r")
1393 (plus:SI
1394 (mult:SI (match_operand:SI 2 "s_register_operand" "r")
1395 (match_operand:SI 1 "s_register_operand" "r"))
1396 (match_operand:SI 3 "s_register_operand" "r")))]
1397 "TARGET_32BIT && arm_arch6"
f7fbdd4a 1398 "mla%?\\t%0, %2, %1, %3"
9da0ec36 1399 [(set_attr "type" "mla")
d952d547 1400 (set_attr "predicable" "yes")
1401 (set_attr "predicable_short_it" "no")]
0d66636f 1402)
b11cae9e 1403
f7fbdd4a 1404(define_insn "*mulsi3addsi_compare0"
bd5b4116 1405 [(set (reg:CC_NOOV CC_REGNUM)
215b30b3 1406 (compare:CC_NOOV
1407 (plus:SI (mult:SI
1408 (match_operand:SI 2 "s_register_operand" "r,r,r,r")
e5fea38e 1409 (match_operand:SI 1 "s_register_operand" "%0,r,0,r"))
1410 (match_operand:SI 3 "s_register_operand" "r,r,0,0"))
215b30b3 1411 (const_int 0)))
9c08d1fa 1412 (set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r,&r")
1413 (plus:SI (mult:SI (match_dup 2) (match_dup 1))
1414 (match_dup 3)))]
58d7d654 1415 "TARGET_ARM && arm_arch6"
1416 "mla%.\\t%0, %2, %1, %3"
1417 [(set_attr "conds" "set")
9da0ec36 1418 (set_attr "type" "mlas")]
58d7d654 1419)
1420
1421(define_insn "*mulsi3addsi_compare0_v6"
1422 [(set (reg:CC_NOOV CC_REGNUM)
1423 (compare:CC_NOOV
1424 (plus:SI (mult:SI
1425 (match_operand:SI 2 "s_register_operand" "r")
1426 (match_operand:SI 1 "s_register_operand" "r"))
1427 (match_operand:SI 3 "s_register_operand" "r"))
1428 (const_int 0)))
1429 (set (match_operand:SI 0 "s_register_operand" "=r")
1430 (plus:SI (mult:SI (match_dup 2) (match_dup 1))
1431 (match_dup 3)))]
1432 "TARGET_ARM && arm_arch6 && optimize_size"
25f905c2 1433 "mla%.\\t%0, %2, %1, %3"
0d66636f 1434 [(set_attr "conds" "set")
9da0ec36 1435 (set_attr "type" "mlas")]
0d66636f 1436)
9c08d1fa 1437
f7fbdd4a 1438(define_insn "*mulsi3addsi_compare0_scratch"
bd5b4116 1439 [(set (reg:CC_NOOV CC_REGNUM)
215b30b3 1440 (compare:CC_NOOV
1441 (plus:SI (mult:SI
1442 (match_operand:SI 2 "s_register_operand" "r,r,r,r")
e5fea38e 1443 (match_operand:SI 1 "s_register_operand" "%0,r,0,r"))
215b30b3 1444 (match_operand:SI 3 "s_register_operand" "?r,r,0,0"))
1445 (const_int 0)))
9c08d1fa 1446 (clobber (match_scratch:SI 0 "=&r,&r,&r,&r"))]
58d7d654 1447 "TARGET_ARM && !arm_arch6"
1448 "mla%.\\t%0, %2, %1, %3"
1449 [(set_attr "conds" "set")
9da0ec36 1450 (set_attr "type" "mlas")]
58d7d654 1451)
1452
1453(define_insn "*mulsi3addsi_compare0_scratch_v6"
1454 [(set (reg:CC_NOOV CC_REGNUM)
1455 (compare:CC_NOOV
1456 (plus:SI (mult:SI
1457 (match_operand:SI 2 "s_register_operand" "r")
1458 (match_operand:SI 1 "s_register_operand" "r"))
1459 (match_operand:SI 3 "s_register_operand" "r"))
1460 (const_int 0)))
1461 (clobber (match_scratch:SI 0 "=r"))]
1462 "TARGET_ARM && arm_arch6 && optimize_size"
25f905c2 1463 "mla%.\\t%0, %2, %1, %3"
cffb2a26 1464 [(set_attr "conds" "set")
9da0ec36 1465 (set_attr "type" "mlas")]
cffb2a26 1466)
f7fbdd4a 1467
89545238 1468(define_insn "*mulsi3subsi"
1469 [(set (match_operand:SI 0 "s_register_operand" "=r")
1470 (minus:SI
1471 (match_operand:SI 3 "s_register_operand" "r")
1472 (mult:SI (match_operand:SI 2 "s_register_operand" "r")
1473 (match_operand:SI 1 "s_register_operand" "r"))))]
1474 "TARGET_32BIT && arm_arch_thumb2"
1475 "mls%?\\t%0, %2, %1, %3"
9da0ec36 1476 [(set_attr "type" "mla")
d952d547 1477 (set_attr "predicable" "yes")
1478 (set_attr "predicable_short_it" "no")]
89545238 1479)
1480
5cdca009 1481(define_expand "maddsidi4"
1482 [(set (match_operand:DI 0 "s_register_operand" "")
1483 (plus:DI
1484 (mult:DI
1485 (sign_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1486 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "")))
1487 (match_operand:DI 3 "s_register_operand" "")))]
1488 "TARGET_32BIT && arm_arch3m"
1489 "")
82b85d08 1490
1491(define_insn "*mulsidi3adddi"
fe8dbf85 1492 [(set (match_operand:DI 0 "s_register_operand" "=&r")
82b85d08 1493 (plus:DI
215b30b3 1494 (mult:DI
fe8dbf85 1495 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "%r"))
1496 (sign_extend:DI (match_operand:SI 3 "s_register_operand" "r")))
1497 (match_operand:DI 1 "s_register_operand" "0")))]
58d7d654 1498 "TARGET_32BIT && arm_arch3m && !arm_arch6"
1499 "smlal%?\\t%Q0, %R0, %3, %2"
9da0ec36 1500 [(set_attr "type" "smlal")
58d7d654 1501 (set_attr "predicable" "yes")]
1502)
1503
1504(define_insn "*mulsidi3adddi_v6"
1505 [(set (match_operand:DI 0 "s_register_operand" "=r")
1506 (plus:DI
1507 (mult:DI
1508 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r"))
1509 (sign_extend:DI (match_operand:SI 3 "s_register_operand" "r")))
1510 (match_operand:DI 1 "s_register_operand" "0")))]
1511 "TARGET_32BIT && arm_arch6"
fe8dbf85 1512 "smlal%?\\t%Q0, %R0, %3, %2"
9da0ec36 1513 [(set_attr "type" "smlal")
d952d547 1514 (set_attr "predicable" "yes")
1515 (set_attr "predicable_short_it" "no")]
0d66636f 1516)
82b85d08 1517
957788b0 1518;; 32x32->64 widening multiply.
1519;; As with mulsi3, the only difference between the v3-5 and v6+
1520;; versions of these patterns is the requirement that the output not
1521;; overlap the inputs, but that still means we have to have a named
1522;; expander and two different starred insns.
1523
1524(define_expand "mulsidi3"
1525 [(set (match_operand:DI 0 "s_register_operand" "")
1526 (mult:DI
1527 (sign_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1528 (sign_extend:DI (match_operand:SI 2 "s_register_operand" ""))))]
1529 "TARGET_32BIT && arm_arch3m"
1530 ""
1531)
1532
1533(define_insn "*mulsidi3_nov6"
f7fbdd4a 1534 [(set (match_operand:DI 0 "s_register_operand" "=&r")
215b30b3 1535 (mult:DI
1536 (sign_extend:DI (match_operand:SI 1 "s_register_operand" "%r"))
1537 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))]
58d7d654 1538 "TARGET_32BIT && arm_arch3m && !arm_arch6"
1539 "smull%?\\t%Q0, %R0, %1, %2"
9da0ec36 1540 [(set_attr "type" "smull")
58d7d654 1541 (set_attr "predicable" "yes")]
1542)
1543
957788b0 1544(define_insn "*mulsidi3_v6"
58d7d654 1545 [(set (match_operand:DI 0 "s_register_operand" "=r")
1546 (mult:DI
1547 (sign_extend:DI (match_operand:SI 1 "s_register_operand" "r"))
1548 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))]
1549 "TARGET_32BIT && arm_arch6"
97499065 1550 "smull%?\\t%Q0, %R0, %1, %2"
9da0ec36 1551 [(set_attr "type" "smull")
d952d547 1552 (set_attr "predicable" "yes")
1553 (set_attr "predicable_short_it" "no")]
0d66636f 1554)
f7fbdd4a 1555
957788b0 1556(define_expand "umulsidi3"
1557 [(set (match_operand:DI 0 "s_register_operand" "")
1558 (mult:DI
1559 (zero_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1560 (zero_extend:DI (match_operand:SI 2 "s_register_operand" ""))))]
1561 "TARGET_32BIT && arm_arch3m"
1562 ""
1563)
1564
1565(define_insn "*umulsidi3_nov6"
f7fbdd4a 1566 [(set (match_operand:DI 0 "s_register_operand" "=&r")
215b30b3 1567 (mult:DI
1568 (zero_extend:DI (match_operand:SI 1 "s_register_operand" "%r"))
1569 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))]
58d7d654 1570 "TARGET_32BIT && arm_arch3m && !arm_arch6"
1571 "umull%?\\t%Q0, %R0, %1, %2"
9da0ec36 1572 [(set_attr "type" "umull")
58d7d654 1573 (set_attr "predicable" "yes")]
1574)
1575
957788b0 1576(define_insn "*umulsidi3_v6"
58d7d654 1577 [(set (match_operand:DI 0 "s_register_operand" "=r")
1578 (mult:DI
1579 (zero_extend:DI (match_operand:SI 1 "s_register_operand" "r"))
1580 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))]
1581 "TARGET_32BIT && arm_arch6"
97499065 1582 "umull%?\\t%Q0, %R0, %1, %2"
9da0ec36 1583 [(set_attr "type" "umull")
d952d547 1584 (set_attr "predicable" "yes")
1585 (set_attr "predicable_short_it" "no")]
0d66636f 1586)
b11cae9e 1587
5cdca009 1588(define_expand "umaddsidi4"
1589 [(set (match_operand:DI 0 "s_register_operand" "")
1590 (plus:DI
1591 (mult:DI
1592 (zero_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1593 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "")))
1594 (match_operand:DI 3 "s_register_operand" "")))]
1595 "TARGET_32BIT && arm_arch3m"
1596 "")
82b85d08 1597
1598(define_insn "*umulsidi3adddi"
8ead09f9 1599 [(set (match_operand:DI 0 "s_register_operand" "=&r")
82b85d08 1600 (plus:DI
215b30b3 1601 (mult:DI
fe8dbf85 1602 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "%r"))
1603 (zero_extend:DI (match_operand:SI 3 "s_register_operand" "r")))
1604 (match_operand:DI 1 "s_register_operand" "0")))]
58d7d654 1605 "TARGET_32BIT && arm_arch3m && !arm_arch6"
1606 "umlal%?\\t%Q0, %R0, %3, %2"
9da0ec36 1607 [(set_attr "type" "umlal")
58d7d654 1608 (set_attr "predicable" "yes")]
1609)
1610
1611(define_insn "*umulsidi3adddi_v6"
1612 [(set (match_operand:DI 0 "s_register_operand" "=r")
1613 (plus:DI
1614 (mult:DI
1615 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r"))
1616 (zero_extend:DI (match_operand:SI 3 "s_register_operand" "r")))
1617 (match_operand:DI 1 "s_register_operand" "0")))]
1618 "TARGET_32BIT && arm_arch6"
fe8dbf85 1619 "umlal%?\\t%Q0, %R0, %3, %2"
9da0ec36 1620 [(set_attr "type" "umlal")
d952d547 1621 (set_attr "predicable" "yes")
1622 (set_attr "predicable_short_it" "no")]
0d66636f 1623)
82b85d08 1624
957788b0 1625(define_expand "smulsi3_highpart"
1626 [(parallel
1627 [(set (match_operand:SI 0 "s_register_operand" "")
1628 (truncate:SI
1629 (lshiftrt:DI
1630 (mult:DI
1631 (sign_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1632 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "")))
1633 (const_int 32))))
1634 (clobber (match_scratch:SI 3 ""))])]
1635 "TARGET_32BIT && arm_arch3m"
1636 ""
1637)
1638
1639(define_insn "*smulsi3_highpart_nov6"
f082f1c4 1640 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r")
1641 (truncate:SI
1642 (lshiftrt:DI
215b30b3 1643 (mult:DI
e5fea38e 1644 (sign_extend:DI (match_operand:SI 1 "s_register_operand" "%0,r"))
215b30b3 1645 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r,r")))
f082f1c4 1646 (const_int 32))))
1647 (clobber (match_scratch:SI 3 "=&r,&r"))]
58d7d654 1648 "TARGET_32BIT && arm_arch3m && !arm_arch6"
1649 "smull%?\\t%3, %0, %2, %1"
9da0ec36 1650 [(set_attr "type" "smull")
58d7d654 1651 (set_attr "predicable" "yes")]
1652)
1653
957788b0 1654(define_insn "*smulsi3_highpart_v6"
58d7d654 1655 [(set (match_operand:SI 0 "s_register_operand" "=r")
1656 (truncate:SI
1657 (lshiftrt:DI
1658 (mult:DI
1659 (sign_extend:DI (match_operand:SI 1 "s_register_operand" "r"))
1660 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r")))
1661 (const_int 32))))
1662 (clobber (match_scratch:SI 3 "=r"))]
1663 "TARGET_32BIT && arm_arch6"
f082f1c4 1664 "smull%?\\t%3, %0, %2, %1"
9da0ec36 1665 [(set_attr "type" "smull")
d952d547 1666 (set_attr "predicable" "yes")
1667 (set_attr "predicable_short_it" "no")]
cffb2a26 1668)
f082f1c4 1669
957788b0 1670(define_expand "umulsi3_highpart"
1671 [(parallel
1672 [(set (match_operand:SI 0 "s_register_operand" "")
1673 (truncate:SI
1674 (lshiftrt:DI
1675 (mult:DI
1676 (zero_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1677 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "")))
1678 (const_int 32))))
1679 (clobber (match_scratch:SI 3 ""))])]
1680 "TARGET_32BIT && arm_arch3m"
1681 ""
1682)
1683
1684(define_insn "*umulsi3_highpart_nov6"
f082f1c4 1685 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r")
1686 (truncate:SI
1687 (lshiftrt:DI
215b30b3 1688 (mult:DI
e5fea38e 1689 (zero_extend:DI (match_operand:SI 1 "s_register_operand" "%0,r"))
215b30b3 1690 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r,r")))
f082f1c4 1691 (const_int 32))))
1692 (clobber (match_scratch:SI 3 "=&r,&r"))]
58d7d654 1693 "TARGET_32BIT && arm_arch3m && !arm_arch6"
1694 "umull%?\\t%3, %0, %2, %1"
9da0ec36 1695 [(set_attr "type" "umull")
58d7d654 1696 (set_attr "predicable" "yes")]
1697)
1698
957788b0 1699(define_insn "*umulsi3_highpart_v6"
58d7d654 1700 [(set (match_operand:SI 0 "s_register_operand" "=r")
1701 (truncate:SI
1702 (lshiftrt:DI
1703 (mult:DI
1704 (zero_extend:DI (match_operand:SI 1 "s_register_operand" "r"))
1705 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r")))
1706 (const_int 32))))
1707 (clobber (match_scratch:SI 3 "=r"))]
1708 "TARGET_32BIT && arm_arch6"
f082f1c4 1709 "umull%?\\t%3, %0, %2, %1"
9da0ec36 1710 [(set_attr "type" "umull")
d952d547 1711 (set_attr "predicable" "yes")
1712 (set_attr "predicable_short_it" "no")]
cffb2a26 1713)
f082f1c4 1714
331beb1a 1715(define_insn "mulhisi3"
1716 [(set (match_operand:SI 0 "s_register_operand" "=r")
1717 (mult:SI (sign_extend:SI
1718 (match_operand:HI 1 "s_register_operand" "%r"))
1719 (sign_extend:SI
1720 (match_operand:HI 2 "s_register_operand" "r"))))]
25f905c2 1721 "TARGET_DSP_MULTIPLY"
61a2d04c 1722 "smulbb%?\\t%0, %1, %2"
9da0ec36 1723 [(set_attr "type" "smulxy")
fec538d9 1724 (set_attr "predicable" "yes")]
1725)
1726
1727(define_insn "*mulhisi3tb"
1728 [(set (match_operand:SI 0 "s_register_operand" "=r")
1729 (mult:SI (ashiftrt:SI
1730 (match_operand:SI 1 "s_register_operand" "r")
1731 (const_int 16))
1732 (sign_extend:SI
1733 (match_operand:HI 2 "s_register_operand" "r"))))]
25f905c2 1734 "TARGET_DSP_MULTIPLY"
fec538d9 1735 "smultb%?\\t%0, %1, %2"
9da0ec36 1736 [(set_attr "type" "smulxy")
d952d547 1737 (set_attr "predicable" "yes")
1738 (set_attr "predicable_short_it" "no")]
fec538d9 1739)
1740
1741(define_insn "*mulhisi3bt"
1742 [(set (match_operand:SI 0 "s_register_operand" "=r")
1743 (mult:SI (sign_extend:SI
1744 (match_operand:HI 1 "s_register_operand" "r"))
1745 (ashiftrt:SI
1746 (match_operand:SI 2 "s_register_operand" "r")
1747 (const_int 16))))]
25f905c2 1748 "TARGET_DSP_MULTIPLY"
fec538d9 1749 "smulbt%?\\t%0, %1, %2"
9da0ec36 1750 [(set_attr "type" "smulxy")
d952d547 1751 (set_attr "predicable" "yes")
1752 (set_attr "predicable_short_it" "no")]
fec538d9 1753)
1754
1755(define_insn "*mulhisi3tt"
1756 [(set (match_operand:SI 0 "s_register_operand" "=r")
1757 (mult:SI (ashiftrt:SI
1758 (match_operand:SI 1 "s_register_operand" "r")
1759 (const_int 16))
1760 (ashiftrt:SI
1761 (match_operand:SI 2 "s_register_operand" "r")
1762 (const_int 16))))]
25f905c2 1763 "TARGET_DSP_MULTIPLY"
fec538d9 1764 "smultt%?\\t%0, %1, %2"
9da0ec36 1765 [(set_attr "type" "smulxy")
d952d547 1766 (set_attr "predicable" "yes")
1767 (set_attr "predicable_short_it" "no")]
331beb1a 1768)
1769
5cdca009 1770(define_insn "maddhisi4"
331beb1a 1771 [(set (match_operand:SI 0 "s_register_operand" "=r")
cfa6c608 1772 (plus:SI (mult:SI (sign_extend:SI
1773 (match_operand:HI 1 "s_register_operand" "r"))
331beb1a 1774 (sign_extend:SI
cfa6c608 1775 (match_operand:HI 2 "s_register_operand" "r")))
1776 (match_operand:SI 3 "s_register_operand" "r")))]
25f905c2 1777 "TARGET_DSP_MULTIPLY"
5cdca009 1778 "smlabb%?\\t%0, %1, %2, %3"
9da0ec36 1779 [(set_attr "type" "smlaxy")
d952d547 1780 (set_attr "predicable" "yes")
1781 (set_attr "predicable_short_it" "no")]
331beb1a 1782)
1783
9a92f368 1784;; Note: there is no maddhisi4ibt because this one is canonical form
1785(define_insn "*maddhisi4tb"
1786 [(set (match_operand:SI 0 "s_register_operand" "=r")
1787 (plus:SI (mult:SI (ashiftrt:SI
1788 (match_operand:SI 1 "s_register_operand" "r")
1789 (const_int 16))
1790 (sign_extend:SI
1791 (match_operand:HI 2 "s_register_operand" "r")))
1792 (match_operand:SI 3 "s_register_operand" "r")))]
1793 "TARGET_DSP_MULTIPLY"
1794 "smlatb%?\\t%0, %1, %2, %3"
9da0ec36 1795 [(set_attr "type" "smlaxy")
d952d547 1796 (set_attr "predicable" "yes")
1797 (set_attr "predicable_short_it" "no")]
9a92f368 1798)
1799
1800(define_insn "*maddhisi4tt"
1801 [(set (match_operand:SI 0 "s_register_operand" "=r")
1802 (plus:SI (mult:SI (ashiftrt:SI
1803 (match_operand:SI 1 "s_register_operand" "r")
1804 (const_int 16))
1805 (ashiftrt:SI
1806 (match_operand:SI 2 "s_register_operand" "r")
1807 (const_int 16)))
1808 (match_operand:SI 3 "s_register_operand" "r")))]
1809 "TARGET_DSP_MULTIPLY"
1810 "smlatt%?\\t%0, %1, %2, %3"
9da0ec36 1811 [(set_attr "type" "smlaxy")
d952d547 1812 (set_attr "predicable" "yes")
1813 (set_attr "predicable_short_it" "no")]
9a92f368 1814)
1815
aff5fb4d 1816(define_insn "maddhidi4"
331beb1a 1817 [(set (match_operand:DI 0 "s_register_operand" "=r")
1818 (plus:DI
331beb1a 1819 (mult:DI (sign_extend:DI
d952d547 1820 (match_operand:HI 1 "s_register_operand" "r"))
331beb1a 1821 (sign_extend:DI
cfa6c608 1822 (match_operand:HI 2 "s_register_operand" "r")))
1823 (match_operand:DI 3 "s_register_operand" "0")))]
25f905c2 1824 "TARGET_DSP_MULTIPLY"
5cdca009 1825 "smlalbb%?\\t%Q0, %R0, %1, %2"
9da0ec36 1826 [(set_attr "type" "smlalxy")
d952d547 1827 (set_attr "predicable" "yes")
1828 (set_attr "predicable_short_it" "no")])
331beb1a 1829
9a92f368 1830;; Note: there is no maddhidi4ibt because this one is canonical form
1831(define_insn "*maddhidi4tb"
1832 [(set (match_operand:DI 0 "s_register_operand" "=r")
1833 (plus:DI
1834 (mult:DI (sign_extend:DI
1835 (ashiftrt:SI
1836 (match_operand:SI 1 "s_register_operand" "r")
1837 (const_int 16)))
1838 (sign_extend:DI
1839 (match_operand:HI 2 "s_register_operand" "r")))
1840 (match_operand:DI 3 "s_register_operand" "0")))]
1841 "TARGET_DSP_MULTIPLY"
1842 "smlaltb%?\\t%Q0, %R0, %1, %2"
9da0ec36 1843 [(set_attr "type" "smlalxy")
d952d547 1844 (set_attr "predicable" "yes")
1845 (set_attr "predicable_short_it" "no")])
9a92f368 1846
1847(define_insn "*maddhidi4tt"
1848 [(set (match_operand:DI 0 "s_register_operand" "=r")
1849 (plus:DI
1850 (mult:DI (sign_extend:DI
1851 (ashiftrt:SI
1852 (match_operand:SI 1 "s_register_operand" "r")
1853 (const_int 16)))
1854 (sign_extend:DI
1855 (ashiftrt:SI
1856 (match_operand:SI 2 "s_register_operand" "r")
1857 (const_int 16))))
1858 (match_operand:DI 3 "s_register_operand" "0")))]
1859 "TARGET_DSP_MULTIPLY"
1860 "smlaltt%?\\t%Q0, %R0, %1, %2"
9da0ec36 1861 [(set_attr "type" "smlalxy")
d952d547 1862 (set_attr "predicable" "yes")
1863 (set_attr "predicable_short_it" "no")])
9a92f368 1864
604f3a0a 1865(define_expand "mulsf3"
1866 [(set (match_operand:SF 0 "s_register_operand" "")
1867 (mult:SF (match_operand:SF 1 "s_register_operand" "")
d86c91f6 1868 (match_operand:SF 2 "s_register_operand" "")))]
25f905c2 1869 "TARGET_32BIT && TARGET_HARD_FLOAT"
604f3a0a 1870 "
604f3a0a 1871")
1872
604f3a0a 1873(define_expand "muldf3"
1874 [(set (match_operand:DF 0 "s_register_operand" "")
1875 (mult:DF (match_operand:DF 1 "s_register_operand" "")
d86c91f6 1876 (match_operand:DF 2 "s_register_operand" "")))]
a50d7267 1877 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
604f3a0a 1878 "
604f3a0a 1879")
b11cae9e 1880\f
1881;; Division insns
1882
7db9af5d 1883(define_expand "divsf3"
1884 [(set (match_operand:SF 0 "s_register_operand" "")
d86c91f6 1885 (div:SF (match_operand:SF 1 "s_register_operand" "")
1886 (match_operand:SF 2 "s_register_operand" "")))]
994606f8 1887 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
7db9af5d 1888 "")
9c08d1fa 1889
7db9af5d 1890(define_expand "divdf3"
1891 [(set (match_operand:DF 0 "s_register_operand" "")
d86c91f6 1892 (div:DF (match_operand:DF 1 "s_register_operand" "")
1893 (match_operand:DF 2 "s_register_operand" "")))]
994606f8 1894 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
7db9af5d 1895 "")
b11cae9e 1896\f
1897;; Boolean and,ior,xor insns
1898
f6ebffac 1899;; Split up double word logical operations
1900
1901;; Split up simple DImode logical operations. Simply perform the logical
1902;; operation on the upper and lower halves of the registers.
1903(define_split
1904 [(set (match_operand:DI 0 "s_register_operand" "")
1905 (match_operator:DI 6 "logical_binary_operator"
1906 [(match_operand:DI 1 "s_register_operand" "")
1907 (match_operand:DI 2 "s_register_operand" "")]))]
25f905c2 1908 "TARGET_32BIT && reload_completed
e2669ea7 1909 && ! (TARGET_NEON && IS_VFP_REGNUM (REGNO (operands[0])))
25f905c2 1910 && ! IS_IWMMXT_REGNUM (REGNO (operands[0]))"
f6ebffac 1911 [(set (match_dup 0) (match_op_dup:SI 6 [(match_dup 1) (match_dup 2)]))
1912 (set (match_dup 3) (match_op_dup:SI 6 [(match_dup 4) (match_dup 5)]))]
1913 "
215b30b3 1914 {
1915 operands[3] = gen_highpart (SImode, operands[0]);
1916 operands[0] = gen_lowpart (SImode, operands[0]);
1917 operands[4] = gen_highpart (SImode, operands[1]);
1918 operands[1] = gen_lowpart (SImode, operands[1]);
1919 operands[5] = gen_highpart (SImode, operands[2]);
1920 operands[2] = gen_lowpart (SImode, operands[2]);
1921 }"
1922)
f6ebffac 1923
f6ebffac 1924(define_split
1925 [(set (match_operand:DI 0 "s_register_operand" "")
1926 (match_operator:DI 6 "logical_binary_operator"
1927 [(sign_extend:DI (match_operand:SI 2 "s_register_operand" ""))
1928 (match_operand:DI 1 "s_register_operand" "")]))]
25f905c2 1929 "TARGET_32BIT && reload_completed"
f6ebffac 1930 [(set (match_dup 0) (match_op_dup:SI 6 [(match_dup 1) (match_dup 2)]))
1931 (set (match_dup 3) (match_op_dup:SI 6
1932 [(ashiftrt:SI (match_dup 2) (const_int 31))
1933 (match_dup 4)]))]
1934 "
215b30b3 1935 {
1936 operands[3] = gen_highpart (SImode, operands[0]);
1937 operands[0] = gen_lowpart (SImode, operands[0]);
1938 operands[4] = gen_highpart (SImode, operands[1]);
1939 operands[1] = gen_lowpart (SImode, operands[1]);
1940 operands[5] = gen_highpart (SImode, operands[2]);
1941 operands[2] = gen_lowpart (SImode, operands[2]);
1942 }"
1943)
f6ebffac 1944
f6ebffac 1945;; The zero extend of operand 2 means we can just copy the high part of
1946;; operand1 into operand0.
1947(define_split
1948 [(set (match_operand:DI 0 "s_register_operand" "")
1949 (ior:DI
1950 (zero_extend:DI (match_operand:SI 2 "s_register_operand" ""))
1951 (match_operand:DI 1 "s_register_operand" "")))]
25f905c2 1952 "TARGET_32BIT && operands[0] != operands[1] && reload_completed"
f6ebffac 1953 [(set (match_dup 0) (ior:SI (match_dup 1) (match_dup 2)))
1954 (set (match_dup 3) (match_dup 4))]
1955 "
215b30b3 1956 {
1957 operands[4] = gen_highpart (SImode, operands[1]);
1958 operands[3] = gen_highpart (SImode, operands[0]);
1959 operands[0] = gen_lowpart (SImode, operands[0]);
1960 operands[1] = gen_lowpart (SImode, operands[1]);
1961 }"
1962)
f6ebffac 1963
1964;; The zero extend of operand 2 means we can just copy the high part of
1965;; operand1 into operand0.
1966(define_split
1967 [(set (match_operand:DI 0 "s_register_operand" "")
1968 (xor:DI
1969 (zero_extend:DI (match_operand:SI 2 "s_register_operand" ""))
1970 (match_operand:DI 1 "s_register_operand" "")))]
25f905c2 1971 "TARGET_32BIT && operands[0] != operands[1] && reload_completed"
f6ebffac 1972 [(set (match_dup 0) (xor:SI (match_dup 1) (match_dup 2)))
1973 (set (match_dup 3) (match_dup 4))]
1974 "
215b30b3 1975 {
1976 operands[4] = gen_highpart (SImode, operands[1]);
1977 operands[3] = gen_highpart (SImode, operands[0]);
1978 operands[0] = gen_lowpart (SImode, operands[0]);
1979 operands[1] = gen_lowpart (SImode, operands[1]);
1980 }"
1981)
f6ebffac 1982
e2669ea7 1983(define_expand "anddi3"
1984 [(set (match_operand:DI 0 "s_register_operand" "")
1985 (and:DI (match_operand:DI 1 "s_register_operand" "")
1986 (match_operand:DI 2 "neon_inv_logic_op2" "")))]
1987 "TARGET_32BIT"
1988 ""
1989)
1990
f6bbdcf6 1991(define_insn_and_split "*anddi3_insn"
0a314dcd 1992 [(set (match_operand:DI 0 "s_register_operand" "=w,w ,&r,&r,&r,&r,?w,?w")
1993 (and:DI (match_operand:DI 1 "s_register_operand" "%w,0 ,0 ,r ,0 ,r ,w ,0")
1994 (match_operand:DI 2 "arm_anddi_operand_neon" "w ,DL,r ,r ,De,De,w ,DL")))]
f6bbdcf6 1995 "TARGET_32BIT && !TARGET_IWMMXT"
1996{
1997 switch (which_alternative)
1998 {
0a314dcd 1999 case 0: /* fall through */
2000 case 6: return "vand\t%P0, %P1, %P2";
2001 case 1: /* fall through */
2002 case 7: return neon_output_logic_immediate ("vand", &operands[2],
2003 DImode, 1, VALID_NEON_QREG_MODE (DImode));
f6bbdcf6 2004 case 2:
0a314dcd 2005 case 3:
2006 case 4:
f6bbdcf6 2007 case 5: /* fall through */
0a314dcd 2008 return "#";
f6bbdcf6 2009 default: gcc_unreachable ();
2010 }
2011}
0a314dcd 2012 "TARGET_32BIT && !TARGET_IWMMXT && reload_completed
2013 && !(IS_VFP_REGNUM (REGNO (operands[0])))"
f6bbdcf6 2014 [(set (match_dup 3) (match_dup 4))
2015 (set (match_dup 5) (match_dup 6))]
2016 "
2017 {
2018 operands[3] = gen_lowpart (SImode, operands[0]);
2019 operands[5] = gen_highpart (SImode, operands[0]);
2020
2021 operands[4] = simplify_gen_binary (AND, SImode,
2022 gen_lowpart (SImode, operands[1]),
2023 gen_lowpart (SImode, operands[2]));
2024 operands[6] = simplify_gen_binary (AND, SImode,
2025 gen_highpart (SImode, operands[1]),
2026 gen_highpart_mode (SImode, DImode, operands[2]));
2027
2028 }"
32093010 2029 [(set_attr "type" "neon_logic,neon_logic,multiple,multiple,\
2030 multiple,multiple,neon_logic,neon_logic")
0a314dcd 2031 (set_attr "arch" "neon_for_64bits,neon_for_64bits,*,*,*,*,
f6bbdcf6 2032 avoid_neon_for_64bits,avoid_neon_for_64bits")
0a314dcd 2033 (set_attr "length" "*,*,8,8,8,8,*,*")
2034 ]
215b30b3 2035)
b11cae9e 2036
a0f94409 2037(define_insn_and_split "*anddi_zesidi_di"
9c08d1fa 2038 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2039 (and:DI (zero_extend:DI
2040 (match_operand:SI 2 "s_register_operand" "r,r"))
e5fea38e 2041 (match_operand:DI 1 "s_register_operand" "0,r")))]
25f905c2 2042 "TARGET_32BIT"
f6ebffac 2043 "#"
25f905c2 2044 "TARGET_32BIT && reload_completed"
a0f94409 2045 ; The zero extend of operand 2 clears the high word of the output
2046 ; operand.
2047 [(set (match_dup 0) (and:SI (match_dup 1) (match_dup 2)))
2048 (set (match_dup 3) (const_int 0))]
2049 "
2050 {
2051 operands[3] = gen_highpart (SImode, operands[0]);
2052 operands[0] = gen_lowpart (SImode, operands[0]);
2053 operands[1] = gen_lowpart (SImode, operands[1]);
2054 }"
1b7da4ac 2055 [(set_attr "length" "8")
2056 (set_attr "type" "multiple")]
215b30b3 2057)
b11cae9e 2058
f7fbdd4a 2059(define_insn "*anddi_sesdi_di"
cffb2a26 2060 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
9c08d1fa 2061 (and:DI (sign_extend:DI
2062 (match_operand:SI 2 "s_register_operand" "r,r"))
e5fea38e 2063 (match_operand:DI 1 "s_register_operand" "0,r")))]
25f905c2 2064 "TARGET_32BIT"
f6ebffac 2065 "#"
1b7da4ac 2066 [(set_attr "length" "8")
2067 (set_attr "type" "multiple")]
cffb2a26 2068)
b11cae9e 2069
87b22bf7 2070(define_expand "andsi3"
cffb2a26 2071 [(set (match_operand:SI 0 "s_register_operand" "")
87b22bf7 2072 (and:SI (match_operand:SI 1 "s_register_operand" "")
2073 (match_operand:SI 2 "reg_or_int_operand" "")))]
cffb2a26 2074 "TARGET_EITHER"
87b22bf7 2075 "
25f905c2 2076 if (TARGET_32BIT)
87b22bf7 2077 {
0438d37f 2078 if (CONST_INT_P (operands[2]))
cffb2a26 2079 {
47b5b27b 2080 if (INTVAL (operands[2]) == 255 && arm_arch6)
2081 {
2082 operands[1] = convert_to_mode (QImode, operands[1], 1);
2083 emit_insn (gen_thumb2_zero_extendqisi2_v6 (operands[0],
2084 operands[1]));
2085 }
2086 else
2087 arm_split_constant (AND, SImode, NULL_RTX,
2088 INTVAL (operands[2]), operands[0],
2089 operands[1],
2090 optimize && can_create_pseudo_p ());
615caa51 2091
cffb2a26 2092 DONE;
2093 }
87b22bf7 2094 }
25f905c2 2095 else /* TARGET_THUMB1 */
cffb2a26 2096 {
0438d37f 2097 if (!CONST_INT_P (operands[2]))
923ffadb 2098 {
2099 rtx tmp = force_reg (SImode, operands[2]);
2100 if (rtx_equal_p (operands[0], operands[1]))
2101 operands[2] = tmp;
2102 else
2103 {
2104 operands[2] = operands[1];
2105 operands[1] = tmp;
2106 }
2107 }
cffb2a26 2108 else
2109 {
2110 int i;
2111
215b30b3 2112 if (((unsigned HOST_WIDE_INT) ~INTVAL (operands[2])) < 256)
cffb2a26 2113 {
215b30b3 2114 operands[2] = force_reg (SImode,
2115 GEN_INT (~INTVAL (operands[2])));
cffb2a26 2116
747b7458 2117 emit_insn (gen_thumb1_bicsi3 (operands[0], operands[2], operands[1]));
cffb2a26 2118
2119 DONE;
2120 }
87b22bf7 2121
cffb2a26 2122 for (i = 9; i <= 31; i++)
2123 {
2124 if ((((HOST_WIDE_INT) 1) << i) - 1 == INTVAL (operands[2]))
2125 {
2126 emit_insn (gen_extzv (operands[0], operands[1], GEN_INT (i),
2127 const0_rtx));
2128 DONE;
2129 }
215b30b3 2130 else if ((((HOST_WIDE_INT) 1) << i) - 1
2131 == ~INTVAL (operands[2]))
cffb2a26 2132 {
2133 rtx shift = GEN_INT (i);
2134 rtx reg = gen_reg_rtx (SImode);
2135
2136 emit_insn (gen_lshrsi3 (reg, operands[1], shift));
2137 emit_insn (gen_ashlsi3 (operands[0], reg, shift));
2138
2139 DONE;
2140 }
2141 }
2142
2143 operands[2] = force_reg (SImode, operands[2]);
2144 }
215b30b3 2145 }
2146 "
cffb2a26 2147)
2148
25f905c2 2149; ??? Check split length for Thumb-2
a0f94409 2150(define_insn_and_split "*arm_andsi3_insn"
29e234a3 2151 [(set (match_operand:SI 0 "s_register_operand" "=r,l,r,r,r")
2152 (and:SI (match_operand:SI 1 "s_register_operand" "%r,0,r,r,r")
2153 (match_operand:SI 2 "reg_or_int_operand" "I,l,K,r,?n")))]
25f905c2 2154 "TARGET_32BIT"
5565501b 2155 "@
29e234a3 2156 and%?\\t%0, %1, %2
5565501b 2157 and%?\\t%0, %1, %2
87b22bf7 2158 bic%?\\t%0, %1, #%B2
65f68e55 2159 and%?\\t%0, %1, %2
87b22bf7 2160 #"
25f905c2 2161 "TARGET_32BIT
0438d37f 2162 && CONST_INT_P (operands[2])
a0f94409 2163 && !(const_ok_for_arm (INTVAL (operands[2]))
2164 || const_ok_for_arm (~INTVAL (operands[2])))"
2165 [(clobber (const_int 0))]
2166 "
96f57e36 2167 arm_split_constant (AND, SImode, curr_insn,
2168 INTVAL (operands[2]), operands[0], operands[1], 0);
a0f94409 2169 DONE;
2170 "
29e234a3 2171 [(set_attr "length" "4,4,4,4,16")
65f68e55 2172 (set_attr "predicable" "yes")
29e234a3 2173 (set_attr "predicable_short_it" "no,yes,no,no,no")
d82e788e 2174 (set_attr "type" "logic_imm,logic_imm,logic_reg,logic_reg,logic_imm")]
cffb2a26 2175)
2176
f7fbdd4a 2177(define_insn "*andsi3_compare0"
bd5b4116 2178 [(set (reg:CC_NOOV CC_REGNUM)
5565501b 2179 (compare:CC_NOOV
65f68e55 2180 (and:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
2181 (match_operand:SI 2 "arm_not_operand" "I,K,r"))
5565501b 2182 (const_int 0)))
65f68e55 2183 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9c08d1fa 2184 (and:SI (match_dup 1) (match_dup 2)))]
25f905c2 2185 "TARGET_32BIT"
5565501b 2186 "@
25f905c2 2187 and%.\\t%0, %1, %2
65f68e55 2188 bic%.\\t%0, %1, #%B2
2189 and%.\\t%0, %1, %2"
2190 [(set_attr "conds" "set")
d82e788e 2191 (set_attr "type" "logics_imm,logics_imm,logics_reg")]
cffb2a26 2192)
9c08d1fa 2193
f7fbdd4a 2194(define_insn "*andsi3_compare0_scratch"
bd5b4116 2195 [(set (reg:CC_NOOV CC_REGNUM)
5565501b 2196 (compare:CC_NOOV
65f68e55 2197 (and:SI (match_operand:SI 0 "s_register_operand" "r,r,r")
2198 (match_operand:SI 1 "arm_not_operand" "I,K,r"))
5565501b 2199 (const_int 0)))
65f68e55 2200 (clobber (match_scratch:SI 2 "=X,r,X"))]
25f905c2 2201 "TARGET_32BIT"
5565501b 2202 "@
2203 tst%?\\t%0, %1
65f68e55 2204 bic%.\\t%2, %0, #%B1
2205 tst%?\\t%0, %1"
2206 [(set_attr "conds" "set")
d82e788e 2207 (set_attr "type" "logics_imm,logics_imm,logics_reg")]
0d66636f 2208)
9c08d1fa 2209
f7fbdd4a 2210(define_insn "*zeroextractsi_compare0_scratch"
bd5b4116 2211 [(set (reg:CC_NOOV CC_REGNUM)
9c08d1fa 2212 (compare:CC_NOOV (zero_extract:SI
2213 (match_operand:SI 0 "s_register_operand" "r")
d952d547 2214 (match_operand 1 "const_int_operand" "n")
206ee9a2 2215 (match_operand 2 "const_int_operand" "n"))
9c08d1fa 2216 (const_int 0)))]
25f905c2 2217 "TARGET_32BIT
cffb2a26 2218 && (INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) < 32
2219 && INTVAL (operands[1]) > 0
2220 && INTVAL (operands[1]) + (INTVAL (operands[2]) & 1) <= 8
2221 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32)"
9c08d1fa 2222 "*
5c49a439 2223 operands[1] = GEN_INT (((1 << INTVAL (operands[1])) - 1)
2224 << INTVAL (operands[2]));
40dbec34 2225 output_asm_insn (\"tst%?\\t%0, %1\", operands);
e2348bcb 2226 return \"\";
0d66636f 2227 "
596e5e8f 2228 [(set_attr "conds" "set")
65f68e55 2229 (set_attr "predicable" "yes")
d952d547 2230 (set_attr "predicable_short_it" "no")
d82e788e 2231 (set_attr "type" "logics_imm")]
0d66636f 2232)
9c08d1fa 2233
f4462328 2234(define_insn_and_split "*ne_zeroextractsi"
c4034607 2235 [(set (match_operand:SI 0 "s_register_operand" "=r")
2236 (ne:SI (zero_extract:SI
2237 (match_operand:SI 1 "s_register_operand" "r")
2238 (match_operand:SI 2 "const_int_operand" "n")
2239 (match_operand:SI 3 "const_int_operand" "n"))
3b8c7f7a 2240 (const_int 0)))
2241 (clobber (reg:CC CC_REGNUM))]
25f905c2 2242 "TARGET_32BIT
cffb2a26 2243 && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
2244 && INTVAL (operands[2]) > 0
2245 && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
2246 && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)"
f4462328 2247 "#"
25f905c2 2248 "TARGET_32BIT
f4462328 2249 && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
2250 && INTVAL (operands[2]) > 0
2251 && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
2252 && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)"
2253 [(parallel [(set (reg:CC_NOOV CC_REGNUM)
2254 (compare:CC_NOOV (and:SI (match_dup 1) (match_dup 2))
2255 (const_int 0)))
2256 (set (match_dup 0) (and:SI (match_dup 1) (match_dup 2)))])
2257 (set (match_dup 0)
2258 (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
2259 (match_dup 0) (const_int 1)))]
2260 "
2261 operands[2] = GEN_INT (((1 << INTVAL (operands[2])) - 1)
2262 << INTVAL (operands[3]));
2263 "
2264 [(set_attr "conds" "clob")
25f905c2 2265 (set (attr "length")
2266 (if_then_else (eq_attr "is_thumb" "yes")
2267 (const_int 12)
1b7da4ac 2268 (const_int 8)))
2269 (set_attr "type" "multiple")]
f4462328 2270)
2271
2272(define_insn_and_split "*ne_zeroextractsi_shifted"
2273 [(set (match_operand:SI 0 "s_register_operand" "=r")
2274 (ne:SI (zero_extract:SI
2275 (match_operand:SI 1 "s_register_operand" "r")
2276 (match_operand:SI 2 "const_int_operand" "n")
2277 (const_int 0))
2278 (const_int 0)))
2279 (clobber (reg:CC CC_REGNUM))]
2280 "TARGET_ARM"
2281 "#"
2282 "TARGET_ARM"
2283 [(parallel [(set (reg:CC_NOOV CC_REGNUM)
2284 (compare:CC_NOOV (ashift:SI (match_dup 1) (match_dup 2))
2285 (const_int 0)))
2286 (set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 2)))])
2287 (set (match_dup 0)
2288 (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
2289 (match_dup 0) (const_int 1)))]
2290 "
2291 operands[2] = GEN_INT (32 - INTVAL (operands[2]));
2292 "
2293 [(set_attr "conds" "clob")
1b7da4ac 2294 (set_attr "length" "8")
2295 (set_attr "type" "multiple")]
f4462328 2296)
2297
2298(define_insn_and_split "*ite_ne_zeroextractsi"
2299 [(set (match_operand:SI 0 "s_register_operand" "=r")
2300 (if_then_else:SI (ne (zero_extract:SI
2301 (match_operand:SI 1 "s_register_operand" "r")
2302 (match_operand:SI 2 "const_int_operand" "n")
2303 (match_operand:SI 3 "const_int_operand" "n"))
2304 (const_int 0))
2305 (match_operand:SI 4 "arm_not_operand" "rIK")
2306 (const_int 0)))
2307 (clobber (reg:CC CC_REGNUM))]
2308 "TARGET_ARM
2309 && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
2310 && INTVAL (operands[2]) > 0
2311 && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
f8d7bf2f 2312 && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)
2313 && !reg_overlap_mentioned_p (operands[0], operands[4])"
f4462328 2314 "#"
2315 "TARGET_ARM
2316 && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
2317 && INTVAL (operands[2]) > 0
2318 && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
f8d7bf2f 2319 && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)
2320 && !reg_overlap_mentioned_p (operands[0], operands[4])"
f4462328 2321 [(parallel [(set (reg:CC_NOOV CC_REGNUM)
2322 (compare:CC_NOOV (and:SI (match_dup 1) (match_dup 2))
2323 (const_int 0)))
2324 (set (match_dup 0) (and:SI (match_dup 1) (match_dup 2)))])
2325 (set (match_dup 0)
2326 (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
2327 (match_dup 0) (match_dup 4)))]
2328 "
c4034607 2329 operands[2] = GEN_INT (((1 << INTVAL (operands[2])) - 1)
f4462328 2330 << INTVAL (operands[3]));
2331 "
2332 [(set_attr "conds" "clob")
1b7da4ac 2333 (set_attr "length" "8")
2334 (set_attr "type" "multiple")]
f4462328 2335)
2336
2337(define_insn_and_split "*ite_ne_zeroextractsi_shifted"
2338 [(set (match_operand:SI 0 "s_register_operand" "=r")
2339 (if_then_else:SI (ne (zero_extract:SI
2340 (match_operand:SI 1 "s_register_operand" "r")
2341 (match_operand:SI 2 "const_int_operand" "n")
2342 (const_int 0))
2343 (const_int 0))
2344 (match_operand:SI 3 "arm_not_operand" "rIK")
2345 (const_int 0)))
2346 (clobber (reg:CC CC_REGNUM))]
f8d7bf2f 2347 "TARGET_ARM && !reg_overlap_mentioned_p (operands[0], operands[3])"
f4462328 2348 "#"
f8d7bf2f 2349 "TARGET_ARM && !reg_overlap_mentioned_p (operands[0], operands[3])"
f4462328 2350 [(parallel [(set (reg:CC_NOOV CC_REGNUM)
2351 (compare:CC_NOOV (ashift:SI (match_dup 1) (match_dup 2))
2352 (const_int 0)))
2353 (set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 2)))])
2354 (set (match_dup 0)
2355 (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
2356 (match_dup 0) (match_dup 3)))]
2357 "
2358 operands[2] = GEN_INT (32 - INTVAL (operands[2]));
0d66636f 2359 "
2360 [(set_attr "conds" "clob")
1b7da4ac 2361 (set_attr "length" "8")
2362 (set_attr "type" "multiple")]
215b30b3 2363)
9c08d1fa 2364
25f905c2 2365;; ??? Use Thumb-2 has bitfield insert/extract instructions.
d7863cfe 2366(define_split
2367 [(set (match_operand:SI 0 "s_register_operand" "")
2368 (match_operator:SI 1 "shiftable_operator"
2369 [(zero_extract:SI (match_operand:SI 2 "s_register_operand" "")
2370 (match_operand:SI 3 "const_int_operand" "")
2371 (match_operand:SI 4 "const_int_operand" ""))
2372 (match_operand:SI 5 "s_register_operand" "")]))
2373 (clobber (match_operand:SI 6 "s_register_operand" ""))]
2374 "TARGET_ARM"
2375 [(set (match_dup 6) (ashift:SI (match_dup 2) (match_dup 3)))
2376 (set (match_dup 0)
2377 (match_op_dup 1
2378 [(lshiftrt:SI (match_dup 6) (match_dup 4))
2379 (match_dup 5)]))]
2380 "{
2381 HOST_WIDE_INT temp = INTVAL (operands[3]);
2382
2383 operands[3] = GEN_INT (32 - temp - INTVAL (operands[4]));
2384 operands[4] = GEN_INT (32 - temp);
2385 }"
2386)
2387
d7863cfe 2388(define_split
2389 [(set (match_operand:SI 0 "s_register_operand" "")
2390 (match_operator:SI 1 "shiftable_operator"
2391 [(sign_extract:SI (match_operand:SI 2 "s_register_operand" "")
2392 (match_operand:SI 3 "const_int_operand" "")
2393 (match_operand:SI 4 "const_int_operand" ""))
2394 (match_operand:SI 5 "s_register_operand" "")]))
2395 (clobber (match_operand:SI 6 "s_register_operand" ""))]
2396 "TARGET_ARM"
2397 [(set (match_dup 6) (ashift:SI (match_dup 2) (match_dup 3)))
2398 (set (match_dup 0)
2399 (match_op_dup 1
2400 [(ashiftrt:SI (match_dup 6) (match_dup 4))
2401 (match_dup 5)]))]
2402 "{
2403 HOST_WIDE_INT temp = INTVAL (operands[3]);
2404
2405 operands[3] = GEN_INT (32 - temp - INTVAL (operands[4]));
2406 operands[4] = GEN_INT (32 - temp);
2407 }"
2408)
2409
a42059fd 2410;;; ??? This pattern is bogus. If operand3 has bits outside the range
2411;;; represented by the bitfield, then this will produce incorrect results.
2412;;; Somewhere, the value needs to be truncated. On targets like the m68k,
ceb2fe0f 2413;;; which have a real bit-field insert instruction, the truncation happens
2414;;; in the bit-field insert instruction itself. Since arm does not have a
2415;;; bit-field insert instruction, we would have to emit code here to truncate
a42059fd 2416;;; the value before we insert. This loses some of the advantage of having
2417;;; this insv pattern, so this pattern needs to be reevalutated.
2418
8a18b90c 2419(define_expand "insv"
eb04cafb 2420 [(set (zero_extract (match_operand 0 "nonimmediate_operand" "")
2421 (match_operand 1 "general_operand" "")
2422 (match_operand 2 "general_operand" ""))
2423 (match_operand 3 "reg_or_int_operand" ""))]
8b054d5a 2424 "TARGET_ARM || arm_arch_thumb2"
8a18b90c 2425 "
215b30b3 2426 {
2427 int start_bit = INTVAL (operands[2]);
2428 int width = INTVAL (operands[1]);
2429 HOST_WIDE_INT mask = (((HOST_WIDE_INT)1) << width) - 1;
2430 rtx target, subtarget;
2431
8b054d5a 2432 if (arm_arch_thumb2)
2433 {
eb04cafb 2434 if (unaligned_access && MEM_P (operands[0])
2435 && s_register_operand (operands[3], GET_MODE (operands[3]))
2436 && (width == 16 || width == 32) && (start_bit % BITS_PER_UNIT) == 0)
8b054d5a 2437 {
eb04cafb 2438 rtx base_addr;
2439
2440 if (BYTES_BIG_ENDIAN)
2441 start_bit = GET_MODE_BITSIZE (GET_MODE (operands[3])) - width
2442 - start_bit;
8b054d5a 2443
eb04cafb 2444 if (width == 32)
8b054d5a 2445 {
eb04cafb 2446 base_addr = adjust_address (operands[0], SImode,
2447 start_bit / BITS_PER_UNIT);
2448 emit_insn (gen_unaligned_storesi (base_addr, operands[3]));
8b054d5a 2449 }
eb04cafb 2450 else
2451 {
2452 rtx tmp = gen_reg_rtx (HImode);
8b054d5a 2453
eb04cafb 2454 base_addr = adjust_address (operands[0], HImode,
2455 start_bit / BITS_PER_UNIT);
2456 emit_move_insn (tmp, gen_lowpart (HImode, operands[3]));
2457 emit_insn (gen_unaligned_storehi (base_addr, tmp));
2458 }
2459 DONE;
8b054d5a 2460 }
eb04cafb 2461 else if (s_register_operand (operands[0], GET_MODE (operands[0])))
8b054d5a 2462 {
eb04cafb 2463 bool use_bfi = TRUE;
8b054d5a 2464
0438d37f 2465 if (CONST_INT_P (operands[3]))
eb04cafb 2466 {
2467 HOST_WIDE_INT val = INTVAL (operands[3]) & mask;
2468
2469 if (val == 0)
2470 {
2471 emit_insn (gen_insv_zero (operands[0], operands[1],
2472 operands[2]));
2473 DONE;
2474 }
2475
2476 /* See if the set can be done with a single orr instruction. */
2477 if (val == mask && const_ok_for_arm (val << start_bit))
2478 use_bfi = FALSE;
2479 }
2480
2481 if (use_bfi)
2482 {
0438d37f 2483 if (!REG_P (operands[3]))
eb04cafb 2484 operands[3] = force_reg (SImode, operands[3]);
2485
2486 emit_insn (gen_insv_t2 (operands[0], operands[1], operands[2],
2487 operands[3]));
2488 DONE;
2489 }
8b054d5a 2490 }
eb04cafb 2491 else
2492 FAIL;
8b054d5a 2493 }
2494
eb04cafb 2495 if (!s_register_operand (operands[0], GET_MODE (operands[0])))
2496 FAIL;
2497
3f8fde42 2498 target = copy_rtx (operands[0]);
215b30b3 2499 /* Avoid using a subreg as a subtarget, and avoid writing a paradoxical
2500 subreg as the final target. */
2501 if (GET_CODE (target) == SUBREG)
2502 {
2503 subtarget = gen_reg_rtx (SImode);
2504 if (GET_MODE_SIZE (GET_MODE (SUBREG_REG (target)))
2505 < GET_MODE_SIZE (SImode))
2506 target = SUBREG_REG (target);
2507 }
2508 else
2509 subtarget = target;
8a18b90c 2510
0438d37f 2511 if (CONST_INT_P (operands[3]))
215b30b3 2512 {
2513 /* Since we are inserting a known constant, we may be able to
2514 reduce the number of bits that we have to clear so that
2515 the mask becomes simple. */
2516 /* ??? This code does not check to see if the new mask is actually
2517 simpler. It may not be. */
2518 rtx op1 = gen_reg_rtx (SImode);
2519 /* ??? Truncate operand3 to fit in the bitfield. See comment before
2520 start of this pattern. */
2521 HOST_WIDE_INT op3_value = mask & INTVAL (operands[3]);
2522 HOST_WIDE_INT mask2 = ((mask & ~op3_value) << start_bit);
2523
c5b3a71b 2524 emit_insn (gen_andsi3 (op1, operands[0],
2525 gen_int_mode (~mask2, SImode)));
215b30b3 2526 emit_insn (gen_iorsi3 (subtarget, op1,
4292ca6b 2527 gen_int_mode (op3_value << start_bit, SImode)));
215b30b3 2528 }
2529 else if (start_bit == 0
2530 && !(const_ok_for_arm (mask)
2531 || const_ok_for_arm (~mask)))
2532 {
2533 /* A Trick, since we are setting the bottom bits in the word,
2534 we can shift operand[3] up, operand[0] down, OR them together
2535 and rotate the result back again. This takes 3 insns, and
5910bb95 2536 the third might be mergeable into another op. */
215b30b3 2537 /* The shift up copes with the possibility that operand[3] is
2538 wider than the bitfield. */
2539 rtx op0 = gen_reg_rtx (SImode);
2540 rtx op1 = gen_reg_rtx (SImode);
2541
2542 emit_insn (gen_ashlsi3 (op0, operands[3], GEN_INT (32 - width)));
2543 emit_insn (gen_lshrsi3 (op1, operands[0], operands[1]));
2544 emit_insn (gen_iorsi3 (op1, op1, op0));
2545 emit_insn (gen_rotlsi3 (subtarget, op1, operands[1]));
2546 }
2547 else if ((width + start_bit == 32)
2548 && !(const_ok_for_arm (mask)
2549 || const_ok_for_arm (~mask)))
2550 {
2551 /* Similar trick, but slightly less efficient. */
8a18b90c 2552
215b30b3 2553 rtx op0 = gen_reg_rtx (SImode);
2554 rtx op1 = gen_reg_rtx (SImode);
8a18b90c 2555
215b30b3 2556 emit_insn (gen_ashlsi3 (op0, operands[3], GEN_INT (32 - width)));
2557 emit_insn (gen_ashlsi3 (op1, operands[0], operands[1]));
2558 emit_insn (gen_lshrsi3 (op1, op1, operands[1]));
2559 emit_insn (gen_iorsi3 (subtarget, op1, op0));
2560 }
2561 else
2562 {
c5b3a71b 2563 rtx op0 = gen_int_mode (mask, SImode);
215b30b3 2564 rtx op1 = gen_reg_rtx (SImode);
2565 rtx op2 = gen_reg_rtx (SImode);
8a18b90c 2566
215b30b3 2567 if (!(const_ok_for_arm (mask) || const_ok_for_arm (~mask)))
2568 {
2569 rtx tmp = gen_reg_rtx (SImode);
8a18b90c 2570
215b30b3 2571 emit_insn (gen_movsi (tmp, op0));
2572 op0 = tmp;
2573 }
8a18b90c 2574
215b30b3 2575 /* Mask out any bits in operand[3] that are not needed. */
2576 emit_insn (gen_andsi3 (op1, operands[3], op0));
8a18b90c 2577
0438d37f 2578 if (CONST_INT_P (op0)
215b30b3 2579 && (const_ok_for_arm (mask << start_bit)
2580 || const_ok_for_arm (~(mask << start_bit))))
2581 {
c5b3a71b 2582 op0 = gen_int_mode (~(mask << start_bit), SImode);
215b30b3 2583 emit_insn (gen_andsi3 (op2, operands[0], op0));
2584 }
2585 else
2586 {
0438d37f 2587 if (CONST_INT_P (op0))
215b30b3 2588 {
2589 rtx tmp = gen_reg_rtx (SImode);
8a18b90c 2590
215b30b3 2591 emit_insn (gen_movsi (tmp, op0));
2592 op0 = tmp;
2593 }
2594
2595 if (start_bit != 0)
2596 emit_insn (gen_ashlsi3 (op0, op0, operands[2]));
a42059fd 2597
215b30b3 2598 emit_insn (gen_andsi_notsi_si (op2, operands[0], op0));
2599 }
8a18b90c 2600
215b30b3 2601 if (start_bit != 0)
2602 emit_insn (gen_ashlsi3 (op1, op1, operands[2]));
8a18b90c 2603
215b30b3 2604 emit_insn (gen_iorsi3 (subtarget, op1, op2));
2605 }
f082f1c4 2606
215b30b3 2607 if (subtarget != target)
2608 {
2609 /* If TARGET is still a SUBREG, then it must be wider than a word,
2610 so we must be careful only to set the subword we were asked to. */
2611 if (GET_CODE (target) == SUBREG)
2612 emit_move_insn (target, subtarget);
2613 else
2614 emit_move_insn (target, gen_lowpart (GET_MODE (target), subtarget));
2615 }
8a18b90c 2616
215b30b3 2617 DONE;
2618 }"
2619)
8a18b90c 2620
8b054d5a 2621(define_insn "insv_zero"
2622 [(set (zero_extract:SI (match_operand:SI 0 "s_register_operand" "+r")
809003b3 2623 (match_operand:SI 1 "const_int_M_operand" "M")
2624 (match_operand:SI 2 "const_int_M_operand" "M"))
8b054d5a 2625 (const_int 0))]
2626 "arm_arch_thumb2"
2627 "bfc%?\t%0, %2, %1"
2628 [(set_attr "length" "4")
d952d547 2629 (set_attr "predicable" "yes")
d82e788e 2630 (set_attr "predicable_short_it" "no")
2631 (set_attr "type" "bfm")]
8b054d5a 2632)
2633
2634(define_insn "insv_t2"
2635 [(set (zero_extract:SI (match_operand:SI 0 "s_register_operand" "+r")
809003b3 2636 (match_operand:SI 1 "const_int_M_operand" "M")
2637 (match_operand:SI 2 "const_int_M_operand" "M"))
8b054d5a 2638 (match_operand:SI 3 "s_register_operand" "r"))]
2639 "arm_arch_thumb2"
2640 "bfi%?\t%0, %3, %2, %1"
2641 [(set_attr "length" "4")
d952d547 2642 (set_attr "predicable" "yes")
d82e788e 2643 (set_attr "predicable_short_it" "no")
2644 (set_attr "type" "bfm")]
8b054d5a 2645)
2646
215b30b3 2647; constants for op 2 will never be given to these patterns.
a0f94409 2648(define_insn_and_split "*anddi_notdi_di"
9c08d1fa 2649 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
e5fea38e 2650 (and:DI (not:DI (match_operand:DI 1 "s_register_operand" "0,r"))
2651 (match_operand:DI 2 "s_register_operand" "r,0")))]
25f905c2 2652 "TARGET_32BIT"
f6ebffac 2653 "#"
e2669ea7 2654 "TARGET_32BIT && reload_completed
2655 && ! (TARGET_NEON && IS_VFP_REGNUM (REGNO (operands[0])))
2656 && ! IS_IWMMXT_REGNUM (REGNO (operands[0]))"
a0f94409 2657 [(set (match_dup 0) (and:SI (not:SI (match_dup 1)) (match_dup 2)))
2658 (set (match_dup 3) (and:SI (not:SI (match_dup 4)) (match_dup 5)))]
2659 "
2660 {
2661 operands[3] = gen_highpart (SImode, operands[0]);
2662 operands[0] = gen_lowpart (SImode, operands[0]);
2663 operands[4] = gen_highpart (SImode, operands[1]);
2664 operands[1] = gen_lowpart (SImode, operands[1]);
2665 operands[5] = gen_highpart (SImode, operands[2]);
2666 operands[2] = gen_lowpart (SImode, operands[2]);
2667 }"
0d66636f 2668 [(set_attr "length" "8")
1b7da4ac 2669 (set_attr "predicable" "yes")
2670 (set_attr "type" "multiple")]
0d66636f 2671)
d952d547 2672
a0f94409 2673(define_insn_and_split "*anddi_notzesidi_di"
9c08d1fa 2674 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2675 (and:DI (not:DI (zero_extend:DI
2676 (match_operand:SI 2 "s_register_operand" "r,r")))
e2348bcb 2677 (match_operand:DI 1 "s_register_operand" "0,?r")))]
25f905c2 2678 "TARGET_32BIT"
e2348bcb 2679 "@
97499065 2680 bic%?\\t%Q0, %Q1, %2
f6ebffac 2681 #"
a0f94409 2682 ; (not (zero_extend ...)) allows us to just copy the high word from
2683 ; operand1 to operand0.
25f905c2 2684 "TARGET_32BIT
a0f94409 2685 && reload_completed
2686 && operands[0] != operands[1]"
5a097f7d 2687 [(set (match_dup 0) (and:SI (not:SI (match_dup 2)) (match_dup 1)))
a0f94409 2688 (set (match_dup 3) (match_dup 4))]
2689 "
2690 {
2691 operands[3] = gen_highpart (SImode, operands[0]);
2692 operands[0] = gen_lowpart (SImode, operands[0]);
2693 operands[4] = gen_highpart (SImode, operands[1]);
2694 operands[1] = gen_lowpart (SImode, operands[1]);
2695 }"
0d66636f 2696 [(set_attr "length" "4,8")
d952d547 2697 (set_attr "predicable" "yes")
1b7da4ac 2698 (set_attr "predicable_short_it" "no")
2699 (set_attr "type" "multiple")]
0d66636f 2700)
d952d547 2701
d8cd5fa0 2702(define_insn_and_split "*anddi_notdi_zesidi"
2703 [(set (match_operand:DI 0 "s_register_operand" "=r")
2704 (and:DI (not:DI (match_operand:DI 2 "s_register_operand" "r"))
2705 (zero_extend:DI
2706 (match_operand:SI 1 "s_register_operand" "r"))))]
2707 "TARGET_32BIT"
2708 "#"
2709 "TARGET_32BIT && reload_completed"
2710 [(set (match_dup 0) (and:SI (not:SI (match_dup 2)) (match_dup 1)))
2711 (set (match_dup 3) (const_int 0))]
2712 "
2713 {
2714 operands[3] = gen_highpart (SImode, operands[0]);
2715 operands[0] = gen_lowpart (SImode, operands[0]);
2716 operands[2] = gen_lowpart (SImode, operands[2]);
2717 }"
2718 [(set_attr "length" "8")
2719 (set_attr "predicable" "yes")
2720 (set_attr "predicable_short_it" "no")
2721 (set_attr "type" "multiple")]
2722)
2723
a0f94409 2724(define_insn_and_split "*anddi_notsesidi_di"
9c08d1fa 2725 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2726 (and:DI (not:DI (sign_extend:DI
2727 (match_operand:SI 2 "s_register_operand" "r,r")))
5a097f7d 2728 (match_operand:DI 1 "s_register_operand" "0,r")))]
25f905c2 2729 "TARGET_32BIT"
f6ebffac 2730 "#"
25f905c2 2731 "TARGET_32BIT && reload_completed"
5a097f7d 2732 [(set (match_dup 0) (and:SI (not:SI (match_dup 2)) (match_dup 1)))
a0f94409 2733 (set (match_dup 3) (and:SI (not:SI
2734 (ashiftrt:SI (match_dup 2) (const_int 31)))
2735 (match_dup 4)))]
2736 "
2737 {
2738 operands[3] = gen_highpart (SImode, operands[0]);
2739 operands[0] = gen_lowpart (SImode, operands[0]);
2740 operands[4] = gen_highpart (SImode, operands[1]);
2741 operands[1] = gen_lowpart (SImode, operands[1]);
2742 }"
0d66636f 2743 [(set_attr "length" "8")
d952d547 2744 (set_attr "predicable" "yes")
1b7da4ac 2745 (set_attr "predicable_short_it" "no")
2746 (set_attr "type" "multiple")]
0d66636f 2747)
d952d547 2748
8a18b90c 2749(define_insn "andsi_notsi_si"
9c08d1fa 2750 [(set (match_operand:SI 0 "s_register_operand" "=r")
2751 (and:SI (not:SI (match_operand:SI 2 "s_register_operand" "r"))
2752 (match_operand:SI 1 "s_register_operand" "r")))]
25f905c2 2753 "TARGET_32BIT"
0d66636f 2754 "bic%?\\t%0, %1, %2"
d952d547 2755 [(set_attr "predicable" "yes")
1b7da4ac 2756 (set_attr "predicable_short_it" "no")
2757 (set_attr "type" "logic_reg")]
0d66636f 2758)
b11cae9e 2759
8a18b90c 2760(define_insn "andsi_not_shiftsi_si"
a2cd141b 2761 [(set (match_operand:SI 0 "s_register_operand" "=r")
2762 (and:SI (not:SI (match_operator:SI 4 "shift_operator"
2763 [(match_operand:SI 2 "s_register_operand" "r")
2764 (match_operand:SI 3 "arm_rhs_operand" "rM")]))
2765 (match_operand:SI 1 "s_register_operand" "r")))]
cffb2a26 2766 "TARGET_ARM"
6c4c2133 2767 "bic%?\\t%0, %1, %2%S4"
344495ea 2768 [(set_attr "predicable" "yes")
331beb1a 2769 (set_attr "shift" "2")
a2cd141b 2770 (set (attr "type") (if_then_else (match_operand 3 "const_int_operand" "")
d82e788e 2771 (const_string "logic_shift_imm")
2772 (const_string "logic_shift_reg")))]
6c4c2133 2773)
8a18b90c 2774
f7fbdd4a 2775(define_insn "*andsi_notsi_si_compare0"
bd5b4116 2776 [(set (reg:CC_NOOV CC_REGNUM)
e2348bcb 2777 (compare:CC_NOOV
2778 (and:SI (not:SI (match_operand:SI 2 "s_register_operand" "r"))
2779 (match_operand:SI 1 "s_register_operand" "r"))
2780 (const_int 0)))
9c08d1fa 2781 (set (match_operand:SI 0 "s_register_operand" "=r")
2782 (and:SI (not:SI (match_dup 2)) (match_dup 1)))]
25f905c2 2783 "TARGET_32BIT"
2784 "bic%.\\t%0, %1, %2"
d82e788e 2785 [(set_attr "conds" "set")
2786 (set_attr "type" "logics_shift_reg")]
0d66636f 2787)
9c08d1fa 2788
f7fbdd4a 2789(define_insn "*andsi_notsi_si_compare0_scratch"
bd5b4116 2790 [(set (reg:CC_NOOV CC_REGNUM)
e2348bcb 2791 (compare:CC_NOOV
2792 (and:SI (not:SI (match_operand:SI 2 "s_register_operand" "r"))
2793 (match_operand:SI 1 "s_register_operand" "r"))
2794 (const_int 0)))
9c08d1fa 2795 (clobber (match_scratch:SI 0 "=r"))]
25f905c2 2796 "TARGET_32BIT"
2797 "bic%.\\t%0, %1, %2"
d82e788e 2798 [(set_attr "conds" "set")
2799 (set_attr "type" "logics_shift_reg")]
0d66636f 2800)
9c08d1fa 2801
e2669ea7 2802(define_expand "iordi3"
2803 [(set (match_operand:DI 0 "s_register_operand" "")
2804 (ior:DI (match_operand:DI 1 "s_register_operand" "")
2805 (match_operand:DI 2 "neon_logic_op2" "")))]
2806 "TARGET_32BIT"
2807 ""
2808)
2809
74d6113f 2810(define_insn_and_split "*iordi3_insn"
2811 [(set (match_operand:DI 0 "s_register_operand" "=w,w ,&r,&r,&r,&r,?w,?w")
2812 (ior:DI (match_operand:DI 1 "s_register_operand" "%w,0 ,0 ,r ,0 ,r ,w ,0")
e0fe6977 2813 (match_operand:DI 2 "arm_iordi_operand_neon" "w ,Dl,r ,r ,Df,Df,w ,Dl")))]
74d6113f 2814 "TARGET_32BIT && !TARGET_IWMMXT"
2815 {
2816 switch (which_alternative)
2817 {
2818 case 0: /* fall through */
2819 case 6: return "vorr\t%P0, %P1, %P2";
2820 case 1: /* fall through */
2821 case 7: return neon_output_logic_immediate ("vorr", &operands[2],
2822 DImode, 0, VALID_NEON_QREG_MODE (DImode));
2823 case 2:
2824 case 3:
2825 case 4:
2826 case 5:
2827 return "#";
2828 default: gcc_unreachable ();
2829 }
2830 }
2831 "TARGET_32BIT && !TARGET_IWMMXT && reload_completed
2832 && !(IS_VFP_REGNUM (REGNO (operands[0])))"
2833 [(set (match_dup 3) (match_dup 4))
2834 (set (match_dup 5) (match_dup 6))]
2835 "
2836 {
2837 operands[3] = gen_lowpart (SImode, operands[0]);
2838 operands[5] = gen_highpart (SImode, operands[0]);
2839
2840 operands[4] = simplify_gen_binary (IOR, SImode,
2841 gen_lowpart (SImode, operands[1]),
2842 gen_lowpart (SImode, operands[2]));
2843 operands[6] = simplify_gen_binary (IOR, SImode,
2844 gen_highpart (SImode, operands[1]),
2845 gen_highpart_mode (SImode, DImode, operands[2]));
2846
2847 }"
32093010 2848 [(set_attr "type" "neon_logic,neon_logic,multiple,multiple,multiple,\
2849 multiple,neon_logic,neon_logic")
e0fe6977 2850 (set_attr "length" "*,*,8,8,8,8,*,*")
74d6113f 2851 (set_attr "arch" "neon_for_64bits,neon_for_64bits,*,*,*,*,avoid_neon_for_64bits,avoid_neon_for_64bits")]
cffb2a26 2852)
9c08d1fa 2853
f7fbdd4a 2854(define_insn "*iordi_zesidi_di"
9c08d1fa 2855 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2856 (ior:DI (zero_extend:DI
2857 (match_operand:SI 2 "s_register_operand" "r,r"))
e2348bcb 2858 (match_operand:DI 1 "s_register_operand" "0,?r")))]
25f905c2 2859 "TARGET_32BIT"
e2348bcb 2860 "@
97499065 2861 orr%?\\t%Q0, %Q1, %2
f6ebffac 2862 #"
0d66636f 2863 [(set_attr "length" "4,8")
d952d547 2864 (set_attr "predicable" "yes")
1b7da4ac 2865 (set_attr "predicable_short_it" "no")
2866 (set_attr "type" "logic_reg,multiple")]
cffb2a26 2867)
9c08d1fa 2868
f7fbdd4a 2869(define_insn "*iordi_sesidi_di"
9c08d1fa 2870 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2871 (ior:DI (sign_extend:DI
2872 (match_operand:SI 2 "s_register_operand" "r,r"))
e5fea38e 2873 (match_operand:DI 1 "s_register_operand" "0,r")))]
25f905c2 2874 "TARGET_32BIT"
f6ebffac 2875 "#"
0d66636f 2876 [(set_attr "length" "8")
1b7da4ac 2877 (set_attr "predicable" "yes")
2878 (set_attr "type" "multiple")]
cffb2a26 2879)
9c08d1fa 2880
87b22bf7 2881(define_expand "iorsi3"
cffb2a26 2882 [(set (match_operand:SI 0 "s_register_operand" "")
87b22bf7 2883 (ior:SI (match_operand:SI 1 "s_register_operand" "")
2884 (match_operand:SI 2 "reg_or_int_operand" "")))]
cffb2a26 2885 "TARGET_EITHER"
87b22bf7 2886 "
0438d37f 2887 if (CONST_INT_P (operands[2]))
87b22bf7 2888 {
25f905c2 2889 if (TARGET_32BIT)
cffb2a26 2890 {
96f57e36 2891 arm_split_constant (IOR, SImode, NULL_RTX,
2892 INTVAL (operands[2]), operands[0], operands[1],
e1ba4a27 2893 optimize && can_create_pseudo_p ());
cffb2a26 2894 DONE;
2895 }
25f905c2 2896 else /* TARGET_THUMB1 */
923ffadb 2897 {
2898 rtx tmp = force_reg (SImode, operands[2]);
2899 if (rtx_equal_p (operands[0], operands[1]))
2900 operands[2] = tmp;
2901 else
2902 {
2903 operands[2] = operands[1];
2904 operands[1] = tmp;
2905 }
2906 }
87b22bf7 2907 }
cffb2a26 2908 "
2909)
87b22bf7 2910
d5d4dc8d 2911(define_insn_and_split "*iorsi3_insn"
29e234a3 2912 [(set (match_operand:SI 0 "s_register_operand" "=r,l,r,r,r")
2913 (ior:SI (match_operand:SI 1 "s_register_operand" "%r,0,r,r,r")
2914 (match_operand:SI 2 "reg_or_int_operand" "I,l,K,r,?n")))]
d5d4dc8d 2915 "TARGET_32BIT"
87b22bf7 2916 "@
29e234a3 2917 orr%?\\t%0, %1, %2
87b22bf7 2918 orr%?\\t%0, %1, %2
d5d4dc8d 2919 orn%?\\t%0, %1, #%B2
65f68e55 2920 orr%?\\t%0, %1, %2
87b22bf7 2921 #"
d5d4dc8d 2922 "TARGET_32BIT
0438d37f 2923 && CONST_INT_P (operands[2])
d5d4dc8d 2924 && !(const_ok_for_arm (INTVAL (operands[2]))
2925 || (TARGET_THUMB2 && const_ok_for_arm (~INTVAL (operands[2]))))"
a0f94409 2926 [(clobber (const_int 0))]
d5d4dc8d 2927{
29e234a3 2928 arm_split_constant (IOR, SImode, curr_insn,
96f57e36 2929 INTVAL (operands[2]), operands[0], operands[1], 0);
a0f94409 2930 DONE;
d5d4dc8d 2931}
29e234a3 2932 [(set_attr "length" "4,4,4,4,16")
2933 (set_attr "arch" "32,t2,t2,32,32")
65f68e55 2934 (set_attr "predicable" "yes")
29e234a3 2935 (set_attr "predicable_short_it" "no,yes,no,no,no")
d82e788e 2936 (set_attr "type" "logic_imm,logic_reg,logic_imm,logic_reg,logic_reg")]
65f68e55 2937)
cffb2a26 2938
a0f94409 2939(define_peephole2
2940 [(match_scratch:SI 3 "r")
372575c7 2941 (set (match_operand:SI 0 "arm_general_register_operand" "")
2942 (ior:SI (match_operand:SI 1 "arm_general_register_operand" "")
87b22bf7 2943 (match_operand:SI 2 "const_int_operand" "")))]
90560cad 2944 "TARGET_ARM
a0f94409 2945 && !const_ok_for_arm (INTVAL (operands[2]))
2946 && const_ok_for_arm (~INTVAL (operands[2]))"
2947 [(set (match_dup 3) (match_dup 2))
2948 (set (match_dup 0) (ior:SI (match_dup 1) (match_dup 3)))]
2949 ""
215b30b3 2950)
a0f94409 2951
f7fbdd4a 2952(define_insn "*iorsi3_compare0"
bd5b4116 2953 [(set (reg:CC_NOOV CC_REGNUM)
65f68e55 2954 (compare:CC_NOOV (ior:SI (match_operand:SI 1 "s_register_operand" "%r,r")
2955 (match_operand:SI 2 "arm_rhs_operand" "I,r"))
9c08d1fa 2956 (const_int 0)))
65f68e55 2957 (set (match_operand:SI 0 "s_register_operand" "=r,r")
9c08d1fa 2958 (ior:SI (match_dup 1) (match_dup 2)))]
25f905c2 2959 "TARGET_32BIT"
2960 "orr%.\\t%0, %1, %2"
65f68e55 2961 [(set_attr "conds" "set")
d82e788e 2962 (set_attr "type" "logics_imm,logics_reg")]
cffb2a26 2963)
9c08d1fa 2964
f7fbdd4a 2965(define_insn "*iorsi3_compare0_scratch"
bd5b4116 2966 [(set (reg:CC_NOOV CC_REGNUM)
65f68e55 2967 (compare:CC_NOOV (ior:SI (match_operand:SI 1 "s_register_operand" "%r,r")
2968 (match_operand:SI 2 "arm_rhs_operand" "I,r"))
9c08d1fa 2969 (const_int 0)))
65f68e55 2970 (clobber (match_scratch:SI 0 "=r,r"))]
25f905c2 2971 "TARGET_32BIT"
2972 "orr%.\\t%0, %1, %2"
65f68e55 2973 [(set_attr "conds" "set")
d82e788e 2974 (set_attr "type" "logics_imm,logics_reg")]
0d66636f 2975)
9c08d1fa 2976
e2669ea7 2977(define_expand "xordi3"
2978 [(set (match_operand:DI 0 "s_register_operand" "")
2979 (xor:DI (match_operand:DI 1 "s_register_operand" "")
8ee7dc6f 2980 (match_operand:DI 2 "arm_xordi_operand" "")))]
e2669ea7 2981 "TARGET_32BIT"
2982 ""
2983)
2984
8ee7dc6f 2985(define_insn_and_split "*xordi3_insn"
2986 [(set (match_operand:DI 0 "s_register_operand" "=w,&r,&r,&r,&r,?w")
205c3b0a 2987 (xor:DI (match_operand:DI 1 "s_register_operand" "%w ,0,r ,0 ,r ,w")
8ee7dc6f 2988 (match_operand:DI 2 "arm_xordi_operand" "w ,r ,r ,Dg,Dg,w")))]
2989 "TARGET_32BIT && !TARGET_IWMMXT"
2990{
2991 switch (which_alternative)
2992 {
2993 case 1:
2994 case 2:
2995 case 3:
2996 case 4: /* fall through */
2997 return "#";
2998 case 0: /* fall through */
2999 case 5: return "veor\t%P0, %P1, %P2";
3000 default: gcc_unreachable ();
3001 }
3002}
3003 "TARGET_32BIT && !TARGET_IWMMXT && reload_completed
3004 && !(IS_VFP_REGNUM (REGNO (operands[0])))"
3005 [(set (match_dup 3) (match_dup 4))
3006 (set (match_dup 5) (match_dup 6))]
3007 "
3008 {
3009 operands[3] = gen_lowpart (SImode, operands[0]);
3010 operands[5] = gen_highpart (SImode, operands[0]);
3011
3012 operands[4] = simplify_gen_binary (XOR, SImode,
3013 gen_lowpart (SImode, operands[1]),
3014 gen_lowpart (SImode, operands[2]));
3015 operands[6] = simplify_gen_binary (XOR, SImode,
3016 gen_highpart (SImode, operands[1]),
3017 gen_highpart_mode (SImode, DImode, operands[2]));
3018
3019 }"
3020 [(set_attr "length" "*,8,8,8,8,*")
32093010 3021 (set_attr "type" "neon_logic,multiple,multiple,multiple,multiple,neon_logic")
8ee7dc6f 3022 (set_attr "arch" "neon_for_64bits,*,*,*,*,avoid_neon_for_64bits")]
cffb2a26 3023)
9c08d1fa 3024
f7fbdd4a 3025(define_insn "*xordi_zesidi_di"
9c08d1fa 3026 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
3027 (xor:DI (zero_extend:DI
3028 (match_operand:SI 2 "s_register_operand" "r,r"))
e2348bcb 3029 (match_operand:DI 1 "s_register_operand" "0,?r")))]
25f905c2 3030 "TARGET_32BIT"
e2348bcb 3031 "@
97499065 3032 eor%?\\t%Q0, %Q1, %2
f6ebffac 3033 #"
0d66636f 3034 [(set_attr "length" "4,8")
d952d547 3035 (set_attr "predicable" "yes")
1b7da4ac 3036 (set_attr "predicable_short_it" "no")
3037 (set_attr "type" "logic_reg")]
cffb2a26 3038)
9c08d1fa 3039
f7fbdd4a 3040(define_insn "*xordi_sesidi_di"
9c08d1fa 3041 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
3042 (xor:DI (sign_extend:DI
3043 (match_operand:SI 2 "s_register_operand" "r,r"))
e5fea38e 3044 (match_operand:DI 1 "s_register_operand" "0,r")))]
25f905c2 3045 "TARGET_32BIT"
f6ebffac 3046 "#"
0d66636f 3047 [(set_attr "length" "8")
1b7da4ac 3048 (set_attr "predicable" "yes")
3049 (set_attr "type" "multiple")]
cffb2a26 3050)
9c08d1fa 3051
cffb2a26 3052(define_expand "xorsi3"
3053 [(set (match_operand:SI 0 "s_register_operand" "")
3054 (xor:SI (match_operand:SI 1 "s_register_operand" "")
923ffadb 3055 (match_operand:SI 2 "reg_or_int_operand" "")))]
cffb2a26 3056 "TARGET_EITHER"
0438d37f 3057 "if (CONST_INT_P (operands[2]))
923ffadb 3058 {
3059 if (TARGET_32BIT)
3060 {
3061 arm_split_constant (XOR, SImode, NULL_RTX,
3062 INTVAL (operands[2]), operands[0], operands[1],
3063 optimize && can_create_pseudo_p ());
3064 DONE;
3065 }
3066 else /* TARGET_THUMB1 */
3067 {
3068 rtx tmp = force_reg (SImode, operands[2]);
3069 if (rtx_equal_p (operands[0], operands[1]))
3070 operands[2] = tmp;
3071 else
3072 {
3073 operands[2] = operands[1];
3074 operands[1] = tmp;
3075 }
3076 }
3077 }"
cffb2a26 3078)
3079
5dcb35d9 3080(define_insn_and_split "*arm_xorsi3"
29e234a3 3081 [(set (match_operand:SI 0 "s_register_operand" "=r,l,r,r")
3082 (xor:SI (match_operand:SI 1 "s_register_operand" "%r,0,r,r")
3083 (match_operand:SI 2 "reg_or_int_operand" "I,l,r,?n")))]
25f905c2 3084 "TARGET_32BIT"
5dcb35d9 3085 "@
29e234a3 3086 eor%?\\t%0, %1, %2
65f68e55 3087 eor%?\\t%0, %1, %2
5dcb35d9 3088 eor%?\\t%0, %1, %2
3089 #"
3090 "TARGET_32BIT
0438d37f 3091 && CONST_INT_P (operands[2])
5dcb35d9 3092 && !const_ok_for_arm (INTVAL (operands[2]))"
3093 [(clobber (const_int 0))]
3094{
3095 arm_split_constant (XOR, SImode, curr_insn,
3096 INTVAL (operands[2]), operands[0], operands[1], 0);
3097 DONE;
3098}
29e234a3 3099 [(set_attr "length" "4,4,4,16")
65f68e55 3100 (set_attr "predicable" "yes")
29e234a3 3101 (set_attr "predicable_short_it" "no,yes,no,no")
1b7da4ac 3102 (set_attr "type" "logic_imm,logic_reg,logic_reg,multiple")]
cffb2a26 3103)
3104
f7fbdd4a 3105(define_insn "*xorsi3_compare0"
bd5b4116 3106 [(set (reg:CC_NOOV CC_REGNUM)
65f68e55 3107 (compare:CC_NOOV (xor:SI (match_operand:SI 1 "s_register_operand" "r,r")
3108 (match_operand:SI 2 "arm_rhs_operand" "I,r"))
9c08d1fa 3109 (const_int 0)))
65f68e55 3110 (set (match_operand:SI 0 "s_register_operand" "=r,r")
9c08d1fa 3111 (xor:SI (match_dup 1) (match_dup 2)))]
25f905c2 3112 "TARGET_32BIT"
3113 "eor%.\\t%0, %1, %2"
65f68e55 3114 [(set_attr "conds" "set")
d82e788e 3115 (set_attr "type" "logics_imm,logics_reg")]
0d66636f 3116)
9c08d1fa 3117
f7fbdd4a 3118(define_insn "*xorsi3_compare0_scratch"
bd5b4116 3119 [(set (reg:CC_NOOV CC_REGNUM)
65f68e55 3120 (compare:CC_NOOV (xor:SI (match_operand:SI 0 "s_register_operand" "r,r")
3121 (match_operand:SI 1 "arm_rhs_operand" "I,r"))
9c08d1fa 3122 (const_int 0)))]
25f905c2 3123 "TARGET_32BIT"
40dbec34 3124 "teq%?\\t%0, %1"
65f68e55 3125 [(set_attr "conds" "set")
d82e788e 3126 (set_attr "type" "logics_imm,logics_reg")]
cffb2a26 3127)
9c08d1fa 3128
215b30b3 3129; By splitting (IOR (AND (NOT A) (NOT B)) C) as D = AND (IOR A B) (NOT C),
3130; (NOT D) we can sometimes merge the final NOT into one of the following
3131; insns.
9c08d1fa 3132
3133(define_split
a058e94a 3134 [(set (match_operand:SI 0 "s_register_operand" "")
3135 (ior:SI (and:SI (not:SI (match_operand:SI 1 "s_register_operand" ""))
3136 (not:SI (match_operand:SI 2 "arm_rhs_operand" "")))
3137 (match_operand:SI 3 "arm_rhs_operand" "")))
3138 (clobber (match_operand:SI 4 "s_register_operand" ""))]
25f905c2 3139 "TARGET_32BIT"
9c08d1fa 3140 [(set (match_dup 4) (and:SI (ior:SI (match_dup 1) (match_dup 2))
3141 (not:SI (match_dup 3))))
3142 (set (match_dup 0) (not:SI (match_dup 4)))]
3143 ""
3144)
3145
ba6a3b2f 3146(define_insn_and_split "*andsi_iorsi3_notsi"
9c08d1fa 3147 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r")
e5fea38e 3148 (and:SI (ior:SI (match_operand:SI 1 "s_register_operand" "%0,r,r")
9c08d1fa 3149 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI"))
3150 (not:SI (match_operand:SI 3 "arm_rhs_operand" "rI,rI,rI"))))]
25f905c2 3151 "TARGET_32BIT"
ba6a3b2f 3152 "#" ; "orr%?\\t%0, %1, %2\;bic%?\\t%0, %0, %3"
3153 "&& reload_completed"
3154 [(set (match_dup 0) (ior:SI (match_dup 1) (match_dup 2)))
3155 (set (match_dup 0) (and:SI (not:SI (match_dup 3)) (match_dup 0)))]
3156 ""
0d66636f 3157 [(set_attr "length" "8")
25f905c2 3158 (set_attr "ce_count" "2")
d952d547 3159 (set_attr "predicable" "yes")
1b7da4ac 3160 (set_attr "predicable_short_it" "no")
3161 (set_attr "type" "multiple")]
cffb2a26 3162)
9c08d1fa 3163
25f905c2 3164; ??? Are these four splitters still beneficial when the Thumb-2 bitfield
3165; insns are available?
d7863cfe 3166(define_split
3167 [(set (match_operand:SI 0 "s_register_operand" "")
3168 (match_operator:SI 1 "logical_binary_operator"
3169 [(zero_extract:SI (match_operand:SI 2 "s_register_operand" "")
3170 (match_operand:SI 3 "const_int_operand" "")
3171 (match_operand:SI 4 "const_int_operand" ""))
3172 (match_operator:SI 9 "logical_binary_operator"
3173 [(lshiftrt:SI (match_operand:SI 5 "s_register_operand" "")
3174 (match_operand:SI 6 "const_int_operand" ""))
3175 (match_operand:SI 7 "s_register_operand" "")])]))
3176 (clobber (match_operand:SI 8 "s_register_operand" ""))]
25f905c2 3177 "TARGET_32BIT
d7863cfe 3178 && GET_CODE (operands[1]) == GET_CODE (operands[9])
3179 && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
3180 [(set (match_dup 8)
3181 (match_op_dup 1
3182 [(ashift:SI (match_dup 2) (match_dup 4))
3183 (match_dup 5)]))
3184 (set (match_dup 0)
3185 (match_op_dup 1
3186 [(lshiftrt:SI (match_dup 8) (match_dup 6))
3187 (match_dup 7)]))]
3188 "
3189 operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
3190")
3191
3192(define_split
3193 [(set (match_operand:SI 0 "s_register_operand" "")
3194 (match_operator:SI 1 "logical_binary_operator"
3195 [(match_operator:SI 9 "logical_binary_operator"
3196 [(lshiftrt:SI (match_operand:SI 5 "s_register_operand" "")
3197 (match_operand:SI 6 "const_int_operand" ""))
3198 (match_operand:SI 7 "s_register_operand" "")])
3199 (zero_extract:SI (match_operand:SI 2 "s_register_operand" "")
3200 (match_operand:SI 3 "const_int_operand" "")
3201 (match_operand:SI 4 "const_int_operand" ""))]))
3202 (clobber (match_operand:SI 8 "s_register_operand" ""))]
25f905c2 3203 "TARGET_32BIT
d7863cfe 3204 && GET_CODE (operands[1]) == GET_CODE (operands[9])
3205 && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
3206 [(set (match_dup 8)
3207 (match_op_dup 1
3208 [(ashift:SI (match_dup 2) (match_dup 4))
3209 (match_dup 5)]))
3210 (set (match_dup 0)
3211 (match_op_dup 1
3212 [(lshiftrt:SI (match_dup 8) (match_dup 6))
3213 (match_dup 7)]))]
3214 "
3215 operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
3216")
3217
3218(define_split
3219 [(set (match_operand:SI 0 "s_register_operand" "")
3220 (match_operator:SI 1 "logical_binary_operator"
3221 [(sign_extract:SI (match_operand:SI 2 "s_register_operand" "")
3222 (match_operand:SI 3 "const_int_operand" "")
3223 (match_operand:SI 4 "const_int_operand" ""))
3224 (match_operator:SI 9 "logical_binary_operator"
3225 [(ashiftrt:SI (match_operand:SI 5 "s_register_operand" "")
3226 (match_operand:SI 6 "const_int_operand" ""))
3227 (match_operand:SI 7 "s_register_operand" "")])]))
3228 (clobber (match_operand:SI 8 "s_register_operand" ""))]
25f905c2 3229 "TARGET_32BIT
d7863cfe 3230 && GET_CODE (operands[1]) == GET_CODE (operands[9])
3231 && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
3232 [(set (match_dup 8)
3233 (match_op_dup 1
3234 [(ashift:SI (match_dup 2) (match_dup 4))
3235 (match_dup 5)]))
3236 (set (match_dup 0)
3237 (match_op_dup 1
3238 [(ashiftrt:SI (match_dup 8) (match_dup 6))
3239 (match_dup 7)]))]
3240 "
3241 operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
3242")
3243
3244(define_split
3245 [(set (match_operand:SI 0 "s_register_operand" "")
3246 (match_operator:SI 1 "logical_binary_operator"
3247 [(match_operator:SI 9 "logical_binary_operator"
3248 [(ashiftrt:SI (match_operand:SI 5 "s_register_operand" "")
3249 (match_operand:SI 6 "const_int_operand" ""))
3250 (match_operand:SI 7 "s_register_operand" "")])
3251 (sign_extract:SI (match_operand:SI 2 "s_register_operand" "")
3252 (match_operand:SI 3 "const_int_operand" "")
3253 (match_operand:SI 4 "const_int_operand" ""))]))
3254 (clobber (match_operand:SI 8 "s_register_operand" ""))]
25f905c2 3255 "TARGET_32BIT
d7863cfe 3256 && GET_CODE (operands[1]) == GET_CODE (operands[9])
3257 && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
3258 [(set (match_dup 8)
3259 (match_op_dup 1
3260 [(ashift:SI (match_dup 2) (match_dup 4))
3261 (match_dup 5)]))
3262 (set (match_dup 0)
3263 (match_op_dup 1
3264 [(ashiftrt:SI (match_dup 8) (match_dup 6))
3265 (match_dup 7)]))]
3266 "
3267 operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
3268")
9c08d1fa 3269\f
3270
3271;; Minimum and maximum insns
3272
8b9dc177 3273(define_expand "smaxsi3"
3274 [(parallel [
3275 (set (match_operand:SI 0 "s_register_operand" "")
3276 (smax:SI (match_operand:SI 1 "s_register_operand" "")
3277 (match_operand:SI 2 "arm_rhs_operand" "")))
3278 (clobber (reg:CC CC_REGNUM))])]
25f905c2 3279 "TARGET_32BIT"
8b9dc177 3280 "
8774928b 3281 if (operands[2] == const0_rtx || operands[2] == constm1_rtx)
8b9dc177 3282 {
3283 /* No need for a clobber of the condition code register here. */
d1f9b275 3284 emit_insn (gen_rtx_SET (operands[0],
8b9dc177 3285 gen_rtx_SMAX (SImode, operands[1],
3286 operands[2])));
3287 DONE;
3288 }
3289")
3290
3291(define_insn "*smax_0"
3292 [(set (match_operand:SI 0 "s_register_operand" "=r")
3293 (smax:SI (match_operand:SI 1 "s_register_operand" "r")
3294 (const_int 0)))]
25f905c2 3295 "TARGET_32BIT"
8b9dc177 3296 "bic%?\\t%0, %1, %1, asr #31"
d952d547 3297 [(set_attr "predicable" "yes")
1b7da4ac 3298 (set_attr "predicable_short_it" "no")
3299 (set_attr "type" "logic_shift_reg")]
8b9dc177 3300)
3301
8774928b 3302(define_insn "*smax_m1"
3303 [(set (match_operand:SI 0 "s_register_operand" "=r")
3304 (smax:SI (match_operand:SI 1 "s_register_operand" "r")
3305 (const_int -1)))]
25f905c2 3306 "TARGET_32BIT"
8774928b 3307 "orr%?\\t%0, %1, %1, asr #31"
d952d547 3308 [(set_attr "predicable" "yes")
1b7da4ac 3309 (set_attr "predicable_short_it" "no")
3310 (set_attr "type" "logic_shift_reg")]
8774928b 3311)
3312
3dc953f2 3313(define_insn_and_split "*arm_smax_insn"
8b9dc177 3314 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
3315 (smax:SI (match_operand:SI 1 "s_register_operand" "%0,?r")
3316 (match_operand:SI 2 "arm_rhs_operand" "rI,rI")))
bd5b4116 3317 (clobber (reg:CC CC_REGNUM))]
cffb2a26 3318 "TARGET_ARM"
3dc953f2 3319 "#"
3320 ; cmp\\t%1, %2\;movlt\\t%0, %2
3321 ; cmp\\t%1, %2\;movge\\t%0, %1\;movlt\\t%0, %2"
3322 "TARGET_ARM"
3323 [(set (reg:CC CC_REGNUM)
3324 (compare:CC (match_dup 1) (match_dup 2)))
3325 (set (match_dup 0)
3326 (if_then_else:SI (ge:SI (reg:CC CC_REGNUM) (const_int 0))
3327 (match_dup 1)
3328 (match_dup 2)))]
3329 ""
cffb2a26 3330 [(set_attr "conds" "clob")
1b7da4ac 3331 (set_attr "length" "8,12")
3332 (set_attr "type" "multiple")]
cffb2a26 3333)
9c08d1fa 3334
8b9dc177 3335(define_expand "sminsi3"
3336 [(parallel [
3337 (set (match_operand:SI 0 "s_register_operand" "")
3338 (smin:SI (match_operand:SI 1 "s_register_operand" "")
3339 (match_operand:SI 2 "arm_rhs_operand" "")))
3340 (clobber (reg:CC CC_REGNUM))])]
25f905c2 3341 "TARGET_32BIT"
8b9dc177 3342 "
3343 if (operands[2] == const0_rtx)
3344 {
3345 /* No need for a clobber of the condition code register here. */
d1f9b275 3346 emit_insn (gen_rtx_SET (operands[0],
8b9dc177 3347 gen_rtx_SMIN (SImode, operands[1],
3348 operands[2])));
3349 DONE;
3350 }
3351")
3352
3353(define_insn "*smin_0"
3354 [(set (match_operand:SI 0 "s_register_operand" "=r")
3355 (smin:SI (match_operand:SI 1 "s_register_operand" "r")
3356 (const_int 0)))]
25f905c2 3357 "TARGET_32BIT"
8b9dc177 3358 "and%?\\t%0, %1, %1, asr #31"
d952d547 3359 [(set_attr "predicable" "yes")
1b7da4ac 3360 (set_attr "predicable_short_it" "no")
3361 (set_attr "type" "logic_shift_reg")]
8b9dc177 3362)
3363
3dc953f2 3364(define_insn_and_split "*arm_smin_insn"
8b9dc177 3365 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
3366 (smin:SI (match_operand:SI 1 "s_register_operand" "%0,?r")
3367 (match_operand:SI 2 "arm_rhs_operand" "rI,rI")))
bd5b4116 3368 (clobber (reg:CC CC_REGNUM))]
cffb2a26 3369 "TARGET_ARM"
3dc953f2 3370 "#"
3371 ; cmp\\t%1, %2\;movge\\t%0, %2
3372 ; cmp\\t%1, %2\;movlt\\t%0, %1\;movge\\t%0, %2"
3373 "TARGET_ARM"
3374 [(set (reg:CC CC_REGNUM)
3375 (compare:CC (match_dup 1) (match_dup 2)))
3376 (set (match_dup 0)
3377 (if_then_else:SI (lt:SI (reg:CC CC_REGNUM) (const_int 0))
3378 (match_dup 1)
3379 (match_dup 2)))]
3380 ""
0d66636f 3381 [(set_attr "conds" "clob")
1b7da4ac 3382 (set_attr "length" "8,12")
3383 (set_attr "type" "multiple,multiple")]
0d66636f 3384)
9c08d1fa 3385
25f905c2 3386(define_expand "umaxsi3"
3387 [(parallel [
3388 (set (match_operand:SI 0 "s_register_operand" "")
3389 (umax:SI (match_operand:SI 1 "s_register_operand" "")
3390 (match_operand:SI 2 "arm_rhs_operand" "")))
3391 (clobber (reg:CC CC_REGNUM))])]
3392 "TARGET_32BIT"
3393 ""
3394)
3395
3dc953f2 3396(define_insn_and_split "*arm_umaxsi3"
9c08d1fa 3397 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
3398 (umax:SI (match_operand:SI 1 "s_register_operand" "0,r,?r")
3399 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
bd5b4116 3400 (clobber (reg:CC CC_REGNUM))]
cffb2a26 3401 "TARGET_ARM"
3dc953f2 3402 "#"
3403 ; cmp\\t%1, %2\;movcc\\t%0, %2
3404 ; cmp\\t%1, %2\;movcs\\t%0, %1
3405 ; cmp\\t%1, %2\;movcs\\t%0, %1\;movcc\\t%0, %2"
3406 "TARGET_ARM"
3407 [(set (reg:CC CC_REGNUM)
3408 (compare:CC (match_dup 1) (match_dup 2)))
3409 (set (match_dup 0)
3410 (if_then_else:SI (geu:SI (reg:CC CC_REGNUM) (const_int 0))
3411 (match_dup 1)
3412 (match_dup 2)))]
3413 ""
0d66636f 3414 [(set_attr "conds" "clob")
1b7da4ac 3415 (set_attr "length" "8,8,12")
3416 (set_attr "type" "store1")]
0d66636f 3417)
9c08d1fa 3418
25f905c2 3419(define_expand "uminsi3"
3420 [(parallel [
3421 (set (match_operand:SI 0 "s_register_operand" "")
3422 (umin:SI (match_operand:SI 1 "s_register_operand" "")
3423 (match_operand:SI 2 "arm_rhs_operand" "")))
3424 (clobber (reg:CC CC_REGNUM))])]
3425 "TARGET_32BIT"
3426 ""
3427)
3428
3dc953f2 3429(define_insn_and_split "*arm_uminsi3"
9c08d1fa 3430 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
3431 (umin:SI (match_operand:SI 1 "s_register_operand" "0,r,?r")
3432 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
bd5b4116 3433 (clobber (reg:CC CC_REGNUM))]
cffb2a26 3434 "TARGET_ARM"
3dc953f2 3435 "#"
3436 ; cmp\\t%1, %2\;movcs\\t%0, %2
3437 ; cmp\\t%1, %2\;movcc\\t%0, %1
3438 ; cmp\\t%1, %2\;movcc\\t%0, %1\;movcs\\t%0, %2"
3439 "TARGET_ARM"
3440 [(set (reg:CC CC_REGNUM)
3441 (compare:CC (match_dup 1) (match_dup 2)))
3442 (set (match_dup 0)
3443 (if_then_else:SI (ltu:SI (reg:CC CC_REGNUM) (const_int 0))
3444 (match_dup 1)
3445 (match_dup 2)))]
3446 ""
0d66636f 3447 [(set_attr "conds" "clob")
1b7da4ac 3448 (set_attr "length" "8,8,12")
3449 (set_attr "type" "store1")]
0d66636f 3450)
9c08d1fa 3451
8a18b90c 3452(define_insn "*store_minmaxsi"
9c08d1fa 3453 [(set (match_operand:SI 0 "memory_operand" "=m")
3454 (match_operator:SI 3 "minmax_operator"
3455 [(match_operand:SI 1 "s_register_operand" "r")
3456 (match_operand:SI 2 "s_register_operand" "r")]))
bd5b4116 3457 (clobber (reg:CC CC_REGNUM))]
b207d152 3458 "TARGET_32BIT && optimize_function_for_size_p (cfun) && !arm_restrict_it"
9c08d1fa 3459 "*
dc55b8a9 3460 operands[3] = gen_rtx_fmt_ee (minmax_code (operands[3]), SImode,
3461 operands[1], operands[2]);
e2348bcb 3462 output_asm_insn (\"cmp\\t%1, %2\", operands);
25f905c2 3463 if (TARGET_THUMB2)
3464 output_asm_insn (\"ite\t%d3\", operands);
e2348bcb 3465 output_asm_insn (\"str%d3\\t%1, %0\", operands);
3466 output_asm_insn (\"str%D3\\t%2, %0\", operands);
3467 return \"\";
0d66636f 3468 "
3469 [(set_attr "conds" "clob")
25f905c2 3470 (set (attr "length")
3471 (if_then_else (eq_attr "is_thumb" "yes")
3472 (const_int 14)
3473 (const_int 12)))
0d66636f 3474 (set_attr "type" "store1")]
3475)
9c08d1fa 3476
8a18b90c 3477; Reject the frame pointer in operand[1], since reloading this after
3478; it has been eliminated can cause carnage.
f7fbdd4a 3479(define_insn "*minmax_arithsi"
9c08d1fa 3480 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
3481 (match_operator:SI 4 "shiftable_operator"
3482 [(match_operator:SI 5 "minmax_operator"
3483 [(match_operand:SI 2 "s_register_operand" "r,r")
3484 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
3485 (match_operand:SI 1 "s_register_operand" "0,?r")]))
bd5b4116 3486 (clobber (reg:CC CC_REGNUM))]
7c36fe71 3487 "TARGET_32BIT && !arm_eliminable_register (operands[1]) && !arm_restrict_it"
9c08d1fa 3488 "*
0d66636f 3489 {
3490 enum rtx_code code = GET_CODE (operands[4]);
25f905c2 3491 bool need_else;
3492
3493 if (which_alternative != 0 || operands[3] != const0_rtx
ca0fc5a2 3494 || (code != PLUS && code != IOR && code != XOR))
25f905c2 3495 need_else = true;
3496 else
3497 need_else = false;
0d66636f 3498
dc55b8a9 3499 operands[5] = gen_rtx_fmt_ee (minmax_code (operands[5]), SImode,
3500 operands[2], operands[3]);
0d66636f 3501 output_asm_insn (\"cmp\\t%2, %3\", operands);
25f905c2 3502 if (TARGET_THUMB2)
3503 {
3504 if (need_else)
3505 output_asm_insn (\"ite\\t%d5\", operands);
3506 else
3507 output_asm_insn (\"it\\t%d5\", operands);
3508 }
0d66636f 3509 output_asm_insn (\"%i4%d5\\t%0, %1, %2\", operands);
25f905c2 3510 if (need_else)
0d66636f 3511 output_asm_insn (\"%i4%D5\\t%0, %1, %3\", operands);
3512 return \"\";
215b30b3 3513 }"
0d66636f 3514 [(set_attr "conds" "clob")
25f905c2 3515 (set (attr "length")
3516 (if_then_else (eq_attr "is_thumb" "yes")
3517 (const_int 14)
1b7da4ac 3518 (const_int 12)))
3519 (set_attr "type" "multiple")]
0d66636f 3520)
9c08d1fa 3521
4164bca1 3522; Reject the frame pointer in operand[1], since reloading this after
3523; it has been eliminated can cause carnage.
3524(define_insn_and_split "*minmax_arithsi_non_canon"
7c36fe71 3525 [(set (match_operand:SI 0 "s_register_operand" "=Ts,Ts")
4164bca1 3526 (minus:SI
7c36fe71 3527 (match_operand:SI 1 "s_register_operand" "0,?Ts")
4164bca1 3528 (match_operator:SI 4 "minmax_operator"
7c36fe71 3529 [(match_operand:SI 2 "s_register_operand" "Ts,Ts")
3530 (match_operand:SI 3 "arm_rhs_operand" "TsI,TsI")])))
4164bca1 3531 (clobber (reg:CC CC_REGNUM))]
7c36fe71 3532 "TARGET_32BIT && !arm_eliminable_register (operands[1])
3533 && !(arm_restrict_it && CONST_INT_P (operands[3]))"
4164bca1 3534 "#"
3535 "TARGET_32BIT && !arm_eliminable_register (operands[1]) && reload_completed"
3536 [(set (reg:CC CC_REGNUM)
3537 (compare:CC (match_dup 2) (match_dup 3)))
3538
3539 (cond_exec (match_op_dup 4 [(reg:CC CC_REGNUM) (const_int 0)])
3540 (set (match_dup 0)
3541 (minus:SI (match_dup 1)
3542 (match_dup 2))))
3543 (cond_exec (match_op_dup 5 [(reg:CC CC_REGNUM) (const_int 0)])
3544 (set (match_dup 0)
36ee0cde 3545 (match_dup 6)))]
4164bca1 3546 {
3754d046 3547 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
4164bca1 3548 operands[2], operands[3]);
3549 enum rtx_code rc = minmax_code (operands[4]);
3550 operands[4] = gen_rtx_fmt_ee (rc, VOIDmode,
3551 operands[2], operands[3]);
3552
3553 if (mode == CCFPmode || mode == CCFPEmode)
3554 rc = reverse_condition_maybe_unordered (rc);
3555 else
3556 rc = reverse_condition (rc);
3557 operands[5] = gen_rtx_fmt_ee (rc, SImode, operands[2], operands[3]);
36ee0cde 3558 if (CONST_INT_P (operands[3]))
3559 operands[6] = plus_constant (SImode, operands[1], -INTVAL (operands[3]));
3560 else
3561 operands[6] = gen_rtx_MINUS (SImode, operands[1], operands[3]);
4164bca1 3562 }
3563 [(set_attr "conds" "clob")
3564 (set (attr "length")
3565 (if_then_else (eq_attr "is_thumb" "yes")
3566 (const_int 14)
1b7da4ac 3567 (const_int 12)))
3568 (set_attr "type" "multiple")]
4164bca1 3569)
3570
b49e3742 3571(define_code_iterator SAT [smin smax])
3572(define_code_iterator SATrev [smin smax])
3573(define_code_attr SATlo [(smin "1") (smax "2")])
3574(define_code_attr SAThi [(smin "2") (smax "1")])
3575
3576(define_insn "*satsi_<SAT:code>"
3577 [(set (match_operand:SI 0 "s_register_operand" "=r")
3578 (SAT:SI (SATrev:SI (match_operand:SI 3 "s_register_operand" "r")
3579 (match_operand:SI 1 "const_int_operand" "i"))
3580 (match_operand:SI 2 "const_int_operand" "i")))]
3581 "TARGET_32BIT && arm_arch6 && <SAT:CODE> != <SATrev:CODE>
3582 && arm_sat_operator_match (operands[<SAT:SATlo>], operands[<SAT:SAThi>], NULL, NULL)"
3583{
3584 int mask;
3585 bool signed_sat;
3586 if (!arm_sat_operator_match (operands[<SAT:SATlo>], operands[<SAT:SAThi>],
3587 &mask, &signed_sat))
3588 gcc_unreachable ();
3589
3590 operands[1] = GEN_INT (mask);
3591 if (signed_sat)
3592 return "ssat%?\t%0, %1, %3";
3593 else
3594 return "usat%?\t%0, %1, %3";
3595}
7c36fe71 3596 [(set_attr "predicable" "yes")
1b7da4ac 3597 (set_attr "predicable_short_it" "no")
3598 (set_attr "type" "alus_imm")]
bebe9bbb 3599)
b49e3742 3600
3601(define_insn "*satsi_<SAT:code>_shift"
3602 [(set (match_operand:SI 0 "s_register_operand" "=r")
3603 (SAT:SI (SATrev:SI (match_operator:SI 3 "sat_shift_operator"
3604 [(match_operand:SI 4 "s_register_operand" "r")
3605 (match_operand:SI 5 "const_int_operand" "i")])
3606 (match_operand:SI 1 "const_int_operand" "i"))
3607 (match_operand:SI 2 "const_int_operand" "i")))]
3608 "TARGET_32BIT && arm_arch6 && <SAT:CODE> != <SATrev:CODE>
3609 && arm_sat_operator_match (operands[<SAT:SATlo>], operands[<SAT:SAThi>], NULL, NULL)"
3610{
3611 int mask;
3612 bool signed_sat;
3613 if (!arm_sat_operator_match (operands[<SAT:SATlo>], operands[<SAT:SAThi>],
3614 &mask, &signed_sat))
3615 gcc_unreachable ();
3616
3617 operands[1] = GEN_INT (mask);
3618 if (signed_sat)
3619 return "ssat%?\t%0, %1, %4%S3";
3620 else
3621 return "usat%?\t%0, %1, %4%S3";
3622}
3623 [(set_attr "predicable" "yes")
7c36fe71 3624 (set_attr "predicable_short_it" "no")
b49e3742 3625 (set_attr "shift" "3")
d82e788e 3626 (set_attr "type" "logic_shift_reg")])
b11cae9e 3627\f
3628;; Shift and rotation insns
3629
a2cd141b 3630(define_expand "ashldi3"
3631 [(set (match_operand:DI 0 "s_register_operand" "")
3632 (ashift:DI (match_operand:DI 1 "s_register_operand" "")
aa06c51c 3633 (match_operand:SI 2 "general_operand" "")))]
25f905c2 3634 "TARGET_32BIT"
a2cd141b 3635 "
aa06c51c 3636 if (TARGET_NEON)
3637 {
3638 /* Delay the decision whether to use NEON or core-regs until
3639 register allocation. */
3640 emit_insn (gen_ashldi3_neon (operands[0], operands[1], operands[2]));
3641 DONE;
3642 }
3643 else
3644 {
3645 /* Only the NEON case can handle in-memory shift counts. */
3646 if (!reg_or_int_operand (operands[2], SImode))
3647 operands[2] = force_reg (SImode, operands[2]);
3648 }
3649
b805622c 3650 if (!CONST_INT_P (operands[2]) && TARGET_REALLY_IWMMXT)
ffcc986d 3651 ; /* No special preparation statements; expand pattern as above. */
3652 else
a2cd141b 3653 {
ffcc986d 3654 rtx scratch1, scratch2;
3655
3656 if (CONST_INT_P (operands[2])
3657 && (HOST_WIDE_INT) INTVAL (operands[2]) == 1)
a2cd141b 3658 {
3659 emit_insn (gen_arm_ashldi3_1bit (operands[0], operands[1]));
3660 DONE;
3661 }
ffcc986d 3662
3663 /* Ideally we should use iwmmxt here if we could know that operands[1]
3664 ends up already living in an iwmmxt register. Otherwise it's
3665 cheaper to have the alternate code being generated than moving
3666 values to iwmmxt regs and back. */
3667
3668 /* If we're optimizing for size, we prefer the libgcc calls. */
3669 if (optimize_function_for_size_p (cfun))
3670 FAIL;
3671
3672 /* Expand operation using core-registers.
3673 'FAIL' would achieve the same thing, but this is a bit smarter. */
3674 scratch1 = gen_reg_rtx (SImode);
3675 scratch2 = gen_reg_rtx (SImode);
3676 arm_emit_coreregs_64bit_shift (ASHIFT, operands[0], operands[1],
3677 operands[2], scratch1, scratch2);
3678 DONE;
a2cd141b 3679 }
a2cd141b 3680 "
3681)
3682
2837e3fb 3683(define_insn "arm_ashldi3_1bit"
50ad1bf9 3684 [(set (match_operand:DI 0 "s_register_operand" "=r,&r")
e5fea38e 3685 (ashift:DI (match_operand:DI 1 "s_register_operand" "0,r")
a2cd141b 3686 (const_int 1)))
3687 (clobber (reg:CC CC_REGNUM))]
25f905c2 3688 "TARGET_32BIT"
2837e3fb 3689 "movs\\t%Q0, %Q1, asl #1\;adc\\t%R0, %R1, %R1"
a2cd141b 3690 [(set_attr "conds" "clob")
1b7da4ac 3691 (set_attr "length" "8")
3692 (set_attr "type" "multiple")]
a2cd141b 3693)
3694
87b22bf7 3695(define_expand "ashlsi3"
cffb2a26 3696 [(set (match_operand:SI 0 "s_register_operand" "")
87b22bf7 3697 (ashift:SI (match_operand:SI 1 "s_register_operand" "")
3698 (match_operand:SI 2 "arm_rhs_operand" "")))]
cffb2a26 3699 "TARGET_EITHER"
87b22bf7 3700 "
0438d37f 3701 if (CONST_INT_P (operands[2])
87b22bf7 3702 && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) > 31)
3703 {
3704 emit_insn (gen_movsi (operands[0], const0_rtx));
3705 DONE;
3706 }
cffb2a26 3707 "
3708)
3709
a2cd141b 3710(define_expand "ashrdi3"
3711 [(set (match_operand:DI 0 "s_register_operand" "")
3712 (ashiftrt:DI (match_operand:DI 1 "s_register_operand" "")
3713 (match_operand:SI 2 "reg_or_int_operand" "")))]
25f905c2 3714 "TARGET_32BIT"
a2cd141b 3715 "
aa06c51c 3716 if (TARGET_NEON)
3717 {
3718 /* Delay the decision whether to use NEON or core-regs until
3719 register allocation. */
3720 emit_insn (gen_ashrdi3_neon (operands[0], operands[1], operands[2]));
3721 DONE;
3722 }
3723
b805622c 3724 if (!CONST_INT_P (operands[2]) && TARGET_REALLY_IWMMXT)
ffcc986d 3725 ; /* No special preparation statements; expand pattern as above. */
3726 else
a2cd141b 3727 {
ffcc986d 3728 rtx scratch1, scratch2;
3729
3730 if (CONST_INT_P (operands[2])
3731 && (HOST_WIDE_INT) INTVAL (operands[2]) == 1)
a2cd141b 3732 {
3733 emit_insn (gen_arm_ashrdi3_1bit (operands[0], operands[1]));
3734 DONE;
3735 }
ffcc986d 3736
3737 /* Ideally we should use iwmmxt here if we could know that operands[1]
3738 ends up already living in an iwmmxt register. Otherwise it's
3739 cheaper to have the alternate code being generated than moving
3740 values to iwmmxt regs and back. */
3741
3742 /* If we're optimizing for size, we prefer the libgcc calls. */
3743 if (optimize_function_for_size_p (cfun))
3744 FAIL;
3745
3746 /* Expand operation using core-registers.
3747 'FAIL' would achieve the same thing, but this is a bit smarter. */
3748 scratch1 = gen_reg_rtx (SImode);
3749 scratch2 = gen_reg_rtx (SImode);
3750 arm_emit_coreregs_64bit_shift (ASHIFTRT, operands[0], operands[1],
3751 operands[2], scratch1, scratch2);
3752 DONE;
a2cd141b 3753 }
a2cd141b 3754 "
3755)
3756
2837e3fb 3757(define_insn "arm_ashrdi3_1bit"
50ad1bf9 3758 [(set (match_operand:DI 0 "s_register_operand" "=r,&r")
e5fea38e 3759 (ashiftrt:DI (match_operand:DI 1 "s_register_operand" "0,r")
a2cd141b 3760 (const_int 1)))
3761 (clobber (reg:CC CC_REGNUM))]
25f905c2 3762 "TARGET_32BIT"
2837e3fb 3763 "movs\\t%R0, %R1, asr #1\;mov\\t%Q0, %Q1, rrx"
a2cd141b 3764 [(set_attr "conds" "clob")
1b7da4ac 3765 (set_attr "length" "8")
3766 (set_attr "type" "multiple")]
a2cd141b 3767)
3768
87b22bf7 3769(define_expand "ashrsi3"
cffb2a26 3770 [(set (match_operand:SI 0 "s_register_operand" "")
87b22bf7 3771 (ashiftrt:SI (match_operand:SI 1 "s_register_operand" "")
3772 (match_operand:SI 2 "arm_rhs_operand" "")))]
cffb2a26 3773 "TARGET_EITHER"
87b22bf7 3774 "
0438d37f 3775 if (CONST_INT_P (operands[2])
87b22bf7 3776 && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) > 31)
3777 operands[2] = GEN_INT (31);
cffb2a26 3778 "
3779)
3780
a2cd141b 3781(define_expand "lshrdi3"
3782 [(set (match_operand:DI 0 "s_register_operand" "")
3783 (lshiftrt:DI (match_operand:DI 1 "s_register_operand" "")
3784 (match_operand:SI 2 "reg_or_int_operand" "")))]
25f905c2 3785 "TARGET_32BIT"
a2cd141b 3786 "
aa06c51c 3787 if (TARGET_NEON)
3788 {
3789 /* Delay the decision whether to use NEON or core-regs until
3790 register allocation. */
3791 emit_insn (gen_lshrdi3_neon (operands[0], operands[1], operands[2]));
3792 DONE;
3793 }
3794
b805622c 3795 if (!CONST_INT_P (operands[2]) && TARGET_REALLY_IWMMXT)
ffcc986d 3796 ; /* No special preparation statements; expand pattern as above. */
3797 else
a2cd141b 3798 {
ffcc986d 3799 rtx scratch1, scratch2;
3800
3801 if (CONST_INT_P (operands[2])
3802 && (HOST_WIDE_INT) INTVAL (operands[2]) == 1)
a2cd141b 3803 {
3804 emit_insn (gen_arm_lshrdi3_1bit (operands[0], operands[1]));
3805 DONE;
3806 }
ffcc986d 3807
3808 /* Ideally we should use iwmmxt here if we could know that operands[1]
3809 ends up already living in an iwmmxt register. Otherwise it's
3810 cheaper to have the alternate code being generated than moving
3811 values to iwmmxt regs and back. */
3812
3813 /* If we're optimizing for size, we prefer the libgcc calls. */
3814 if (optimize_function_for_size_p (cfun))
3815 FAIL;
3816
3817 /* Expand operation using core-registers.
3818 'FAIL' would achieve the same thing, but this is a bit smarter. */
3819 scratch1 = gen_reg_rtx (SImode);
3820 scratch2 = gen_reg_rtx (SImode);
3821 arm_emit_coreregs_64bit_shift (LSHIFTRT, operands[0], operands[1],
3822 operands[2], scratch1, scratch2);
3823 DONE;
a2cd141b 3824 }
a2cd141b 3825 "
3826)
3827
2837e3fb 3828(define_insn "arm_lshrdi3_1bit"
50ad1bf9 3829 [(set (match_operand:DI 0 "s_register_operand" "=r,&r")
e5fea38e 3830 (lshiftrt:DI (match_operand:DI 1 "s_register_operand" "0,r")
a2cd141b 3831 (const_int 1)))
3832 (clobber (reg:CC CC_REGNUM))]
25f905c2 3833 "TARGET_32BIT"
2837e3fb 3834 "movs\\t%R0, %R1, lsr #1\;mov\\t%Q0, %Q1, rrx"
a2cd141b 3835 [(set_attr "conds" "clob")
1b7da4ac 3836 (set_attr "length" "8")
3837 (set_attr "type" "multiple")]
a2cd141b 3838)
3839
87b22bf7 3840(define_expand "lshrsi3"
cffb2a26 3841 [(set (match_operand:SI 0 "s_register_operand" "")
87b22bf7 3842 (lshiftrt:SI (match_operand:SI 1 "s_register_operand" "")
3843 (match_operand:SI 2 "arm_rhs_operand" "")))]
cffb2a26 3844 "TARGET_EITHER"
87b22bf7 3845 "
0438d37f 3846 if (CONST_INT_P (operands[2])
87b22bf7 3847 && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) > 31)
3848 {
3849 emit_insn (gen_movsi (operands[0], const0_rtx));
3850 DONE;
3851 }
cffb2a26 3852 "
3853)
3854
87b22bf7 3855(define_expand "rotlsi3"
cffb2a26 3856 [(set (match_operand:SI 0 "s_register_operand" "")
87b22bf7 3857 (rotatert:SI (match_operand:SI 1 "s_register_operand" "")
3858 (match_operand:SI 2 "reg_or_int_operand" "")))]
25f905c2 3859 "TARGET_32BIT"
87b22bf7 3860 "
0438d37f 3861 if (CONST_INT_P (operands[2]))
87b22bf7 3862 operands[2] = GEN_INT ((32 - INTVAL (operands[2])) % 32);
3863 else
b11cae9e 3864 {
87b22bf7 3865 rtx reg = gen_reg_rtx (SImode);
3866 emit_insn (gen_subsi3 (reg, GEN_INT (32), operands[2]));
3867 operands[2] = reg;
b11cae9e 3868 }
cffb2a26 3869 "
3870)
9c08d1fa 3871
87b22bf7 3872(define_expand "rotrsi3"
cffb2a26 3873 [(set (match_operand:SI 0 "s_register_operand" "")
87b22bf7 3874 (rotatert:SI (match_operand:SI 1 "s_register_operand" "")
3875 (match_operand:SI 2 "arm_rhs_operand" "")))]
cffb2a26 3876 "TARGET_EITHER"
87b22bf7 3877 "
25f905c2 3878 if (TARGET_32BIT)
cffb2a26 3879 {
0438d37f 3880 if (CONST_INT_P (operands[2])
cffb2a26 3881 && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) > 31)
3882 operands[2] = GEN_INT (INTVAL (operands[2]) % 32);
3883 }
25f905c2 3884 else /* TARGET_THUMB1 */
cffb2a26 3885 {
0438d37f 3886 if (CONST_INT_P (operands [2]))
cffb2a26 3887 operands [2] = force_reg (SImode, operands[2]);
3888 }
3889 "
3890)
87b22bf7 3891
cffb2a26 3892(define_insn "*arm_shiftsi3"
88c29385 3893 [(set (match_operand:SI 0 "s_register_operand" "=l,l,r,r")
cffb2a26 3894 (match_operator:SI 3 "shift_operator"
88c29385 3895 [(match_operand:SI 1 "s_register_operand" "0,l,r,r")
3896 (match_operand:SI 2 "reg_or_int_operand" "l,M,M,r")]))]
25f905c2 3897 "TARGET_32BIT"
3898 "* return arm_output_shift(operands, 0);"
344495ea 3899 [(set_attr "predicable" "yes")
88c29385 3900 (set_attr "arch" "t2,t2,*,*")
3901 (set_attr "predicable_short_it" "yes,yes,no,no")
7c36fe71 3902 (set_attr "length" "4")
331beb1a 3903 (set_attr "shift" "1")
88c29385 3904 (set_attr "type" "alu_shift_reg,alu_shift_imm,alu_shift_imm,alu_shift_reg")]
6c4c2133 3905)
87b22bf7 3906
f7fbdd4a 3907(define_insn "*shiftsi3_compare0"
bd5b4116 3908 [(set (reg:CC_NOOV CC_REGNUM)
87b22bf7 3909 (compare:CC_NOOV (match_operator:SI 3 "shift_operator"
6b6abc9c 3910 [(match_operand:SI 1 "s_register_operand" "r,r")
3911 (match_operand:SI 2 "arm_rhs_operand" "M,r")])
9c08d1fa 3912 (const_int 0)))
6b6abc9c 3913 (set (match_operand:SI 0 "s_register_operand" "=r,r")
87b22bf7 3914 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))]
25f905c2 3915 "TARGET_32BIT"
3916 "* return arm_output_shift(operands, 1);"
344495ea 3917 [(set_attr "conds" "set")
331beb1a 3918 (set_attr "shift" "1")
d82e788e 3919 (set_attr "type" "alus_shift_imm,alus_shift_reg")]
0d66636f 3920)
9c08d1fa 3921
f7fbdd4a 3922(define_insn "*shiftsi3_compare0_scratch"
bd5b4116 3923 [(set (reg:CC_NOOV CC_REGNUM)
87b22bf7 3924 (compare:CC_NOOV (match_operator:SI 3 "shift_operator"
6b6abc9c 3925 [(match_operand:SI 1 "s_register_operand" "r,r")
3926 (match_operand:SI 2 "arm_rhs_operand" "M,r")])
9c08d1fa 3927 (const_int 0)))
6b6abc9c 3928 (clobber (match_scratch:SI 0 "=r,r"))]
25f905c2 3929 "TARGET_32BIT"
3930 "* return arm_output_shift(operands, 1);"
344495ea 3931 [(set_attr "conds" "set")
6b6abc9c 3932 (set_attr "shift" "1")
d82e788e 3933 (set_attr "type" "shift_imm,shift_reg")]
0d66636f 3934)
9c08d1fa 3935
d5d4dc8d 3936(define_insn "*not_shiftsi"
3937 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
87b22bf7 3938 (not:SI (match_operator:SI 3 "shift_operator"
d5d4dc8d 3939 [(match_operand:SI 1 "s_register_operand" "r,r")
3940 (match_operand:SI 2 "shift_amount_operand" "M,rM")])))]
3941 "TARGET_32BIT"
6c4c2133 3942 "mvn%?\\t%0, %1%S3"
344495ea 3943 [(set_attr "predicable" "yes")
d952d547 3944 (set_attr "predicable_short_it" "no")
331beb1a 3945 (set_attr "shift" "1")
d5d4dc8d 3946 (set_attr "arch" "32,a")
1aed5204 3947 (set_attr "type" "mvn_shift,mvn_shift_reg")])
9c08d1fa 3948
d5d4dc8d 3949(define_insn "*not_shiftsi_compare0"
bd5b4116 3950 [(set (reg:CC_NOOV CC_REGNUM)
d5d4dc8d 3951 (compare:CC_NOOV
3952 (not:SI (match_operator:SI 3 "shift_operator"
3953 [(match_operand:SI 1 "s_register_operand" "r,r")
3954 (match_operand:SI 2 "shift_amount_operand" "M,rM")]))
3955 (const_int 0)))
3956 (set (match_operand:SI 0 "s_register_operand" "=r,r")
87b22bf7 3957 (not:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)])))]
d5d4dc8d 3958 "TARGET_32BIT"
25f905c2 3959 "mvn%.\\t%0, %1%S3"
344495ea 3960 [(set_attr "conds" "set")
331beb1a 3961 (set_attr "shift" "1")
d5d4dc8d 3962 (set_attr "arch" "32,a")
1aed5204 3963 (set_attr "type" "mvn_shift,mvn_shift_reg")])
9c08d1fa 3964
d5d4dc8d 3965(define_insn "*not_shiftsi_compare0_scratch"
bd5b4116 3966 [(set (reg:CC_NOOV CC_REGNUM)
d5d4dc8d 3967 (compare:CC_NOOV
3968 (not:SI (match_operator:SI 3 "shift_operator"
3969 [(match_operand:SI 1 "s_register_operand" "r,r")
3970 (match_operand:SI 2 "shift_amount_operand" "M,rM")]))
3971 (const_int 0)))
3972 (clobber (match_scratch:SI 0 "=r,r"))]
3973 "TARGET_32BIT"
25f905c2 3974 "mvn%.\\t%0, %1%S3"
344495ea 3975 [(set_attr "conds" "set")
331beb1a 3976 (set_attr "shift" "1")
d5d4dc8d 3977 (set_attr "arch" "32,a")
1aed5204 3978 (set_attr "type" "mvn_shift,mvn_shift_reg")])
9c08d1fa 3979
cffb2a26 3980;; We don't really have extzv, but defining this using shifts helps
3981;; to reduce register pressure later on.
3982
3983(define_expand "extzv"
eb04cafb 3984 [(set (match_operand 0 "s_register_operand" "")
3985 (zero_extract (match_operand 1 "nonimmediate_operand" "")
3986 (match_operand 2 "const_int_operand" "")
3987 (match_operand 3 "const_int_operand" "")))]
8b054d5a 3988 "TARGET_THUMB1 || arm_arch_thumb2"
cffb2a26 3989 "
3990 {
3991 HOST_WIDE_INT lshift = 32 - INTVAL (operands[2]) - INTVAL (operands[3]);
3992 HOST_WIDE_INT rshift = 32 - INTVAL (operands[2]);
3993
8b054d5a 3994 if (arm_arch_thumb2)
3995 {
eb04cafb 3996 HOST_WIDE_INT width = INTVAL (operands[2]);
3997 HOST_WIDE_INT bitpos = INTVAL (operands[3]);
3998
3999 if (unaligned_access && MEM_P (operands[1])
4000 && (width == 16 || width == 32) && (bitpos % BITS_PER_UNIT) == 0)
4001 {
4002 rtx base_addr;
4003
4004 if (BYTES_BIG_ENDIAN)
4005 bitpos = GET_MODE_BITSIZE (GET_MODE (operands[0])) - width
4006 - bitpos;
4007
4008 if (width == 32)
4009 {
4010 base_addr = adjust_address (operands[1], SImode,
4011 bitpos / BITS_PER_UNIT);
4012 emit_insn (gen_unaligned_loadsi (operands[0], base_addr));
4013 }
4014 else
4015 {
4016 rtx dest = operands[0];
4017 rtx tmp = gen_reg_rtx (SImode);
4018
4019 /* We may get a paradoxical subreg here. Strip it off. */
4020 if (GET_CODE (dest) == SUBREG
4021 && GET_MODE (dest) == SImode
4022 && GET_MODE (SUBREG_REG (dest)) == HImode)
4023 dest = SUBREG_REG (dest);
4024
4025 if (GET_MODE_BITSIZE (GET_MODE (dest)) != width)
4026 FAIL;
4027
4028 base_addr = adjust_address (operands[1], HImode,
4029 bitpos / BITS_PER_UNIT);
4030 emit_insn (gen_unaligned_loadhiu (tmp, base_addr));
4031 emit_move_insn (gen_lowpart (SImode, dest), tmp);
4032 }
4033 DONE;
4034 }
4035 else if (s_register_operand (operands[1], GET_MODE (operands[1])))
4036 {
4037 emit_insn (gen_extzv_t2 (operands[0], operands[1], operands[2],
4038 operands[3]));
4039 DONE;
4040 }
4041 else
4042 FAIL;
8b054d5a 4043 }
eb04cafb 4044
4045 if (!s_register_operand (operands[1], GET_MODE (operands[1])))
4046 FAIL;
8b054d5a 4047
cffb2a26 4048 operands[3] = GEN_INT (rshift);
4049
4050 if (lshift == 0)
4051 {
4052 emit_insn (gen_lshrsi3 (operands[0], operands[1], operands[3]));
4053 DONE;
4054 }
4055
eb04cafb 4056 emit_insn (gen_extzv_t1 (operands[0], operands[1], GEN_INT (lshift),
4057 operands[3], gen_reg_rtx (SImode)));
4058 DONE;
215b30b3 4059 }"
cffb2a26 4060)
4061
eb04cafb 4062;; Helper for extzv, for the Thumb-1 register-shifts case.
4063
4064(define_expand "extzv_t1"
4065 [(set (match_operand:SI 4 "s_register_operand" "")
4066 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
4067 (match_operand:SI 2 "const_int_operand" "")))
4068 (set (match_operand:SI 0 "s_register_operand" "")
4069 (lshiftrt:SI (match_dup 4)
4070 (match_operand:SI 3 "const_int_operand" "")))]
4071 "TARGET_THUMB1"
4072 "")
4073
4074(define_expand "extv"
4075 [(set (match_operand 0 "s_register_operand" "")
4076 (sign_extract (match_operand 1 "nonimmediate_operand" "")
4077 (match_operand 2 "const_int_operand" "")
4078 (match_operand 3 "const_int_operand" "")))]
4079 "arm_arch_thumb2"
4080{
4081 HOST_WIDE_INT width = INTVAL (operands[2]);
4082 HOST_WIDE_INT bitpos = INTVAL (operands[3]);
4083
4084 if (unaligned_access && MEM_P (operands[1]) && (width == 16 || width == 32)
4085 && (bitpos % BITS_PER_UNIT) == 0)
4086 {
4087 rtx base_addr;
4088
4089 if (BYTES_BIG_ENDIAN)
4090 bitpos = GET_MODE_BITSIZE (GET_MODE (operands[0])) - width - bitpos;
4091
4092 if (width == 32)
4093 {
4094 base_addr = adjust_address (operands[1], SImode,
4095 bitpos / BITS_PER_UNIT);
4096 emit_insn (gen_unaligned_loadsi (operands[0], base_addr));
4097 }
4098 else
4099 {
4100 rtx dest = operands[0];
4101 rtx tmp = gen_reg_rtx (SImode);
4102
4103 /* We may get a paradoxical subreg here. Strip it off. */
4104 if (GET_CODE (dest) == SUBREG
4105 && GET_MODE (dest) == SImode
4106 && GET_MODE (SUBREG_REG (dest)) == HImode)
4107 dest = SUBREG_REG (dest);
4108
4109 if (GET_MODE_BITSIZE (GET_MODE (dest)) != width)
4110 FAIL;
4111
4112 base_addr = adjust_address (operands[1], HImode,
4113 bitpos / BITS_PER_UNIT);
4114 emit_insn (gen_unaligned_loadhis (tmp, base_addr));
4115 emit_move_insn (gen_lowpart (SImode, dest), tmp);
4116 }
4117
4118 DONE;
4119 }
4120 else if (!s_register_operand (operands[1], GET_MODE (operands[1])))
4121 FAIL;
4122 else if (GET_MODE (operands[0]) == SImode
4123 && GET_MODE (operands[1]) == SImode)
4124 {
4125 emit_insn (gen_extv_regsi (operands[0], operands[1], operands[2],
4126 operands[3]));
4127 DONE;
4128 }
4129
4130 FAIL;
4131})
4132
4133; Helper to expand register forms of extv with the proper modes.
4134
4135(define_expand "extv_regsi"
4136 [(set (match_operand:SI 0 "s_register_operand" "")
4137 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "")
4138 (match_operand 2 "const_int_operand" "")
4139 (match_operand 3 "const_int_operand" "")))]
4140 ""
4141{
4142})
4143
4144; ARMv6+ unaligned load/store instructions (used for packed structure accesses).
4145
4146(define_insn "unaligned_loadsi"
4147 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
4148 (unspec:SI [(match_operand:SI 1 "memory_operand" "Uw,m")]
4149 UNSPEC_UNALIGNED_LOAD))]
4150 "unaligned_access && TARGET_32BIT"
4151 "ldr%?\t%0, %1\t@ unaligned"
4152 [(set_attr "arch" "t2,any")
4153 (set_attr "length" "2,4")
4154 (set_attr "predicable" "yes")
d952d547 4155 (set_attr "predicable_short_it" "yes,no")
eb04cafb 4156 (set_attr "type" "load1")])
4157
4158(define_insn "unaligned_loadhis"
4159 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
4160 (sign_extend:SI
e3f4ccee 4161 (unspec:HI [(match_operand:HI 1 "memory_operand" "Uw,Uh")]
eb04cafb 4162 UNSPEC_UNALIGNED_LOAD)))]
4163 "unaligned_access && TARGET_32BIT"
4164 "ldr%(sh%)\t%0, %1\t@ unaligned"
4165 [(set_attr "arch" "t2,any")
4166 (set_attr "length" "2,4")
4167 (set_attr "predicable" "yes")
d952d547 4168 (set_attr "predicable_short_it" "yes,no")
eb04cafb 4169 (set_attr "type" "load_byte")])
4170
4171(define_insn "unaligned_loadhiu"
4172 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
4173 (zero_extend:SI
4174 (unspec:HI [(match_operand:HI 1 "memory_operand" "Uw,m")]
4175 UNSPEC_UNALIGNED_LOAD)))]
4176 "unaligned_access && TARGET_32BIT"
4177 "ldr%(h%)\t%0, %1\t@ unaligned"
4178 [(set_attr "arch" "t2,any")
4179 (set_attr "length" "2,4")
4180 (set_attr "predicable" "yes")
d952d547 4181 (set_attr "predicable_short_it" "yes,no")
eb04cafb 4182 (set_attr "type" "load_byte")])
4183
4184(define_insn "unaligned_storesi"
4185 [(set (match_operand:SI 0 "memory_operand" "=Uw,m")
4186 (unspec:SI [(match_operand:SI 1 "s_register_operand" "l,r")]
4187 UNSPEC_UNALIGNED_STORE))]
4188 "unaligned_access && TARGET_32BIT"
4189 "str%?\t%1, %0\t@ unaligned"
4190 [(set_attr "arch" "t2,any")
4191 (set_attr "length" "2,4")
4192 (set_attr "predicable" "yes")
d952d547 4193 (set_attr "predicable_short_it" "yes,no")
eb04cafb 4194 (set_attr "type" "store1")])
4195
4196(define_insn "unaligned_storehi"
4197 [(set (match_operand:HI 0 "memory_operand" "=Uw,m")
4198 (unspec:HI [(match_operand:HI 1 "s_register_operand" "l,r")]
4199 UNSPEC_UNALIGNED_STORE))]
4200 "unaligned_access && TARGET_32BIT"
4201 "str%(h%)\t%1, %0\t@ unaligned"
4202 [(set_attr "arch" "t2,any")
4203 (set_attr "length" "2,4")
4204 (set_attr "predicable" "yes")
d952d547 4205 (set_attr "predicable_short_it" "yes,no")
eb04cafb 4206 (set_attr "type" "store1")])
4207
ae51a965 4208;; Unaligned double-word load and store.
4209;; Split after reload into two unaligned single-word accesses.
4210;; It prevents lower_subreg from splitting some other aligned
4211;; double-word accesses too early. Used for internal memcpy.
4212
4213(define_insn_and_split "unaligned_loaddi"
4214 [(set (match_operand:DI 0 "s_register_operand" "=l,r")
4215 (unspec:DI [(match_operand:DI 1 "memory_operand" "o,o")]
4216 UNSPEC_UNALIGNED_LOAD))]
4217 "unaligned_access && TARGET_32BIT"
4218 "#"
4219 "&& reload_completed"
4220 [(set (match_dup 0) (unspec:SI [(match_dup 1)] UNSPEC_UNALIGNED_LOAD))
4221 (set (match_dup 2) (unspec:SI [(match_dup 3)] UNSPEC_UNALIGNED_LOAD))]
4222 {
4223 operands[2] = gen_highpart (SImode, operands[0]);
4224 operands[0] = gen_lowpart (SImode, operands[0]);
4225 operands[3] = gen_highpart (SImode, operands[1]);
4226 operands[1] = gen_lowpart (SImode, operands[1]);
4227
4228 /* If the first destination register overlaps with the base address,
4229 swap the order in which the loads are emitted. */
4230 if (reg_overlap_mentioned_p (operands[0], operands[1]))
4231 {
f145bcba 4232 std::swap (operands[1], operands[3]);
4233 std::swap (operands[0], operands[2]);
ae51a965 4234 }
4235 }
4236 [(set_attr "arch" "t2,any")
4237 (set_attr "length" "4,8")
4238 (set_attr "predicable" "yes")
4239 (set_attr "type" "load2")])
4240
4241(define_insn_and_split "unaligned_storedi"
4242 [(set (match_operand:DI 0 "memory_operand" "=o,o")
4243 (unspec:DI [(match_operand:DI 1 "s_register_operand" "l,r")]
4244 UNSPEC_UNALIGNED_STORE))]
4245 "unaligned_access && TARGET_32BIT"
4246 "#"
4247 "&& reload_completed"
4248 [(set (match_dup 0) (unspec:SI [(match_dup 1)] UNSPEC_UNALIGNED_STORE))
4249 (set (match_dup 2) (unspec:SI [(match_dup 3)] UNSPEC_UNALIGNED_STORE))]
4250 {
4251 operands[2] = gen_highpart (SImode, operands[0]);
4252 operands[0] = gen_lowpart (SImode, operands[0]);
4253 operands[3] = gen_highpart (SImode, operands[1]);
4254 operands[1] = gen_lowpart (SImode, operands[1]);
4255 }
4256 [(set_attr "arch" "t2,any")
4257 (set_attr "length" "4,8")
4258 (set_attr "predicable" "yes")
4259 (set_attr "type" "store2")])
4260
4261
eb04cafb 4262(define_insn "*extv_reg"
8b054d5a 4263 [(set (match_operand:SI 0 "s_register_operand" "=r")
4264 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
809003b3 4265 (match_operand:SI 2 "const_int_M_operand" "M")
4266 (match_operand:SI 3 "const_int_M_operand" "M")))]
8b054d5a 4267 "arm_arch_thumb2"
4268 "sbfx%?\t%0, %1, %3, %2"
4269 [(set_attr "length" "4")
d952d547 4270 (set_attr "predicable" "yes")
d82e788e 4271 (set_attr "predicable_short_it" "no")
4272 (set_attr "type" "bfm")]
8b054d5a 4273)
4274
4275(define_insn "extzv_t2"
4276 [(set (match_operand:SI 0 "s_register_operand" "=r")
4277 (zero_extract:SI (match_operand:SI 1 "s_register_operand" "r")
809003b3 4278 (match_operand:SI 2 "const_int_M_operand" "M")
4279 (match_operand:SI 3 "const_int_M_operand" "M")))]
8b054d5a 4280 "arm_arch_thumb2"
4281 "ubfx%?\t%0, %1, %3, %2"
4282 [(set_attr "length" "4")
d952d547 4283 (set_attr "predicable" "yes")
d82e788e 4284 (set_attr "predicable_short_it" "no")
4285 (set_attr "type" "bfm")]
8b054d5a 4286)
4287
7d3cda8c 4288
4289;; Division instructions
4290(define_insn "divsi3"
4291 [(set (match_operand:SI 0 "s_register_operand" "=r")
4292 (div:SI (match_operand:SI 1 "s_register_operand" "r")
4293 (match_operand:SI 2 "s_register_operand" "r")))]
4294 "TARGET_IDIV"
4295 "sdiv%?\t%0, %1, %2"
4296 [(set_attr "predicable" "yes")
d952d547 4297 (set_attr "predicable_short_it" "no")
9da0ec36 4298 (set_attr "type" "sdiv")]
7d3cda8c 4299)
4300
4301(define_insn "udivsi3"
4302 [(set (match_operand:SI 0 "s_register_operand" "=r")
4303 (udiv:SI (match_operand:SI 1 "s_register_operand" "r")
4304 (match_operand:SI 2 "s_register_operand" "r")))]
4305 "TARGET_IDIV"
4306 "udiv%?\t%0, %1, %2"
4307 [(set_attr "predicable" "yes")
d952d547 4308 (set_attr "predicable_short_it" "no")
9da0ec36 4309 (set_attr "type" "udiv")]
7d3cda8c 4310)
4311
b11cae9e 4312\f
4313;; Unary arithmetic insns
4314
cffb2a26 4315(define_expand "negdi2"
4316 [(parallel
8135a42b 4317 [(set (match_operand:DI 0 "s_register_operand" "")
4318 (neg:DI (match_operand:DI 1 "s_register_operand" "")))
bd5b4116 4319 (clobber (reg:CC CC_REGNUM))])]
cffb2a26 4320 "TARGET_EITHER"
774d2fbb 4321 {
4322 if (TARGET_NEON)
4323 {
4324 emit_insn (gen_negdi2_neon (operands[0], operands[1]));
4325 DONE;
4326 }
4327 }
cffb2a26 4328)
4329
4330;; The constraints here are to prevent a *partial* overlap (where %Q0 == %R1).
e5fea38e 4331;; The first alternative allows the common case of a *full* overlap.
ba6a3b2f 4332(define_insn_and_split "*arm_negdi2"
458a8706 4333 [(set (match_operand:DI 0 "s_register_operand" "=r,&r")
e5fea38e 4334 (neg:DI (match_operand:DI 1 "s_register_operand" "0,r")))
bd5b4116 4335 (clobber (reg:CC CC_REGNUM))]
cffb2a26 4336 "TARGET_ARM"
ba6a3b2f 4337 "#" ; "rsbs\\t%Q0, %Q1, #0\;rsc\\t%R0, %R1, #0"
4338 "&& reload_completed"
4339 [(parallel [(set (reg:CC CC_REGNUM)
4340 (compare:CC (const_int 0) (match_dup 1)))
4341 (set (match_dup 0) (minus:SI (const_int 0) (match_dup 1)))])
4342 (set (match_dup 2) (minus:SI (minus:SI (const_int 0) (match_dup 3))
4343 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
4344 {
4345 operands[2] = gen_highpart (SImode, operands[0]);
4346 operands[0] = gen_lowpart (SImode, operands[0]);
4347 operands[3] = gen_highpart (SImode, operands[1]);
4348 operands[1] = gen_lowpart (SImode, operands[1]);
4349 }
cffb2a26 4350 [(set_attr "conds" "clob")
1b7da4ac 4351 (set_attr "length" "8")
4352 (set_attr "type" "multiple")]
cffb2a26 4353)
b11cae9e 4354
cffb2a26 4355(define_expand "negsi2"
4356 [(set (match_operand:SI 0 "s_register_operand" "")
4357 (neg:SI (match_operand:SI 1 "s_register_operand" "")))]
4358 "TARGET_EITHER"
b11cae9e 4359 ""
cffb2a26 4360)
4361
4362(define_insn "*arm_negsi2"
d952d547 4363 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
4364 (neg:SI (match_operand:SI 1 "s_register_operand" "l,r")))]
25f905c2 4365 "TARGET_32BIT"
cffb2a26 4366 "rsb%?\\t%0, %1, #0"
d952d547 4367 [(set_attr "predicable" "yes")
4368 (set_attr "predicable_short_it" "yes,no")
4369 (set_attr "arch" "t2,*")
1b7da4ac 4370 (set_attr "length" "4")
112eda6f 4371 (set_attr "type" "alu_sreg")]
cffb2a26 4372)
4373
604f3a0a 4374(define_expand "negsf2"
4375 [(set (match_operand:SF 0 "s_register_operand" "")
4376 (neg:SF (match_operand:SF 1 "s_register_operand" "")))]
994606f8 4377 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
604f3a0a 4378 ""
4379)
4380
4381(define_expand "negdf2"
4382 [(set (match_operand:DF 0 "s_register_operand" "")
4383 (neg:DF (match_operand:DF 1 "s_register_operand" "")))]
994606f8 4384 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
604f3a0a 4385 "")
4386
7eaf2be0 4387(define_insn_and_split "*zextendsidi_negsi"
4388 [(set (match_operand:DI 0 "s_register_operand" "=r")
4389 (zero_extend:DI (neg:SI (match_operand:SI 1 "s_register_operand" "r"))))]
4390 "TARGET_32BIT"
4391 "#"
4392 ""
4393 [(set (match_dup 2)
4394 (neg:SI (match_dup 1)))
4395 (set (match_dup 3)
4396 (const_int 0))]
4397 {
4398 operands[2] = gen_lowpart (SImode, operands[0]);
4399 operands[3] = gen_highpart (SImode, operands[0]);
4400 }
4401 [(set_attr "length" "8")
4402 (set_attr "type" "multiple")]
4403)
4404
83e2b922 4405;; Negate an extended 32-bit value.
4406(define_insn_and_split "*negdi_extendsidi"
61fa8ff2 4407 [(set (match_operand:DI 0 "s_register_operand" "=l,r")
4408 (neg:DI (sign_extend:DI
4409 (match_operand:SI 1 "s_register_operand" "l,r"))))
83e2b922 4410 (clobber (reg:CC CC_REGNUM))]
4411 "TARGET_32BIT"
61fa8ff2 4412 "#"
83e2b922 4413 "&& reload_completed"
4414 [(const_int 0)]
4415 {
61fa8ff2 4416 rtx low = gen_lowpart (SImode, operands[0]);
4417 rtx high = gen_highpart (SImode, operands[0]);
4418
4419 if (reg_overlap_mentioned_p (low, operands[1]))
4420 {
4421 /* Input overlaps the low word of the output. Use:
4422 asr Rhi, Rin, #31
4423 rsbs Rlo, Rin, #0
4424 rsc Rhi, Rhi, #0 (thumb2: sbc Rhi, Rhi, Rhi, lsl #1). */
4425 rtx cc_reg = gen_rtx_REG (CC_Cmode, CC_REGNUM);
4426
d1f9b275 4427 emit_insn (gen_rtx_SET (high,
61fa8ff2 4428 gen_rtx_ASHIFTRT (SImode, operands[1],
4429 GEN_INT (31))));
4430
4431 emit_insn (gen_subsi3_compare (low, const0_rtx, operands[1]));
4432 if (TARGET_ARM)
d1f9b275 4433 emit_insn (gen_rtx_SET (high,
61fa8ff2 4434 gen_rtx_MINUS (SImode,
4435 gen_rtx_MINUS (SImode,
4436 const0_rtx,
4437 high),
4438 gen_rtx_LTU (SImode,
4439 cc_reg,
4440 const0_rtx))));
4441 else
4442 {
4443 rtx two_x = gen_rtx_ASHIFT (SImode, high, GEN_INT (1));
d1f9b275 4444 emit_insn (gen_rtx_SET (high,
61fa8ff2 4445 gen_rtx_MINUS (SImode,
4446 gen_rtx_MINUS (SImode,
4447 high,
4448 two_x),
4449 gen_rtx_LTU (SImode,
4450 cc_reg,
4451 const0_rtx))));
4452 }
4453 }
4454 else
4455 {
4456 /* No overlap, or overlap on high word. Use:
4457 rsb Rlo, Rin, #0
4458 bic Rhi, Rlo, Rin
4459 asr Rhi, Rhi, #31
4460 Flags not needed for this sequence. */
d1f9b275 4461 emit_insn (gen_rtx_SET (low, gen_rtx_NEG (SImode, operands[1])));
4462 emit_insn (gen_rtx_SET (high,
61fa8ff2 4463 gen_rtx_AND (SImode,
4464 gen_rtx_NOT (SImode, operands[1]),
4465 low)));
d1f9b275 4466 emit_insn (gen_rtx_SET (high,
61fa8ff2 4467 gen_rtx_ASHIFTRT (SImode, high,
4468 GEN_INT (31))));
4469 }
4470 DONE;
83e2b922 4471 }
61fa8ff2 4472 [(set_attr "length" "12")
4473 (set_attr "arch" "t2,*")
1b7da4ac 4474 (set_attr "type" "multiple")]
83e2b922 4475)
4476
4477(define_insn_and_split "*negdi_zero_extendsidi"
4478 [(set (match_operand:DI 0 "s_register_operand" "=r,&r")
4479 (neg:DI (zero_extend:DI (match_operand:SI 1 "s_register_operand" "0,r"))))
4480 (clobber (reg:CC CC_REGNUM))]
4481 "TARGET_32BIT"
4482 "#" ; "rsbs\\t%Q0, %1, #0\;sbc\\t%R0,%R0,%R0"
4483 ;; Don't care what register is input to sbc,
4484 ;; since we just just need to propagate the carry.
4485 "&& reload_completed"
4486 [(parallel [(set (reg:CC CC_REGNUM)
4487 (compare:CC (const_int 0) (match_dup 1)))
4488 (set (match_dup 0) (minus:SI (const_int 0) (match_dup 1)))])
4489 (set (match_dup 2) (minus:SI (minus:SI (match_dup 2) (match_dup 2))
4490 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
4491 {
4492 operands[2] = gen_highpart (SImode, operands[0]);
4493 operands[0] = gen_lowpart (SImode, operands[0]);
4494 }
4495 [(set_attr "conds" "clob")
1b7da4ac 4496 (set_attr "length" "8")
4497 (set_attr "type" "multiple")] ;; length in thumb is 4
83e2b922 4498)
4499
9c08d1fa 4500;; abssi2 doesn't really clobber the condition codes if a different register
4501;; is being set. To keep things simple, assume during rtl manipulations that
4502;; it does, but tell the final scan operator the truth. Similarly for
4503;; (neg (abs...))
4504
604f3a0a 4505(define_expand "abssi2"
4506 [(parallel
4507 [(set (match_operand:SI 0 "s_register_operand" "")
4508 (abs:SI (match_operand:SI 1 "s_register_operand" "")))
ba156559 4509 (clobber (match_dup 2))])]
4510 "TARGET_EITHER"
4511 "
25f905c2 4512 if (TARGET_THUMB1)
ba156559 4513 operands[2] = gen_rtx_SCRATCH (SImode);
4514 else
4515 operands[2] = gen_rtx_REG (CCmode, CC_REGNUM);
4516")
604f3a0a 4517
ba6a3b2f 4518(define_insn_and_split "*arm_abssi2"
ba156559 4519 [(set (match_operand:SI 0 "s_register_operand" "=r,&r")
9c08d1fa 4520 (abs:SI (match_operand:SI 1 "s_register_operand" "0,r")))
bd5b4116 4521 (clobber (reg:CC CC_REGNUM))]
cffb2a26 4522 "TARGET_ARM"
ba6a3b2f 4523 "#"
4524 "&& reload_completed"
4525 [(const_int 0)]
4526 {
4527 /* if (which_alternative == 0) */
4528 if (REGNO(operands[0]) == REGNO(operands[1]))
4529 {
4530 /* Emit the pattern:
4531 cmp\\t%0, #0\;rsblt\\t%0, %0, #0
4532 [(set (reg:CC CC_REGNUM)
4533 (compare:CC (match_dup 0) (const_int 0)))
4534 (cond_exec (lt:CC (reg:CC CC_REGNUM) (const_int 0))
4535 (set (match_dup 0) (minus:SI (const_int 0) (match_dup 1))))]
4536 */
d1f9b275 4537 emit_insn (gen_rtx_SET (gen_rtx_REG (CCmode, CC_REGNUM),
ba6a3b2f 4538 gen_rtx_COMPARE (CCmode, operands[0], const0_rtx)));
4539 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
4540 (gen_rtx_LT (SImode,
4541 gen_rtx_REG (CCmode, CC_REGNUM),
4542 const0_rtx)),
d1f9b275 4543 (gen_rtx_SET (operands[0],
ba6a3b2f 4544 (gen_rtx_MINUS (SImode,
4545 const0_rtx,
4546 operands[1]))))));
4547 DONE;
4548 }
4549 else
4550 {
4551 /* Emit the pattern:
4552 alt1: eor%?\\t%0, %1, %1, asr #31\;sub%?\\t%0, %0, %1, asr #31
4553 [(set (match_dup 0)
4554 (xor:SI (match_dup 1)
4555 (ashiftrt:SI (match_dup 1) (const_int 31))))
4556 (set (match_dup 0)
4557 (minus:SI (match_dup 0)
4558 (ashiftrt:SI (match_dup 1) (const_int 31))))]
4559 */
d1f9b275 4560 emit_insn (gen_rtx_SET (operands[0],
ba6a3b2f 4561 gen_rtx_XOR (SImode,
4562 gen_rtx_ASHIFTRT (SImode,
4563 operands[1],
4564 GEN_INT (31)),
4565 operands[1])));
d1f9b275 4566 emit_insn (gen_rtx_SET (operands[0],
ba6a3b2f 4567 gen_rtx_MINUS (SImode,
4568 operands[0],
4569 gen_rtx_ASHIFTRT (SImode,
4570 operands[1],
4571 GEN_INT (31)))));
4572 DONE;
4573 }
4574 }
cffb2a26 4575 [(set_attr "conds" "clob,*")
331beb1a 4576 (set_attr "shift" "1")
2ad08b65 4577 (set_attr "predicable" "no, yes")
1b7da4ac 4578 (set_attr "length" "8")
4579 (set_attr "type" "multiple")]
cffb2a26 4580)
9c08d1fa 4581
ba6a3b2f 4582(define_insn_and_split "*arm_neg_abssi2"
9c08d1fa 4583 [(set (match_operand:SI 0 "s_register_operand" "=r,&r")
4584 (neg:SI (abs:SI (match_operand:SI 1 "s_register_operand" "0,r"))))
bd5b4116 4585 (clobber (reg:CC CC_REGNUM))]
cffb2a26 4586 "TARGET_ARM"
ba6a3b2f 4587 "#"
4588 "&& reload_completed"
4589 [(const_int 0)]
4590 {
4591 /* if (which_alternative == 0) */
4592 if (REGNO (operands[0]) == REGNO (operands[1]))
4593 {
4594 /* Emit the pattern:
4595 cmp\\t%0, #0\;rsbgt\\t%0, %0, #0
4596 */
d1f9b275 4597 emit_insn (gen_rtx_SET (gen_rtx_REG (CCmode, CC_REGNUM),
ba6a3b2f 4598 gen_rtx_COMPARE (CCmode, operands[0], const0_rtx)));
4599 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
4600 gen_rtx_GT (SImode,
4601 gen_rtx_REG (CCmode, CC_REGNUM),
4602 const0_rtx),
d1f9b275 4603 gen_rtx_SET (operands[0],
ba6a3b2f 4604 (gen_rtx_MINUS (SImode,
4605 const0_rtx,
4606 operands[1])))));
4607 }
4608 else
4609 {
4610 /* Emit the pattern:
4611 eor%?\\t%0, %1, %1, asr #31\;rsb%?\\t%0, %0, %1, asr #31
4612 */
d1f9b275 4613 emit_insn (gen_rtx_SET (operands[0],
ba6a3b2f 4614 gen_rtx_XOR (SImode,
4615 gen_rtx_ASHIFTRT (SImode,
4616 operands[1],
4617 GEN_INT (31)),
4618 operands[1])));
d1f9b275 4619 emit_insn (gen_rtx_SET (operands[0],
ba6a3b2f 4620 gen_rtx_MINUS (SImode,
4621 gen_rtx_ASHIFTRT (SImode,
4622 operands[1],
4623 GEN_INT (31)),
4624 operands[0])));
4625 }
4626 DONE;
4627 }
cffb2a26 4628 [(set_attr "conds" "clob,*")
331beb1a 4629 (set_attr "shift" "1")
2ad08b65 4630 (set_attr "predicable" "no, yes")
1b7da4ac 4631 (set_attr "length" "8")
4632 (set_attr "type" "multiple")]
cffb2a26 4633)
b11cae9e 4634
604f3a0a 4635(define_expand "abssf2"
4636 [(set (match_operand:SF 0 "s_register_operand" "")
4637 (abs:SF (match_operand:SF 1 "s_register_operand" "")))]
25f905c2 4638 "TARGET_32BIT && TARGET_HARD_FLOAT"
604f3a0a 4639 "")
4640
604f3a0a 4641(define_expand "absdf2"
4642 [(set (match_operand:DF 0 "s_register_operand" "")
4643 (abs:DF (match_operand:DF 1 "s_register_operand" "")))]
a50d7267 4644 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
604f3a0a 4645 "")
4646
7db9af5d 4647(define_expand "sqrtsf2"
4648 [(set (match_operand:SF 0 "s_register_operand" "")
4649 (sqrt:SF (match_operand:SF 1 "s_register_operand" "")))]
994606f8 4650 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
7db9af5d 4651 "")
9c08d1fa 4652
7db9af5d 4653(define_expand "sqrtdf2"
4654 [(set (match_operand:DF 0 "s_register_operand" "")
4655 (sqrt:DF (match_operand:DF 1 "s_register_operand" "")))]
994606f8 4656 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
7db9af5d 4657 "")
9c08d1fa 4658
a0f94409 4659(define_insn_and_split "one_cmpldi2"
10efb95f 4660 [(set (match_operand:DI 0 "s_register_operand" "=w,&r,&r,?w")
4661 (not:DI (match_operand:DI 1 "s_register_operand" " w, 0, r, w")))]
25f905c2 4662 "TARGET_32BIT"
10efb95f 4663 "@
4664 vmvn\t%P0, %P1
4665 #
4666 #
4667 vmvn\t%P0, %P1"
4668 "TARGET_32BIT && reload_completed
4669 && arm_general_register_operand (operands[0], DImode)"
a0f94409 4670 [(set (match_dup 0) (not:SI (match_dup 1)))
4671 (set (match_dup 2) (not:SI (match_dup 3)))]
4672 "
4673 {
4674 operands[2] = gen_highpart (SImode, operands[0]);
4675 operands[0] = gen_lowpart (SImode, operands[0]);
4676 operands[3] = gen_highpart (SImode, operands[1]);
4677 operands[1] = gen_lowpart (SImode, operands[1]);
4678 }"
10efb95f 4679 [(set_attr "length" "*,8,8,*")
4680 (set_attr "predicable" "no,yes,yes,no")
32093010 4681 (set_attr "type" "neon_move,multiple,multiple,neon_move")
b6779ddc 4682 (set_attr "arch" "neon_for_64bits,*,*,avoid_neon_for_64bits")]
cffb2a26 4683)
b11cae9e 4684
cffb2a26 4685(define_expand "one_cmplsi2"
4686 [(set (match_operand:SI 0 "s_register_operand" "")
4687 (not:SI (match_operand:SI 1 "s_register_operand" "")))]
4688 "TARGET_EITHER"
b11cae9e 4689 ""
cffb2a26 4690)
4691
4692(define_insn "*arm_one_cmplsi2"
d952d547 4693 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
4694 (not:SI (match_operand:SI 1 "s_register_operand" "l,r")))]
25f905c2 4695 "TARGET_32BIT"
cffb2a26 4696 "mvn%?\\t%0, %1"
d2a518d1 4697 [(set_attr "predicable" "yes")
d952d547 4698 (set_attr "predicable_short_it" "yes,no")
4699 (set_attr "arch" "t2,*")
4700 (set_attr "length" "4")
1aed5204 4701 (set_attr "type" "mvn_reg")]
cffb2a26 4702)
4703
f7fbdd4a 4704(define_insn "*notsi_compare0"
bd5b4116 4705 [(set (reg:CC_NOOV CC_REGNUM)
9c08d1fa 4706 (compare:CC_NOOV (not:SI (match_operand:SI 1 "s_register_operand" "r"))
4707 (const_int 0)))
4708 (set (match_operand:SI 0 "s_register_operand" "=r")
4709 (not:SI (match_dup 1)))]
25f905c2 4710 "TARGET_32BIT"
4711 "mvn%.\\t%0, %1"
d2a518d1 4712 [(set_attr "conds" "set")
1aed5204 4713 (set_attr "type" "mvn_reg")]
cffb2a26 4714)
9c08d1fa 4715
f7fbdd4a 4716(define_insn "*notsi_compare0_scratch"
bd5b4116 4717 [(set (reg:CC_NOOV CC_REGNUM)
9c08d1fa 4718 (compare:CC_NOOV (not:SI (match_operand:SI 1 "s_register_operand" "r"))
4719 (const_int 0)))
4720 (clobber (match_scratch:SI 0 "=r"))]
25f905c2 4721 "TARGET_32BIT"
4722 "mvn%.\\t%0, %1"
d2a518d1 4723 [(set_attr "conds" "set")
1aed5204 4724 (set_attr "type" "mvn_reg")]
cffb2a26 4725)
b11cae9e 4726\f
4727;; Fixed <--> Floating conversion insns
4728
9b8516be 4729(define_expand "floatsihf2"
4730 [(set (match_operand:HF 0 "general_operand" "")
4731 (float:HF (match_operand:SI 1 "general_operand" "")))]
4732 "TARGET_EITHER"
4733 "
4734 {
4735 rtx op1 = gen_reg_rtx (SFmode);
4736 expand_float (op1, operands[1], 0);
4737 op1 = convert_to_mode (HFmode, op1, 0);
4738 emit_move_insn (operands[0], op1);
4739 DONE;
4740 }"
4741)
4742
4743(define_expand "floatdihf2"
4744 [(set (match_operand:HF 0 "general_operand" "")
4745 (float:HF (match_operand:DI 1 "general_operand" "")))]
4746 "TARGET_EITHER"
4747 "
4748 {
4749 rtx op1 = gen_reg_rtx (SFmode);
4750 expand_float (op1, operands[1], 0);
4751 op1 = convert_to_mode (HFmode, op1, 0);
4752 emit_move_insn (operands[0], op1);
4753 DONE;
4754 }"
4755)
4756
604f3a0a 4757(define_expand "floatsisf2"
4758 [(set (match_operand:SF 0 "s_register_operand" "")
4759 (float:SF (match_operand:SI 1 "s_register_operand" "")))]
25f905c2 4760 "TARGET_32BIT && TARGET_HARD_FLOAT"
604f3a0a 4761 "
604f3a0a 4762")
4763
604f3a0a 4764(define_expand "floatsidf2"
4765 [(set (match_operand:DF 0 "s_register_operand" "")
4766 (float:DF (match_operand:SI 1 "s_register_operand" "")))]
a50d7267 4767 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
604f3a0a 4768 "
604f3a0a 4769")
4770
9b8516be 4771(define_expand "fix_trunchfsi2"
4772 [(set (match_operand:SI 0 "general_operand" "")
4773 (fix:SI (fix:HF (match_operand:HF 1 "general_operand" ""))))]
4774 "TARGET_EITHER"
4775 "
4776 {
4777 rtx op1 = convert_to_mode (SFmode, operands[1], 0);
4778 expand_fix (operands[0], op1, 0);
4779 DONE;
4780 }"
4781)
4782
4783(define_expand "fix_trunchfdi2"
4784 [(set (match_operand:DI 0 "general_operand" "")
4785 (fix:DI (fix:HF (match_operand:HF 1 "general_operand" ""))))]
4786 "TARGET_EITHER"
4787 "
4788 {
4789 rtx op1 = convert_to_mode (SFmode, operands[1], 0);
4790 expand_fix (operands[0], op1, 0);
4791 DONE;
4792 }"
4793)
4794
604f3a0a 4795(define_expand "fix_truncsfsi2"
4796 [(set (match_operand:SI 0 "s_register_operand" "")
a33d5c9c 4797 (fix:SI (fix:SF (match_operand:SF 1 "s_register_operand" ""))))]
25f905c2 4798 "TARGET_32BIT && TARGET_HARD_FLOAT"
604f3a0a 4799 "
604f3a0a 4800")
4801
604f3a0a 4802(define_expand "fix_truncdfsi2"
4803 [(set (match_operand:SI 0 "s_register_operand" "")
a33d5c9c 4804 (fix:SI (fix:DF (match_operand:DF 1 "s_register_operand" ""))))]
a50d7267 4805 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
604f3a0a 4806 "
604f3a0a 4807")
4808
f544c6d2 4809;; Truncation insns
b11cae9e 4810
604f3a0a 4811(define_expand "truncdfsf2"
4812 [(set (match_operand:SF 0 "s_register_operand" "")
4813 (float_truncate:SF
4814 (match_operand:DF 1 "s_register_operand" "")))]
a50d7267 4815 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
604f3a0a 4816 ""
4817)
9b8516be 4818
4819/* DFmode -> HFmode conversions have to go through SFmode. */
4820(define_expand "truncdfhf2"
4821 [(set (match_operand:HF 0 "general_operand" "")
4822 (float_truncate:HF
4823 (match_operand:DF 1 "general_operand" "")))]
4824 "TARGET_EITHER"
4825 "
4826 {
4827 rtx op1;
4828 op1 = convert_to_mode (SFmode, operands[1], 0);
4829 op1 = convert_to_mode (HFmode, op1, 0);
4830 emit_move_insn (operands[0], op1);
4831 DONE;
4832 }"
4833)
b11cae9e 4834\f
9c08d1fa 4835;; Zero and sign extension instructions.
b11cae9e 4836
848e66ac 4837(define_insn "zero_extend<mode>di2"
6aa689e8 4838 [(set (match_operand:DI 0 "s_register_operand" "=w,r,?r,w")
6d97728e 4839 (zero_extend:DI (match_operand:QHSI 1 "<qhs_zextenddi_op>"
4840 "<qhs_zextenddi_cstr>")))]
848e66ac 4841 "TARGET_32BIT <qhs_zextenddi_cond>"
4842 "#"
6aa689e8 4843 [(set_attr "length" "8,4,8,8")
b6779ddc 4844 (set_attr "arch" "neon_for_64bits,*,*,avoid_neon_for_64bits")
848e66ac 4845 (set_attr "ce_count" "2")
efbb5e19 4846 (set_attr "predicable" "yes")
4847 (set_attr "type" "multiple,mov_reg,multiple,multiple")]
25f905c2 4848)
4849
848e66ac 4850(define_insn "extend<mode>di2"
6aa689e8 4851 [(set (match_operand:DI 0 "s_register_operand" "=w,r,?r,?r,w")
63d204a8 4852 (sign_extend:DI (match_operand:QHSI 1 "<qhs_extenddi_op>"
4853 "<qhs_extenddi_cstr>")))]
848e66ac 4854 "TARGET_32BIT <qhs_sextenddi_cond>"
4855 "#"
6aa689e8 4856 [(set_attr "length" "8,4,8,8,8")
848e66ac 4857 (set_attr "ce_count" "2")
4858 (set_attr "shift" "1")
8012d2c2 4859 (set_attr "predicable" "yes")
1b7da4ac 4860 (set_attr "arch" "neon_for_64bits,*,a,t,avoid_neon_for_64bits")
4861 (set_attr "type" "multiple,mov_reg,multiple,multiple,multiple")]
0d66636f 4862)
9c08d1fa 4863
848e66ac 4864;; Splits for all extensions to DImode
4865(define_split
4866 [(set (match_operand:DI 0 "s_register_operand" "")
4867 (zero_extend:DI (match_operand 1 "nonimmediate_operand" "")))]
6aa689e8 4868 "TARGET_32BIT && reload_completed && !IS_VFP_REGNUM (REGNO (operands[0]))"
848e66ac 4869 [(set (match_dup 0) (match_dup 1))]
4870{
848e66ac 4871 rtx lo_part = gen_lowpart (SImode, operands[0]);
3754d046 4872 machine_mode src_mode = GET_MODE (operands[1]);
848e66ac 4873
4874 if (REG_P (operands[0])
4875 && !reg_overlap_mentioned_p (operands[0], operands[1]))
4876 emit_clobber (operands[0]);
4877 if (!REG_P (lo_part) || src_mode != SImode
4878 || !rtx_equal_p (lo_part, operands[1]))
4879 {
4880 if (src_mode == SImode)
4881 emit_move_insn (lo_part, operands[1]);
4882 else
d1f9b275 4883 emit_insn (gen_rtx_SET (lo_part,
848e66ac 4884 gen_rtx_ZERO_EXTEND (SImode, operands[1])));
4885 operands[1] = lo_part;
4886 }
4887 operands[0] = gen_highpart (SImode, operands[0]);
4888 operands[1] = const0_rtx;
4889})
9c08d1fa 4890
848e66ac 4891(define_split
25f905c2 4892 [(set (match_operand:DI 0 "s_register_operand" "")
848e66ac 4893 (sign_extend:DI (match_operand 1 "nonimmediate_operand" "")))]
6aa689e8 4894 "TARGET_32BIT && reload_completed && !IS_VFP_REGNUM (REGNO (operands[0]))"
848e66ac 4895 [(set (match_dup 0) (ashiftrt:SI (match_dup 1) (const_int 31)))]
4896{
4897 rtx lo_part = gen_lowpart (SImode, operands[0]);
3754d046 4898 machine_mode src_mode = GET_MODE (operands[1]);
25f905c2 4899
848e66ac 4900 if (REG_P (operands[0])
4901 && !reg_overlap_mentioned_p (operands[0], operands[1]))
4902 emit_clobber (operands[0]);
4903
4904 if (!REG_P (lo_part) || src_mode != SImode
4905 || !rtx_equal_p (lo_part, operands[1]))
4906 {
4907 if (src_mode == SImode)
4908 emit_move_insn (lo_part, operands[1]);
4909 else
d1f9b275 4910 emit_insn (gen_rtx_SET (lo_part,
848e66ac 4911 gen_rtx_SIGN_EXTEND (SImode, operands[1])));
4912 operands[1] = lo_part;
4913 }
4914 operands[0] = gen_highpart (SImode, operands[0]);
4915})
9c08d1fa 4916
4917(define_expand "zero_extendhisi2"
ef51b8e1 4918 [(set (match_operand:SI 0 "s_register_operand" "")
4919 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
cffb2a26 4920 "TARGET_EITHER"
ef51b8e1 4921{
4922 if (TARGET_ARM && !arm_arch4 && MEM_P (operands[1]))
f7fbdd4a 4923 {
ef51b8e1 4924 emit_insn (gen_movhi_bytes (operands[0], operands[1]));
4925 DONE;
25f7a26e 4926 }
ef51b8e1 4927 if (!arm_arch6 && !MEM_P (operands[1]))
4928 {
4929 rtx t = gen_lowpart (SImode, operands[1]);
4930 rtx tmp = gen_reg_rtx (SImode);
4931 emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (16)));
4932 emit_insn (gen_lshrsi3 (operands[0], tmp, GEN_INT (16)));
4933 DONE;
4934 }
4935})
9c08d1fa 4936
ef51b8e1 4937(define_split
b146458f 4938 [(set (match_operand:SI 0 "s_register_operand" "")
4939 (zero_extend:SI (match_operand:HI 1 "s_register_operand" "")))]
ef51b8e1 4940 "!TARGET_THUMB2 && !arm_arch6"
4941 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
4942 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 16)))]
4943{
4944 operands[2] = gen_lowpart (SImode, operands[1]);
4945})
4946
cffb2a26 4947(define_insn "*arm_zero_extendhisi2"
ef51b8e1 4948 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4949 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
a2cd141b 4950 "TARGET_ARM && arm_arch4 && !arm_arch6"
ef51b8e1 4951 "@
4952 #
4953 ldr%(h%)\\t%0, %1"
d82e788e 4954 [(set_attr "type" "alu_shift_reg,load_byte")
848e66ac 4955 (set_attr "predicable" "yes")]
cffb2a26 4956)
f7fbdd4a 4957
a2cd141b 4958(define_insn "*arm_zero_extendhisi2_v6"
4959 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
e3f4ccee 4960 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,Uh")))]
a2cd141b 4961 "TARGET_ARM && arm_arch6"
4962 "@
4963 uxth%?\\t%0, %1
25f905c2 4964 ldr%(h%)\\t%0, %1"
65f68e55 4965 [(set_attr "predicable" "yes")
6b6abc9c 4966 (set_attr "type" "extend,load_byte")]
a2cd141b 4967)
4968
4969(define_insn "*arm_zero_extendhisi2addsi"
4970 [(set (match_operand:SI 0 "s_register_operand" "=r")
4971 (plus:SI (zero_extend:SI (match_operand:HI 1 "s_register_operand" "r"))
4972 (match_operand:SI 2 "s_register_operand" "r")))]
25f905c2 4973 "TARGET_INT_SIMD"
a2cd141b 4974 "uxtah%?\\t%0, %2, %1"
d82e788e 4975 [(set_attr "type" "alu_shift_reg")
d952d547 4976 (set_attr "predicable" "yes")
4977 (set_attr "predicable_short_it" "no")]
a2cd141b 4978)
4979
87b22bf7 4980(define_expand "zero_extendqisi2"
cffb2a26 4981 [(set (match_operand:SI 0 "s_register_operand" "")
4982 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))]
4983 "TARGET_EITHER"
ef51b8e1 4984{
0438d37f 4985 if (TARGET_ARM && !arm_arch6 && !MEM_P (operands[1]))
87b22bf7 4986 {
ef51b8e1 4987 emit_insn (gen_andsi3 (operands[0],
4988 gen_lowpart (SImode, operands[1]),
4989 GEN_INT (255)));
4990 DONE;
4991 }
4992 if (!arm_arch6 && !MEM_P (operands[1]))
4993 {
4994 rtx t = gen_lowpart (SImode, operands[1]);
4995 rtx tmp = gen_reg_rtx (SImode);
4996 emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (24)));
4997 emit_insn (gen_lshrsi3 (operands[0], tmp, GEN_INT (24)));
4998 DONE;
4999 }
5000})
cffb2a26 5001
ef51b8e1 5002(define_split
b146458f 5003 [(set (match_operand:SI 0 "s_register_operand" "")
5004 (zero_extend:SI (match_operand:QI 1 "s_register_operand" "")))]
ef51b8e1 5005 "!arm_arch6"
5006 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 24)))
5007 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 24)))]
5008{
5009 operands[2] = simplify_gen_subreg (SImode, operands[1], QImode, 0);
5010 if (TARGET_ARM)
5011 {
5012 emit_insn (gen_andsi3 (operands[0], operands[2], GEN_INT (255)));
87b22bf7 5013 DONE;
5014 }
ef51b8e1 5015})
9c08d1fa 5016
cffb2a26 5017(define_insn "*arm_zero_extendqisi2"
ef51b8e1 5018 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5019 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
a2cd141b 5020 "TARGET_ARM && !arm_arch6"
ef51b8e1 5021 "@
5022 #
5023 ldr%(b%)\\t%0, %1\\t%@ zero_extendqisi2"
5024 [(set_attr "length" "8,4")
d82e788e 5025 (set_attr "type" "alu_shift_reg,load_byte")
848e66ac 5026 (set_attr "predicable" "yes")]
cffb2a26 5027)
87b22bf7 5028
a2cd141b 5029(define_insn "*arm_zero_extendqisi2_v6"
5030 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
e3f4ccee 5031 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "r,Uh")))]
a2cd141b 5032 "TARGET_ARM && arm_arch6"
5033 "@
25f905c2 5034 uxtb%(%)\\t%0, %1
5035 ldr%(b%)\\t%0, %1\\t%@ zero_extendqisi2"
6b6abc9c 5036 [(set_attr "type" "extend,load_byte")
848e66ac 5037 (set_attr "predicable" "yes")]
a2cd141b 5038)
5039
5040(define_insn "*arm_zero_extendqisi2addsi"
5041 [(set (match_operand:SI 0 "s_register_operand" "=r")
5042 (plus:SI (zero_extend:SI (match_operand:QI 1 "s_register_operand" "r"))
5043 (match_operand:SI 2 "s_register_operand" "r")))]
25f905c2 5044 "TARGET_INT_SIMD"
a2cd141b 5045 "uxtab%?\\t%0, %2, %1"
5046 [(set_attr "predicable" "yes")
d952d547 5047 (set_attr "predicable_short_it" "no")
d82e788e 5048 (set_attr "type" "alu_shift_reg")]
a2cd141b 5049)
5050
87b22bf7 5051(define_split
5052 [(set (match_operand:SI 0 "s_register_operand" "")
5053 (zero_extend:SI (subreg:QI (match_operand:SI 1 "" "") 0)))
5054 (clobber (match_operand:SI 2 "s_register_operand" ""))]
0438d37f 5055 "TARGET_32BIT && (!MEM_P (operands[1])) && ! BYTES_BIG_ENDIAN"
87b22bf7 5056 [(set (match_dup 2) (match_dup 1))
5057 (set (match_dup 0) (and:SI (match_dup 2) (const_int 255)))]
cffb2a26 5058 ""
5059)
9c08d1fa 5060
8a4d25d6 5061(define_split
5062 [(set (match_operand:SI 0 "s_register_operand" "")
5063 (zero_extend:SI (subreg:QI (match_operand:SI 1 "" "") 3)))
5064 (clobber (match_operand:SI 2 "s_register_operand" ""))]
0438d37f 5065 "TARGET_32BIT && (!MEM_P (operands[1])) && BYTES_BIG_ENDIAN"
8a4d25d6 5066 [(set (match_dup 2) (match_dup 1))
5067 (set (match_dup 0) (and:SI (match_dup 2) (const_int 255)))]
5068 ""
5069)
5070
1c274529 5071
5072(define_split
5073 [(set (match_operand:SI 0 "s_register_operand" "")
9b23f0a7 5074 (IOR_XOR:SI (and:SI (ashift:SI
1c274529 5075 (match_operand:SI 1 "s_register_operand" "")
5076 (match_operand:SI 2 "const_int_operand" ""))
5077 (match_operand:SI 3 "const_int_operand" ""))
5078 (zero_extend:SI
5079 (match_operator 5 "subreg_lowpart_operator"
5080 [(match_operand:SI 4 "s_register_operand" "")]))))]
5081 "TARGET_32BIT
63787642 5082 && ((unsigned HOST_WIDE_INT) INTVAL (operands[3])
1c274529 5083 == (GET_MODE_MASK (GET_MODE (operands[5]))
5084 & (GET_MODE_MASK (GET_MODE (operands[5]))
5085 << (INTVAL (operands[2])))))"
9b23f0a7 5086 [(set (match_dup 0) (IOR_XOR:SI (ashift:SI (match_dup 1) (match_dup 2))
1c274529 5087 (match_dup 4)))
5088 (set (match_dup 0) (zero_extend:SI (match_dup 5)))]
5089 "operands[5] = gen_lowpart (GET_MODE (operands[5]), operands[0]);"
5090)
5091
f7fbdd4a 5092(define_insn "*compareqi_eq0"
bd5b4116 5093 [(set (reg:CC_Z CC_REGNUM)
206ee9a2 5094 (compare:CC_Z (match_operand:QI 0 "s_register_operand" "r")
87b22bf7 5095 (const_int 0)))]
25f905c2 5096 "TARGET_32BIT"
596e5e8f 5097 "tst%?\\t%0, #255"
5098 [(set_attr "conds" "set")
d952d547 5099 (set_attr "predicable" "yes")
1b7da4ac 5100 (set_attr "predicable_short_it" "no")
5101 (set_attr "type" "logic_imm")]
cffb2a26 5102)
b11cae9e 5103
b11cae9e 5104(define_expand "extendhisi2"
ef51b8e1 5105 [(set (match_operand:SI 0 "s_register_operand" "")
5106 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
cffb2a26 5107 "TARGET_EITHER"
ef51b8e1 5108{
5109 if (TARGET_THUMB1)
5110 {
5111 emit_insn (gen_thumb1_extendhisi2 (operands[0], operands[1]));
5112 DONE;
5113 }
5114 if (MEM_P (operands[1]) && TARGET_ARM && !arm_arch4)
5115 {
5116 emit_insn (gen_extendhisi2_mem (operands[0], operands[1]));
5117 DONE;
5118 }
ed29c566 5119
ef51b8e1 5120 if (!arm_arch6 && !MEM_P (operands[1]))
5121 {
5122 rtx t = gen_lowpart (SImode, operands[1]);
5123 rtx tmp = gen_reg_rtx (SImode);
5124 emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (16)));
5125 emit_insn (gen_ashrsi3 (operands[0], tmp, GEN_INT (16)));
5126 DONE;
5127 }
5128})
cffb2a26 5129
ef51b8e1 5130(define_split
5131 [(parallel
5132 [(set (match_operand:SI 0 "register_operand" "")
5133 (sign_extend:SI (match_operand:HI 1 "register_operand" "")))
5134 (clobber (match_scratch:SI 2 ""))])]
5135 "!arm_arch6"
5136 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
5137 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 16)))]
5138{
5139 operands[2] = simplify_gen_subreg (SImode, operands[1], HImode, 0);
5140})
25f7a26e 5141
25f905c2 5142;; This pattern will only be used when ldsh is not available
25f7a26e 5143(define_expand "extendhisi2_mem"
eab14235 5144 [(set (match_dup 2) (zero_extend:SI (match_operand:HI 1 "" "")))
25f7a26e 5145 (set (match_dup 3)
eab14235 5146 (zero_extend:SI (match_dup 7)))
25f7a26e 5147 (set (match_dup 6) (ashift:SI (match_dup 4) (const_int 24)))
5148 (set (match_operand:SI 0 "" "")
5149 (ior:SI (ashiftrt:SI (match_dup 6) (const_int 16)) (match_dup 5)))]
cffb2a26 5150 "TARGET_ARM"
25f7a26e 5151 "
215b30b3 5152 {
5153 rtx mem1, mem2;
5154 rtx addr = copy_to_mode_reg (SImode, XEXP (operands[1], 0));
5155
788fcce0 5156 mem1 = change_address (operands[1], QImode, addr);
29c05e22 5157 mem2 = change_address (operands[1], QImode,
5158 plus_constant (Pmode, addr, 1));
215b30b3 5159 operands[0] = gen_lowpart (SImode, operands[0]);
5160 operands[1] = mem1;
5161 operands[2] = gen_reg_rtx (SImode);
5162 operands[3] = gen_reg_rtx (SImode);
5163 operands[6] = gen_reg_rtx (SImode);
5164 operands[7] = mem2;
25f7a26e 5165
215b30b3 5166 if (BYTES_BIG_ENDIAN)
5167 {
5168 operands[4] = operands[2];
5169 operands[5] = operands[3];
5170 }
5171 else
5172 {
5173 operands[4] = operands[3];
5174 operands[5] = operands[2];
5175 }
5176 }"
5177)
b11cae9e 5178
ef51b8e1 5179(define_split
5180 [(set (match_operand:SI 0 "register_operand" "")
5181 (sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
5182 "!arm_arch6"
5183 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
5184 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 16)))]
5185{
5186 operands[2] = simplify_gen_subreg (SImode, operands[1], HImode, 0);
5187})
5188
a2cd141b 5189(define_insn "*arm_extendhisi2"
ef51b8e1 5190 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
e3f4ccee 5191 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,Uh")))]
a2cd141b 5192 "TARGET_ARM && arm_arch4 && !arm_arch6"
ef51b8e1 5193 "@
5194 #
5195 ldr%(sh%)\\t%0, %1"
5196 [(set_attr "length" "8,4")
d82e788e 5197 (set_attr "type" "alu_shift_reg,load_byte")
e3f4ccee 5198 (set_attr "predicable" "yes")]
cffb2a26 5199)
f7fbdd4a 5200
25f905c2 5201;; ??? Check Thumb-2 pool range
a2cd141b 5202(define_insn "*arm_extendhisi2_v6"
5203 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
e3f4ccee 5204 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,Uh")))]
25f905c2 5205 "TARGET_32BIT && arm_arch6"
a2cd141b 5206 "@
5207 sxth%?\\t%0, %1
25f905c2 5208 ldr%(sh%)\\t%0, %1"
6b6abc9c 5209 [(set_attr "type" "extend,load_byte")
a2cd141b 5210 (set_attr "predicable" "yes")
e3f4ccee 5211 (set_attr "predicable_short_it" "no")]
a2cd141b 5212)
5213
5214(define_insn "*arm_extendhisi2addsi"
5215 [(set (match_operand:SI 0 "s_register_operand" "=r")
5216 (plus:SI (sign_extend:SI (match_operand:HI 1 "s_register_operand" "r"))
5217 (match_operand:SI 2 "s_register_operand" "r")))]
25f905c2 5218 "TARGET_INT_SIMD"
a2cd141b 5219 "sxtah%?\\t%0, %2, %1"
1b7da4ac 5220 [(set_attr "type" "alu_shift_reg")]
a2cd141b 5221)
5222
c8f69309 5223(define_expand "extendqihi2"
5224 [(set (match_dup 2)
bed7d9a5 5225 (ashift:SI (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "")
c8f69309 5226 (const_int 24)))
9c08d1fa 5227 (set (match_operand:HI 0 "s_register_operand" "")
c8f69309 5228 (ashiftrt:SI (match_dup 2)
5229 (const_int 24)))]
cffb2a26 5230 "TARGET_ARM"
c8f69309 5231 "
215b30b3 5232 {
0438d37f 5233 if (arm_arch4 && MEM_P (operands[1]))
215b30b3 5234 {
d1f9b275 5235 emit_insn (gen_rtx_SET (operands[0],
215b30b3 5236 gen_rtx_SIGN_EXTEND (HImode, operands[1])));
5237 DONE;
5238 }
5239 if (!s_register_operand (operands[1], QImode))
5240 operands[1] = copy_to_mode_reg (QImode, operands[1]);
5241 operands[0] = gen_lowpart (SImode, operands[0]);
5242 operands[1] = gen_lowpart (SImode, operands[1]);
5243 operands[2] = gen_reg_rtx (SImode);
5244 }"
5245)
f7fbdd4a 5246
25f905c2 5247(define_insn "*arm_extendqihi_insn"
b4e8a300 5248 [(set (match_operand:HI 0 "s_register_operand" "=r")
bed7d9a5 5249 (sign_extend:HI (match_operand:QI 1 "arm_extendqisi_mem_op" "Uq")))]
cffb2a26 5250 "TARGET_ARM && arm_arch4"
25f905c2 5251 "ldr%(sb%)\\t%0, %1"
a2cd141b 5252 [(set_attr "type" "load_byte")
e3f4ccee 5253 (set_attr "predicable" "yes")]
cffb2a26 5254)
3fc2009e 5255
b11cae9e 5256(define_expand "extendqisi2"
ef51b8e1 5257 [(set (match_operand:SI 0 "s_register_operand" "")
5258 (sign_extend:SI (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "")))]
cffb2a26 5259 "TARGET_EITHER"
ef51b8e1 5260{
5261 if (!arm_arch4 && MEM_P (operands[1]))
5262 operands[1] = copy_to_mode_reg (QImode, operands[1]);
a2cd141b 5263
ef51b8e1 5264 if (!arm_arch6 && !MEM_P (operands[1]))
5265 {
5266 rtx t = gen_lowpart (SImode, operands[1]);
5267 rtx tmp = gen_reg_rtx (SImode);
5268 emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (24)));
5269 emit_insn (gen_ashrsi3 (operands[0], tmp, GEN_INT (24)));
5270 DONE;
5271 }
5272})
a2cd141b 5273
ef51b8e1 5274(define_split
5275 [(set (match_operand:SI 0 "register_operand" "")
5276 (sign_extend:SI (match_operand:QI 1 "register_operand" "")))]
5277 "!arm_arch6"
5278 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 24)))
5279 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 24)))]
5280{
5281 operands[2] = simplify_gen_subreg (SImode, operands[1], QImode, 0);
5282})
f7fbdd4a 5283
a2cd141b 5284(define_insn "*arm_extendqisi"
ef51b8e1 5285 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5286 (sign_extend:SI (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "r,Uq")))]
a2cd141b 5287 "TARGET_ARM && arm_arch4 && !arm_arch6"
ef51b8e1 5288 "@
5289 #
5290 ldr%(sb%)\\t%0, %1"
5291 [(set_attr "length" "8,4")
d82e788e 5292 (set_attr "type" "alu_shift_reg,load_byte")
e3f4ccee 5293 (set_attr "predicable" "yes")]
cffb2a26 5294)
3fc2009e 5295
a2cd141b 5296(define_insn "*arm_extendqisi_v6"
5297 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
bed7d9a5 5298 (sign_extend:SI
5299 (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "r,Uq")))]
a2cd141b 5300 "TARGET_ARM && arm_arch6"
b4e8a300 5301 "@
5302 sxtb%?\\t%0, %1
25f905c2 5303 ldr%(sb%)\\t%0, %1"
6b6abc9c 5304 [(set_attr "type" "extend,load_byte")
e3f4ccee 5305 (set_attr "predicable" "yes")]
a2cd141b 5306)
5307
5308(define_insn "*arm_extendqisi2addsi"
5309 [(set (match_operand:SI 0 "s_register_operand" "=r")
5310 (plus:SI (sign_extend:SI (match_operand:QI 1 "s_register_operand" "r"))
5311 (match_operand:SI 2 "s_register_operand" "r")))]
25f905c2 5312 "TARGET_INT_SIMD"
a2cd141b 5313 "sxtab%?\\t%0, %2, %1"
d82e788e 5314 [(set_attr "type" "alu_shift_reg")
d952d547 5315 (set_attr "predicable" "yes")
5316 (set_attr "predicable_short_it" "no")]
a2cd141b 5317)
5318
caedf871 5319(define_expand "extendsfdf2"
5320 [(set (match_operand:DF 0 "s_register_operand" "")
5321 (float_extend:DF (match_operand:SF 1 "s_register_operand" "")))]
a50d7267 5322 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
caedf871 5323 ""
5324)
9b8516be 5325
5326/* HFmode -> DFmode conversions have to go through SFmode. */
5327(define_expand "extendhfdf2"
5328 [(set (match_operand:DF 0 "general_operand" "")
5329 (float_extend:DF (match_operand:HF 1 "general_operand" "")))]
5330 "TARGET_EITHER"
5331 "
5332 {
5333 rtx op1;
5334 op1 = convert_to_mode (SFmode, operands[1], 0);
5335 op1 = convert_to_mode (DFmode, op1, 0);
5336 emit_insn (gen_movdf (operands[0], op1));
5337 DONE;
5338 }"
5339)
b11cae9e 5340\f
5341;; Move insns (including loads and stores)
5342
5343;; XXX Just some ideas about movti.
9c08d1fa 5344;; I don't think these are a good idea on the arm, there just aren't enough
5345;; registers
b11cae9e 5346;;(define_expand "loadti"
9c08d1fa 5347;; [(set (match_operand:TI 0 "s_register_operand" "")
b11cae9e 5348;; (mem:TI (match_operand:SI 1 "address_operand" "")))]
5349;; "" "")
5350
5351;;(define_expand "storeti"
5352;; [(set (mem:TI (match_operand:TI 0 "address_operand" ""))
9c08d1fa 5353;; (match_operand:TI 1 "s_register_operand" ""))]
b11cae9e 5354;; "" "")
5355
5356;;(define_expand "movti"
5357;; [(set (match_operand:TI 0 "general_operand" "")
5358;; (match_operand:TI 1 "general_operand" ""))]
5359;; ""
5360;; "
5361;;{
5362;; rtx insn;
5363;;
0438d37f 5364;; if (MEM_P (operands[0]) && MEM_P (operands[1]))
b11cae9e 5365;; operands[1] = copy_to_reg (operands[1]);
0438d37f 5366;; if (MEM_P (operands[0]))
b11cae9e 5367;; insn = gen_storeti (XEXP (operands[0], 0), operands[1]);
0438d37f 5368;; else if (MEM_P (operands[1]))
b11cae9e 5369;; insn = gen_loadti (operands[0], XEXP (operands[1], 0));
5370;; else
5371;; FAIL;
5372;;
5373;; emit_insn (insn);
5374;; DONE;
5375;;}")
5376
a2f10574 5377;; Recognize garbage generated above.
b11cae9e 5378
5379;;(define_insn ""
5380;; [(set (match_operand:TI 0 "general_operand" "=r,r,r,<,>,m")
5381;; (match_operand:TI 1 "general_operand" "<,>,m,r,r,r"))]
5382;; ""
5383;; "*
5384;; {
5385;; register mem = (which_alternative < 3);
0d66636f 5386;; register const char *template;
b11cae9e 5387;;
5388;; operands[mem] = XEXP (operands[mem], 0);
5389;; switch (which_alternative)
5390;; {
5391;; case 0: template = \"ldmdb\\t%1!, %M0\"; break;
5392;; case 1: template = \"ldmia\\t%1!, %M0\"; break;
5393;; case 2: template = \"ldmia\\t%1, %M0\"; break;
5394;; case 3: template = \"stmdb\\t%0!, %M1\"; break;
5395;; case 4: template = \"stmia\\t%0!, %M1\"; break;
5396;; case 5: template = \"stmia\\t%0, %M1\"; break;
5397;; }
e2348bcb 5398;; output_asm_insn (template, operands);
5399;; return \"\";
b11cae9e 5400;; }")
5401
cffb2a26 5402(define_expand "movdi"
5403 [(set (match_operand:DI 0 "general_operand" "")
5404 (match_operand:DI 1 "general_operand" ""))]
5405 "TARGET_EITHER"
5406 "
e1ba4a27 5407 if (can_create_pseudo_p ())
cffb2a26 5408 {
0438d37f 5409 if (!REG_P (operands[0]))
b2778788 5410 operands[1] = force_reg (DImode, operands[1]);
cffb2a26 5411 }
5412 "
5413)
b11cae9e 5414
cffb2a26 5415(define_insn "*arm_movdi"
353cf59a 5416 [(set (match_operand:DI 0 "nonimmediate_di_operand" "=r, r, r, q, m")
5417 (match_operand:DI 1 "di_operand" "rDa,Db,Dc,mi,q"))]
cde1623a 5418 "TARGET_32BIT
b805622c 5419 && !(TARGET_HARD_FLOAT && TARGET_VFP)
b2778788 5420 && !TARGET_IWMMXT
5421 && ( register_operand (operands[0], DImode)
5422 || register_operand (operands[1], DImode))"
b11cae9e 5423 "*
d51f92df 5424 switch (which_alternative)
5425 {
5426 case 0:
5427 case 1:
5428 case 2:
5429 return \"#\";
5430 default:
26ff80c0 5431 return output_move_double (operands, true, NULL);
d51f92df 5432 }
cffb2a26 5433 "
359a6e9f 5434 [(set_attr "length" "8,12,16,8,8")
1b7da4ac 5435 (set_attr "type" "multiple,multiple,multiple,load2,store2")
cde1623a 5436 (set_attr "arm_pool_range" "*,*,*,1020,*")
8848d797 5437 (set_attr "arm_neg_pool_range" "*,*,*,1004,*")
42e1de19 5438 (set_attr "thumb2_pool_range" "*,*,*,4094,*")
cde1623a 5439 (set_attr "thumb2_neg_pool_range" "*,*,*,0,*")]
cffb2a26 5440)
5441
d51f92df 5442(define_split
5443 [(set (match_operand:ANY64 0 "arm_general_register_operand" "")
e6dd3afa 5444 (match_operand:ANY64 1 "immediate_operand" ""))]
25f905c2 5445 "TARGET_32BIT
d51f92df 5446 && reload_completed
5447 && (arm_const_double_inline_cost (operands[1])
861033d5 5448 <= arm_max_const_double_inline_cost ())"
d51f92df 5449 [(const_int 0)]
5450 "
5451 arm_split_constant (SET, SImode, curr_insn,
5452 INTVAL (gen_lowpart (SImode, operands[1])),
5453 gen_lowpart (SImode, operands[0]), NULL_RTX, 0);
5454 arm_split_constant (SET, SImode, curr_insn,
5455 INTVAL (gen_highpart_mode (SImode,
5456 GET_MODE (operands[0]),
5457 operands[1])),
5458 gen_highpart (SImode, operands[0]), NULL_RTX, 0);
5459 DONE;
5460 "
5461)
5462
e5ba9289 5463; If optimizing for size, or if we have load delay slots, then
5464; we want to split the constant into two separate operations.
5465; In both cases this may split a trivial part into a single data op
5466; leaving a single complex constant to load. We can also get longer
5467; offsets in a LDR which means we get better chances of sharing the pool
5468; entries. Finally, we can normally do a better job of scheduling
5469; LDR instructions than we can with LDM.
5470; This pattern will only match if the one above did not.
5471(define_split
5472 [(set (match_operand:ANY64 0 "arm_general_register_operand" "")
5473 (match_operand:ANY64 1 "const_double_operand" ""))]
5474 "TARGET_ARM && reload_completed
5475 && arm_const_double_by_parts (operands[1])"
5476 [(set (match_dup 0) (match_dup 1))
5477 (set (match_dup 2) (match_dup 3))]
5478 "
5479 operands[2] = gen_highpart (SImode, operands[0]);
5480 operands[3] = gen_highpart_mode (SImode, GET_MODE (operands[0]),
5481 operands[1]);
5482 operands[0] = gen_lowpart (SImode, operands[0]);
5483 operands[1] = gen_lowpart (SImode, operands[1]);
5484 "
5485)
5486
d51f92df 5487(define_split
5488 [(set (match_operand:ANY64 0 "arm_general_register_operand" "")
5489 (match_operand:ANY64 1 "arm_general_register_operand" ""))]
5490 "TARGET_EITHER && reload_completed"
5491 [(set (match_dup 0) (match_dup 1))
5492 (set (match_dup 2) (match_dup 3))]
5493 "
5494 operands[2] = gen_highpart (SImode, operands[0]);
5495 operands[3] = gen_highpart (SImode, operands[1]);
5496 operands[0] = gen_lowpart (SImode, operands[0]);
5497 operands[1] = gen_lowpart (SImode, operands[1]);
5498
5499 /* Handle a partial overlap. */
5500 if (rtx_equal_p (operands[0], operands[3]))
5501 {
5502 rtx tmp0 = operands[0];
5503 rtx tmp1 = operands[1];
5504
5505 operands[0] = operands[2];
5506 operands[1] = operands[3];
5507 operands[2] = tmp0;
5508 operands[3] = tmp1;
5509 }
5510 "
5511)
5512
a8a3b539 5513;; We can't actually do base+index doubleword loads if the index and
5514;; destination overlap. Split here so that we at least have chance to
5515;; schedule.
5516(define_split
5517 [(set (match_operand:DI 0 "s_register_operand" "")
5518 (mem:DI (plus:SI (match_operand:SI 1 "s_register_operand" "")
5519 (match_operand:SI 2 "s_register_operand" ""))))]
5520 "TARGET_LDRD
5521 && reg_overlap_mentioned_p (operands[0], operands[1])
5522 && reg_overlap_mentioned_p (operands[0], operands[2])"
5523 [(set (match_dup 4)
5524 (plus:SI (match_dup 1)
5525 (match_dup 2)))
5526 (set (match_dup 0)
5527 (mem:DI (match_dup 4)))]
5528 "
5529 operands[4] = gen_rtx_REG (SImode, REGNO(operands[0]));
5530 "
5531)
5532
9c08d1fa 5533(define_expand "movsi"
5534 [(set (match_operand:SI 0 "general_operand" "")
5535 (match_operand:SI 1 "general_operand" ""))]
cffb2a26 5536 "TARGET_EITHER"
9c08d1fa 5537 "
befb0bac 5538 {
e348ff3e 5539 rtx base, offset, tmp;
5540
25f905c2 5541 if (TARGET_32BIT)
9c08d1fa 5542 {
674a8f0b 5543 /* Everything except mem = const or mem = mem can be done easily. */
0438d37f 5544 if (MEM_P (operands[0]))
cffb2a26 5545 operands[1] = force_reg (SImode, operands[1]);
a2cd141b 5546 if (arm_general_register_operand (operands[0], SImode)
0438d37f 5547 && CONST_INT_P (operands[1])
cffb2a26 5548 && !(const_ok_for_arm (INTVAL (operands[1]))
5549 || const_ok_for_arm (~INTVAL (operands[1]))))
5550 {
96f57e36 5551 arm_split_constant (SET, SImode, NULL_RTX,
5552 INTVAL (operands[1]), operands[0], NULL_RTX,
e1ba4a27 5553 optimize && can_create_pseudo_p ());
cffb2a26 5554 DONE;
5555 }
5556 }
25f905c2 5557 else /* TARGET_THUMB1... */
cffb2a26 5558 {
e1ba4a27 5559 if (can_create_pseudo_p ())
cffb2a26 5560 {
0438d37f 5561 if (!REG_P (operands[0]))
cffb2a26 5562 operands[1] = force_reg (SImode, operands[1]);
5563 }
9c08d1fa 5564 }
f655717d 5565
e348ff3e 5566 if (ARM_OFFSETS_MUST_BE_WITHIN_SECTIONS_P)
5567 {
5568 split_const (operands[1], &base, &offset);
5569 if (GET_CODE (base) == SYMBOL_REF
5570 && !offset_within_block_p (base, INTVAL (offset)))
5571 {
b308ddcf 5572 tmp = can_create_pseudo_p () ? gen_reg_rtx (SImode) : operands[0];
e348ff3e 5573 emit_move_insn (tmp, base);
5574 emit_insn (gen_addsi3 (operands[0], tmp, offset));
5575 DONE;
5576 }
5577 }
5578
f655717d 5579 /* Recognize the case where operand[1] is a reference to thread-local
5580 data and load its address to a register. */
5581 if (arm_tls_referenced_p (operands[1]))
5582 {
5583 rtx tmp = operands[1];
5584 rtx addend = NULL;
5585
5586 if (GET_CODE (tmp) == CONST && GET_CODE (XEXP (tmp, 0)) == PLUS)
5587 {
5588 addend = XEXP (XEXP (tmp, 0), 1);
5589 tmp = XEXP (XEXP (tmp, 0), 0);
5590 }
5591
5592 gcc_assert (GET_CODE (tmp) == SYMBOL_REF);
5593 gcc_assert (SYMBOL_REF_TLS_MODEL (tmp) != 0);
5594
e1ba4a27 5595 tmp = legitimize_tls_address (tmp,
5596 !can_create_pseudo_p () ? operands[0] : 0);
f655717d 5597 if (addend)
5598 {
5599 tmp = gen_rtx_PLUS (SImode, tmp, addend);
5600 tmp = force_operand (tmp, operands[0]);
5601 }
5602 operands[1] = tmp;
5603 }
5604 else if (flag_pic
5605 && (CONSTANT_P (operands[1])
5606 || symbol_mentioned_p (operands[1])
5607 || label_mentioned_p (operands[1])))
5608 operands[1] = legitimize_pic_address (operands[1], SImode,
e1ba4a27 5609 (!can_create_pseudo_p ()
5610 ? operands[0]
5611 : 0));
befb0bac 5612 }
215b30b3 5613 "
5614)
9c08d1fa 5615
d0e6a121 5616;; The ARM LO_SUM and HIGH are backwards - HIGH sets the low bits, and
5617;; LO_SUM adds in the high bits. Fortunately these are opaque operations
5618;; so this does not matter.
5619(define_insn "*arm_movt"
5620 [(set (match_operand:SI 0 "nonimmediate_operand" "=r")
5621 (lo_sum:SI (match_operand:SI 1 "nonimmediate_operand" "0")
5622 (match_operand:SI 2 "general_operand" "i")))]
c9b2ce40 5623 "arm_arch_thumb2"
d0e6a121 5624 "movt%?\t%0, #:upper16:%c2"
5625 [(set_attr "predicable" "yes")
d952d547 5626 (set_attr "predicable_short_it" "no")
1b7da4ac 5627 (set_attr "length" "4")
282b4c75 5628 (set_attr "type" "alu_sreg")]
d0e6a121 5629)
5630
cffb2a26 5631(define_insn "*arm_movsi_insn"
aaa37ad6 5632 [(set (match_operand:SI 0 "nonimmediate_operand" "=rk,r,r,r,rk,m")
110eae03 5633 (match_operand:SI 1 "general_operand" "rk, I,K,j,mi,rk"))]
755eb2b4 5634 "TARGET_ARM && ! TARGET_IWMMXT
a2cd141b 5635 && !(TARGET_HARD_FLOAT && TARGET_VFP)
cffb2a26 5636 && ( register_operand (operands[0], SImode)
5637 || register_operand (operands[1], SImode))"
f7fbdd4a 5638 "@
aaa37ad6 5639 mov%?\\t%0, %1
f7fbdd4a 5640 mov%?\\t%0, %1
5641 mvn%?\\t%0, #%B1
25f905c2 5642 movw%?\\t%0, %1
f7fbdd4a 5643 ldr%?\\t%0, %1
5644 str%?\\t%1, %0"
1aed5204 5645 [(set_attr "type" "mov_reg,mov_imm,mvn_imm,mov_imm,load1,store1")
0d66636f 5646 (set_attr "predicable" "yes")
aaa37ad6 5647 (set_attr "pool_range" "*,*,*,*,4096,*")
5648 (set_attr "neg_pool_range" "*,*,*,*,4084,*")]
cffb2a26 5649)
87b22bf7 5650
5651(define_split
a2cd141b 5652 [(set (match_operand:SI 0 "arm_general_register_operand" "")
87b22bf7 5653 (match_operand:SI 1 "const_int_operand" ""))]
25f905c2 5654 "TARGET_32BIT
215b30b3 5655 && (!(const_ok_for_arm (INTVAL (operands[1]))
5656 || const_ok_for_arm (~INTVAL (operands[1]))))"
87b22bf7 5657 [(clobber (const_int 0))]
5658 "
96f57e36 5659 arm_split_constant (SET, SImode, NULL_RTX,
5660 INTVAL (operands[1]), operands[0], NULL_RTX, 0);
87b22bf7 5661 DONE;
215b30b3 5662 "
5663)
9c08d1fa 5664
861033d5 5665;; A normal way to do (symbol + offset) requires three instructions at least
5666;; (depends on how big the offset is) as below:
5667;; movw r0, #:lower16:g
5668;; movw r0, #:upper16:g
5669;; adds r0, #4
5670;;
5671;; A better way would be:
5672;; movw r0, #:lower16:g+4
5673;; movw r0, #:upper16:g+4
5674;;
5675;; The limitation of this way is that the length of offset should be a 16-bit
5676;; signed value, because current assembler only supports REL type relocation for
5677;; such case. If the more powerful RELA type is supported in future, we should
5678;; update this pattern to go with better way.
5679(define_split
5680 [(set (match_operand:SI 0 "arm_general_register_operand" "")
5681 (const:SI (plus:SI (match_operand:SI 1 "general_operand" "")
5682 (match_operand:SI 2 "const_int_operand" ""))))]
5683 "TARGET_THUMB2
5684 && arm_disable_literal_pool
5685 && reload_completed
5686 && GET_CODE (operands[1]) == SYMBOL_REF"
5687 [(clobber (const_int 0))]
5688 "
5689 int offset = INTVAL (operands[2]);
5690
5691 if (offset < -0x8000 || offset > 0x7fff)
5692 {
5693 arm_emit_movpair (operands[0], operands[1]);
d1f9b275 5694 emit_insn (gen_rtx_SET (operands[0],
861033d5 5695 gen_rtx_PLUS (SImode, operands[0], operands[2])));
5696 }
5697 else
5698 {
5699 rtx op = gen_rtx_CONST (SImode,
5700 gen_rtx_PLUS (SImode, operands[1], operands[2]));
5701 arm_emit_movpair (operands[0], op);
5702 }
5703 "
5704)
5705
b8d5d078 5706;; Split symbol_refs at the later stage (after cprop), instead of generating
5707;; movt/movw pair directly at expand. Otherwise corresponding high_sum
5708;; and lo_sum would be merged back into memory load at cprop. However,
5709;; if the default is to prefer movt/movw rather than a load from the constant
5710;; pool, the performance is better.
5711(define_split
5712 [(set (match_operand:SI 0 "arm_general_register_operand" "")
5713 (match_operand:SI 1 "general_operand" ""))]
5714 "TARGET_32BIT
5715 && TARGET_USE_MOVT && GET_CODE (operands[1]) == SYMBOL_REF
5716 && !flag_pic && !target_word_relocations
5717 && !arm_tls_referenced_p (operands[1])"
5718 [(clobber (const_int 0))]
5719{
5720 arm_emit_movpair (operands[0], operands[1]);
5721 DONE;
5722})
5723
bc360af8 5724;; When generating pic, we need to load the symbol offset into a register.
5725;; So that the optimizer does not confuse this with a normal symbol load
5726;; we use an unspec. The offset will be loaded from a constant pool entry,
5727;; since that is the only type of relocation we can use.
cffb2a26 5728
bc360af8 5729;; Wrap calculation of the whole PIC address in a single pattern for the
5730;; benefit of optimizers, particularly, PRE and HOIST. Calculation of
5731;; a PIC address involves two loads from memory, so we want to CSE it
5732;; as often as possible.
5733;; This pattern will be split into one of the pic_load_addr_* patterns
5734;; and a move after GCSE optimizations.
5735;;
5736;; Note: Update arm.c: legitimize_pic_address() when changing this pattern.
5737(define_expand "calculate_pic_address"
94f8caca 5738 [(set (match_operand:SI 0 "register_operand" "")
5739 (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "")
5740 (unspec:SI [(match_operand:SI 2 "" "")]
5741 UNSPEC_PIC_SYM))))]
5742 "flag_pic"
5743)
5744
5745;; Split calculate_pic_address into pic_load_addr_* and a move.
5746(define_split
5747 [(set (match_operand:SI 0 "register_operand" "")
5748 (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "")
5749 (unspec:SI [(match_operand:SI 2 "" "")]
5750 UNSPEC_PIC_SYM))))]
5751 "flag_pic"
5752 [(set (match_dup 3) (unspec:SI [(match_dup 2)] UNSPEC_PIC_SYM))
5753 (set (match_dup 0) (mem:SI (plus:SI (match_dup 1) (match_dup 3))))]
5754 "operands[3] = can_create_pseudo_p () ? gen_reg_rtx (SImode) : operands[0];"
5755)
5756
350ccca5 5757;; operand1 is the memory address to go into
5758;; pic_load_addr_32bit.
5759;; operand2 is the PIC label to be emitted
5760;; from pic_add_dot_plus_eight.
5761;; We do this to allow hoisting of the entire insn.
5762(define_insn_and_split "pic_load_addr_unified"
5763 [(set (match_operand:SI 0 "s_register_operand" "=r,r,l")
5764 (unspec:SI [(match_operand:SI 1 "" "mX,mX,mX")
5765 (match_operand:SI 2 "" "")]
5766 UNSPEC_PIC_UNIFIED))]
5767 "flag_pic"
5768 "#"
5769 "&& reload_completed"
5770 [(set (match_dup 0) (unspec:SI [(match_dup 1)] UNSPEC_PIC_SYM))
5771 (set (match_dup 0) (unspec:SI [(match_dup 0) (match_dup 3)
5772 (match_dup 2)] UNSPEC_PIC_BASE))]
5773 "operands[3] = TARGET_THUMB ? GEN_INT (4) : GEN_INT (8);"
5774 [(set_attr "type" "load1,load1,load1")
42e1de19 5775 (set_attr "pool_range" "4096,4094,1022")
350ccca5 5776 (set_attr "neg_pool_range" "4084,0,0")
5777 (set_attr "arch" "a,t2,t1")
5778 (set_attr "length" "8,6,4")]
5779)
5780
67336bcf 5781;; The rather odd constraints on the following are to force reload to leave
5782;; the insn alone, and to force the minipool generation pass to then move
5783;; the GOT symbol to memory.
849170fd 5784
b3cd5f55 5785(define_insn "pic_load_addr_32bit"
849170fd 5786 [(set (match_operand:SI 0 "s_register_operand" "=r")
e1159bbe 5787 (unspec:SI [(match_operand:SI 1 "" "mX")] UNSPEC_PIC_SYM))]
b3cd5f55 5788 "TARGET_32BIT && flag_pic"
67336bcf 5789 "ldr%?\\t%0, %1"
a2cd141b 5790 [(set_attr "type" "load1")
42e1de19 5791 (set (attr "pool_range")
5792 (if_then_else (eq_attr "is_thumb" "no")
5793 (const_int 4096)
5794 (const_int 4094)))
b3cd5f55 5795 (set (attr "neg_pool_range")
5796 (if_then_else (eq_attr "is_thumb" "no")
5797 (const_int 4084)
5798 (const_int 0)))]
8c4d8060 5799)
5800
25f905c2 5801(define_insn "pic_load_addr_thumb1"
8c4d8060 5802 [(set (match_operand:SI 0 "s_register_operand" "=l")
e1159bbe 5803 (unspec:SI [(match_operand:SI 1 "" "mX")] UNSPEC_PIC_SYM))]
25f905c2 5804 "TARGET_THUMB1 && flag_pic"
8c4d8060 5805 "ldr\\t%0, %1"
a2cd141b 5806 [(set_attr "type" "load1")
42e1de19 5807 (set (attr "pool_range") (const_int 1018))]
cffb2a26 5808)
849170fd 5809
cffb2a26 5810(define_insn "pic_add_dot_plus_four"
15d5d060 5811 [(set (match_operand:SI 0 "register_operand" "=r")
c0c1fba5 5812 (unspec:SI [(match_operand:SI 1 "register_operand" "0")
5813 (const_int 4)
beef0fb5 5814 (match_operand 2 "" "")]
5815 UNSPEC_PIC_BASE))]
b3cd5f55 5816 "TARGET_THUMB"
cffb2a26 5817 "*
6cdcb15c 5818 (*targetm.asm_out.internal_label) (asm_out_file, \"LPIC\",
5819 INTVAL (operands[2]));
cffb2a26 5820 return \"add\\t%0, %|pc\";
5821 "
1b7da4ac 5822 [(set_attr "length" "2")
112eda6f 5823 (set_attr "type" "alu_sreg")]
cffb2a26 5824)
849170fd 5825
5826(define_insn "pic_add_dot_plus_eight"
15d5d060 5827 [(set (match_operand:SI 0 "register_operand" "=r")
c0c1fba5 5828 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
5829 (const_int 8)
beef0fb5 5830 (match_operand 2 "" "")]
5831 UNSPEC_PIC_BASE))]
f655717d 5832 "TARGET_ARM"
c4034607 5833 "*
6cdcb15c 5834 (*targetm.asm_out.internal_label) (asm_out_file, \"LPIC\",
5835 INTVAL (operands[2]));
15d5d060 5836 return \"add%?\\t%0, %|pc, %1\";
cffb2a26 5837 "
1b7da4ac 5838 [(set_attr "predicable" "yes")
112eda6f 5839 (set_attr "type" "alu_sreg")]
cffb2a26 5840)
849170fd 5841
f655717d 5842(define_insn "tls_load_dot_plus_eight"
cc071db6 5843 [(set (match_operand:SI 0 "register_operand" "=r")
c0c1fba5 5844 (mem:SI (unspec:SI [(match_operand:SI 1 "register_operand" "r")
5845 (const_int 8)
beef0fb5 5846 (match_operand 2 "" "")]
5847 UNSPEC_PIC_BASE)))]
f655717d 5848 "TARGET_ARM"
5849 "*
6cdcb15c 5850 (*targetm.asm_out.internal_label) (asm_out_file, \"LPIC\",
5851 INTVAL (operands[2]));
f655717d 5852 return \"ldr%?\\t%0, [%|pc, %1]\t\t@ tls_load_dot_plus_eight\";
5853 "
1b7da4ac 5854 [(set_attr "predicable" "yes")
5855 (set_attr "type" "load1")]
f655717d 5856)
5857
5858;; PIC references to local variables can generate pic_add_dot_plus_eight
5859;; followed by a load. These sequences can be crunched down to
5860;; tls_load_dot_plus_eight by a peephole.
5861
5862(define_peephole2
c0c1fba5 5863 [(set (match_operand:SI 0 "register_operand" "")
5864 (unspec:SI [(match_operand:SI 3 "register_operand" "")
5865 (const_int 8)
5866 (match_operand 1 "" "")]
5867 UNSPEC_PIC_BASE))
2d05dfad 5868 (set (match_operand:SI 2 "arm_general_register_operand" "")
5869 (mem:SI (match_dup 0)))]
f655717d 5870 "TARGET_ARM && peep2_reg_dead_p (2, operands[0])"
c0c1fba5 5871 [(set (match_dup 2)
5872 (mem:SI (unspec:SI [(match_dup 3)
5873 (const_int 8)
5874 (match_dup 1)]
5875 UNSPEC_PIC_BASE)))]
f655717d 5876 ""
5877)
5878
bac7fc85 5879(define_insn "pic_offset_arm"
5880 [(set (match_operand:SI 0 "register_operand" "=r")
5881 (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
5882 (unspec:SI [(match_operand:SI 2 "" "X")]
5883 UNSPEC_PIC_OFFSET))))]
5884 "TARGET_VXWORKS_RTP && TARGET_ARM && flag_pic"
5885 "ldr%?\\t%0, [%1,%2]"
5886 [(set_attr "type" "load1")]
5887)
5888
95373f08 5889(define_expand "builtin_setjmp_receiver"
5890 [(label_ref (match_operand 0 "" ""))]
5891 "flag_pic"
5892 "
5893{
b935b306 5894 /* r3 is clobbered by set/longjmp, so we can use it as a scratch
5895 register. */
2cb7d577 5896 if (arm_pic_register != INVALID_REGNUM)
5897 arm_load_pic_register (1UL << 3);
95373f08 5898 DONE;
5899}")
5900
9c08d1fa 5901;; If copying one reg to another we can set the condition codes according to
5902;; its value. Such a move is common after a return from subroutine and the
5903;; result is being tested against zero.
5904
f7fbdd4a 5905(define_insn "*movsi_compare0"
bd5b4116 5906 [(set (reg:CC CC_REGNUM)
cffb2a26 5907 (compare:CC (match_operand:SI 1 "s_register_operand" "0,r")
5908 (const_int 0)))
5909 (set (match_operand:SI 0 "s_register_operand" "=r,r")
5910 (match_dup 1))]
25f905c2 5911 "TARGET_32BIT"
e2348bcb 5912 "@
40dbec34 5913 cmp%?\\t%0, #0
25f905c2 5914 sub%.\\t%0, %1, #0"
65f68e55 5915 [(set_attr "conds" "set")
d82e788e 5916 (set_attr "type" "alus_imm,alus_imm")]
cffb2a26 5917)
b11cae9e 5918
b11cae9e 5919;; Subroutine to store a half word from a register into memory.
5920;; Operand 0 is the source register (HImode)
c8f69309 5921;; Operand 1 is the destination address in a register (SImode)
b11cae9e 5922
9c08d1fa 5923;; In both this routine and the next, we must be careful not to spill
01cc3b75 5924;; a memory address of reg+large_const into a separate PLUS insn, since this
9c08d1fa 5925;; can generate unrecognizable rtl.
5926
b11cae9e 5927(define_expand "storehi"
c8f69309 5928 [;; store the low byte
f082f1c4 5929 (set (match_operand 1 "" "") (match_dup 3))
b11cae9e 5930 ;; extract the high byte
c8f69309 5931 (set (match_dup 2)
5932 (ashiftrt:SI (match_operand 0 "" "") (const_int 8)))
b11cae9e 5933 ;; store the high byte
787f8210 5934 (set (match_dup 4) (match_dup 5))]
cffb2a26 5935 "TARGET_ARM"
b11cae9e 5936 "
215b30b3 5937 {
537ffcfc 5938 rtx op1 = operands[1];
5939 rtx addr = XEXP (op1, 0);
215b30b3 5940 enum rtx_code code = GET_CODE (addr);
5941
0438d37f 5942 if ((code == PLUS && !CONST_INT_P (XEXP (addr, 1)))
215b30b3 5943 || code == MINUS)
537ffcfc 5944 op1 = replace_equiv_address (operands[1], force_reg (SImode, addr));
215b30b3 5945
537ffcfc 5946 operands[4] = adjust_address (op1, QImode, 1);
e513d163 5947 operands[1] = adjust_address (operands[1], QImode, 0);
215b30b3 5948 operands[3] = gen_lowpart (QImode, operands[0]);
5949 operands[0] = gen_lowpart (SImode, operands[0]);
787f8210 5950 operands[2] = gen_reg_rtx (SImode);
5951 operands[5] = gen_lowpart (QImode, operands[2]);
215b30b3 5952 }"
5953)
b11cae9e 5954
c7597b5d 5955(define_expand "storehi_bigend"
f082f1c4 5956 [(set (match_dup 4) (match_dup 3))
c7597b5d 5957 (set (match_dup 2)
5958 (ashiftrt:SI (match_operand 0 "" "") (const_int 8)))
787f8210 5959 (set (match_operand 1 "" "") (match_dup 5))]
cffb2a26 5960 "TARGET_ARM"
b11cae9e 5961 "
215b30b3 5962 {
537ffcfc 5963 rtx op1 = operands[1];
5964 rtx addr = XEXP (op1, 0);
215b30b3 5965 enum rtx_code code = GET_CODE (addr);
5966
0438d37f 5967 if ((code == PLUS && !CONST_INT_P (XEXP (addr, 1)))
215b30b3 5968 || code == MINUS)
537ffcfc 5969 op1 = replace_equiv_address (op1, force_reg (SImode, addr));
215b30b3 5970
537ffcfc 5971 operands[4] = adjust_address (op1, QImode, 1);
e513d163 5972 operands[1] = adjust_address (operands[1], QImode, 0);
215b30b3 5973 operands[3] = gen_lowpart (QImode, operands[0]);
5974 operands[0] = gen_lowpart (SImode, operands[0]);
5975 operands[2] = gen_reg_rtx (SImode);
787f8210 5976 operands[5] = gen_lowpart (QImode, operands[2]);
215b30b3 5977 }"
5978)
c7597b5d 5979
5980;; Subroutine to store a half word integer constant into memory.
5981(define_expand "storeinthi"
f082f1c4 5982 [(set (match_operand 0 "" "")
787f8210 5983 (match_operand 1 "" ""))
9e8503e6 5984 (set (match_dup 3) (match_dup 2))]
cffb2a26 5985 "TARGET_ARM"
c7597b5d 5986 "
215b30b3 5987 {
5988 HOST_WIDE_INT value = INTVAL (operands[1]);
5989 rtx addr = XEXP (operands[0], 0);
537ffcfc 5990 rtx op0 = operands[0];
215b30b3 5991 enum rtx_code code = GET_CODE (addr);
c7597b5d 5992
0438d37f 5993 if ((code == PLUS && !CONST_INT_P (XEXP (addr, 1)))
215b30b3 5994 || code == MINUS)
537ffcfc 5995 op0 = replace_equiv_address (op0, force_reg (SImode, addr));
c7597b5d 5996
215b30b3 5997 operands[1] = gen_reg_rtx (SImode);
5998 if (BYTES_BIG_ENDIAN)
5999 {
6000 emit_insn (gen_movsi (operands[1], GEN_INT ((value >> 8) & 255)));
6001 if ((value & 255) == ((value >> 8) & 255))
6002 operands[2] = operands[1];
6003 else
6004 {
6005 operands[2] = gen_reg_rtx (SImode);
6006 emit_insn (gen_movsi (operands[2], GEN_INT (value & 255)));
6007 }
6008 }
6009 else
6010 {
6011 emit_insn (gen_movsi (operands[1], GEN_INT (value & 255)));
6012 if ((value & 255) == ((value >> 8) & 255))
6013 operands[2] = operands[1];
6014 else
6015 {
6016 operands[2] = gen_reg_rtx (SImode);
6017 emit_insn (gen_movsi (operands[2], GEN_INT ((value >> 8) & 255)));
6018 }
6019 }
c7597b5d 6020
537ffcfc 6021 operands[3] = adjust_address (op0, QImode, 1);
e513d163 6022 operands[0] = adjust_address (operands[0], QImode, 0);
9e8503e6 6023 operands[2] = gen_lowpart (QImode, operands[2]);
787f8210 6024 operands[1] = gen_lowpart (QImode, operands[1]);
215b30b3 6025 }"
6026)
b11cae9e 6027
f7fbdd4a 6028(define_expand "storehi_single_op"
6029 [(set (match_operand:HI 0 "memory_operand" "")
6030 (match_operand:HI 1 "general_operand" ""))]
25f905c2 6031 "TARGET_32BIT && arm_arch4"
f7fbdd4a 6032 "
215b30b3 6033 if (!s_register_operand (operands[1], HImode))
f7fbdd4a 6034 operands[1] = copy_to_mode_reg (HImode, operands[1]);
215b30b3 6035 "
6036)
f7fbdd4a 6037
b11cae9e 6038(define_expand "movhi"
6039 [(set (match_operand:HI 0 "general_operand" "")
c8f69309 6040 (match_operand:HI 1 "general_operand" ""))]
cffb2a26 6041 "TARGET_EITHER"
b11cae9e 6042 "
cffb2a26 6043 if (TARGET_ARM)
b11cae9e 6044 {
e1ba4a27 6045 if (can_create_pseudo_p ())
cffb2a26 6046 {
0438d37f 6047 if (MEM_P (operands[0]))
b11cae9e 6048 {
cffb2a26 6049 if (arm_arch4)
6050 {
6051 emit_insn (gen_storehi_single_op (operands[0], operands[1]));
6052 DONE;
6053 }
0438d37f 6054 if (CONST_INT_P (operands[1]))
cffb2a26 6055 emit_insn (gen_storeinthi (operands[0], operands[1]));
c7597b5d 6056 else
cffb2a26 6057 {
0438d37f 6058 if (MEM_P (operands[1]))
cffb2a26 6059 operands[1] = force_reg (HImode, operands[1]);
6060 if (BYTES_BIG_ENDIAN)
6061 emit_insn (gen_storehi_bigend (operands[1], operands[0]));
6062 else
6063 emit_insn (gen_storehi (operands[1], operands[0]));
6064 }
6065 DONE;
b11cae9e 6066 }
cffb2a26 6067 /* Sign extend a constant, and keep it in an SImode reg. */
0438d37f 6068 else if (CONST_INT_P (operands[1]))
9c08d1fa 6069 {
cffb2a26 6070 rtx reg = gen_reg_rtx (SImode);
6071 HOST_WIDE_INT val = INTVAL (operands[1]) & 0xffff;
6072
6073 /* If the constant is already valid, leave it alone. */
215b30b3 6074 if (!const_ok_for_arm (val))
cffb2a26 6075 {
6076 /* If setting all the top bits will make the constant
6077 loadable in a single instruction, then set them.
6078 Otherwise, sign extend the number. */
6079
215b30b3 6080 if (const_ok_for_arm (~(val | ~0xffff)))
cffb2a26 6081 val |= ~0xffff;
6082 else if (val & 0x8000)
6083 val |= ~0xffff;
6084 }
6085
6086 emit_insn (gen_movsi (reg, GEN_INT (val)));
9e8503e6 6087 operands[1] = gen_lowpart (HImode, reg);
9c08d1fa 6088 }
e1ba4a27 6089 else if (arm_arch4 && optimize && can_create_pseudo_p ()
0438d37f 6090 && MEM_P (operands[1]))
0045890a 6091 {
6092 rtx reg = gen_reg_rtx (SImode);
6093
6094 emit_insn (gen_zero_extendhisi2 (reg, operands[1]));
6095 operands[1] = gen_lowpart (HImode, reg);
6096 }
215b30b3 6097 else if (!arm_arch4)
f7fbdd4a 6098 {
0438d37f 6099 if (MEM_P (operands[1]))
cffb2a26 6100 {
c1a66faf 6101 rtx base;
6102 rtx offset = const0_rtx;
6103 rtx reg = gen_reg_rtx (SImode);
6104
0438d37f 6105 if ((REG_P (base = XEXP (operands[1], 0))
c1a66faf 6106 || (GET_CODE (base) == PLUS
0438d37f 6107 && (CONST_INT_P (offset = XEXP (base, 1)))
c1a66faf 6108 && ((INTVAL(offset) & 1) != 1)
0438d37f 6109 && REG_P (base = XEXP (base, 0))))
c1a66faf 6110 && REGNO_POINTER_ALIGN (REGNO (base)) >= 32)
206ee9a2 6111 {
8deb3959 6112 rtx new_rtx;
c1a66faf 6113
8deb3959 6114 new_rtx = widen_memory_access (operands[1], SImode,
6115 ((INTVAL (offset) & ~3)
6116 - INTVAL (offset)));
6117 emit_insn (gen_movsi (reg, new_rtx));
c1a66faf 6118 if (((INTVAL (offset) & 2) != 0)
6119 ^ (BYTES_BIG_ENDIAN ? 1 : 0))
6120 {
6121 rtx reg2 = gen_reg_rtx (SImode);
6122
6123 emit_insn (gen_lshrsi3 (reg2, reg, GEN_INT (16)));
6124 reg = reg2;
6125 }
206ee9a2 6126 }
c1a66faf 6127 else
6128 emit_insn (gen_movhi_bytes (reg, operands[1]));
6129
6130 operands[1] = gen_lowpart (HImode, reg);
cffb2a26 6131 }
6132 }
6133 }
674a8f0b 6134 /* Handle loading a large integer during reload. */
0438d37f 6135 else if (CONST_INT_P (operands[1])
215b30b3 6136 && !const_ok_for_arm (INTVAL (operands[1]))
6137 && !const_ok_for_arm (~INTVAL (operands[1])))
cffb2a26 6138 {
6139 /* Writing a constant to memory needs a scratch, which should
6140 be handled with SECONDARY_RELOADs. */
0438d37f 6141 gcc_assert (REG_P (operands[0]));
cffb2a26 6142
6143 operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
6144 emit_insn (gen_movsi (operands[0], operands[1]));
6145 DONE;
6146 }
6147 }
25f905c2 6148 else if (TARGET_THUMB2)
6149 {
6150 /* Thumb-2 can do everything except mem=mem and mem=const easily. */
e1ba4a27 6151 if (can_create_pseudo_p ())
25f905c2 6152 {
0438d37f 6153 if (!REG_P (operands[0]))
25f905c2 6154 operands[1] = force_reg (HImode, operands[1]);
6155 /* Zero extend a constant, and keep it in an SImode reg. */
0438d37f 6156 else if (CONST_INT_P (operands[1]))
25f905c2 6157 {
6158 rtx reg = gen_reg_rtx (SImode);
6159 HOST_WIDE_INT val = INTVAL (operands[1]) & 0xffff;
6160
6161 emit_insn (gen_movsi (reg, GEN_INT (val)));
6162 operands[1] = gen_lowpart (HImode, reg);
6163 }
6164 }
6165 }
6166 else /* TARGET_THUMB1 */
cffb2a26 6167 {
e1ba4a27 6168 if (can_create_pseudo_p ())
cffb2a26 6169 {
0438d37f 6170 if (CONST_INT_P (operands[1]))
6cffc037 6171 {
6172 rtx reg = gen_reg_rtx (SImode);
6173
6174 emit_insn (gen_movsi (reg, operands[1]));
6175 operands[1] = gen_lowpart (HImode, reg);
6176 }
cffb2a26 6177
6178 /* ??? We shouldn't really get invalid addresses here, but this can
215b30b3 6179 happen if we are passed a SP (never OK for HImode/QImode) or
bc409cb4 6180 virtual register (also rejected as illegitimate for HImode/QImode)
6181 relative address. */
cffb2a26 6182 /* ??? This should perhaps be fixed elsewhere, for instance, in
6183 fixup_stack_1, by checking for other kinds of invalid addresses,
6184 e.g. a bare reference to a virtual register. This may confuse the
6185 alpha though, which must handle this case differently. */
0438d37f 6186 if (MEM_P (operands[0])
215b30b3 6187 && !memory_address_p (GET_MODE (operands[0]),
6188 XEXP (operands[0], 0)))
537ffcfc 6189 operands[0]
6190 = replace_equiv_address (operands[0],
6191 copy_to_reg (XEXP (operands[0], 0)));
cffb2a26 6192
0438d37f 6193 if (MEM_P (operands[1])
215b30b3 6194 && !memory_address_p (GET_MODE (operands[1]),
6195 XEXP (operands[1], 0)))
537ffcfc 6196 operands[1]
6197 = replace_equiv_address (operands[1],
6198 copy_to_reg (XEXP (operands[1], 0)));
6cffc037 6199
0438d37f 6200 if (MEM_P (operands[1]) && optimize > 0)
6cffc037 6201 {
6202 rtx reg = gen_reg_rtx (SImode);
6203
6204 emit_insn (gen_zero_extendhisi2 (reg, operands[1]));
6205 operands[1] = gen_lowpart (HImode, reg);
6206 }
6207
0438d37f 6208 if (MEM_P (operands[0]))
6cffc037 6209 operands[1] = force_reg (HImode, operands[1]);
cffb2a26 6210 }
0438d37f 6211 else if (CONST_INT_P (operands[1])
234f6557 6212 && !satisfies_constraint_I (operands[1]))
cffb2a26 6213 {
6cffc037 6214 /* Handle loading a large integer during reload. */
6215
cffb2a26 6216 /* Writing a constant to memory needs a scratch, which should
6217 be handled with SECONDARY_RELOADs. */
0438d37f 6218 gcc_assert (REG_P (operands[0]));
cffb2a26 6219
1a83b3ff 6220 operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
cffb2a26 6221 emit_insn (gen_movsi (operands[0], operands[1]));
6222 DONE;
6223 }
b11cae9e 6224 }
cffb2a26 6225 "
6226)
6227
25f7a26e 6228(define_expand "movhi_bytes"
eab14235 6229 [(set (match_dup 2) (zero_extend:SI (match_operand:HI 1 "" "")))
25f7a26e 6230 (set (match_dup 3)
eab14235 6231 (zero_extend:SI (match_dup 6)))
25f7a26e 6232 (set (match_operand:SI 0 "" "")
6233 (ior:SI (ashift:SI (match_dup 4) (const_int 8)) (match_dup 5)))]
cffb2a26 6234 "TARGET_ARM"
25f7a26e 6235 "
215b30b3 6236 {
6237 rtx mem1, mem2;
6238 rtx addr = copy_to_mode_reg (SImode, XEXP (operands[1], 0));
6239
788fcce0 6240 mem1 = change_address (operands[1], QImode, addr);
29c05e22 6241 mem2 = change_address (operands[1], QImode,
6242 plus_constant (Pmode, addr, 1));
215b30b3 6243 operands[0] = gen_lowpart (SImode, operands[0]);
6244 operands[1] = mem1;
6245 operands[2] = gen_reg_rtx (SImode);
6246 operands[3] = gen_reg_rtx (SImode);
6247 operands[6] = mem2;
25f7a26e 6248
215b30b3 6249 if (BYTES_BIG_ENDIAN)
6250 {
6251 operands[4] = operands[2];
6252 operands[5] = operands[3];
6253 }
6254 else
6255 {
6256 operands[4] = operands[3];
6257 operands[5] = operands[2];
6258 }
6259 }"
6260)
25f7a26e 6261
c7597b5d 6262(define_expand "movhi_bigend"
6263 [(set (match_dup 2)
6264 (rotate:SI (subreg:SI (match_operand:HI 1 "memory_operand" "") 0)
6265 (const_int 16)))
6266 (set (match_dup 3)
6267 (ashiftrt:SI (match_dup 2) (const_int 16)))
6268 (set (match_operand:HI 0 "s_register_operand" "")
787f8210 6269 (match_dup 4))]
cffb2a26 6270 "TARGET_ARM"
c7597b5d 6271 "
6272 operands[2] = gen_reg_rtx (SImode);
6273 operands[3] = gen_reg_rtx (SImode);
787f8210 6274 operands[4] = gen_lowpart (HImode, operands[3]);
215b30b3 6275 "
6276)
b11cae9e 6277
a2f10574 6278;; Pattern to recognize insn generated default case above
f7fbdd4a 6279(define_insn "*movhi_insn_arch4"
e4585731 6280 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m,r")
6281 (match_operand:HI 1 "general_operand" "rIk,K,n,r,mi"))]
cffb2a26 6282 "TARGET_ARM
6283 && arm_arch4
85e02ccb 6284 && (register_operand (operands[0], HImode)
6285 || register_operand (operands[1], HImode))"
f7fbdd4a 6286 "@
6287 mov%?\\t%0, %1\\t%@ movhi
6288 mvn%?\\t%0, #%B1\\t%@ movhi
b1c1a101 6289 movw%?\\t%0, %L1\\t%@ movhi
25f905c2 6290 str%(h%)\\t%1, %0\\t%@ movhi
6291 ldr%(h%)\\t%0, %1\\t%@ movhi"
65f68e55 6292 [(set_attr "predicable" "yes")
e4585731 6293 (set_attr "pool_range" "*,*,*,*,256")
6294 (set_attr "neg_pool_range" "*,*,*,*,244")
6295 (set_attr "arch" "*,*,v6t2,*,*")
65f68e55 6296 (set_attr_alternative "type"
6297 [(if_then_else (match_operand 1 "const_int_operand" "")
1aed5204 6298 (const_string "mov_imm" )
6299 (const_string "mov_reg"))
6300 (const_string "mvn_imm")
e4585731 6301 (const_string "mov_imm")
65f68e55 6302 (const_string "store1")
6303 (const_string "load1")])]
cffb2a26 6304)
f7fbdd4a 6305
f7fbdd4a 6306(define_insn "*movhi_bytes"
65f68e55 6307 [(set (match_operand:HI 0 "s_register_operand" "=r,r,r")
5fd254ed 6308 (match_operand:HI 1 "arm_rhs_operand" "I,rk,K"))]
c1a66faf 6309 "TARGET_ARM"
25f7a26e 6310 "@
65f68e55 6311 mov%?\\t%0, %1\\t%@ movhi
25f7a26e 6312 mov%?\\t%0, %1\\t%@ movhi
0d66636f 6313 mvn%?\\t%0, #%B1\\t%@ movhi"
d2a518d1 6314 [(set_attr "predicable" "yes")
1aed5204 6315 (set_attr "type" "mov_imm,mov_reg,mvn_imm")]
0d66636f 6316)
cffb2a26 6317
bc5c7e08 6318;; We use a DImode scratch because we may occasionally need an additional
6319;; temporary if the address isn't offsettable -- push_reload doesn't seem
6320;; to take any notice of the "o" constraints on reload_memory_operand operand.
d3373b54 6321(define_expand "reload_outhi"
cffb2a26 6322 [(parallel [(match_operand:HI 0 "arm_reload_memory_operand" "=o")
215b30b3 6323 (match_operand:HI 1 "s_register_operand" "r")
6324 (match_operand:DI 2 "s_register_operand" "=&l")])]
cffb2a26 6325 "TARGET_EITHER"
6326 "if (TARGET_ARM)
6327 arm_reload_out_hi (operands);
6328 else
6329 thumb_reload_out_hi (operands);
d3373b54 6330 DONE;
cffb2a26 6331 "
6332)
d3373b54 6333
25f7a26e 6334(define_expand "reload_inhi"
6335 [(parallel [(match_operand:HI 0 "s_register_operand" "=r")
cffb2a26 6336 (match_operand:HI 1 "arm_reload_memory_operand" "o")
bc5c7e08 6337 (match_operand:DI 2 "s_register_operand" "=&r")])]
c1a66faf 6338 "TARGET_EITHER"
25f7a26e 6339 "
cffb2a26 6340 if (TARGET_ARM)
6341 arm_reload_in_hi (operands);
6342 else
6343 thumb_reload_out_hi (operands);
25f7a26e 6344 DONE;
6345")
6346
9c08d1fa 6347(define_expand "movqi"
6348 [(set (match_operand:QI 0 "general_operand" "")
6349 (match_operand:QI 1 "general_operand" ""))]
cffb2a26 6350 "TARGET_EITHER"
9c08d1fa 6351 "
6cffc037 6352 /* Everything except mem = const or mem = mem can be done easily */
0045890a 6353
e1ba4a27 6354 if (can_create_pseudo_p ())
cffb2a26 6355 {
0438d37f 6356 if (CONST_INT_P (operands[1]))
6cffc037 6357 {
6358 rtx reg = gen_reg_rtx (SImode);
6359
03770691 6360 /* For thumb we want an unsigned immediate, then we are more likely
6361 to be able to use a movs insn. */
6362 if (TARGET_THUMB)
6363 operands[1] = GEN_INT (INTVAL (operands[1]) & 255);
6364
6cffc037 6365 emit_insn (gen_movsi (reg, operands[1]));
6366 operands[1] = gen_lowpart (QImode, reg);
6367 }
cffb2a26 6368
6cffc037 6369 if (TARGET_THUMB)
6370 {
cffb2a26 6371 /* ??? We shouldn't really get invalid addresses here, but this can
215b30b3 6372 happen if we are passed a SP (never OK for HImode/QImode) or
bc409cb4 6373 virtual register (also rejected as illegitimate for HImode/QImode)
6374 relative address. */
cffb2a26 6375 /* ??? This should perhaps be fixed elsewhere, for instance, in
6376 fixup_stack_1, by checking for other kinds of invalid addresses,
6377 e.g. a bare reference to a virtual register. This may confuse the
6378 alpha though, which must handle this case differently. */
0438d37f 6379 if (MEM_P (operands[0])
215b30b3 6380 && !memory_address_p (GET_MODE (operands[0]),
cffb2a26 6381 XEXP (operands[0], 0)))
537ffcfc 6382 operands[0]
6383 = replace_equiv_address (operands[0],
6384 copy_to_reg (XEXP (operands[0], 0)));
0438d37f 6385 if (MEM_P (operands[1])
215b30b3 6386 && !memory_address_p (GET_MODE (operands[1]),
cffb2a26 6387 XEXP (operands[1], 0)))
537ffcfc 6388 operands[1]
6389 = replace_equiv_address (operands[1],
6390 copy_to_reg (XEXP (operands[1], 0)));
6cffc037 6391 }
6392
0438d37f 6393 if (MEM_P (operands[1]) && optimize > 0)
6cffc037 6394 {
6395 rtx reg = gen_reg_rtx (SImode);
6396
6397 emit_insn (gen_zero_extendqisi2 (reg, operands[1]));
6398 operands[1] = gen_lowpart (QImode, reg);
6399 }
6400
0438d37f 6401 if (MEM_P (operands[0]))
6cffc037 6402 operands[1] = force_reg (QImode, operands[1]);
6403 }
6404 else if (TARGET_THUMB
0438d37f 6405 && CONST_INT_P (operands[1])
234f6557 6406 && !satisfies_constraint_I (operands[1]))
6cffc037 6407 {
674a8f0b 6408 /* Handle loading a large integer during reload. */
cffb2a26 6409
6cffc037 6410 /* Writing a constant to memory needs a scratch, which should
6411 be handled with SECONDARY_RELOADs. */
0438d37f 6412 gcc_assert (REG_P (operands[0]));
6cffc037 6413
6414 operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
6415 emit_insn (gen_movsi (operands[0], operands[1]));
6416 DONE;
cffb2a26 6417 }
6418 "
6419)
b11cae9e 6420
cffb2a26 6421(define_insn "*arm_movqi_insn"
fd711051 6422 [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,r,l,r,l,Uu,r,m")
490f62ca 6423 (match_operand:QI 1 "general_operand" "rk,rk,I,Py,K,Uu,l,Uh,r"))]
25f905c2 6424 "TARGET_32BIT
cffb2a26 6425 && ( register_operand (operands[0], QImode)
6426 || register_operand (operands[1], QImode))"
5565501b 6427 "@
fd711051 6428 mov%?\\t%0, %1
6429 mov%?\\t%0, %1
65f68e55 6430 mov%?\\t%0, %1
5565501b 6431 mov%?\\t%0, %1
6432 mvn%?\\t%0, #%B1
25f905c2 6433 ldr%(b%)\\t%0, %1
a54e3e7b 6434 str%(b%)\\t%1, %0
6435 ldr%(b%)\\t%0, %1
25f905c2 6436 str%(b%)\\t%1, %0"
1aed5204 6437 [(set_attr "type" "mov_reg,mov_reg,mov_imm,mov_imm,mvn_imm,load1,store1,load1,store1")
a54e3e7b 6438 (set_attr "predicable" "yes")
fd711051 6439 (set_attr "predicable_short_it" "yes,yes,yes,no,no,no,no,no,no")
6440 (set_attr "arch" "t2,any,any,t2,any,t2,t2,any,any")
6441 (set_attr "length" "2,4,4,2,4,2,2,4,4")]
cffb2a26 6442)
6443
9b8516be 6444;; HFmode moves
6445(define_expand "movhf"
6446 [(set (match_operand:HF 0 "general_operand" "")
6447 (match_operand:HF 1 "general_operand" ""))]
6448 "TARGET_EITHER"
6449 "
6450 if (TARGET_32BIT)
6451 {
0438d37f 6452 if (MEM_P (operands[0]))
9b8516be 6453 operands[1] = force_reg (HFmode, operands[1]);
6454 }
6455 else /* TARGET_THUMB1 */
6456 {
6457 if (can_create_pseudo_p ())
6458 {
0438d37f 6459 if (!REG_P (operands[0]))
9b8516be 6460 operands[1] = force_reg (HFmode, operands[1]);
6461 }
6462 }
6463 "
6464)
6465
6466(define_insn "*arm32_movhf"
6467 [(set (match_operand:HF 0 "nonimmediate_operand" "=r,m,r,r")
6468 (match_operand:HF 1 "general_operand" " m,r,r,F"))]
7c36fe71 6469 "TARGET_32BIT && !(TARGET_HARD_FLOAT && TARGET_FP16) && !arm_restrict_it
9b8516be 6470 && ( s_register_operand (operands[0], HFmode)
6471 || s_register_operand (operands[1], HFmode))"
6472 "*
6473 switch (which_alternative)
6474 {
6475 case 0: /* ARM register from memory */
6476 return \"ldr%(h%)\\t%0, %1\\t%@ __fp16\";
6477 case 1: /* memory from ARM register */
6478 return \"str%(h%)\\t%1, %0\\t%@ __fp16\";
6479 case 2: /* ARM register from ARM register */
6480 return \"mov%?\\t%0, %1\\t%@ __fp16\";
6481 case 3: /* ARM register from constant */
6482 {
6483 REAL_VALUE_TYPE r;
6484 long bits;
6485 rtx ops[4];
6486
6487 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
6488 bits = real_to_target (NULL, &r, HFmode);
6489 ops[0] = operands[0];
6490 ops[1] = GEN_INT (bits);
6491 ops[2] = GEN_INT (bits & 0xff00);
6492 ops[3] = GEN_INT (bits & 0x00ff);
6493
6494 if (arm_arch_thumb2)
6495 output_asm_insn (\"movw%?\\t%0, %1\", ops);
6496 else
6497 output_asm_insn (\"mov%?\\t%0, %2\;orr%?\\t%0, %0, %3\", ops);
6498 return \"\";
6499 }
6500 default:
6501 gcc_unreachable ();
6502 }
6503 "
6504 [(set_attr "conds" "unconditional")
ad4fc3c0 6505 (set_attr "type" "load1,store1,mov_reg,multiple")
9b8516be 6506 (set_attr "length" "4,4,4,8")
d2a518d1 6507 (set_attr "predicable" "yes")]
9b8516be 6508)
6509
87b22bf7 6510(define_expand "movsf"
6511 [(set (match_operand:SF 0 "general_operand" "")
6512 (match_operand:SF 1 "general_operand" ""))]
cffb2a26 6513 "TARGET_EITHER"
87b22bf7 6514 "
25f905c2 6515 if (TARGET_32BIT)
cffb2a26 6516 {
0438d37f 6517 if (MEM_P (operands[0]))
cffb2a26 6518 operands[1] = force_reg (SFmode, operands[1]);
6519 }
25f905c2 6520 else /* TARGET_THUMB1 */
cffb2a26 6521 {
e1ba4a27 6522 if (can_create_pseudo_p ())
cffb2a26 6523 {
0438d37f 6524 if (!REG_P (operands[0]))
cffb2a26 6525 operands[1] = force_reg (SFmode, operands[1]);
6526 }
6527 }
6528 "
6529)
6530
03d440a6 6531;; Transform a floating-point move of a constant into a core register into
6532;; an SImode operation.
cffb2a26 6533(define_split
03d440a6 6534 [(set (match_operand:SF 0 "arm_general_register_operand" "")
cffb2a26 6535 (match_operand:SF 1 "immediate_operand" ""))]
339034d0 6536 "TARGET_EITHER
cffb2a26 6537 && reload_completed
0438d37f 6538 && CONST_DOUBLE_P (operands[1])"
cffb2a26 6539 [(set (match_dup 2) (match_dup 3))]
6540 "
6541 operands[2] = gen_lowpart (SImode, operands[0]);
6542 operands[3] = gen_lowpart (SImode, operands[1]);
6543 if (operands[2] == 0 || operands[3] == 0)
6544 FAIL;
215b30b3 6545 "
6546)
87b22bf7 6547
cffb2a26 6548(define_insn "*arm_movsf_soft_insn"
6549 [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,m")
6550 (match_operand:SF 1 "general_operand" "r,mE,r"))]
cde1623a 6551 "TARGET_32BIT
cffb2a26 6552 && TARGET_SOFT_FLOAT
0438d37f 6553 && (!MEM_P (operands[0])
215b30b3 6554 || register_operand (operands[1], SFmode))"
9a1112d7 6555 "@
6556 mov%?\\t%0, %1
6557 ldr%?\\t%0, %1\\t%@ float
6558 str%?\\t%1, %0\\t%@ float"
cde1623a 6559 [(set_attr "predicable" "yes")
7c36fe71 6560 (set_attr "predicable_short_it" "no")
1aed5204 6561 (set_attr "type" "mov_reg,load1,store1")
42e1de19 6562 (set_attr "arm_pool_range" "*,4096,*")
6563 (set_attr "thumb2_pool_range" "*,4094,*")
cde1623a 6564 (set_attr "arm_neg_pool_range" "*,4084,*")
6565 (set_attr "thumb2_neg_pool_range" "*,0,*")]
cffb2a26 6566)
6567
9c08d1fa 6568(define_expand "movdf"
87b22bf7 6569 [(set (match_operand:DF 0 "general_operand" "")
6570 (match_operand:DF 1 "general_operand" ""))]
cffb2a26 6571 "TARGET_EITHER"
9c08d1fa 6572 "
25f905c2 6573 if (TARGET_32BIT)
cffb2a26 6574 {
0438d37f 6575 if (MEM_P (operands[0]))
cffb2a26 6576 operands[1] = force_reg (DFmode, operands[1]);
6577 }
6578 else /* TARGET_THUMB */
6579 {
e1ba4a27 6580 if (can_create_pseudo_p ())
cffb2a26 6581 {
0438d37f 6582 if (!REG_P (operands[0]))
cffb2a26 6583 operands[1] = force_reg (DFmode, operands[1]);
6584 }
6585 }
6586 "
6587)
b11cae9e 6588
9c08d1fa 6589;; Reloading a df mode value stored in integer regs to memory can require a
6590;; scratch reg.
6591(define_expand "reload_outdf"
cffb2a26 6592 [(match_operand:DF 0 "arm_reload_memory_operand" "=o")
87b22bf7 6593 (match_operand:DF 1 "s_register_operand" "r")
6594 (match_operand:SI 2 "s_register_operand" "=&r")]
06adefdc 6595 "TARGET_THUMB2"
87b22bf7 6596 "
215b30b3 6597 {
6598 enum rtx_code code = GET_CODE (XEXP (operands[0], 0));
f7fbdd4a 6599
215b30b3 6600 if (code == REG)
6601 operands[2] = XEXP (operands[0], 0);
6602 else if (code == POST_INC || code == PRE_DEC)
6603 {
6604 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
6605 operands[1] = gen_rtx_SUBREG (DImode, operands[1], 0);
6606 emit_insn (gen_movdi (operands[0], operands[1]));
6607 DONE;
6608 }
6609 else if (code == PRE_INC)
6610 {
6611 rtx reg = XEXP (XEXP (operands[0], 0), 0);
f7fbdd4a 6612
215b30b3 6613 emit_insn (gen_addsi3 (reg, reg, GEN_INT (8)));
6614 operands[2] = reg;
6615 }
6616 else if (code == POST_DEC)
6617 operands[2] = XEXP (XEXP (operands[0], 0), 0);
6618 else
6619 emit_insn (gen_addsi3 (operands[2], XEXP (XEXP (operands[0], 0), 0),
6620 XEXP (XEXP (operands[0], 0), 1)));
f7fbdd4a 6621
d1f9b275 6622 emit_insn (gen_rtx_SET (replace_equiv_address (operands[0], operands[2]),
215b30b3 6623 operands[1]));
f7fbdd4a 6624
215b30b3 6625 if (code == POST_DEC)
6626 emit_insn (gen_addsi3 (operands[2], operands[2], GEN_INT (-8)));
6627
6628 DONE;
6629 }"
6630)
9c08d1fa 6631
9a1112d7 6632(define_insn "*movdf_soft_insn"
353cf59a 6633 [(set (match_operand:DF 0 "nonimmediate_soft_df_operand" "=r,r,r,q,m")
6634 (match_operand:DF 1 "soft_df_operand" "rDa,Db,Dc,mF,q"))]
cde1623a 6635 "TARGET_32BIT && TARGET_SOFT_FLOAT
b2778788 6636 && ( register_operand (operands[0], DFmode)
6637 || register_operand (operands[1], DFmode))"
d51f92df 6638 "*
6639 switch (which_alternative)
6640 {
6641 case 0:
6642 case 1:
6643 case 2:
6644 return \"#\";
6645 default:
26ff80c0 6646 return output_move_double (operands, true, NULL);
d51f92df 6647 }
6648 "
359a6e9f 6649 [(set_attr "length" "8,12,16,8,8")
1b7da4ac 6650 (set_attr "type" "multiple,multiple,multiple,load2,store2")
42e1de19 6651 (set_attr "arm_pool_range" "*,*,*,1020,*")
6652 (set_attr "thumb2_pool_range" "*,*,*,1018,*")
8848d797 6653 (set_attr "arm_neg_pool_range" "*,*,*,1004,*")
cde1623a 6654 (set_attr "thumb2_neg_pool_range" "*,*,*,0,*")]
cffb2a26 6655)
b11cae9e 6656\f
b11cae9e 6657
9c08d1fa 6658;; load- and store-multiple insns
6659;; The arm can load/store any set of registers, provided that they are in
320ea44d 6660;; ascending order, but these expanders assume a contiguous set.
b11cae9e 6661
9c08d1fa 6662(define_expand "load_multiple"
6663 [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
6664 (match_operand:SI 1 "" ""))
6665 (use (match_operand:SI 2 "" ""))])]
25f905c2 6666 "TARGET_32BIT"
9580c25f 6667{
6668 HOST_WIDE_INT offset = 0;
6669
bd5b4116 6670 /* Support only fixed point registers. */
0438d37f 6671 if (!CONST_INT_P (operands[2])
6e628811 6672 || INTVAL (operands[2]) > MAX_LDM_STM_OPS
9c08d1fa 6673 || INTVAL (operands[2]) < 2
0438d37f 6674 || !MEM_P (operands[1])
6675 || !REG_P (operands[0])
bd5b4116 6676 || REGNO (operands[0]) > (LAST_ARM_REGNUM - 1)
6677 || REGNO (operands[0]) + INTVAL (operands[2]) > LAST_ARM_REGNUM)
9c08d1fa 6678 FAIL;
6679
6680 operands[3]
320ea44d 6681 = arm_gen_load_multiple (arm_regs_in_sequence + REGNO (operands[0]),
6682 INTVAL (operands[2]),
f082f1c4 6683 force_reg (SImode, XEXP (operands[1], 0)),
320ea44d 6684 FALSE, operands[1], &offset);
9580c25f 6685})
b11cae9e 6686
9c08d1fa 6687(define_expand "store_multiple"
6688 [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
6689 (match_operand:SI 1 "" ""))
6690 (use (match_operand:SI 2 "" ""))])]
25f905c2 6691 "TARGET_32BIT"
9580c25f 6692{
6693 HOST_WIDE_INT offset = 0;
6694
674a8f0b 6695 /* Support only fixed point registers. */
0438d37f 6696 if (!CONST_INT_P (operands[2])
6e628811 6697 || INTVAL (operands[2]) > MAX_LDM_STM_OPS
9c08d1fa 6698 || INTVAL (operands[2]) < 2
0438d37f 6699 || !REG_P (operands[1])
6700 || !MEM_P (operands[0])
bd5b4116 6701 || REGNO (operands[1]) > (LAST_ARM_REGNUM - 1)
6702 || REGNO (operands[1]) + INTVAL (operands[2]) > LAST_ARM_REGNUM)
9c08d1fa 6703 FAIL;
6704
6705 operands[3]
320ea44d 6706 = arm_gen_store_multiple (arm_regs_in_sequence + REGNO (operands[1]),
6707 INTVAL (operands[2]),
f082f1c4 6708 force_reg (SImode, XEXP (operands[0], 0)),
320ea44d 6709 FALSE, operands[0], &offset);
9580c25f 6710})
b11cae9e 6711
9c08d1fa 6712
e34ebfca 6713(define_expand "setmemsi"
6714 [(match_operand:BLK 0 "general_operand" "")
6715 (match_operand:SI 1 "const_int_operand" "")
6716 (match_operand:SI 2 "const_int_operand" "")
6717 (match_operand:SI 3 "const_int_operand" "")]
6718 "TARGET_32BIT"
6719{
6720 if (arm_gen_setmem (operands))
6721 DONE;
6722
6723 FAIL;
6724})
6725
6726
9c08d1fa 6727;; Move a block of memory if it is word aligned and MORE than 2 words long.
6728;; We could let this apply for blocks of less than this, but it clobbers so
6729;; many registers that there is then probably a better way.
6730
008c057d 6731(define_expand "movmemqi"
34191dd1 6732 [(match_operand:BLK 0 "general_operand" "")
6733 (match_operand:BLK 1 "general_operand" "")
6734 (match_operand:SI 2 "const_int_operand" "")
6735 (match_operand:SI 3 "const_int_operand" "")]
ae51a965 6736 ""
9c08d1fa 6737 "
25f905c2 6738 if (TARGET_32BIT)
cffb2a26 6739 {
ae51a965 6740 if (TARGET_LDRD && current_tune->prefer_ldrd_strd
6741 && !optimize_function_for_size_p (cfun))
6742 {
6743 if (gen_movmem_ldrd_strd (operands))
6744 DONE;
6745 FAIL;
6746 }
6747
008c057d 6748 if (arm_gen_movmemqi (operands))
cffb2a26 6749 DONE;
6750 FAIL;
6751 }
25f905c2 6752 else /* TARGET_THUMB1 */
cffb2a26 6753 {
6754 if ( INTVAL (operands[3]) != 4
6755 || INTVAL (operands[2]) > 48)
6756 FAIL;
6757
008c057d 6758 thumb_expand_movmemqi (operands);
cffb2a26 6759 DONE;
6760 }
6761 "
6762)
9c08d1fa 6763\f
b11cae9e 6764
341940e8 6765;; Compare & branch insns
8d232dc7 6766;; The range calculations are based as follows:
341940e8 6767;; For forward branches, the address calculation returns the address of
6768;; the next instruction. This is 2 beyond the branch instruction.
6769;; For backward branches, the address calculation returns the address of
6770;; the first instruction in this pattern (cmp). This is 2 before the branch
6771;; instruction for the shortest sequence, and 4 before the branch instruction
6772;; if we have to jump around an unconditional branch.
6773;; To the basic branch range the PC offset must be added (this is +4).
6774;; So for forward branches we have
6775;; (pos_range - pos_base_offs + pc_offs) = (pos_range - 2 + 4).
6776;; And for backward branches we have
6777;; (neg_range - neg_base_offs + pc_offs) = (neg_range - (-2 or -4) + 4).
6778;;
6779;; For a 'b' pos_range = 2046, neg_range = -2048 giving (-2040->2048).
6780;; For a 'b<cond>' pos_range = 254, neg_range = -256 giving (-250 ->256).
cffb2a26 6781
aeac46d4 6782(define_expand "cbranchsi4"
6783 [(set (pc) (if_then_else
aa06947a 6784 (match_operator 0 "expandable_comparison_operator"
aeac46d4 6785 [(match_operand:SI 1 "s_register_operand" "")
6786 (match_operand:SI 2 "nonmemory_operand" "")])
6787 (label_ref (match_operand 3 "" ""))
6788 (pc)))]
f9aa4160 6789 "TARGET_EITHER"
aeac46d4 6790 "
74f4459c 6791 if (!TARGET_THUMB1)
6792 {
f9aa4160 6793 if (!arm_validize_comparison (&operands[0], &operands[1], &operands[2]))
6794 FAIL;
74f4459c 6795 emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
6796 operands[3]));
6797 DONE;
6798 }
25f905c2 6799 if (thumb1_cmpneg_operand (operands[2], SImode))
aeac46d4 6800 {
6801 emit_jump_insn (gen_cbranchsi4_scratch (NULL, operands[1], operands[2],
6802 operands[3], operands[0]));
6803 DONE;
6804 }
25f905c2 6805 if (!thumb1_cmp_operand (operands[2], SImode))
aeac46d4 6806 operands[2] = force_reg (SImode, operands[2]);
6807 ")
6808
74f4459c 6809(define_expand "cbranchsf4"
6810 [(set (pc) (if_then_else
aa06947a 6811 (match_operator 0 "expandable_comparison_operator"
74f4459c 6812 [(match_operand:SF 1 "s_register_operand" "")
6813 (match_operand:SF 2 "arm_float_compare_operand" "")])
6814 (label_ref (match_operand 3 "" ""))
6815 (pc)))]
6816 "TARGET_32BIT && TARGET_HARD_FLOAT"
6817 "emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
6818 operands[3])); DONE;"
6819)
6820
6821(define_expand "cbranchdf4"
6822 [(set (pc) (if_then_else
aa06947a 6823 (match_operator 0 "expandable_comparison_operator"
74f4459c 6824 [(match_operand:DF 1 "s_register_operand" "")
6825 (match_operand:DF 2 "arm_float_compare_operand" "")])
6826 (label_ref (match_operand 3 "" ""))
6827 (pc)))]
a50d7267 6828 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
74f4459c 6829 "emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
6830 operands[3])); DONE;"
6831)
6832
74f4459c 6833(define_expand "cbranchdi4"
6834 [(set (pc) (if_then_else
aa06947a 6835 (match_operator 0 "expandable_comparison_operator"
b8eae306 6836 [(match_operand:DI 1 "s_register_operand" "")
a8045a4f 6837 (match_operand:DI 2 "cmpdi_operand" "")])
74f4459c 6838 (label_ref (match_operand 3 "" ""))
6839 (pc)))]
a8045a4f 6840 "TARGET_32BIT"
6841 "{
0438d37f 6842 if (!arm_validize_comparison (&operands[0], &operands[1], &operands[2]))
f9aa4160 6843 FAIL;
6844 emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
a8045a4f 6845 operands[3]));
6846 DONE;
6847 }"
74f4459c 6848)
6849
9c08d1fa 6850;; Comparison and test insns
6851
cffb2a26 6852(define_insn "*arm_cmpsi_insn"
bd5b4116 6853 [(set (reg:CC CC_REGNUM)
f9f234ec 6854 (compare:CC (match_operand:SI 0 "s_register_operand" "l,r,r,r,r")
6855 (match_operand:SI 1 "arm_add_operand" "Py,r,r,I,L")))]
25f905c2 6856 "TARGET_32BIT"
5565501b 6857 "@
a6864a24 6858 cmp%?\\t%0, %1
6859 cmp%?\\t%0, %1
aea4c774 6860 cmp%?\\t%0, %1
f9f234ec 6861 cmp%?\\t%0, %1
aea4c774 6862 cmn%?\\t%0, #%n1"
a6864a24 6863 [(set_attr "conds" "set")
f9f234ec 6864 (set_attr "arch" "t2,t2,any,any,any")
6865 (set_attr "length" "2,2,4,4,4")
65f68e55 6866 (set_attr "predicable" "yes")
f9f234ec 6867 (set_attr "predicable_short_it" "yes,yes,yes,no,no")
112eda6f 6868 (set_attr "type" "alus_imm,alus_sreg,alus_sreg,alus_imm,alus_imm")]
cffb2a26 6869)
b11cae9e 6870
d5d4dc8d 6871(define_insn "*cmpsi_shiftsi"
bd5b4116 6872 [(set (reg:CC CC_REGNUM)
d82e788e 6873 (compare:CC (match_operand:SI 0 "s_register_operand" "r,r,r")
cffb2a26 6874 (match_operator:SI 3 "shift_operator"
d82e788e 6875 [(match_operand:SI 1 "s_register_operand" "r,r,r")
6876 (match_operand:SI 2 "shift_amount_operand" "M,r,M")])))]
d5d4dc8d 6877 "TARGET_32BIT"
f9f234ec 6878 "cmp\\t%0, %1%S3"
344495ea 6879 [(set_attr "conds" "set")
331beb1a 6880 (set_attr "shift" "1")
d82e788e 6881 (set_attr "arch" "32,a,a")
282b4c75 6882 (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")])
b11cae9e 6883
d5d4dc8d 6884(define_insn "*cmpsi_shiftsi_swp"
bd5b4116 6885 [(set (reg:CC_SWP CC_REGNUM)
aea4c774 6886 (compare:CC_SWP (match_operator:SI 3 "shift_operator"
d82e788e 6887 [(match_operand:SI 1 "s_register_operand" "r,r,r")
6888 (match_operand:SI 2 "shift_amount_operand" "M,r,M")])
6889 (match_operand:SI 0 "s_register_operand" "r,r,r")))]
d5d4dc8d 6890 "TARGET_32BIT"
aea4c774 6891 "cmp%?\\t%0, %1%S3"
344495ea 6892 [(set_attr "conds" "set")
331beb1a 6893 (set_attr "shift" "1")
d82e788e 6894 (set_attr "arch" "32,a,a")
282b4c75 6895 (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")])
b11cae9e 6896
25f905c2 6897(define_insn "*arm_cmpsi_negshiftsi_si"
aed179ae 6898 [(set (reg:CC_Z CC_REGNUM)
6899 (compare:CC_Z
6900 (neg:SI (match_operator:SI 1 "shift_operator"
6901 [(match_operand:SI 2 "s_register_operand" "r")
6902 (match_operand:SI 3 "reg_or_int_operand" "rM")]))
6903 (match_operand:SI 0 "s_register_operand" "r")))]
cffb2a26 6904 "TARGET_ARM"
aed179ae 6905 "cmn%?\\t%0, %2%S1"
344495ea 6906 [(set_attr "conds" "set")
aed179ae 6907 (set (attr "type") (if_then_else (match_operand 3 "const_int_operand" "")
d82e788e 6908 (const_string "alus_shift_imm")
6909 (const_string "alus_shift_reg")))
596e5e8f 6910 (set_attr "predicable" "yes")]
0d66636f 6911)
b11cae9e 6912
a8045a4f 6913;; DImode comparisons. The generic code generates branches that
6914;; if-conversion can not reduce to a conditional compare, so we do
6915;; that directly.
6916
ba6a3b2f 6917(define_insn_and_split "*arm_cmpdi_insn"
a8045a4f 6918 [(set (reg:CC_NCV CC_REGNUM)
6919 (compare:CC_NCV (match_operand:DI 0 "s_register_operand" "r")
6920 (match_operand:DI 1 "arm_di_operand" "rDi")))
6921 (clobber (match_scratch:SI 2 "=r"))]
b805622c 6922 "TARGET_32BIT"
ba6a3b2f 6923 "#" ; "cmp\\t%Q0, %Q1\;sbcs\\t%2, %R0, %R1"
6924 "&& reload_completed"
6925 [(set (reg:CC CC_REGNUM)
6926 (compare:CC (match_dup 0) (match_dup 1)))
6927 (parallel [(set (reg:CC CC_REGNUM)
6928 (compare:CC (match_dup 3) (match_dup 4)))
6929 (set (match_dup 2)
6930 (minus:SI (match_dup 5)
6931 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))])]
6932 {
6933 operands[3] = gen_highpart (SImode, operands[0]);
6934 operands[0] = gen_lowpart (SImode, operands[0]);
6935 if (CONST_INT_P (operands[1]))
6936 {
6937 operands[4] = GEN_INT (~INTVAL (gen_highpart_mode (SImode,
6938 DImode,
6939 operands[1])));
6940 operands[5] = gen_rtx_PLUS (SImode, operands[3], operands[4]);
6941 }
6942 else
6943 {
6944 operands[4] = gen_highpart (SImode, operands[1]);
6945 operands[5] = gen_rtx_MINUS (SImode, operands[3], operands[4]);
6946 }
6947 operands[1] = gen_lowpart (SImode, operands[1]);
6948 operands[2] = gen_lowpart (SImode, operands[2]);
6949 }
a8045a4f 6950 [(set_attr "conds" "set")
1b7da4ac 6951 (set_attr "length" "8")
6952 (set_attr "type" "multiple")]
a8045a4f 6953)
6954
ba6a3b2f 6955(define_insn_and_split "*arm_cmpdi_unsigned"
a8045a4f 6956 [(set (reg:CC_CZ CC_REGNUM)
1a86364b 6957 (compare:CC_CZ (match_operand:DI 0 "s_register_operand" "l,r,r,r")
6958 (match_operand:DI 1 "arm_di_operand" "Py,r,Di,rDi")))]
7c36fe71 6959
48a98053 6960 "TARGET_32BIT"
ba6a3b2f 6961 "#" ; "cmp\\t%R0, %R1\;it eq\;cmpeq\\t%Q0, %Q1"
6962 "&& reload_completed"
6963 [(set (reg:CC CC_REGNUM)
6964 (compare:CC (match_dup 2) (match_dup 3)))
6965 (cond_exec (eq:SI (reg:CC CC_REGNUM) (const_int 0))
6966 (set (reg:CC CC_REGNUM)
6967 (compare:CC (match_dup 0) (match_dup 1))))]
6968 {
6969 operands[2] = gen_highpart (SImode, operands[0]);
6970 operands[0] = gen_lowpart (SImode, operands[0]);
6971 if (CONST_INT_P (operands[1]))
6972 operands[3] = gen_highpart_mode (SImode, DImode, operands[1]);
6973 else
6974 operands[3] = gen_highpart (SImode, operands[1]);
6975 operands[1] = gen_lowpart (SImode, operands[1]);
6976 }
a8045a4f 6977 [(set_attr "conds" "set")
1a86364b 6978 (set_attr "enabled_for_depr_it" "yes,yes,no,*")
6979 (set_attr "arch" "t2,t2,t2,a")
6980 (set_attr "length" "6,6,10,8")
1b7da4ac 6981 (set_attr "type" "multiple")]
a8045a4f 6982)
6983
6984(define_insn "*arm_cmpdi_zero"
6985 [(set (reg:CC_Z CC_REGNUM)
6986 (compare:CC_Z (match_operand:DI 0 "s_register_operand" "r")
6987 (const_int 0)))
6988 (clobber (match_scratch:SI 1 "=r"))]
6989 "TARGET_32BIT"
6990 "orr%.\\t%1, %Q0, %R0"
1b7da4ac 6991 [(set_attr "conds" "set")
6992 (set_attr "type" "logics_reg")]
a8045a4f 6993)
6994
9c08d1fa 6995; This insn allows redundant compares to be removed by cse, nothing should
6996; ever appear in the output file since (set (reg x) (reg x)) is a no-op that
6997; is deleted later on. The match_dup will match the mode here, so that
6998; mode changes of the condition codes aren't lost by this even though we don't
6999; specify what they are.
7000
8a18b90c 7001(define_insn "*deleted_compare"
9c08d1fa 7002 [(set (match_operand 0 "cc_register" "") (match_dup 0))]
25f905c2 7003 "TARGET_32BIT"
40dbec34 7004 "\\t%@ deleted compare"
cffb2a26 7005 [(set_attr "conds" "set")
1b7da4ac 7006 (set_attr "length" "0")
7007 (set_attr "type" "no_insn")]
cffb2a26 7008)
9c08d1fa 7009
7010\f
7011;; Conditional branch insns
7012
74f4459c 7013(define_expand "cbranch_cc"
9c08d1fa 7014 [(set (pc)
74f4459c 7015 (if_then_else (match_operator 0 "" [(match_operand 1 "" "")
7016 (match_operand 2 "" "")])
7017 (label_ref (match_operand 3 "" ""))
9c08d1fa 7018 (pc)))]
25f905c2 7019 "TARGET_32BIT"
74f4459c 7020 "operands[1] = arm_gen_compare_reg (GET_CODE (operands[0]),
e1b93706 7021 operands[1], operands[2], NULL_RTX);
74f4459c 7022 operands[2] = const0_rtx;"
8fa3ba89 7023)
7024
7025;;
7026;; Patterns to match conditional branch insns.
7027;;
7028
ffcc986d 7029(define_insn "arm_cond_branch"
9c08d1fa 7030 [(set (pc)
8fa3ba89 7031 (if_then_else (match_operator 1 "arm_comparison_operator"
8a18b90c 7032 [(match_operand 2 "cc_register" "") (const_int 0)])
9c08d1fa 7033 (label_ref (match_operand 0 "" ""))
7034 (pc)))]
25f905c2 7035 "TARGET_32BIT"
d75350ce 7036 "*
9c08d1fa 7037 if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
cffb2a26 7038 {
7039 arm_ccfsm_state += 2;
7040 return \"\";
7041 }
e2348bcb 7042 return \"b%d1\\t%l0\";
cffb2a26 7043 "
a2cd141b 7044 [(set_attr "conds" "use")
a6864a24 7045 (set_attr "type" "branch")
7046 (set (attr "length")
7047 (if_then_else
0bf497f5 7048 (and (match_test "TARGET_THUMB2")
a6864a24 7049 (and (ge (minus (match_dup 0) (pc)) (const_int -250))
7050 (le (minus (match_dup 0) (pc)) (const_int 256))))
7051 (const_int 2)
7052 (const_int 4)))]
cffb2a26 7053)
d75350ce 7054
cffb2a26 7055(define_insn "*arm_cond_branch_reversed"
9c08d1fa 7056 [(set (pc)
8fa3ba89 7057 (if_then_else (match_operator 1 "arm_comparison_operator"
8a18b90c 7058 [(match_operand 2 "cc_register" "") (const_int 0)])
9c08d1fa 7059 (pc)
7060 (label_ref (match_operand 0 "" ""))))]
25f905c2 7061 "TARGET_32BIT"
d75350ce 7062 "*
9c08d1fa 7063 if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
cffb2a26 7064 {
7065 arm_ccfsm_state += 2;
7066 return \"\";
7067 }
e2348bcb 7068 return \"b%D1\\t%l0\";
cffb2a26 7069 "
a2cd141b 7070 [(set_attr "conds" "use")
a6864a24 7071 (set_attr "type" "branch")
7072 (set (attr "length")
7073 (if_then_else
0bf497f5 7074 (and (match_test "TARGET_THUMB2")
a6864a24 7075 (and (ge (minus (match_dup 0) (pc)) (const_int -250))
7076 (le (minus (match_dup 0) (pc)) (const_int 256))))
7077 (const_int 2)
7078 (const_int 4)))]
cffb2a26 7079)
7080
b11cae9e 7081\f
9c08d1fa 7082
7083; scc insns
7084
74f4459c 7085(define_expand "cstore_cc"
7db9af5d 7086 [(set (match_operand:SI 0 "s_register_operand" "")
74f4459c 7087 (match_operator:SI 1 "" [(match_operand 2 "" "")
7088 (match_operand 3 "" "")]))]
25f905c2 7089 "TARGET_32BIT"
74f4459c 7090 "operands[2] = arm_gen_compare_reg (GET_CODE (operands[1]),
e1b93706 7091 operands[2], operands[3], NULL_RTX);
74f4459c 7092 operands[3] = const0_rtx;"
8fa3ba89 7093)
7094
a3b84066 7095(define_insn_and_split "*mov_scc"
9c08d1fa 7096 [(set (match_operand:SI 0 "s_register_operand" "=r")
8fa3ba89 7097 (match_operator:SI 1 "arm_comparison_operator"
8a18b90c 7098 [(match_operand 2 "cc_register" "") (const_int 0)]))]
cffb2a26 7099 "TARGET_ARM"
a3b84066 7100 "#" ; "mov%D1\\t%0, #0\;mov%d1\\t%0, #1"
7101 "TARGET_ARM"
7102 [(set (match_dup 0)
7103 (if_then_else:SI (match_dup 1)
7104 (const_int 1)
7105 (const_int 0)))]
7106 ""
cffb2a26 7107 [(set_attr "conds" "use")
1b7da4ac 7108 (set_attr "length" "8")
7109 (set_attr "type" "multiple")]
cffb2a26 7110)
9c08d1fa 7111
a3b84066 7112(define_insn_and_split "*mov_negscc"
9c08d1fa 7113 [(set (match_operand:SI 0 "s_register_operand" "=r")
8fa3ba89 7114 (neg:SI (match_operator:SI 1 "arm_comparison_operator"
8a18b90c 7115 [(match_operand 2 "cc_register" "") (const_int 0)])))]
cffb2a26 7116 "TARGET_ARM"
a3b84066 7117 "#" ; "mov%D1\\t%0, #0\;mvn%d1\\t%0, #0"
7118 "TARGET_ARM"
7119 [(set (match_dup 0)
7120 (if_then_else:SI (match_dup 1)
7121 (match_dup 3)
7122 (const_int 0)))]
7123 {
7124 operands[3] = GEN_INT (~0);
7125 }
cffb2a26 7126 [(set_attr "conds" "use")
1b7da4ac 7127 (set_attr "length" "8")
7128 (set_attr "type" "multiple")]
cffb2a26 7129)
9c08d1fa 7130
a3b84066 7131(define_insn_and_split "*mov_notscc"
9c08d1fa 7132 [(set (match_operand:SI 0 "s_register_operand" "=r")
8fa3ba89 7133 (not:SI (match_operator:SI 1 "arm_comparison_operator"
8a18b90c 7134 [(match_operand 2 "cc_register" "") (const_int 0)])))]
cffb2a26 7135 "TARGET_ARM"
a3b84066 7136 "#" ; "mvn%D1\\t%0, #0\;mvn%d1\\t%0, #1"
7137 "TARGET_ARM"
7138 [(set (match_dup 0)
7139 (if_then_else:SI (match_dup 1)
7140 (match_dup 3)
7141 (match_dup 4)))]
7142 {
7143 operands[3] = GEN_INT (~1);
7144 operands[4] = GEN_INT (~0);
7145 }
cffb2a26 7146 [(set_attr "conds" "use")
1b7da4ac 7147 (set_attr "length" "8")
7148 (set_attr "type" "multiple")]
cffb2a26 7149)
9c08d1fa 7150
595d88b5 7151(define_expand "cstoresi4"
7152 [(set (match_operand:SI 0 "s_register_operand" "")
aa06947a 7153 (match_operator:SI 1 "expandable_comparison_operator"
595d88b5 7154 [(match_operand:SI 2 "s_register_operand" "")
7155 (match_operand:SI 3 "reg_or_int_operand" "")]))]
74f4459c 7156 "TARGET_32BIT || TARGET_THUMB1"
595d88b5 7157 "{
7158 rtx op3, scratch, scratch2;
7159
74f4459c 7160 if (!TARGET_THUMB1)
7161 {
7162 if (!arm_add_operand (operands[3], SImode))
7163 operands[3] = force_reg (SImode, operands[3]);
7164 emit_insn (gen_cstore_cc (operands[0], operands[1],
7165 operands[2], operands[3]));
7166 DONE;
7167 }
7168
595d88b5 7169 if (operands[3] == const0_rtx)
7170 {
7171 switch (GET_CODE (operands[1]))
7172 {
7173 case EQ:
25f905c2 7174 emit_insn (gen_cstoresi_eq0_thumb1 (operands[0], operands[2]));
595d88b5 7175 break;
7176
7177 case NE:
25f905c2 7178 emit_insn (gen_cstoresi_ne0_thumb1 (operands[0], operands[2]));
595d88b5 7179 break;
7180
7181 case LE:
7182 scratch = expand_binop (SImode, add_optab, operands[2], constm1_rtx,
7183 NULL_RTX, 0, OPTAB_WIDEN);
7184 scratch = expand_binop (SImode, ior_optab, operands[2], scratch,
7185 NULL_RTX, 0, OPTAB_WIDEN);
7186 expand_binop (SImode, lshr_optab, scratch, GEN_INT (31),
7187 operands[0], 1, OPTAB_WIDEN);
7188 break;
7189
7190 case GE:
7191 scratch = expand_unop (SImode, one_cmpl_optab, operands[2],
7192 NULL_RTX, 1);
7193 expand_binop (SImode, lshr_optab, scratch, GEN_INT (31),
7194 NULL_RTX, 1, OPTAB_WIDEN);
7195 break;
7196
7197 case GT:
7198 scratch = expand_binop (SImode, ashr_optab, operands[2],
7199 GEN_INT (31), NULL_RTX, 0, OPTAB_WIDEN);
7200 scratch = expand_binop (SImode, sub_optab, scratch, operands[2],
7201 NULL_RTX, 0, OPTAB_WIDEN);
7202 expand_binop (SImode, lshr_optab, scratch, GEN_INT (31), operands[0],
7203 0, OPTAB_WIDEN);
7204 break;
7205
7206 /* LT is handled by generic code. No need for unsigned with 0. */
7207 default:
7208 FAIL;
7209 }
7210 DONE;
7211 }
7212
7213 switch (GET_CODE (operands[1]))
7214 {
7215 case EQ:
7216 scratch = expand_binop (SImode, sub_optab, operands[2], operands[3],
7217 NULL_RTX, 0, OPTAB_WIDEN);
25f905c2 7218 emit_insn (gen_cstoresi_eq0_thumb1 (operands[0], scratch));
595d88b5 7219 break;
7220
7221 case NE:
7222 scratch = expand_binop (SImode, sub_optab, operands[2], operands[3],
7223 NULL_RTX, 0, OPTAB_WIDEN);
25f905c2 7224 emit_insn (gen_cstoresi_ne0_thumb1 (operands[0], scratch));
595d88b5 7225 break;
7226
7227 case LE:
7228 op3 = force_reg (SImode, operands[3]);
7229
7230 scratch = expand_binop (SImode, lshr_optab, operands[2], GEN_INT (31),
7231 NULL_RTX, 1, OPTAB_WIDEN);
7232 scratch2 = expand_binop (SImode, ashr_optab, op3, GEN_INT (31),
7233 NULL_RTX, 0, OPTAB_WIDEN);
25f905c2 7234 emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch2,
595d88b5 7235 op3, operands[2]));
7236 break;
7237
7238 case GE:
7239 op3 = operands[3];
25f905c2 7240 if (!thumb1_cmp_operand (op3, SImode))
595d88b5 7241 op3 = force_reg (SImode, op3);
7242 scratch = expand_binop (SImode, ashr_optab, operands[2], GEN_INT (31),
7243 NULL_RTX, 0, OPTAB_WIDEN);
7244 scratch2 = expand_binop (SImode, lshr_optab, op3, GEN_INT (31),
7245 NULL_RTX, 1, OPTAB_WIDEN);
25f905c2 7246 emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch2,
595d88b5 7247 operands[2], op3));
7248 break;
7249
7250 case LEU:
7251 op3 = force_reg (SImode, operands[3]);
7252 scratch = force_reg (SImode, const0_rtx);
25f905c2 7253 emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch,
595d88b5 7254 op3, operands[2]));
7255 break;
7256
7257 case GEU:
7258 op3 = operands[3];
25f905c2 7259 if (!thumb1_cmp_operand (op3, SImode))
595d88b5 7260 op3 = force_reg (SImode, op3);
7261 scratch = force_reg (SImode, const0_rtx);
25f905c2 7262 emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch,
595d88b5 7263 operands[2], op3));
7264 break;
7265
7266 case LTU:
7267 op3 = operands[3];
25f905c2 7268 if (!thumb1_cmp_operand (op3, SImode))
595d88b5 7269 op3 = force_reg (SImode, op3);
7270 scratch = gen_reg_rtx (SImode);
408b7ae5 7271 emit_insn (gen_cstoresi_ltu_thumb1 (operands[0], operands[2], op3));
595d88b5 7272 break;
7273
7274 case GTU:
7275 op3 = force_reg (SImode, operands[3]);
7276 scratch = gen_reg_rtx (SImode);
408b7ae5 7277 emit_insn (gen_cstoresi_ltu_thumb1 (operands[0], op3, operands[2]));
595d88b5 7278 break;
7279
7280 /* No good sequences for GT, LT. */
7281 default:
7282 FAIL;
7283 }
7284 DONE;
7285}")
7286
74f4459c 7287(define_expand "cstoresf4"
7288 [(set (match_operand:SI 0 "s_register_operand" "")
aa06947a 7289 (match_operator:SI 1 "expandable_comparison_operator"
74f4459c 7290 [(match_operand:SF 2 "s_register_operand" "")
7291 (match_operand:SF 3 "arm_float_compare_operand" "")]))]
7292 "TARGET_32BIT && TARGET_HARD_FLOAT"
7293 "emit_insn (gen_cstore_cc (operands[0], operands[1],
7294 operands[2], operands[3])); DONE;"
7295)
7296
7297(define_expand "cstoredf4"
7298 [(set (match_operand:SI 0 "s_register_operand" "")
aa06947a 7299 (match_operator:SI 1 "expandable_comparison_operator"
74f4459c 7300 [(match_operand:DF 2 "s_register_operand" "")
7301 (match_operand:DF 3 "arm_float_compare_operand" "")]))]
d63ed457 7302 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
74f4459c 7303 "emit_insn (gen_cstore_cc (operands[0], operands[1],
7304 operands[2], operands[3])); DONE;"
7305)
7306
74f4459c 7307(define_expand "cstoredi4"
7308 [(set (match_operand:SI 0 "s_register_operand" "")
aa06947a 7309 (match_operator:SI 1 "expandable_comparison_operator"
b8eae306 7310 [(match_operand:DI 2 "s_register_operand" "")
a8045a4f 7311 (match_operand:DI 3 "cmpdi_operand" "")]))]
7312 "TARGET_32BIT"
7313 "{
f9aa4160 7314 if (!arm_validize_comparison (&operands[1],
7315 &operands[2],
7316 &operands[3]))
7317 FAIL;
7318 emit_insn (gen_cstore_cc (operands[0], operands[1], operands[2],
a8045a4f 7319 operands[3]));
7320 DONE;
7321 }"
74f4459c 7322)
7323
9c08d1fa 7324\f
39b5e676 7325;; Conditional move insns
7326
7327(define_expand "movsicc"
8a18b90c 7328 [(set (match_operand:SI 0 "s_register_operand" "")
aa06947a 7329 (if_then_else:SI (match_operand 1 "expandable_comparison_operator" "")
aea4c774 7330 (match_operand:SI 2 "arm_not_operand" "")
8a18b90c 7331 (match_operand:SI 3 "arm_not_operand" "")))]
25f905c2 7332 "TARGET_32BIT"
39b5e676 7333 "
215b30b3 7334 {
f9aa4160 7335 enum rtx_code code;
278b301d 7336 rtx ccreg;
7337
f9aa4160 7338 if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0),
7339 &XEXP (operands[1], 1)))
278b301d 7340 FAIL;
f9aa4160 7341
7342 code = GET_CODE (operands[1]);
74f4459c 7343 ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
e1b93706 7344 XEXP (operands[1], 1), NULL_RTX);
29bb088d 7345 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
215b30b3 7346 }"
7347)
39b5e676 7348
7349(define_expand "movsfcc"
8a18b90c 7350 [(set (match_operand:SF 0 "s_register_operand" "")
4df97ffc 7351 (if_then_else:SF (match_operand 1 "arm_cond_move_operator" "")
8a18b90c 7352 (match_operand:SF 2 "s_register_operand" "")
d86c91f6 7353 (match_operand:SF 3 "s_register_operand" "")))]
19f6bf8d 7354 "TARGET_32BIT && TARGET_HARD_FLOAT"
39b5e676 7355 "
215b30b3 7356 {
7357 enum rtx_code code = GET_CODE (operands[1]);
7358 rtx ccreg;
f082f1c4 7359
f9aa4160 7360 if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0),
7361 &XEXP (operands[1], 1)))
7362 FAIL;
39b5e676 7363
f9aa4160 7364 code = GET_CODE (operands[1]);
74f4459c 7365 ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
e1b93706 7366 XEXP (operands[1], 1), NULL_RTX);
29bb088d 7367 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
215b30b3 7368 }"
7369)
39b5e676 7370
7371(define_expand "movdfcc"
8a18b90c 7372 [(set (match_operand:DF 0 "s_register_operand" "")
4df97ffc 7373 (if_then_else:DF (match_operand 1 "arm_cond_move_operator" "")
8a18b90c 7374 (match_operand:DF 2 "s_register_operand" "")
d86c91f6 7375 (match_operand:DF 3 "s_register_operand" "")))]
994606f8 7376 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
39b5e676 7377 "
215b30b3 7378 {
7379 enum rtx_code code = GET_CODE (operands[1]);
278b301d 7380 rtx ccreg;
39b5e676 7381
f9aa4160 7382 if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0),
7383 &XEXP (operands[1], 1)))
7384 FAIL;
7385 code = GET_CODE (operands[1]);
74f4459c 7386 ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
e1b93706 7387 XEXP (operands[1], 1), NULL_RTX);
29bb088d 7388 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
215b30b3 7389 }"
7390)
39b5e676 7391
91cb50d2 7392(define_insn "*cmov<mode>"
7393 [(set (match_operand:SDF 0 "s_register_operand" "=<F_constraint>")
7394 (if_then_else:SDF (match_operator 1 "arm_vsel_comparison_operator"
7395 [(match_operand 2 "cc_register" "") (const_int 0)])
7396 (match_operand:SDF 3 "s_register_operand"
7397 "<F_constraint>")
7398 (match_operand:SDF 4 "s_register_operand"
7399 "<F_constraint>")))]
7400 "TARGET_HARD_FLOAT && TARGET_FPU_ARMV8 <vfp_double_cond>"
7401 "*
7402 {
7403 enum arm_cond_code code = maybe_get_arm_condition_code (operands[1]);
7404 switch (code)
7405 {
7406 case ARM_GE:
7407 case ARM_GT:
7408 case ARM_EQ:
7409 case ARM_VS:
7410 return \"vsel%d1.<V_if_elem>\\t%<V_reg>0, %<V_reg>3, %<V_reg>4\";
7411 case ARM_LT:
7412 case ARM_LE:
7413 case ARM_NE:
7414 case ARM_VC:
7415 return \"vsel%D1.<V_if_elem>\\t%<V_reg>0, %<V_reg>4, %<V_reg>3\";
7416 default:
7417 gcc_unreachable ();
7418 }
7419 return \"\";
7420 }"
7421 [(set_attr "conds" "use")
6664d308 7422 (set_attr "type" "fcsel")]
91cb50d2 7423)
7424
190efb17 7425(define_insn_and_split "*movsicc_insn"
f082f1c4 7426 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r,r,r,r,r")
8a18b90c 7427 (if_then_else:SI
8fa3ba89 7428 (match_operator 3 "arm_comparison_operator"
8a18b90c 7429 [(match_operand 4 "cc_register" "") (const_int 0)])
f082f1c4 7430 (match_operand:SI 1 "arm_not_operand" "0,0,rI,K,rI,rI,K,K")
7431 (match_operand:SI 2 "arm_not_operand" "rI,K,0,0,rI,K,rI,K")))]
cffb2a26 7432 "TARGET_ARM"
39b5e676 7433 "@
8a18b90c 7434 mov%D3\\t%0, %2
7435 mvn%D3\\t%0, #%B2
f082f1c4 7436 mov%d3\\t%0, %1
7437 mvn%d3\\t%0, #%B1
190efb17 7438 #
7439 #
7440 #
7441 #"
7442 ; alt4: mov%d3\\t%0, %1\;mov%D3\\t%0, %2
7443 ; alt5: mov%d3\\t%0, %1\;mvn%D3\\t%0, #%B2
7444 ; alt6: mvn%d3\\t%0, #%B1\;mov%D3\\t%0, %2
7445 ; alt7: mvn%d3\\t%0, #%B1\;mvn%D3\\t%0, #%B2"
7446 "&& reload_completed"
7447 [(const_int 0)]
7448 {
7449 enum rtx_code rev_code;
3754d046 7450 machine_mode mode;
190efb17 7451 rtx rev_cond;
7452
7453 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
7454 operands[3],
d1f9b275 7455 gen_rtx_SET (operands[0], operands[1])));
190efb17 7456
7457 rev_code = GET_CODE (operands[3]);
7458 mode = GET_MODE (operands[4]);
7459 if (mode == CCFPmode || mode == CCFPEmode)
7460 rev_code = reverse_condition_maybe_unordered (rev_code);
7461 else
7462 rev_code = reverse_condition (rev_code);
7463
7464 rev_cond = gen_rtx_fmt_ee (rev_code,
7465 VOIDmode,
7466 operands[4],
7467 const0_rtx);
7468 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
7469 rev_cond,
d1f9b275 7470 gen_rtx_SET (operands[0], operands[2])));
190efb17 7471 DONE;
7472 }
f082f1c4 7473 [(set_attr "length" "4,4,4,4,8,8,8,8")
d2a518d1 7474 (set_attr "conds" "use")
65f68e55 7475 (set_attr_alternative "type"
7476 [(if_then_else (match_operand 2 "const_int_operand" "")
1aed5204 7477 (const_string "mov_imm")
7478 (const_string "mov_reg"))
7479 (const_string "mvn_imm")
65f68e55 7480 (if_then_else (match_operand 1 "const_int_operand" "")
1aed5204 7481 (const_string "mov_imm")
7482 (const_string "mov_reg"))
7483 (const_string "mvn_imm")
282b4c75 7484 (const_string "multiple")
7485 (const_string "multiple")
7486 (const_string "multiple")
7487 (const_string "multiple")])]
215b30b3 7488)
39b5e676 7489
39b5e676 7490(define_insn "*movsfcc_soft_insn"
f082f1c4 7491 [(set (match_operand:SF 0 "s_register_operand" "=r,r")
8fa3ba89 7492 (if_then_else:SF (match_operator 3 "arm_comparison_operator"
8a18b90c 7493 [(match_operand 4 "cc_register" "") (const_int 0)])
f082f1c4 7494 (match_operand:SF 1 "s_register_operand" "0,r")
7495 (match_operand:SF 2 "s_register_operand" "r,0")))]
cffb2a26 7496 "TARGET_ARM && TARGET_SOFT_FLOAT"
f082f1c4 7497 "@
7498 mov%D3\\t%0, %2
7499 mov%d3\\t%0, %1"
d2a518d1 7500 [(set_attr "conds" "use")
1aed5204 7501 (set_attr "type" "mov_reg")]
8fa3ba89 7502)
39b5e676 7503
39b5e676 7504\f
9c08d1fa 7505;; Jump and linkage insns
7506
cffb2a26 7507(define_expand "jump"
9c08d1fa 7508 [(set (pc)
7509 (label_ref (match_operand 0 "" "")))]
cffb2a26 7510 "TARGET_EITHER"
9c08d1fa 7511 ""
cffb2a26 7512)
7513
7514(define_insn "*arm_jump"
7515 [(set (pc)
7516 (label_ref (match_operand 0 "" "")))]
25f905c2 7517 "TARGET_32BIT"
9c08d1fa 7518 "*
0d66636f 7519 {
7520 if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
7521 {
7522 arm_ccfsm_state += 2;
7523 return \"\";
7524 }
7525 return \"b%?\\t%l0\";
7526 }
7527 "
a6864a24 7528 [(set_attr "predicable" "yes")
7529 (set (attr "length")
7530 (if_then_else
0bf497f5 7531 (and (match_test "TARGET_THUMB2")
a6864a24 7532 (and (ge (minus (match_dup 0) (pc)) (const_int -2044))
7533 (le (minus (match_dup 0) (pc)) (const_int 2048))))
7534 (const_int 2)
1b7da4ac 7535 (const_int 4)))
7536 (set_attr "type" "branch")]
0d66636f 7537)
9c08d1fa 7538
d3373b54 7539(define_expand "call"
7540 [(parallel [(call (match_operand 0 "memory_operand" "")
7541 (match_operand 1 "general_operand" ""))
cffb2a26 7542 (use (match_operand 2 "" ""))
bd5b4116 7543 (clobber (reg:SI LR_REGNUM))])]
cffb2a26 7544 "TARGET_EITHER"
6c4c2133 7545 "
7546 {
bac7fc85 7547 rtx callee, pat;
bbe777ea 7548
bbe777ea 7549 /* In an untyped call, we can get NULL for operand 2. */
7550 if (operands[2] == NULL_RTX)
7551 operands[2] = const0_rtx;
7552
de55252a 7553 /* Decide if we should generate indirect calls by loading the
85c36fd1 7554 32-bit address of the callee into a register before performing the
de55252a 7555 branch and link. */
7556 callee = XEXP (operands[0], 0);
7557 if (GET_CODE (callee) == SYMBOL_REF
7558 ? arm_is_long_call_p (SYMBOL_REF_DECL (callee))
7559 : !REG_P (callee))
bbe777ea 7560 XEXP (operands[0], 0) = force_reg (Pmode, callee);
bac7fc85 7561
7562 pat = gen_call_internal (operands[0], operands[1], operands[2]);
ca373797 7563 arm_emit_call_insn (pat, XEXP (operands[0], 0), false);
bac7fc85 7564 DONE;
6c4c2133 7565 }"
7566)
d3373b54 7567
bac7fc85 7568(define_expand "call_internal"
7569 [(parallel [(call (match_operand 0 "memory_operand" "")
7570 (match_operand 1 "general_operand" ""))
7571 (use (match_operand 2 "" ""))
7572 (clobber (reg:SI LR_REGNUM))])])
7573
f1039640 7574(define_insn "*call_reg_armv5"
d3373b54 7575 [(call (mem:SI (match_operand:SI 0 "s_register_operand" "r"))
cffb2a26 7576 (match_operand 1 "" ""))
7577 (use (match_operand 2 "" ""))
bd5b4116 7578 (clobber (reg:SI LR_REGNUM))]
33ae7c4b 7579 "TARGET_ARM && arm_arch5 && !SIBLING_CALL_P (insn)"
f1039640 7580 "blx%?\\t%0"
7581 [(set_attr "type" "call")]
7582)
7583
7584(define_insn "*call_reg_arm"
7585 [(call (mem:SI (match_operand:SI 0 "s_register_operand" "r"))
7586 (match_operand 1 "" ""))
7587 (use (match_operand 2 "" ""))
7588 (clobber (reg:SI LR_REGNUM))]
33ae7c4b 7589 "TARGET_ARM && !arm_arch5 && !SIBLING_CALL_P (insn)"
9c08d1fa 7590 "*
5565501b 7591 return output_call (operands);
cffb2a26 7592 "
7593 ;; length is worst case, normally it is only two
7594 [(set_attr "length" "12")
7595 (set_attr "type" "call")]
7596)
9c08d1fa 7597
89504fc1 7598
7599;; Note: not used for armv5+ because the sequence used (ldr pc, ...) is not
7600;; considered a function call by the branch predictor of some cores (PR40887).
7601;; Falls back to blx rN (*call_reg_armv5).
7602
f7fbdd4a 7603(define_insn "*call_mem"
a3c63a9d 7604 [(call (mem:SI (match_operand:SI 0 "call_memory_operand" "m"))
cffb2a26 7605 (match_operand 1 "" ""))
7606 (use (match_operand 2 "" ""))
bd5b4116 7607 (clobber (reg:SI LR_REGNUM))]
33ae7c4b 7608 "TARGET_ARM && !arm_arch5 && !SIBLING_CALL_P (insn)"
9c08d1fa 7609 "*
5565501b 7610 return output_call_mem (operands);
cffb2a26 7611 "
7612 [(set_attr "length" "12")
7613 (set_attr "type" "call")]
7614)
7615
d3373b54 7616(define_expand "call_value"
e0698af7 7617 [(parallel [(set (match_operand 0 "" "")
7618 (call (match_operand 1 "memory_operand" "")
7619 (match_operand 2 "general_operand" "")))
cffb2a26 7620 (use (match_operand 3 "" ""))
bd5b4116 7621 (clobber (reg:SI LR_REGNUM))])]
cffb2a26 7622 "TARGET_EITHER"
6c4c2133 7623 "
7624 {
bac7fc85 7625 rtx pat, callee;
bbe777ea 7626
7627 /* In an untyped call, we can get NULL for operand 2. */
7628 if (operands[3] == 0)
7629 operands[3] = const0_rtx;
7630
de55252a 7631 /* Decide if we should generate indirect calls by loading the
7632 32-bit address of the callee into a register before performing the
7633 branch and link. */
7634 callee = XEXP (operands[1], 0);
7635 if (GET_CODE (callee) == SYMBOL_REF
7636 ? arm_is_long_call_p (SYMBOL_REF_DECL (callee))
7637 : !REG_P (callee))
78fe751b 7638 XEXP (operands[1], 0) = force_reg (Pmode, callee);
bac7fc85 7639
7640 pat = gen_call_value_internal (operands[0], operands[1],
7641 operands[2], operands[3]);
ca373797 7642 arm_emit_call_insn (pat, XEXP (operands[1], 0), false);
bac7fc85 7643 DONE;
6c4c2133 7644 }"
7645)
d3373b54 7646
bac7fc85 7647(define_expand "call_value_internal"
7648 [(parallel [(set (match_operand 0 "" "")
7649 (call (match_operand 1 "memory_operand" "")
7650 (match_operand 2 "general_operand" "")))
7651 (use (match_operand 3 "" ""))
7652 (clobber (reg:SI LR_REGNUM))])])
7653
f1039640 7654(define_insn "*call_value_reg_armv5"
27ed6835 7655 [(set (match_operand 0 "" "")
755eb2b4 7656 (call (mem:SI (match_operand:SI 1 "s_register_operand" "r"))
cffb2a26 7657 (match_operand 2 "" "")))
bbe777ea 7658 (use (match_operand 3 "" ""))
bd5b4116 7659 (clobber (reg:SI LR_REGNUM))]
33ae7c4b 7660 "TARGET_ARM && arm_arch5 && !SIBLING_CALL_P (insn)"
f1039640 7661 "blx%?\\t%1"
7662 [(set_attr "type" "call")]
7663)
7664
7665(define_insn "*call_value_reg_arm"
7666 [(set (match_operand 0 "" "")
7667 (call (mem:SI (match_operand:SI 1 "s_register_operand" "r"))
7668 (match_operand 2 "" "")))
7669 (use (match_operand 3 "" ""))
7670 (clobber (reg:SI LR_REGNUM))]
33ae7c4b 7671 "TARGET_ARM && !arm_arch5 && !SIBLING_CALL_P (insn)"
9c08d1fa 7672 "*
215b30b3 7673 return output_call (&operands[1]);
cffb2a26 7674 "
7675 [(set_attr "length" "12")
7676 (set_attr "type" "call")]
7677)
9c08d1fa 7678
89504fc1 7679;; Note: see *call_mem
7680
f7fbdd4a 7681(define_insn "*call_value_mem"
27ed6835 7682 [(set (match_operand 0 "" "")
a3c63a9d 7683 (call (mem:SI (match_operand:SI 1 "call_memory_operand" "m"))
cffb2a26 7684 (match_operand 2 "" "")))
bbe777ea 7685 (use (match_operand 3 "" ""))
bd5b4116 7686 (clobber (reg:SI LR_REGNUM))]
33ae7c4b 7687 "TARGET_ARM && !arm_arch5 && (!CONSTANT_ADDRESS_P (XEXP (operands[1], 0)))
7688 && !SIBLING_CALL_P (insn)"
9c08d1fa 7689 "*
215b30b3 7690 return output_call_mem (&operands[1]);
cffb2a26 7691 "
7692 [(set_attr "length" "12")
7693 (set_attr "type" "call")]
7694)
9c08d1fa 7695
7696;; Allow calls to SYMBOL_REFs specially as they are not valid general addresses
7697;; The 'a' causes the operand to be treated as an address, i.e. no '#' output.
7698
f7fbdd4a 7699(define_insn "*call_symbol"
27ed6835 7700 [(call (mem:SI (match_operand:SI 0 "" ""))
cffb2a26 7701 (match_operand 1 "" ""))
bbe777ea 7702 (use (match_operand 2 "" ""))
bd5b4116 7703 (clobber (reg:SI LR_REGNUM))]
d68c2c10 7704 "TARGET_32BIT
33ae7c4b 7705 && !SIBLING_CALL_P (insn)
cffb2a26 7706 && (GET_CODE (operands[0]) == SYMBOL_REF)
de55252a 7707 && !arm_is_long_call_p (SYMBOL_REF_DECL (operands[0]))"
6ebaa29d 7708 "*
7709 {
55c1e470 7710 return NEED_PLT_RELOC ? \"bl%?\\t%a0(PLT)\" : \"bl%?\\t%a0\";
6ebaa29d 7711 }"
cffb2a26 7712 [(set_attr "type" "call")]
7713)
9c08d1fa 7714
f7fbdd4a 7715(define_insn "*call_value_symbol"
ccd90aaa 7716 [(set (match_operand 0 "" "")
27ed6835 7717 (call (mem:SI (match_operand:SI 1 "" ""))
dd6d7504 7718 (match_operand:SI 2 "" "")))
bbe777ea 7719 (use (match_operand 3 "" ""))
bd5b4116 7720 (clobber (reg:SI LR_REGNUM))]
d68c2c10 7721 "TARGET_32BIT
33ae7c4b 7722 && !SIBLING_CALL_P (insn)
cffb2a26 7723 && (GET_CODE (operands[1]) == SYMBOL_REF)
de55252a 7724 && !arm_is_long_call_p (SYMBOL_REF_DECL (operands[1]))"
6ebaa29d 7725 "*
7726 {
55c1e470 7727 return NEED_PLT_RELOC ? \"bl%?\\t%a1(PLT)\" : \"bl%?\\t%a1\";
6ebaa29d 7728 }"
cffb2a26 7729 [(set_attr "type" "call")]
7730)
7731
ca373797 7732(define_expand "sibcall_internal"
7733 [(parallel [(call (match_operand 0 "memory_operand" "")
7734 (match_operand 1 "general_operand" ""))
7735 (return)
7736 (use (match_operand 2 "" ""))])])
7737
1c494086 7738;; We may also be able to do sibcalls for Thumb, but it's much harder...
7739(define_expand "sibcall"
7740 [(parallel [(call (match_operand 0 "memory_operand" "")
7741 (match_operand 1 "general_operand" ""))
2ba80634 7742 (return)
7743 (use (match_operand 2 "" ""))])]
d68c2c10 7744 "TARGET_32BIT"
1c494086 7745 "
7746 {
ca373797 7747 rtx pat;
7748
3112c3f7 7749 if ((!REG_P (XEXP (operands[0], 0))
7750 && GET_CODE (XEXP (operands[0], 0)) != SYMBOL_REF)
7751 || (GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
7752 && arm_is_long_call_p (SYMBOL_REF_DECL (XEXP (operands[0], 0)))))
33ae7c4b 7753 XEXP (operands[0], 0) = force_reg (SImode, XEXP (operands[0], 0));
7754
1c494086 7755 if (operands[2] == NULL_RTX)
7756 operands[2] = const0_rtx;
ca373797 7757
7758 pat = gen_sibcall_internal (operands[0], operands[1], operands[2]);
7759 arm_emit_call_insn (pat, operands[0], true);
7760 DONE;
1c494086 7761 }"
7762)
7763
ca373797 7764(define_expand "sibcall_value_internal"
7765 [(parallel [(set (match_operand 0 "" "")
7766 (call (match_operand 1 "memory_operand" "")
7767 (match_operand 2 "general_operand" "")))
7768 (return)
7769 (use (match_operand 3 "" ""))])])
7770
1c494086 7771(define_expand "sibcall_value"
ccd90aaa 7772 [(parallel [(set (match_operand 0 "" "")
1c494086 7773 (call (match_operand 1 "memory_operand" "")
7774 (match_operand 2 "general_operand" "")))
2ba80634 7775 (return)
7776 (use (match_operand 3 "" ""))])]
d68c2c10 7777 "TARGET_32BIT"
1c494086 7778 "
7779 {
ca373797 7780 rtx pat;
7781
3112c3f7 7782 if ((!REG_P (XEXP (operands[1], 0))
7783 && GET_CODE (XEXP (operands[1], 0)) != SYMBOL_REF)
7784 || (GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
7785 && arm_is_long_call_p (SYMBOL_REF_DECL (XEXP (operands[1], 0)))))
33ae7c4b 7786 XEXP (operands[1], 0) = force_reg (SImode, XEXP (operands[1], 0));
7787
1c494086 7788 if (operands[3] == NULL_RTX)
7789 operands[3] = const0_rtx;
ca373797 7790
7791 pat = gen_sibcall_value_internal (operands[0], operands[1],
7792 operands[2], operands[3]);
7793 arm_emit_call_insn (pat, operands[1], true);
7794 DONE;
1c494086 7795 }"
7796)
7797
7798(define_insn "*sibcall_insn"
84ce8e5c 7799 [(call (mem:SI (match_operand:SI 0 "call_insn_operand" "Cs, US"))
1c494086 7800 (match_operand 1 "" ""))
2ba80634 7801 (return)
7802 (use (match_operand 2 "" ""))]
33ae7c4b 7803 "TARGET_32BIT && SIBLING_CALL_P (insn)"
1c494086 7804 "*
33ae7c4b 7805 if (which_alternative == 1)
7806 return NEED_PLT_RELOC ? \"b%?\\t%a0(PLT)\" : \"b%?\\t%a0\";
7807 else
7808 {
7809 if (arm_arch5 || arm_arch4t)
947d113e 7810 return \"bx%?\\t%0\\t%@ indirect register sibling call\";
33ae7c4b 7811 else
7812 return \"mov%?\\t%|pc, %0\\t%@ indirect register sibling call\";
7813 }
1c494086 7814 "
7815 [(set_attr "type" "call")]
7816)
7817
7818(define_insn "*sibcall_value_insn"
84ce8e5c 7819 [(set (match_operand 0 "" "")
7820 (call (mem:SI (match_operand:SI 1 "call_insn_operand" "Cs,US"))
1c494086 7821 (match_operand 2 "" "")))
2ba80634 7822 (return)
7823 (use (match_operand 3 "" ""))]
33ae7c4b 7824 "TARGET_32BIT && SIBLING_CALL_P (insn)"
1c494086 7825 "*
33ae7c4b 7826 if (which_alternative == 1)
7827 return NEED_PLT_RELOC ? \"b%?\\t%a1(PLT)\" : \"b%?\\t%a1\";
7828 else
7829 {
7830 if (arm_arch5 || arm_arch4t)
84ce8e5c 7831 return \"bx%?\\t%1\";
33ae7c4b 7832 else
7833 return \"mov%?\\t%|pc, %1\\t@ indirect sibling call \";
7834 }
1c494086 7835 "
7836 [(set_attr "type" "call")]
7837)
7838
0686440e 7839(define_expand "<return_str>return"
9b23f0a7 7840 [(RETURNS)]
8cba51a5 7841 "(TARGET_ARM || (TARGET_THUMB2
7842 && ARM_FUNC_TYPE (arm_current_func_type ()) == ARM_FT_NORMAL
7843 && !IS_STACKALIGN (arm_current_func_type ())))
0686440e 7844 <return_cond_false>"
8cba51a5 7845 "
7846 {
7847 if (TARGET_THUMB2)
7848 {
0686440e 7849 thumb2_expand_return (<return_simple_p>);
8cba51a5 7850 DONE;
7851 }
7852 }
7853 "
7854)
d68c2c10 7855
9c08d1fa 7856;; Often the return insn will be the same as loading from memory, so set attr
d68c2c10 7857(define_insn "*arm_return"
9c08d1fa 7858 [(return)]
cffb2a26 7859 "TARGET_ARM && USE_RETURN_INSN (FALSE)"
9c08d1fa 7860 "*
9c08d1fa 7861 {
cffb2a26 7862 if (arm_ccfsm_state == 2)
7863 {
7864 arm_ccfsm_state += 2;
7865 return \"\";
7866 }
e2549f81 7867 return output_return_instruction (const_true_rtx, true, false, false);
cffb2a26 7868 }"
a2cd141b 7869 [(set_attr "type" "load1")
755eb2b4 7870 (set_attr "length" "12")
0d66636f 7871 (set_attr "predicable" "yes")]
cffb2a26 7872)
9c08d1fa 7873
0686440e 7874(define_insn "*cond_<return_str>return"
9c08d1fa 7875 [(set (pc)
8fa3ba89 7876 (if_then_else (match_operator 0 "arm_comparison_operator"
8a18b90c 7877 [(match_operand 1 "cc_register" "") (const_int 0)])
9b23f0a7 7878 (RETURNS)
9c08d1fa 7879 (pc)))]
0686440e 7880 "TARGET_ARM <return_cond_true>"
9c08d1fa 7881 "*
8fa3ba89 7882 {
7883 if (arm_ccfsm_state == 2)
7884 {
7885 arm_ccfsm_state += 2;
7886 return \"\";
7887 }
0686440e 7888 return output_return_instruction (operands[0], true, false,
7889 <return_simple_p>);
8fa3ba89 7890 }"
7891 [(set_attr "conds" "use")
755eb2b4 7892 (set_attr "length" "12")
a2cd141b 7893 (set_attr "type" "load1")]
8fa3ba89 7894)
9c08d1fa 7895
0686440e 7896(define_insn "*cond_<return_str>return_inverted"
9c08d1fa 7897 [(set (pc)
8fa3ba89 7898 (if_then_else (match_operator 0 "arm_comparison_operator"
8a18b90c 7899 [(match_operand 1 "cc_register" "") (const_int 0)])
9c08d1fa 7900 (pc)
9b23f0a7 7901 (RETURNS)))]
0686440e 7902 "TARGET_ARM <return_cond_true>"
9c08d1fa 7903 "*
8fa3ba89 7904 {
7905 if (arm_ccfsm_state == 2)
7906 {
7907 arm_ccfsm_state += 2;
7908 return \"\";
7909 }
0686440e 7910 return output_return_instruction (operands[0], true, true,
7911 <return_simple_p>);
8fa3ba89 7912 }"
7913 [(set_attr "conds" "use")
37a1317b 7914 (set_attr "length" "12")
a2cd141b 7915 (set_attr "type" "load1")]
8fa3ba89 7916)
9c08d1fa 7917
e2549f81 7918(define_insn "*arm_simple_return"
7919 [(simple_return)]
7920 "TARGET_ARM"
7921 "*
7922 {
7923 if (arm_ccfsm_state == 2)
7924 {
7925 arm_ccfsm_state += 2;
7926 return \"\";
7927 }
7928 return output_return_instruction (const_true_rtx, true, false, true);
7929 }"
7930 [(set_attr "type" "branch")
7931 (set_attr "length" "4")
7932 (set_attr "predicable" "yes")]
7933)
7934
68121397 7935;; Generate a sequence of instructions to determine if the processor is
7936;; in 26-bit or 32-bit mode, and return the appropriate return address
7937;; mask.
7938
7939(define_expand "return_addr_mask"
7940 [(set (match_dup 1)
7941 (compare:CC_NOOV (unspec [(const_int 0)] UNSPEC_CHECK_ARCH)
7942 (const_int 0)))
7943 (set (match_operand:SI 0 "s_register_operand" "")
7944 (if_then_else:SI (eq (match_dup 1) (const_int 0))
7945 (const_int -1)
7946 (const_int 67108860)))] ; 0x03fffffc
7947 "TARGET_ARM"
7948 "
62eddbd4 7949 operands[1] = gen_rtx_REG (CC_NOOVmode, CC_REGNUM);
68121397 7950 ")
7951
7952(define_insn "*check_arch2"
7953 [(set (match_operand:CC_NOOV 0 "cc_register" "")
7954 (compare:CC_NOOV (unspec [(const_int 0)] UNSPEC_CHECK_ARCH)
7955 (const_int 0)))]
7956 "TARGET_ARM"
7957 "teq\\t%|r0, %|r0\;teq\\t%|pc, %|pc"
7958 [(set_attr "length" "8")
1b7da4ac 7959 (set_attr "conds" "set")
7960 (set_attr "type" "multiple")]
68121397 7961)
7962
9c08d1fa 7963;; Call subroutine returning any type.
7964
7965(define_expand "untyped_call"
7966 [(parallel [(call (match_operand 0 "" "")
7967 (const_int 0))
7968 (match_operand 1 "" "")
7969 (match_operand 2 "" "")])]
ccd90aaa 7970 "TARGET_EITHER"
9c08d1fa 7971 "
215b30b3 7972 {
7973 int i;
ccd90aaa 7974 rtx par = gen_rtx_PARALLEL (VOIDmode,
7975 rtvec_alloc (XVECLEN (operands[2], 0)));
7976 rtx addr = gen_reg_rtx (Pmode);
7977 rtx mem;
7978 int size = 0;
9c08d1fa 7979
ccd90aaa 7980 emit_move_insn (addr, XEXP (operands[1], 0));
7981 mem = change_address (operands[1], BLKmode, addr);
9c08d1fa 7982
215b30b3 7983 for (i = 0; i < XVECLEN (operands[2], 0); i++)
7984 {
ccd90aaa 7985 rtx src = SET_SRC (XVECEXP (operands[2], 0, i));
9c08d1fa 7986
ccd90aaa 7987 /* Default code only uses r0 as a return value, but we could
7988 be using anything up to 4 registers. */
7989 if (REGNO (src) == R0_REGNUM)
7990 src = gen_rtx_REG (TImode, R0_REGNUM);
7991
7992 XVECEXP (par, 0, i) = gen_rtx_EXPR_LIST (VOIDmode, src,
7993 GEN_INT (size));
7994 size += GET_MODE_SIZE (GET_MODE (src));
7995 }
7996
7997 emit_call_insn (GEN_CALL_VALUE (par, operands[0], const0_rtx, NULL,
7998 const0_rtx));
7999
8000 size = 0;
8001
8002 for (i = 0; i < XVECLEN (par, 0); i++)
8003 {
8004 HOST_WIDE_INT offset = 0;
8005 rtx reg = XEXP (XVECEXP (par, 0, i), 0);
8006
8007 if (size != 0)
29c05e22 8008 emit_move_insn (addr, plus_constant (Pmode, addr, size));
ccd90aaa 8009
8010 mem = change_address (mem, GET_MODE (reg), NULL);
8011 if (REGNO (reg) == R0_REGNUM)
8012 {
8013 /* On thumb we have to use a write-back instruction. */
320ea44d 8014 emit_insn (arm_gen_store_multiple (arm_regs_in_sequence, 4, addr,
8015 TARGET_THUMB ? TRUE : FALSE, mem, &offset));
ccd90aaa 8016 size = TARGET_ARM ? 16 : 0;
8017 }
8018 else
8019 {
8020 emit_move_insn (mem, reg);
8021 size = GET_MODE_SIZE (GET_MODE (reg));
8022 }
215b30b3 8023 }
9c08d1fa 8024
215b30b3 8025 /* The optimizer does not know that the call sets the function value
8026 registers we stored in the result block. We avoid problems by
8027 claiming that all hard registers are used and clobbered at this
8028 point. */
8029 emit_insn (gen_blockage ());
8030
8031 DONE;
8032 }"
8033)
9c08d1fa 8034
ccd90aaa 8035(define_expand "untyped_return"
8036 [(match_operand:BLK 0 "memory_operand" "")
8037 (match_operand 1 "" "")]
8038 "TARGET_EITHER"
8039 "
8040 {
8041 int i;
8042 rtx addr = gen_reg_rtx (Pmode);
8043 rtx mem;
8044 int size = 0;
8045
8046 emit_move_insn (addr, XEXP (operands[0], 0));
8047 mem = change_address (operands[0], BLKmode, addr);
8048
8049 for (i = 0; i < XVECLEN (operands[1], 0); i++)
8050 {
8051 HOST_WIDE_INT offset = 0;
8052 rtx reg = SET_DEST (XVECEXP (operands[1], 0, i));
8053
8054 if (size != 0)
29c05e22 8055 emit_move_insn (addr, plus_constant (Pmode, addr, size));
ccd90aaa 8056
8057 mem = change_address (mem, GET_MODE (reg), NULL);
8058 if (REGNO (reg) == R0_REGNUM)
8059 {
8060 /* On thumb we have to use a write-back instruction. */
320ea44d 8061 emit_insn (arm_gen_load_multiple (arm_regs_in_sequence, 4, addr,
8062 TARGET_THUMB ? TRUE : FALSE, mem, &offset));
ccd90aaa 8063 size = TARGET_ARM ? 16 : 0;
8064 }
8065 else
8066 {
8067 emit_move_insn (reg, mem);
8068 size = GET_MODE_SIZE (GET_MODE (reg));
8069 }
8070 }
8071
8072 /* Emit USE insns before the return. */
8073 for (i = 0; i < XVECLEN (operands[1], 0); i++)
18b42941 8074 emit_use (SET_DEST (XVECEXP (operands[1], 0, i)));
ccd90aaa 8075
8076 /* Construct the return. */
8077 expand_naked_return ();
8078
8079 DONE;
8080 }"
8081)
8082
9c08d1fa 8083;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
8084;; all of memory. This blocks insns from being moved across this point.
8085
8086(define_insn "blockage"
e1159bbe 8087 [(unspec_volatile [(const_int 0)] VUNSPEC_BLOCKAGE)]
cffb2a26 8088 "TARGET_EITHER"
9c08d1fa 8089 ""
cffb2a26 8090 [(set_attr "length" "0")
8091 (set_attr "type" "block")]
8092)
9c08d1fa 8093
f7fbdd4a 8094(define_expand "casesi"
8095 [(match_operand:SI 0 "s_register_operand" "") ; index to jump on
aea4c774 8096 (match_operand:SI 1 "const_int_operand" "") ; lower bound
8097 (match_operand:SI 2 "const_int_operand" "") ; total range
f7fbdd4a 8098 (match_operand:SI 3 "" "") ; table label
8099 (match_operand:SI 4 "" "")] ; Out of range label
e6ac8414 8100 "TARGET_32BIT || optimize_size || flag_pic"
f7fbdd4a 8101 "
215b30b3 8102 {
e6ac8414 8103 enum insn_code code;
215b30b3 8104 if (operands[1] != const0_rtx)
8105 {
e6ac8414 8106 rtx reg = gen_reg_rtx (SImode);
f7fbdd4a 8107
215b30b3 8108 emit_insn (gen_addsi3 (reg, operands[0],
d022fa24 8109 gen_int_mode (-INTVAL (operands[1]),
8110 SImode)));
215b30b3 8111 operands[0] = reg;
8112 }
9c08d1fa 8113
25f905c2 8114 if (TARGET_ARM)
e6ac8414 8115 code = CODE_FOR_arm_casesi_internal;
3db2019b 8116 else if (TARGET_THUMB1)
e6ac8414 8117 code = CODE_FOR_thumb1_casesi_internal_pic;
25f905c2 8118 else if (flag_pic)
e6ac8414 8119 code = CODE_FOR_thumb2_casesi_internal_pic;
25f905c2 8120 else
e6ac8414 8121 code = CODE_FOR_thumb2_casesi_internal;
8122
8123 if (!insn_data[(int) code].operand[1].predicate(operands[2], SImode))
8124 operands[2] = force_reg (SImode, operands[2]);
8125
8126 emit_jump_insn (GEN_FCN ((int) code) (operands[0], operands[2],
8127 operands[3], operands[4]));
215b30b3 8128 DONE;
8129 }"
8130)
f7fbdd4a 8131
f082f1c4 8132;; The USE in this pattern is needed to tell flow analysis that this is
8133;; a CASESI insn. It has no other purpose.
25f905c2 8134(define_insn "arm_casesi_internal"
f082f1c4 8135 [(parallel [(set (pc)
8136 (if_then_else
8137 (leu (match_operand:SI 0 "s_register_operand" "r")
8138 (match_operand:SI 1 "arm_rhs_operand" "rI"))
8139 (mem:SI (plus:SI (mult:SI (match_dup 0) (const_int 4))
8140 (label_ref (match_operand 2 "" ""))))
8141 (label_ref (match_operand 3 "" ""))))
bd5b4116 8142 (clobber (reg:CC CC_REGNUM))
f082f1c4 8143 (use (label_ref (match_dup 2)))])]
cffb2a26 8144 "TARGET_ARM"
f7fbdd4a 8145 "*
0d66636f 8146 if (flag_pic)
8147 return \"cmp\\t%0, %1\;addls\\t%|pc, %|pc, %0, asl #2\;b\\t%l3\";
8148 return \"cmp\\t%0, %1\;ldrls\\t%|pc, [%|pc, %0, asl #2]\;b\\t%l3\";
8149 "
8150 [(set_attr "conds" "clob")
1b7da4ac 8151 (set_attr "length" "12")
8152 (set_attr "type" "multiple")]
0d66636f 8153)
9c08d1fa 8154
cffb2a26 8155(define_expand "indirect_jump"
9c08d1fa 8156 [(set (pc)
cffb2a26 8157 (match_operand:SI 0 "s_register_operand" ""))]
8158 "TARGET_EITHER"
25f905c2 8159 "
8160 /* Thumb-2 doesn't have mov pc, reg. Explicitly set the low bit of the
8161 address and use bx. */
8162 if (TARGET_THUMB2)
8163 {
8164 rtx tmp;
8165 tmp = gen_reg_rtx (SImode);
8166 emit_insn (gen_iorsi3 (tmp, operands[0], GEN_INT(1)));
8167 operands[0] = tmp;
8168 }
8169 "
cffb2a26 8170)
8171
f1039640 8172;; NB Never uses BX.
cffb2a26 8173(define_insn "*arm_indirect_jump"
8174 [(set (pc)
8175 (match_operand:SI 0 "s_register_operand" "r"))]
8176 "TARGET_ARM"
8177 "mov%?\\t%|pc, %0\\t%@ indirect register jump"
1b7da4ac 8178 [(set_attr "predicable" "yes")
8179 (set_attr "type" "branch")]
cffb2a26 8180)
9c08d1fa 8181
f7fbdd4a 8182(define_insn "*load_indirect_jump"
9c08d1fa 8183 [(set (pc)
8184 (match_operand:SI 0 "memory_operand" "m"))]
cffb2a26 8185 "TARGET_ARM"
8186 "ldr%?\\t%|pc, %0\\t%@ indirect memory jump"
a2cd141b 8187 [(set_attr "type" "load1")
61a2d04c 8188 (set_attr "pool_range" "4096")
8189 (set_attr "neg_pool_range" "4084")
0d66636f 8190 (set_attr "predicable" "yes")]
cffb2a26 8191)
8192
9c08d1fa 8193\f
8194;; Misc insns
8195
8196(define_insn "nop"
8197 [(const_int 0)]
cffb2a26 8198 "TARGET_EITHER"
8199 "*
25f905c2 8200 if (TARGET_UNIFIED_ASM)
8201 return \"nop\";
cffb2a26 8202 if (TARGET_ARM)
8203 return \"mov%?\\t%|r0, %|r0\\t%@ nop\";
8204 return \"mov\\tr8, r8\";
8205 "
8206 [(set (attr "length")
8207 (if_then_else (eq_attr "is_thumb" "yes")
8208 (const_int 2)
1b7da4ac 8209 (const_int 4)))
8210 (set_attr "type" "mov_reg")]
cffb2a26 8211)
8212
ad9d4399 8213(define_insn "trap"
8214 [(trap_if (const_int 1) (const_int 0))]
8215 ""
8216 "*
8217 if (TARGET_ARM)
8218 return \".inst\\t0xe7f000f0\";
8219 else
8220 return \".inst\\t0xdeff\";
8221 "
8222 [(set (attr "length")
8223 (if_then_else (eq_attr "is_thumb" "yes")
8224 (const_int 2)
8225 (const_int 4)))
8226 (set_attr "type" "trap")
8227 (set_attr "conds" "unconditional")]
8228)
8229
9c08d1fa 8230\f
8231;; Patterns to allow combination of arithmetic, cond code and shifts
8232
0abea32c 8233(define_insn "*<arith_shift_insn>_multsi"
8234 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9b23f0a7 8235 (SHIFTABLE_OPS:SI
0abea32c 8236 (mult:SI (match_operand:SI 2 "s_register_operand" "r,r")
8237 (match_operand:SI 3 "power_of_two_operand" ""))
8238 (match_operand:SI 1 "s_register_operand" "rk,<t2_binop0>")))]
d5d4dc8d 8239 "TARGET_32BIT"
0abea32c 8240 "<arith_shift_insn>%?\\t%0, %1, %2, lsl %b3"
8241 [(set_attr "predicable" "yes")
8242 (set_attr "predicable_short_it" "no")
753d9835 8243 (set_attr "shift" "2")
0abea32c 8244 (set_attr "arch" "a,t2")
8245 (set_attr "type" "alu_shift_imm")])
8246
8247(define_insn "*<arith_shift_insn>_shiftsi"
8248 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9b23f0a7 8249 (SHIFTABLE_OPS:SI
0abea32c 8250 (match_operator:SI 2 "shift_nomul_operator"
8251 [(match_operand:SI 3 "s_register_operand" "r,r,r")
8252 (match_operand:SI 4 "shift_amount_operand" "M,M,r")])
8253 (match_operand:SI 1 "s_register_operand" "rk,<t2_binop0>,rk")))]
a021b821 8254 "TARGET_32BIT && GET_CODE (operands[2]) != MULT"
0abea32c 8255 "<arith_shift_insn>%?\\t%0, %1, %3%S2"
344495ea 8256 [(set_attr "predicable" "yes")
74ef923b 8257 (set_attr "predicable_short_it" "no")
753d9835 8258 (set_attr "shift" "3")
0abea32c 8259 (set_attr "arch" "a,t2,a")
8260 (set_attr "type" "alu_shift_imm,alu_shift_imm,alu_shift_reg")])
9c08d1fa 8261
d7863cfe 8262(define_split
8263 [(set (match_operand:SI 0 "s_register_operand" "")
8264 (match_operator:SI 1 "shiftable_operator"
8265 [(match_operator:SI 2 "shiftable_operator"
8266 [(match_operator:SI 3 "shift_operator"
8267 [(match_operand:SI 4 "s_register_operand" "")
8268 (match_operand:SI 5 "reg_or_int_operand" "")])
8269 (match_operand:SI 6 "s_register_operand" "")])
8270 (match_operand:SI 7 "arm_rhs_operand" "")]))
8271 (clobber (match_operand:SI 8 "s_register_operand" ""))]
d5d4dc8d 8272 "TARGET_32BIT"
d7863cfe 8273 [(set (match_dup 8)
8274 (match_op_dup 2 [(match_op_dup 3 [(match_dup 4) (match_dup 5)])
8275 (match_dup 6)]))
8276 (set (match_dup 0)
8277 (match_op_dup 1 [(match_dup 8) (match_dup 7)]))]
8278 "")
8279
f7fbdd4a 8280(define_insn "*arith_shiftsi_compare0"
bd5b4116 8281 [(set (reg:CC_NOOV CC_REGNUM)
d5d4dc8d 8282 (compare:CC_NOOV
8283 (match_operator:SI 1 "shiftable_operator"
8284 [(match_operator:SI 3 "shift_operator"
8285 [(match_operand:SI 4 "s_register_operand" "r,r")
8286 (match_operand:SI 5 "shift_amount_operand" "M,r")])
8287 (match_operand:SI 2 "s_register_operand" "r,r")])
8288 (const_int 0)))
8289 (set (match_operand:SI 0 "s_register_operand" "=r,r")
9c08d1fa 8290 (match_op_dup 1 [(match_op_dup 3 [(match_dup 4) (match_dup 5)])
8291 (match_dup 2)]))]
d5d4dc8d 8292 "TARGET_32BIT"
25f905c2 8293 "%i1%.\\t%0, %2, %4%S3"
344495ea 8294 [(set_attr "conds" "set")
331beb1a 8295 (set_attr "shift" "4")
d5d4dc8d 8296 (set_attr "arch" "32,a")
d82e788e 8297 (set_attr "type" "alus_shift_imm,alus_shift_reg")])
9c08d1fa 8298
f7fbdd4a 8299(define_insn "*arith_shiftsi_compare0_scratch"
bd5b4116 8300 [(set (reg:CC_NOOV CC_REGNUM)
d5d4dc8d 8301 (compare:CC_NOOV
8302 (match_operator:SI 1 "shiftable_operator"
8303 [(match_operator:SI 3 "shift_operator"
8304 [(match_operand:SI 4 "s_register_operand" "r,r")
8305 (match_operand:SI 5 "shift_amount_operand" "M,r")])
8306 (match_operand:SI 2 "s_register_operand" "r,r")])
8307 (const_int 0)))
8308 (clobber (match_scratch:SI 0 "=r,r"))]
8309 "TARGET_32BIT"
25f905c2 8310 "%i1%.\\t%0, %2, %4%S3"
344495ea 8311 [(set_attr "conds" "set")
331beb1a 8312 (set_attr "shift" "4")
d5d4dc8d 8313 (set_attr "arch" "32,a")
d82e788e 8314 (set_attr "type" "alus_shift_imm,alus_shift_reg")])
9c08d1fa 8315
f7fbdd4a 8316(define_insn "*sub_shiftsi"
d5d4dc8d 8317 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8318 (minus:SI (match_operand:SI 1 "s_register_operand" "r,r")
9c08d1fa 8319 (match_operator:SI 2 "shift_operator"
d5d4dc8d 8320 [(match_operand:SI 3 "s_register_operand" "r,r")
8321 (match_operand:SI 4 "shift_amount_operand" "M,r")])))]
8322 "TARGET_32BIT"
6c4c2133 8323 "sub%?\\t%0, %1, %3%S2"
344495ea 8324 [(set_attr "predicable" "yes")
331beb1a 8325 (set_attr "shift" "3")
d5d4dc8d 8326 (set_attr "arch" "32,a")
d82e788e 8327 (set_attr "type" "alus_shift_imm,alus_shift_reg")])
9c08d1fa 8328
f7fbdd4a 8329(define_insn "*sub_shiftsi_compare0"
bd5b4116 8330 [(set (reg:CC_NOOV CC_REGNUM)
40dbec34 8331 (compare:CC_NOOV
d82e788e 8332 (minus:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
40dbec34 8333 (match_operator:SI 2 "shift_operator"
d82e788e 8334 [(match_operand:SI 3 "s_register_operand" "r,r,r")
8335 (match_operand:SI 4 "shift_amount_operand" "M,r,M")]))
40dbec34 8336 (const_int 0)))
d82e788e 8337 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
d5d4dc8d 8338 (minus:SI (match_dup 1)
8339 (match_op_dup 2 [(match_dup 3) (match_dup 4)])))]
8340 "TARGET_32BIT"
25f905c2 8341 "sub%.\\t%0, %1, %3%S2"
344495ea 8342 [(set_attr "conds" "set")
a2cd141b 8343 (set_attr "shift" "3")
d82e788e 8344 (set_attr "arch" "32,a,a")
8345 (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")])
9c08d1fa 8346
f7fbdd4a 8347(define_insn "*sub_shiftsi_compare0_scratch"
bd5b4116 8348 [(set (reg:CC_NOOV CC_REGNUM)
40dbec34 8349 (compare:CC_NOOV
d82e788e 8350 (minus:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
40dbec34 8351 (match_operator:SI 2 "shift_operator"
d82e788e 8352 [(match_operand:SI 3 "s_register_operand" "r,r,r")
8353 (match_operand:SI 4 "shift_amount_operand" "M,r,M")]))
40dbec34 8354 (const_int 0)))
d82e788e 8355 (clobber (match_scratch:SI 0 "=r,r,r"))]
d5d4dc8d 8356 "TARGET_32BIT"
25f905c2 8357 "sub%.\\t%0, %1, %3%S2"
344495ea 8358 [(set_attr "conds" "set")
a2cd141b 8359 (set_attr "shift" "3")
d82e788e 8360 (set_attr "arch" "32,a,a")
8361 (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")])
9c08d1fa 8362\f
8363
190efb17 8364(define_insn_and_split "*and_scc"
9c08d1fa 8365 [(set (match_operand:SI 0 "s_register_operand" "=r")
8fa3ba89 8366 (and:SI (match_operator:SI 1 "arm_comparison_operator"
190efb17 8367 [(match_operand 2 "cc_register" "") (const_int 0)])
8368 (match_operand:SI 3 "s_register_operand" "r")))]
cffb2a26 8369 "TARGET_ARM"
190efb17 8370 "#" ; "mov%D1\\t%0, #0\;and%d1\\t%0, %3, #1"
8371 "&& reload_completed"
8372 [(cond_exec (match_dup 5) (set (match_dup 0) (const_int 0)))
8373 (cond_exec (match_dup 4) (set (match_dup 0)
8374 (and:SI (match_dup 3) (const_int 1))))]
8375 {
3754d046 8376 machine_mode mode = GET_MODE (operands[2]);
190efb17 8377 enum rtx_code rc = GET_CODE (operands[1]);
8378
8379 /* Note that operands[4] is the same as operands[1],
8380 but with VOIDmode as the result. */
8381 operands[4] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
8382 if (mode == CCFPmode || mode == CCFPEmode)
8383 rc = reverse_condition_maybe_unordered (rc);
8384 else
8385 rc = reverse_condition (rc);
8386 operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
8387 }
8fa3ba89 8388 [(set_attr "conds" "use")
1b7da4ac 8389 (set_attr "type" "multiple")
8fa3ba89 8390 (set_attr "length" "8")]
8391)
9c08d1fa 8392
190efb17 8393(define_insn_and_split "*ior_scc"
9c08d1fa 8394 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
190efb17 8395 (ior:SI (match_operator:SI 1 "arm_comparison_operator"
8396 [(match_operand 2 "cc_register" "") (const_int 0)])
8397 (match_operand:SI 3 "s_register_operand" "0,?r")))]
cffb2a26 8398 "TARGET_ARM"
e2348bcb 8399 "@
190efb17 8400 orr%d1\\t%0, %3, #1
8401 #"
8402 "&& reload_completed
8403 && REGNO (operands [0]) != REGNO (operands[3])"
8404 ;; && which_alternative == 1
8405 ; mov%D1\\t%0, %3\;orr%d1\\t%0, %3, #1
8406 [(cond_exec (match_dup 5) (set (match_dup 0) (match_dup 3)))
8407 (cond_exec (match_dup 4) (set (match_dup 0)
8408 (ior:SI (match_dup 3) (const_int 1))))]
8409 {
3754d046 8410 machine_mode mode = GET_MODE (operands[2]);
190efb17 8411 enum rtx_code rc = GET_CODE (operands[1]);
8412
8413 /* Note that operands[4] is the same as operands[1],
8414 but with VOIDmode as the result. */
8415 operands[4] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
8416 if (mode == CCFPmode || mode == CCFPEmode)
8417 rc = reverse_condition_maybe_unordered (rc);
8418 else
8419 rc = reverse_condition (rc);
8420 operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
8421 }
8fa3ba89 8422 [(set_attr "conds" "use")
1b7da4ac 8423 (set_attr "length" "4,8")
8424 (set_attr "type" "logic_imm,multiple")]
8fa3ba89 8425)
9c08d1fa 8426
2df9477b 8427; A series of splitters for the compare_scc pattern below. Note that
8428; order is important.
8429(define_split
8430 [(set (match_operand:SI 0 "s_register_operand" "")
8431 (lt:SI (match_operand:SI 1 "s_register_operand" "")
8432 (const_int 0)))
8433 (clobber (reg:CC CC_REGNUM))]
8434 "TARGET_32BIT && reload_completed"
8435 [(set (match_dup 0) (lshiftrt:SI (match_dup 1) (const_int 31)))])
8436
8437(define_split
8438 [(set (match_operand:SI 0 "s_register_operand" "")
8439 (ge:SI (match_operand:SI 1 "s_register_operand" "")
8440 (const_int 0)))
8441 (clobber (reg:CC CC_REGNUM))]
8442 "TARGET_32BIT && reload_completed"
8443 [(set (match_dup 0) (not:SI (match_dup 1)))
8444 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 31)))])
8445
98562479 8446(define_split
8447 [(set (match_operand:SI 0 "s_register_operand" "")
8448 (eq:SI (match_operand:SI 1 "s_register_operand" "")
8449 (const_int 0)))
8450 (clobber (reg:CC CC_REGNUM))]
8451 "arm_arch5 && TARGET_32BIT"
8452 [(set (match_dup 0) (clz:SI (match_dup 1)))
8453 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 5)))]
8454)
8455
2df9477b 8456(define_split
8457 [(set (match_operand:SI 0 "s_register_operand" "")
8458 (eq:SI (match_operand:SI 1 "s_register_operand" "")
8459 (const_int 0)))
8460 (clobber (reg:CC CC_REGNUM))]
8461 "TARGET_32BIT && reload_completed"
8462 [(parallel
080c0b9a 8463 [(set (reg:CC CC_REGNUM)
8464 (compare:CC (const_int 1) (match_dup 1)))
2df9477b 8465 (set (match_dup 0)
8466 (minus:SI (const_int 1) (match_dup 1)))])
080c0b9a 8467 (cond_exec (ltu:CC (reg:CC CC_REGNUM) (const_int 0))
2df9477b 8468 (set (match_dup 0) (const_int 0)))])
8469
8470(define_split
8471 [(set (match_operand:SI 0 "s_register_operand" "")
8472 (ne:SI (match_operand:SI 1 "s_register_operand" "")
8473 (match_operand:SI 2 "const_int_operand" "")))
8474 (clobber (reg:CC CC_REGNUM))]
8475 "TARGET_32BIT && reload_completed"
8476 [(parallel
8477 [(set (reg:CC CC_REGNUM)
8478 (compare:CC (match_dup 1) (match_dup 2)))
8479 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 3)))])
8480 (cond_exec (ne:CC (reg:CC CC_REGNUM) (const_int 0))
8481 (set (match_dup 0) (const_int 1)))]
8482{
8483 operands[3] = GEN_INT (-INTVAL (operands[2]));
8484})
8485
8486(define_split
8487 [(set (match_operand:SI 0 "s_register_operand" "")
8488 (ne:SI (match_operand:SI 1 "s_register_operand" "")
8489 (match_operand:SI 2 "arm_add_operand" "")))
8490 (clobber (reg:CC CC_REGNUM))]
8491 "TARGET_32BIT && reload_completed"
8492 [(parallel
8493 [(set (reg:CC_NOOV CC_REGNUM)
8494 (compare:CC_NOOV (minus:SI (match_dup 1) (match_dup 2))
8495 (const_int 0)))
8496 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
8497 (cond_exec (ne:CC_NOOV (reg:CC_NOOV CC_REGNUM) (const_int 0))
8498 (set (match_dup 0) (const_int 1)))])
8499
8500(define_insn_and_split "*compare_scc"
fd711051 8501 [(set (match_operand:SI 0 "s_register_operand" "=Ts,Ts")
8fa3ba89 8502 (match_operator:SI 1 "arm_comparison_operator"
5565501b 8503 [(match_operand:SI 2 "s_register_operand" "r,r")
8504 (match_operand:SI 3 "arm_add_operand" "rI,L")]))
bd5b4116 8505 (clobber (reg:CC CC_REGNUM))]
2df9477b 8506 "TARGET_32BIT"
8507 "#"
8508 "&& reload_completed"
8509 [(set (reg:CC CC_REGNUM) (compare:CC (match_dup 2) (match_dup 3)))
8510 (cond_exec (match_dup 4) (set (match_dup 0) (const_int 0)))
8511 (cond_exec (match_dup 5) (set (match_dup 0) (const_int 1)))]
8512{
8513 rtx tmp1;
3754d046 8514 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
2df9477b 8515 operands[2], operands[3]);
8516 enum rtx_code rc = GET_CODE (operands[1]);
e2348bcb 8517
2df9477b 8518 tmp1 = gen_rtx_REG (mode, CC_REGNUM);
080c0b9a 8519
2df9477b 8520 operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, tmp1, const0_rtx);
8521 if (mode == CCFPmode || mode == CCFPEmode)
8522 rc = reverse_condition_maybe_unordered (rc);
8523 else
8524 rc = reverse_condition (rc);
8525 operands[4] = gen_rtx_fmt_ee (rc, VOIDmode, tmp1, const0_rtx);
1b7da4ac 8526}
8527 [(set_attr "type" "multiple")]
8528)
9c08d1fa 8529
080c0b9a 8530;; Attempt to improve the sequence generated by the compare_scc splitters
8531;; not to use conditional execution.
98562479 8532
8533;; Rd = (eq (reg1) (const_int0)) // ARMv5
8534;; clz Rd, reg1
8535;; lsr Rd, Rd, #5
080c0b9a 8536(define_peephole2
8537 [(set (reg:CC CC_REGNUM)
8538 (compare:CC (match_operand:SI 1 "register_operand" "")
98562479 8539 (const_int 0)))
8540 (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
8541 (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
8542 (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
8543 (set (match_dup 0) (const_int 1)))]
8544 "arm_arch5 && TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)"
8545 [(set (match_dup 0) (clz:SI (match_dup 1)))
8546 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 5)))]
8547)
8548
8549;; Rd = (eq (reg1) (const_int0)) // !ARMv5
8550;; negs Rd, reg1
8551;; adc Rd, Rd, reg1
8552(define_peephole2
8553 [(set (reg:CC CC_REGNUM)
8554 (compare:CC (match_operand:SI 1 "register_operand" "")
8555 (const_int 0)))
080c0b9a 8556 (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
8557 (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
8558 (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
8559 (set (match_dup 0) (const_int 1)))
98562479 8560 (match_scratch:SI 2 "r")]
8561 "TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)"
922b6913 8562 [(parallel
8563 [(set (reg:CC CC_REGNUM)
98562479 8564 (compare:CC (const_int 0) (match_dup 1)))
8565 (set (match_dup 2) (minus:SI (const_int 0) (match_dup 1)))])
8566 (set (match_dup 0)
8567 (plus:SI (plus:SI (match_dup 1) (match_dup 2))
8568 (geu:SI (reg:CC CC_REGNUM) (const_int 0))))]
8569)
8570
31991287 8571;; Rd = (eq (reg1) (reg2/imm)) // ARMv5 and optimising for speed.
98562479 8572;; sub Rd, Reg1, reg2
8573;; clz Rd, Rd
8574;; lsr Rd, Rd, #5
8575(define_peephole2
8576 [(set (reg:CC CC_REGNUM)
8577 (compare:CC (match_operand:SI 1 "register_operand" "")
8578 (match_operand:SI 2 "arm_rhs_operand" "")))
8579 (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
8580 (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
8581 (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
8582 (set (match_dup 0) (const_int 1)))]
31991287 8583 "arm_arch5 && TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)
8584 && !(TARGET_THUMB2 && optimize_insn_for_size_p ())"
98562479 8585 [(set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))
8586 (set (match_dup 0) (clz:SI (match_dup 0)))
8587 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 5)))]
8588)
8589
8590
31991287 8591;; Rd = (eq (reg1) (reg2)) // ! ARMv5 or optimising for size.
98562479 8592;; sub T1, Reg1, reg2
8593;; negs Rd, T1
8594;; adc Rd, Rd, T1
8595(define_peephole2
8596 [(set (reg:CC CC_REGNUM)
8597 (compare:CC (match_operand:SI 1 "register_operand" "")
8598 (match_operand:SI 2 "arm_rhs_operand" "")))
8599 (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
8600 (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
8601 (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
8602 (set (match_dup 0) (const_int 1)))
8603 (match_scratch:SI 3 "r")]
8604 "TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)"
31991287 8605 [(set (match_dup 3) (match_dup 4))
080c0b9a 8606 (parallel
8607 [(set (reg:CC CC_REGNUM)
8608 (compare:CC (const_int 0) (match_dup 3)))
8609 (set (match_dup 0) (minus:SI (const_int 0) (match_dup 3)))])
98562479 8610 (set (match_dup 0)
8611 (plus:SI (plus:SI (match_dup 0) (match_dup 3))
8612 (geu:SI (reg:CC CC_REGNUM) (const_int 0))))]
31991287 8613 "
8614 if (CONST_INT_P (operands[2]))
8615 operands[4] = plus_constant (SImode, operands[1], -INTVAL (operands[2]));
8616 else
8617 operands[4] = gen_rtx_MINUS (SImode, operands[1], operands[2]);
8618 ")
080c0b9a 8619
f7fbdd4a 8620(define_insn "*cond_move"
9c08d1fa 8621 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
aea4c774 8622 (if_then_else:SI (match_operator 3 "equality_operator"
8fa3ba89 8623 [(match_operator 4 "arm_comparison_operator"
8a18b90c 8624 [(match_operand 5 "cc_register" "") (const_int 0)])
aea4c774 8625 (const_int 0)])
8626 (match_operand:SI 1 "arm_rhs_operand" "0,rI,?rI")
8627 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))]
cffb2a26 8628 "TARGET_ARM"
9c08d1fa 8629 "*
8fa3ba89 8630 if (GET_CODE (operands[3]) == NE)
8631 {
8632 if (which_alternative != 1)
8633 output_asm_insn (\"mov%D4\\t%0, %2\", operands);
8634 if (which_alternative != 0)
8635 output_asm_insn (\"mov%d4\\t%0, %1\", operands);
8636 return \"\";
8637 }
8638 if (which_alternative != 0)
8639 output_asm_insn (\"mov%D4\\t%0, %1\", operands);
8640 if (which_alternative != 1)
8641 output_asm_insn (\"mov%d4\\t%0, %2\", operands);
8642 return \"\";
8643 "
8644 [(set_attr "conds" "use")
282b4c75 8645 (set_attr_alternative "type"
8646 [(if_then_else (match_operand 2 "const_int_operand" "")
8647 (const_string "mov_imm")
8648 (const_string "mov_reg"))
8649 (if_then_else (match_operand 1 "const_int_operand" "")
8650 (const_string "mov_imm")
8651 (const_string "mov_reg"))
8652 (const_string "multiple")])
8fa3ba89 8653 (set_attr "length" "4,4,8")]
8654)
9c08d1fa 8655
f7fbdd4a 8656(define_insn "*cond_arith"
9c08d1fa 8657 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8658 (match_operator:SI 5 "shiftable_operator"
8fa3ba89 8659 [(match_operator:SI 4 "arm_comparison_operator"
9c08d1fa 8660 [(match_operand:SI 2 "s_register_operand" "r,r")
8661 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
8662 (match_operand:SI 1 "s_register_operand" "0,?r")]))
bd5b4116 8663 (clobber (reg:CC CC_REGNUM))]
cffb2a26 8664 "TARGET_ARM"
9c08d1fa 8665 "*
8fa3ba89 8666 if (GET_CODE (operands[4]) == LT && operands[3] == const0_rtx)
8667 return \"%i5\\t%0, %1, %2, lsr #31\";
40dbec34 8668
8fa3ba89 8669 output_asm_insn (\"cmp\\t%2, %3\", operands);
8670 if (GET_CODE (operands[5]) == AND)
8671 output_asm_insn (\"mov%D4\\t%0, #0\", operands);
8672 else if (GET_CODE (operands[5]) == MINUS)
8673 output_asm_insn (\"rsb%D4\\t%0, %1, #0\", operands);
8674 else if (which_alternative != 0)
8675 output_asm_insn (\"mov%D4\\t%0, %1\", operands);
8676 return \"%i5%d4\\t%0, %1, #1\";
8677 "
8678 [(set_attr "conds" "clob")
1b7da4ac 8679 (set_attr "length" "12")
8680 (set_attr "type" "multiple")]
8fa3ba89 8681)
9c08d1fa 8682
f7fbdd4a 8683(define_insn "*cond_sub"
9c08d1fa 8684 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8685 (minus:SI (match_operand:SI 1 "s_register_operand" "0,?r")
8fa3ba89 8686 (match_operator:SI 4 "arm_comparison_operator"
9c08d1fa 8687 [(match_operand:SI 2 "s_register_operand" "r,r")
8688 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))
bd5b4116 8689 (clobber (reg:CC CC_REGNUM))]
cffb2a26 8690 "TARGET_ARM"
9c08d1fa 8691 "*
8fa3ba89 8692 output_asm_insn (\"cmp\\t%2, %3\", operands);
8693 if (which_alternative != 0)
8694 output_asm_insn (\"mov%D4\\t%0, %1\", operands);
8695 return \"sub%d4\\t%0, %1, #1\";
8696 "
8697 [(set_attr "conds" "clob")
1b7da4ac 8698 (set_attr "length" "8,12")
8699 (set_attr "type" "multiple")]
8fa3ba89 8700)
9c08d1fa 8701
aea4c774 8702(define_insn "*cmp_ite0"
cffb2a26 8703 [(set (match_operand 6 "dominant_cc_register" "")
aea4c774 8704 (compare
8705 (if_then_else:SI
8fa3ba89 8706 (match_operator 4 "arm_comparison_operator"
2ff91fec 8707 [(match_operand:SI 0 "s_register_operand"
8708 "l,l,l,r,r,r,r,r,r")
8709 (match_operand:SI 1 "arm_add_operand"
8710 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
8fa3ba89 8711 (match_operator:SI 5 "arm_comparison_operator"
2ff91fec 8712 [(match_operand:SI 2 "s_register_operand"
8713 "l,r,r,l,l,r,r,r,r")
8714 (match_operand:SI 3 "arm_add_operand"
8715 "lPy,rI,L,lPy,lPy,rI,rI,L,L")])
aea4c774 8716 (const_int 0))
8717 (const_int 0)))]
2ff91fec 8718 "TARGET_32BIT"
9c08d1fa 8719 "*
aea4c774 8720 {
2ff91fec 8721 static const char * const cmp1[NUM_OF_COND_CMP][2] =
8722 {
8723 {\"cmp%d5\\t%0, %1\",
8724 \"cmp%d4\\t%2, %3\"},
8725 {\"cmn%d5\\t%0, #%n1\",
8726 \"cmp%d4\\t%2, %3\"},
8727 {\"cmp%d5\\t%0, %1\",
8728 \"cmn%d4\\t%2, #%n3\"},
8729 {\"cmn%d5\\t%0, #%n1\",
8730 \"cmn%d4\\t%2, #%n3\"}
8731 };
8732 static const char * const cmp2[NUM_OF_COND_CMP][2] =
8733 {
8734 {\"cmp\\t%2, %3\",
8735 \"cmp\\t%0, %1\"},
8736 {\"cmp\\t%2, %3\",
8737 \"cmn\\t%0, #%n1\"},
8738 {\"cmn\\t%2, #%n3\",
8739 \"cmp\\t%0, %1\"},
8740 {\"cmn\\t%2, #%n3\",
8741 \"cmn\\t%0, #%n1\"}
8742 };
8743 static const char * const ite[2] =
8fa3ba89 8744 {
2ff91fec 8745 \"it\\t%d5\",
8746 \"it\\t%d4\"
8fa3ba89 8747 };
2ff91fec 8748 static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
8749 CMP_CMP, CMN_CMP, CMP_CMP,
8750 CMN_CMP, CMP_CMN, CMN_CMN};
8fa3ba89 8751 int swap =
8752 comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4]));
8753
2ff91fec 8754 output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
8755 if (TARGET_THUMB2) {
8756 output_asm_insn (ite[swap], operands);
8757 }
8758 output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
8759 return \"\";
8fa3ba89 8760 }"
8761 [(set_attr "conds" "set")
2ff91fec 8762 (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
1b7da4ac 8763 (set_attr "type" "multiple")
2ff91fec 8764 (set_attr_alternative "length"
8765 [(const_int 6)
8766 (const_int 8)
8767 (const_int 8)
8768 (const_int 8)
8769 (const_int 8)
8770 (if_then_else (eq_attr "is_thumb" "no")
8771 (const_int 8)
8772 (const_int 10))
8773 (if_then_else (eq_attr "is_thumb" "no")
8774 (const_int 8)
8775 (const_int 10))
8776 (if_then_else (eq_attr "is_thumb" "no")
8777 (const_int 8)
8778 (const_int 10))
8779 (if_then_else (eq_attr "is_thumb" "no")
8780 (const_int 8)
8781 (const_int 10))])]
8fa3ba89 8782)
9c08d1fa 8783
aea4c774 8784(define_insn "*cmp_ite1"
cffb2a26 8785 [(set (match_operand 6 "dominant_cc_register" "")
aea4c774 8786 (compare
8787 (if_then_else:SI
8fa3ba89 8788 (match_operator 4 "arm_comparison_operator"
2ff91fec 8789 [(match_operand:SI 0 "s_register_operand"
8790 "l,l,l,r,r,r,r,r,r")
8791 (match_operand:SI 1 "arm_add_operand"
8792 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
8fa3ba89 8793 (match_operator:SI 5 "arm_comparison_operator"
2ff91fec 8794 [(match_operand:SI 2 "s_register_operand"
8795 "l,r,r,l,l,r,r,r,r")
8796 (match_operand:SI 3 "arm_add_operand"
8797 "lPy,rI,L,lPy,lPy,rI,rI,L,L")])
aea4c774 8798 (const_int 1))
8799 (const_int 0)))]
2ff91fec 8800 "TARGET_32BIT"
9c08d1fa 8801 "*
9c08d1fa 8802 {
2ff91fec 8803 static const char * const cmp1[NUM_OF_COND_CMP][2] =
8804 {
8805 {\"cmp\\t%0, %1\",
8806 \"cmp\\t%2, %3\"},
8807 {\"cmn\\t%0, #%n1\",
8808 \"cmp\\t%2, %3\"},
8809 {\"cmp\\t%0, %1\",
8810 \"cmn\\t%2, #%n3\"},
8811 {\"cmn\\t%0, #%n1\",
8812 \"cmn\\t%2, #%n3\"}
8813 };
8814 static const char * const cmp2[NUM_OF_COND_CMP][2] =
215b30b3 8815 {
2ff91fec 8816 {\"cmp%d4\\t%2, %3\",
8817 \"cmp%D5\\t%0, %1\"},
8818 {\"cmp%d4\\t%2, %3\",
8819 \"cmn%D5\\t%0, #%n1\"},
8820 {\"cmn%d4\\t%2, #%n3\",
8821 \"cmp%D5\\t%0, %1\"},
8822 {\"cmn%d4\\t%2, #%n3\",
8823 \"cmn%D5\\t%0, #%n1\"}
215b30b3 8824 };
2ff91fec 8825 static const char * const ite[2] =
8826 {
8827 \"it\\t%d4\",
8828 \"it\\t%D5\"
8829 };
8830 static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
8831 CMP_CMP, CMN_CMP, CMP_CMP,
8832 CMN_CMP, CMP_CMN, CMN_CMN};
215b30b3 8833 int swap =
8834 comparison_dominates_p (GET_CODE (operands[5]),
8835 reverse_condition (GET_CODE (operands[4])));
8836
2ff91fec 8837 output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
8838 if (TARGET_THUMB2) {
8839 output_asm_insn (ite[swap], operands);
8840 }
8841 output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
8842 return \"\";
215b30b3 8843 }"
8fa3ba89 8844 [(set_attr "conds" "set")
2ff91fec 8845 (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
8846 (set_attr_alternative "length"
8847 [(const_int 6)
8848 (const_int 8)
8849 (const_int 8)
8850 (const_int 8)
8851 (const_int 8)
8852 (if_then_else (eq_attr "is_thumb" "no")
8853 (const_int 8)
8854 (const_int 10))
8855 (if_then_else (eq_attr "is_thumb" "no")
8856 (const_int 8)
8857 (const_int 10))
8858 (if_then_else (eq_attr "is_thumb" "no")
8859 (const_int 8)
8860 (const_int 10))
8861 (if_then_else (eq_attr "is_thumb" "no")
8862 (const_int 8)
1b7da4ac 8863 (const_int 10))])
8864 (set_attr "type" "multiple")]
8fa3ba89 8865)
9c08d1fa 8866
f6c53574 8867(define_insn "*cmp_and"
8868 [(set (match_operand 6 "dominant_cc_register" "")
8869 (compare
8870 (and:SI
8871 (match_operator 4 "arm_comparison_operator"
2ff91fec 8872 [(match_operand:SI 0 "s_register_operand"
8873 "l,l,l,r,r,r,r,r,r")
8874 (match_operand:SI 1 "arm_add_operand"
8875 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
f6c53574 8876 (match_operator:SI 5 "arm_comparison_operator"
2ff91fec 8877 [(match_operand:SI 2 "s_register_operand"
8878 "l,r,r,l,l,r,r,r,r")
8879 (match_operand:SI 3 "arm_add_operand"
8880 "lPy,rI,L,lPy,lPy,rI,rI,L,L")]))
f6c53574 8881 (const_int 0)))]
2ff91fec 8882 "TARGET_32BIT"
f6c53574 8883 "*
8884 {
2ff91fec 8885 static const char *const cmp1[NUM_OF_COND_CMP][2] =
f6c53574 8886 {
2ff91fec 8887 {\"cmp%d5\\t%0, %1\",
8888 \"cmp%d4\\t%2, %3\"},
8889 {\"cmn%d5\\t%0, #%n1\",
8890 \"cmp%d4\\t%2, %3\"},
8891 {\"cmp%d5\\t%0, %1\",
8892 \"cmn%d4\\t%2, #%n3\"},
8893 {\"cmn%d5\\t%0, #%n1\",
8894 \"cmn%d4\\t%2, #%n3\"}
f6c53574 8895 };
2ff91fec 8896 static const char *const cmp2[NUM_OF_COND_CMP][2] =
8897 {
8898 {\"cmp\\t%2, %3\",
8899 \"cmp\\t%0, %1\"},
8900 {\"cmp\\t%2, %3\",
8901 \"cmn\\t%0, #%n1\"},
8902 {\"cmn\\t%2, #%n3\",
8903 \"cmp\\t%0, %1\"},
8904 {\"cmn\\t%2, #%n3\",
8905 \"cmn\\t%0, #%n1\"}
8906 };
8907 static const char *const ite[2] =
8908 {
8909 \"it\\t%d5\",
8910 \"it\\t%d4\"
8911 };
8912 static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
8913 CMP_CMP, CMN_CMP, CMP_CMP,
8914 CMN_CMP, CMP_CMN, CMN_CMN};
f6c53574 8915 int swap =
8916 comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4]));
8917
2ff91fec 8918 output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
8919 if (TARGET_THUMB2) {
8920 output_asm_insn (ite[swap], operands);
8921 }
8922 output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
8923 return \"\";
f6c53574 8924 }"
8925 [(set_attr "conds" "set")
8926 (set_attr "predicable" "no")
2ff91fec 8927 (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
8928 (set_attr_alternative "length"
8929 [(const_int 6)
8930 (const_int 8)
8931 (const_int 8)
8932 (const_int 8)
8933 (const_int 8)
8934 (if_then_else (eq_attr "is_thumb" "no")
8935 (const_int 8)
8936 (const_int 10))
8937 (if_then_else (eq_attr "is_thumb" "no")
8938 (const_int 8)
8939 (const_int 10))
8940 (if_then_else (eq_attr "is_thumb" "no")
8941 (const_int 8)
8942 (const_int 10))
8943 (if_then_else (eq_attr "is_thumb" "no")
8944 (const_int 8)
1b7da4ac 8945 (const_int 10))])
8946 (set_attr "type" "multiple")]
f6c53574 8947)
8948
8949(define_insn "*cmp_ior"
8950 [(set (match_operand 6 "dominant_cc_register" "")
8951 (compare
8952 (ior:SI
8953 (match_operator 4 "arm_comparison_operator"
2ff91fec 8954 [(match_operand:SI 0 "s_register_operand"
8955 "l,l,l,r,r,r,r,r,r")
8956 (match_operand:SI 1 "arm_add_operand"
8957 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
f6c53574 8958 (match_operator:SI 5 "arm_comparison_operator"
2ff91fec 8959 [(match_operand:SI 2 "s_register_operand"
8960 "l,r,r,l,l,r,r,r,r")
8961 (match_operand:SI 3 "arm_add_operand"
8962 "lPy,rI,L,lPy,lPy,rI,rI,L,L")]))
f6c53574 8963 (const_int 0)))]
2ff91fec 8964 "TARGET_32BIT"
f6c53574 8965 "*
f6c53574 8966 {
2ff91fec 8967 static const char *const cmp1[NUM_OF_COND_CMP][2] =
8968 {
8969 {\"cmp\\t%0, %1\",
8970 \"cmp\\t%2, %3\"},
8971 {\"cmn\\t%0, #%n1\",
8972 \"cmp\\t%2, %3\"},
8973 {\"cmp\\t%0, %1\",
8974 \"cmn\\t%2, #%n3\"},
8975 {\"cmn\\t%0, #%n1\",
8976 \"cmn\\t%2, #%n3\"}
8977 };
8978 static const char *const cmp2[NUM_OF_COND_CMP][2] =
8979 {
8980 {\"cmp%D4\\t%2, %3\",
8981 \"cmp%D5\\t%0, %1\"},
8982 {\"cmp%D4\\t%2, %3\",
8983 \"cmn%D5\\t%0, #%n1\"},
8984 {\"cmn%D4\\t%2, #%n3\",
8985 \"cmp%D5\\t%0, %1\"},
8986 {\"cmn%D4\\t%2, #%n3\",
8987 \"cmn%D5\\t%0, #%n1\"}
8988 };
8989 static const char *const ite[2] =
8990 {
8991 \"it\\t%D4\",
8992 \"it\\t%D5\"
8993 };
8994 static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
8995 CMP_CMP, CMN_CMP, CMP_CMP,
8996 CMN_CMP, CMP_CMN, CMN_CMN};
8997 int swap =
8998 comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4]));
8999
9000 output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
9001 if (TARGET_THUMB2) {
9002 output_asm_insn (ite[swap], operands);
9003 }
9004 output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
9005 return \"\";
9006 }
9007 "
f6c53574 9008 [(set_attr "conds" "set")
2ff91fec 9009 (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
9010 (set_attr_alternative "length"
9011 [(const_int 6)
9012 (const_int 8)
9013 (const_int 8)
9014 (const_int 8)
9015 (const_int 8)
9016 (if_then_else (eq_attr "is_thumb" "no")
9017 (const_int 8)
9018 (const_int 10))
9019 (if_then_else (eq_attr "is_thumb" "no")
9020 (const_int 8)
9021 (const_int 10))
9022 (if_then_else (eq_attr "is_thumb" "no")
9023 (const_int 8)
9024 (const_int 10))
9025 (if_then_else (eq_attr "is_thumb" "no")
9026 (const_int 8)
1b7da4ac 9027 (const_int 10))])
9028 (set_attr "type" "multiple")]
f6c53574 9029)
9030
3c5afce6 9031(define_insn_and_split "*ior_scc_scc"
fd711051 9032 [(set (match_operand:SI 0 "s_register_operand" "=Ts")
3c5afce6 9033 (ior:SI (match_operator:SI 3 "arm_comparison_operator"
9034 [(match_operand:SI 1 "s_register_operand" "r")
9035 (match_operand:SI 2 "arm_add_operand" "rIL")])
9036 (match_operator:SI 6 "arm_comparison_operator"
9037 [(match_operand:SI 4 "s_register_operand" "r")
9038 (match_operand:SI 5 "arm_add_operand" "rIL")])))
9039 (clobber (reg:CC CC_REGNUM))]
2ff91fec 9040 "TARGET_32BIT
3c5afce6 9041 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_OR_Y)
9042 != CCmode)"
9043 "#"
2ff91fec 9044 "TARGET_32BIT && reload_completed"
3c5afce6 9045 [(set (match_dup 7)
9046 (compare
9047 (ior:SI
9048 (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9049 (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9050 (const_int 0)))
9051 (set (match_dup 0) (ne:SI (match_dup 7) (const_int 0)))]
9052 "operands[7]
9053 = gen_rtx_REG (arm_select_dominance_cc_mode (operands[3], operands[6],
9054 DOM_CC_X_OR_Y),
601f584c 9055 CC_REGNUM);"
9056 [(set_attr "conds" "clob")
1b7da4ac 9057 (set_attr "length" "16")
9058 (set_attr "type" "multiple")]
9059)
601f584c 9060
9061; If the above pattern is followed by a CMP insn, then the compare is
9062; redundant, since we can rework the conditional instruction that follows.
9063(define_insn_and_split "*ior_scc_scc_cmp"
9064 [(set (match_operand 0 "dominant_cc_register" "")
9065 (compare (ior:SI (match_operator:SI 3 "arm_comparison_operator"
9066 [(match_operand:SI 1 "s_register_operand" "r")
9067 (match_operand:SI 2 "arm_add_operand" "rIL")])
9068 (match_operator:SI 6 "arm_comparison_operator"
9069 [(match_operand:SI 4 "s_register_operand" "r")
9070 (match_operand:SI 5 "arm_add_operand" "rIL")]))
9071 (const_int 0)))
fd711051 9072 (set (match_operand:SI 7 "s_register_operand" "=Ts")
601f584c 9073 (ior:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9074 (match_op_dup 6 [(match_dup 4) (match_dup 5)])))]
2ff91fec 9075 "TARGET_32BIT"
601f584c 9076 "#"
2ff91fec 9077 "TARGET_32BIT && reload_completed"
601f584c 9078 [(set (match_dup 0)
9079 (compare
9080 (ior:SI
9081 (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9082 (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9083 (const_int 0)))
9084 (set (match_dup 7) (ne:SI (match_dup 0) (const_int 0)))]
9085 ""
9086 [(set_attr "conds" "set")
1b7da4ac 9087 (set_attr "length" "16")
9088 (set_attr "type" "multiple")]
9089)
3c5afce6 9090
9091(define_insn_and_split "*and_scc_scc"
fd711051 9092 [(set (match_operand:SI 0 "s_register_operand" "=Ts")
3c5afce6 9093 (and:SI (match_operator:SI 3 "arm_comparison_operator"
9094 [(match_operand:SI 1 "s_register_operand" "r")
9095 (match_operand:SI 2 "arm_add_operand" "rIL")])
9096 (match_operator:SI 6 "arm_comparison_operator"
9097 [(match_operand:SI 4 "s_register_operand" "r")
9098 (match_operand:SI 5 "arm_add_operand" "rIL")])))
9099 (clobber (reg:CC CC_REGNUM))]
2ff91fec 9100 "TARGET_32BIT
3c5afce6 9101 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y)
9102 != CCmode)"
9103 "#"
2ff91fec 9104 "TARGET_32BIT && reload_completed
601f584c 9105 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y)
9106 != CCmode)"
3c5afce6 9107 [(set (match_dup 7)
9108 (compare
9109 (and:SI
9110 (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9111 (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9112 (const_int 0)))
9113 (set (match_dup 0) (ne:SI (match_dup 7) (const_int 0)))]
9114 "operands[7]
9115 = gen_rtx_REG (arm_select_dominance_cc_mode (operands[3], operands[6],
9116 DOM_CC_X_AND_Y),
601f584c 9117 CC_REGNUM);"
9118 [(set_attr "conds" "clob")
1b7da4ac 9119 (set_attr "length" "16")
9120 (set_attr "type" "multiple")]
9121)
601f584c 9122
9123; If the above pattern is followed by a CMP insn, then the compare is
9124; redundant, since we can rework the conditional instruction that follows.
9125(define_insn_and_split "*and_scc_scc_cmp"
9126 [(set (match_operand 0 "dominant_cc_register" "")
9127 (compare (and:SI (match_operator:SI 3 "arm_comparison_operator"
9128 [(match_operand:SI 1 "s_register_operand" "r")
9129 (match_operand:SI 2 "arm_add_operand" "rIL")])
9130 (match_operator:SI 6 "arm_comparison_operator"
9131 [(match_operand:SI 4 "s_register_operand" "r")
9132 (match_operand:SI 5 "arm_add_operand" "rIL")]))
9133 (const_int 0)))
fd711051 9134 (set (match_operand:SI 7 "s_register_operand" "=Ts")
601f584c 9135 (and:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9136 (match_op_dup 6 [(match_dup 4) (match_dup 5)])))]
2ff91fec 9137 "TARGET_32BIT"
601f584c 9138 "#"
2ff91fec 9139 "TARGET_32BIT && reload_completed"
601f584c 9140 [(set (match_dup 0)
9141 (compare
9142 (and:SI
9143 (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9144 (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9145 (const_int 0)))
9146 (set (match_dup 7) (ne:SI (match_dup 0) (const_int 0)))]
9147 ""
9148 [(set_attr "conds" "set")
1b7da4ac 9149 (set_attr "length" "16")
9150 (set_attr "type" "multiple")]
9151)
601f584c 9152
9153;; If there is no dominance in the comparison, then we can still save an
9154;; instruction in the AND case, since we can know that the second compare
9155;; need only zero the value if false (if true, then the value is already
9156;; correct).
9157(define_insn_and_split "*and_scc_scc_nodom"
fd711051 9158 [(set (match_operand:SI 0 "s_register_operand" "=&Ts,&Ts,&Ts")
601f584c 9159 (and:SI (match_operator:SI 3 "arm_comparison_operator"
9160 [(match_operand:SI 1 "s_register_operand" "r,r,0")
9161 (match_operand:SI 2 "arm_add_operand" "rIL,0,rIL")])
9162 (match_operator:SI 6 "arm_comparison_operator"
9163 [(match_operand:SI 4 "s_register_operand" "r,r,r")
9164 (match_operand:SI 5 "arm_add_operand" "rIL,rIL,rIL")])))
9165 (clobber (reg:CC CC_REGNUM))]
2ff91fec 9166 "TARGET_32BIT
601f584c 9167 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y)
9168 == CCmode)"
9169 "#"
2ff91fec 9170 "TARGET_32BIT && reload_completed"
601f584c 9171 [(parallel [(set (match_dup 0)
9172 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
9173 (clobber (reg:CC CC_REGNUM))])
9174 (set (match_dup 7) (match_op_dup 8 [(match_dup 4) (match_dup 5)]))
9175 (set (match_dup 0)
9176 (if_then_else:SI (match_op_dup 6 [(match_dup 7) (const_int 0)])
9177 (match_dup 0)
9178 (const_int 0)))]
9179 "operands[7] = gen_rtx_REG (SELECT_CC_MODE (GET_CODE (operands[6]),
9180 operands[4], operands[5]),
9181 CC_REGNUM);
9182 operands[8] = gen_rtx_COMPARE (GET_MODE (operands[7]), operands[4],
9183 operands[5]);"
9184 [(set_attr "conds" "clob")
1b7da4ac 9185 (set_attr "length" "20")
9186 (set_attr "type" "multiple")]
9187)
3c5afce6 9188
3a0bdee0 9189(define_split
9190 [(set (reg:CC_NOOV CC_REGNUM)
9191 (compare:CC_NOOV (ior:SI
9192 (and:SI (match_operand:SI 0 "s_register_operand" "")
9193 (const_int 1))
b0694be0 9194 (match_operator:SI 1 "arm_comparison_operator"
3a0bdee0 9195 [(match_operand:SI 2 "s_register_operand" "")
9196 (match_operand:SI 3 "arm_add_operand" "")]))
9197 (const_int 0)))
9198 (clobber (match_operand:SI 4 "s_register_operand" ""))]
9199 "TARGET_ARM"
9200 [(set (match_dup 4)
9201 (ior:SI (match_op_dup 1 [(match_dup 2) (match_dup 3)])
9202 (match_dup 0)))
9203 (set (reg:CC_NOOV CC_REGNUM)
9204 (compare:CC_NOOV (and:SI (match_dup 4) (const_int 1))
9205 (const_int 0)))]
9206 "")
9207
9208(define_split
9209 [(set (reg:CC_NOOV CC_REGNUM)
9210 (compare:CC_NOOV (ior:SI
b0694be0 9211 (match_operator:SI 1 "arm_comparison_operator"
3a0bdee0 9212 [(match_operand:SI 2 "s_register_operand" "")
9213 (match_operand:SI 3 "arm_add_operand" "")])
9214 (and:SI (match_operand:SI 0 "s_register_operand" "")
9215 (const_int 1)))
9216 (const_int 0)))
9217 (clobber (match_operand:SI 4 "s_register_operand" ""))]
9218 "TARGET_ARM"
9219 [(set (match_dup 4)
9220 (ior:SI (match_op_dup 1 [(match_dup 2) (match_dup 3)])
9221 (match_dup 0)))
9222 (set (reg:CC_NOOV CC_REGNUM)
9223 (compare:CC_NOOV (and:SI (match_dup 4) (const_int 1))
9224 (const_int 0)))]
9225 "")
25f905c2 9226;; ??? The conditional patterns above need checking for Thumb-2 usefulness
3a0bdee0 9227
190efb17 9228(define_insn_and_split "*negscc"
9c08d1fa 9229 [(set (match_operand:SI 0 "s_register_operand" "=r")
8fa3ba89 9230 (neg:SI (match_operator 3 "arm_comparison_operator"
9c08d1fa 9231 [(match_operand:SI 1 "s_register_operand" "r")
9232 (match_operand:SI 2 "arm_rhs_operand" "rI")])))
bd5b4116 9233 (clobber (reg:CC CC_REGNUM))]
cffb2a26 9234 "TARGET_ARM"
190efb17 9235 "#"
9236 "&& reload_completed"
9237 [(const_int 0)]
9238 {
9239 rtx cc_reg = gen_rtx_REG (CCmode, CC_REGNUM);
e2348bcb 9240
190efb17 9241 if (GET_CODE (operands[3]) == LT && operands[2] == const0_rtx)
9242 {
9243 /* Emit mov\\t%0, %1, asr #31 */
d1f9b275 9244 emit_insn (gen_rtx_SET (operands[0],
190efb17 9245 gen_rtx_ASHIFTRT (SImode,
9246 operands[1],
9247 GEN_INT (31))));
9248 DONE;
9249 }
9250 else if (GET_CODE (operands[3]) == NE)
9251 {
9252 /* Emit subs\\t%0, %1, %2\;mvnne\\t%0, #0 */
9253 if (CONST_INT_P (operands[2]))
9254 emit_insn (gen_cmpsi2_addneg (operands[0], operands[1], operands[2],
9255 GEN_INT (- INTVAL (operands[2]))));
9256 else
9257 emit_insn (gen_subsi3_compare (operands[0], operands[1], operands[2]));
9258
9259 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
9260 gen_rtx_NE (SImode,
9261 cc_reg,
9262 const0_rtx),
d1f9b275 9263 gen_rtx_SET (operands[0],
190efb17 9264 GEN_INT (~0))));
9265 DONE;
9266 }
9267 else
9268 {
9269 /* Emit: cmp\\t%1, %2\;mov%D3\\t%0, #0\;mvn%d3\\t%0, #0 */
d1f9b275 9270 emit_insn (gen_rtx_SET (cc_reg,
190efb17 9271 gen_rtx_COMPARE (CCmode, operands[1], operands[2])));
9272 enum rtx_code rc = GET_CODE (operands[3]);
9273
9274 rc = reverse_condition (rc);
9275 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
9276 gen_rtx_fmt_ee (rc,
9277 VOIDmode,
9278 cc_reg,
9279 const0_rtx),
d1f9b275 9280 gen_rtx_SET (operands[0], const0_rtx)));
190efb17 9281 rc = GET_CODE (operands[3]);
9282 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
9283 gen_rtx_fmt_ee (rc,
9284 VOIDmode,
9285 cc_reg,
9286 const0_rtx),
d1f9b275 9287 gen_rtx_SET (operands[0],
190efb17 9288 GEN_INT (~0))));
9289 DONE;
9290 }
9291 FAIL;
9292 }
8fa3ba89 9293 [(set_attr "conds" "clob")
1b7da4ac 9294 (set_attr "length" "12")
9295 (set_attr "type" "multiple")]
8fa3ba89 9296)
9c08d1fa 9297
90404b57 9298(define_insn_and_split "movcond_addsi"
9299 [(set (match_operand:SI 0 "s_register_operand" "=r,l,r")
9300 (if_then_else:SI
9301 (match_operator 5 "comparison_operator"
9302 [(plus:SI (match_operand:SI 3 "s_register_operand" "r,r,r")
9303 (match_operand:SI 4 "arm_add_operand" "rIL,rIL,rIL"))
9304 (const_int 0)])
9305 (match_operand:SI 1 "arm_rhs_operand" "rI,rPy,r")
9306 (match_operand:SI 2 "arm_rhs_operand" "rI,rPy,r")))
9307 (clobber (reg:CC CC_REGNUM))]
9308 "TARGET_32BIT"
9309 "#"
9310 "&& reload_completed"
9311 [(set (reg:CC_NOOV CC_REGNUM)
9312 (compare:CC_NOOV
9313 (plus:SI (match_dup 3)
9314 (match_dup 4))
9315 (const_int 0)))
9316 (set (match_dup 0) (match_dup 1))
9317 (cond_exec (match_dup 6)
9318 (set (match_dup 0) (match_dup 2)))]
9319 "
9320 {
3754d046 9321 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[5]),
90404b57 9322 operands[3], operands[4]);
9323 enum rtx_code rc = GET_CODE (operands[5]);
90404b57 9324 operands[6] = gen_rtx_REG (mode, CC_REGNUM);
9325 gcc_assert (!(mode == CCFPmode || mode == CCFPEmode));
4d01ce2f 9326 if (REGNO (operands[2]) != REGNO (operands[0]))
9327 rc = reverse_condition (rc);
f145bcba 9328 else
9329 std::swap (operands[1], operands[2]);
90404b57 9330
9331 operands[6] = gen_rtx_fmt_ee (rc, VOIDmode, operands[6], const0_rtx);
9332 }
9333 "
9334 [(set_attr "conds" "clob")
1b7da4ac 9335 (set_attr "enabled_for_depr_it" "no,yes,yes")
9336 (set_attr "type" "multiple")]
90404b57 9337)
9338
9c08d1fa 9339(define_insn "movcond"
9340 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
5565501b 9341 (if_then_else:SI
8fa3ba89 9342 (match_operator 5 "arm_comparison_operator"
5565501b 9343 [(match_operand:SI 3 "s_register_operand" "r,r,r")
9344 (match_operand:SI 4 "arm_add_operand" "rIL,rIL,rIL")])
9345 (match_operand:SI 1 "arm_rhs_operand" "0,rI,?rI")
9346 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
bd5b4116 9347 (clobber (reg:CC CC_REGNUM))]
cffb2a26 9348 "TARGET_ARM"
9c08d1fa 9349 "*
9350 if (GET_CODE (operands[5]) == LT
9351 && (operands[4] == const0_rtx))
9352 {
0438d37f 9353 if (which_alternative != 1 && REG_P (operands[1]))
9c08d1fa 9354 {
9c08d1fa 9355 if (operands[2] == const0_rtx)
e2348bcb 9356 return \"and\\t%0, %1, %3, asr #31\";
9357 return \"ands\\t%0, %1, %3, asr #32\;movcc\\t%0, %2\";
9c08d1fa 9358 }
0438d37f 9359 else if (which_alternative != 0 && REG_P (operands[2]))
9c08d1fa 9360 {
9c08d1fa 9361 if (operands[1] == const0_rtx)
e2348bcb 9362 return \"bic\\t%0, %2, %3, asr #31\";
9363 return \"bics\\t%0, %2, %3, asr #32\;movcs\\t%0, %1\";
9c08d1fa 9364 }
9365 /* The only case that falls through to here is when both ops 1 & 2
674a8f0b 9366 are constants. */
9c08d1fa 9367 }
e2348bcb 9368
9c08d1fa 9369 if (GET_CODE (operands[5]) == GE
9370 && (operands[4] == const0_rtx))
9371 {
0438d37f 9372 if (which_alternative != 1 && REG_P (operands[1]))
9c08d1fa 9373 {
9c08d1fa 9374 if (operands[2] == const0_rtx)
e2348bcb 9375 return \"bic\\t%0, %1, %3, asr #31\";
9376 return \"bics\\t%0, %1, %3, asr #32\;movcs\\t%0, %2\";
9c08d1fa 9377 }
0438d37f 9378 else if (which_alternative != 0 && REG_P (operands[2]))
9c08d1fa 9379 {
9c08d1fa 9380 if (operands[1] == const0_rtx)
e2348bcb 9381 return \"and\\t%0, %2, %3, asr #31\";
9382 return \"ands\\t%0, %2, %3, asr #32\;movcc\\t%0, %1\";
9c08d1fa 9383 }
9384 /* The only case that falls through to here is when both ops 1 & 2
674a8f0b 9385 are constants. */
9c08d1fa 9386 }
0438d37f 9387 if (CONST_INT_P (operands[4])
9c08d1fa 9388 && !const_ok_for_arm (INTVAL (operands[4])))
e2348bcb 9389 output_asm_insn (\"cmn\\t%3, #%n4\", operands);
9c08d1fa 9390 else
e2348bcb 9391 output_asm_insn (\"cmp\\t%3, %4\", operands);
9c08d1fa 9392 if (which_alternative != 0)
e2348bcb 9393 output_asm_insn (\"mov%d5\\t%0, %1\", operands);
9c08d1fa 9394 if (which_alternative != 1)
e2348bcb 9395 output_asm_insn (\"mov%D5\\t%0, %2\", operands);
9c08d1fa 9396 return \"\";
215b30b3 9397 "
8fa3ba89 9398 [(set_attr "conds" "clob")
1b7da4ac 9399 (set_attr "length" "8,8,12")
9400 (set_attr "type" "multiple")]
8fa3ba89 9401)
9c08d1fa 9402
25f905c2 9403;; ??? The patterns below need checking for Thumb-2 usefulness.
9404
8a18b90c 9405(define_insn "*ifcompare_plus_move"
9406 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8fa3ba89 9407 (if_then_else:SI (match_operator 6 "arm_comparison_operator"
8a18b90c 9408 [(match_operand:SI 4 "s_register_operand" "r,r")
9409 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
9410 (plus:SI
9411 (match_operand:SI 2 "s_register_operand" "r,r")
9412 (match_operand:SI 3 "arm_add_operand" "rIL,rIL"))
129a2fe4 9413 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))
bd5b4116 9414 (clobber (reg:CC CC_REGNUM))]
cffb2a26 9415 "TARGET_ARM"
8a18b90c 9416 "#"
8fa3ba89 9417 [(set_attr "conds" "clob")
1b7da4ac 9418 (set_attr "length" "8,12")
9419 (set_attr "type" "multiple")]
8fa3ba89 9420)
8a18b90c 9421
9422(define_insn "*if_plus_move"
129a2fe4 9423 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r")
8a18b90c 9424 (if_then_else:SI
8fa3ba89 9425 (match_operator 4 "arm_comparison_operator"
8a18b90c 9426 [(match_operand 5 "cc_register" "") (const_int 0)])
9427 (plus:SI
129a2fe4 9428 (match_operand:SI 2 "s_register_operand" "r,r,r,r")
9429 (match_operand:SI 3 "arm_add_operand" "rI,L,rI,L"))
9430 (match_operand:SI 1 "arm_rhs_operand" "0,0,?rI,?rI")))]
cffb2a26 9431 "TARGET_ARM"
8a18b90c 9432 "@
9433 add%d4\\t%0, %2, %3
9434 sub%d4\\t%0, %2, #%n3
9435 add%d4\\t%0, %2, %3\;mov%D4\\t%0, %1
129a2fe4 9436 sub%d4\\t%0, %2, #%n3\;mov%D4\\t%0, %1"
8fa3ba89 9437 [(set_attr "conds" "use")
9438 (set_attr "length" "4,4,8,8")
65f68e55 9439 (set_attr_alternative "type"
9440 [(if_then_else (match_operand 3 "const_int_operand" "")
d82e788e 9441 (const_string "alu_imm" )
112eda6f 9442 (const_string "alu_sreg"))
d82e788e 9443 (const_string "alu_imm")
282b4c75 9444 (const_string "multiple")
9445 (const_string "multiple")])]
8fa3ba89 9446)
8a18b90c 9447
9448(define_insn "*ifcompare_move_plus"
5565501b 9449 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8fa3ba89 9450 (if_then_else:SI (match_operator 6 "arm_comparison_operator"
8a18b90c 9451 [(match_operand:SI 4 "s_register_operand" "r,r")
9452 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
129a2fe4 9453 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
8a18b90c 9454 (plus:SI
9455 (match_operand:SI 2 "s_register_operand" "r,r")
9456 (match_operand:SI 3 "arm_add_operand" "rIL,rIL"))))
bd5b4116 9457 (clobber (reg:CC CC_REGNUM))]
cffb2a26 9458 "TARGET_ARM"
8a18b90c 9459 "#"
8fa3ba89 9460 [(set_attr "conds" "clob")
1b7da4ac 9461 (set_attr "length" "8,12")
9462 (set_attr "type" "multiple")]
8fa3ba89 9463)
8a18b90c 9464
9465(define_insn "*if_move_plus"
129a2fe4 9466 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r")
8a18b90c 9467 (if_then_else:SI
8fa3ba89 9468 (match_operator 4 "arm_comparison_operator"
8a18b90c 9469 [(match_operand 5 "cc_register" "") (const_int 0)])
129a2fe4 9470 (match_operand:SI 1 "arm_rhs_operand" "0,0,?rI,?rI")
8a18b90c 9471 (plus:SI
129a2fe4 9472 (match_operand:SI 2 "s_register_operand" "r,r,r,r")
9473 (match_operand:SI 3 "arm_add_operand" "rI,L,rI,L"))))]
cffb2a26 9474 "TARGET_ARM"
8a18b90c 9475 "@
9476 add%D4\\t%0, %2, %3
9477 sub%D4\\t%0, %2, #%n3
9478 add%D4\\t%0, %2, %3\;mov%d4\\t%0, %1
129a2fe4 9479 sub%D4\\t%0, %2, #%n3\;mov%d4\\t%0, %1"
8fa3ba89 9480 [(set_attr "conds" "use")
9481 (set_attr "length" "4,4,8,8")
282b4c75 9482 (set_attr_alternative "type"
9483 [(if_then_else (match_operand 3 "const_int_operand" "")
9484 (const_string "alu_imm" )
9485 (const_string "alu_sreg"))
9486 (const_string "alu_imm")
9487 (const_string "multiple")
9488 (const_string "multiple")])]
8fa3ba89 9489)
8a18b90c 9490
9491(define_insn "*ifcompare_arith_arith"
9492 [(set (match_operand:SI 0 "s_register_operand" "=r")
8fa3ba89 9493 (if_then_else:SI (match_operator 9 "arm_comparison_operator"
8a18b90c 9494 [(match_operand:SI 5 "s_register_operand" "r")
9495 (match_operand:SI 6 "arm_add_operand" "rIL")])
9c08d1fa 9496 (match_operator:SI 8 "shiftable_operator"
8a18b90c 9497 [(match_operand:SI 1 "s_register_operand" "r")
9498 (match_operand:SI 2 "arm_rhs_operand" "rI")])
9c08d1fa 9499 (match_operator:SI 7 "shiftable_operator"
8a18b90c 9500 [(match_operand:SI 3 "s_register_operand" "r")
9501 (match_operand:SI 4 "arm_rhs_operand" "rI")])))
bd5b4116 9502 (clobber (reg:CC CC_REGNUM))]
cffb2a26 9503 "TARGET_ARM"
8a18b90c 9504 "#"
8fa3ba89 9505 [(set_attr "conds" "clob")
1b7da4ac 9506 (set_attr "length" "12")
9507 (set_attr "type" "multiple")]
8fa3ba89 9508)
9c08d1fa 9509
8a18b90c 9510(define_insn "*if_arith_arith"
9511 [(set (match_operand:SI 0 "s_register_operand" "=r")
8fa3ba89 9512 (if_then_else:SI (match_operator 5 "arm_comparison_operator"
8a18b90c 9513 [(match_operand 8 "cc_register" "") (const_int 0)])
9514 (match_operator:SI 6 "shiftable_operator"
9515 [(match_operand:SI 1 "s_register_operand" "r")
9516 (match_operand:SI 2 "arm_rhs_operand" "rI")])
9517 (match_operator:SI 7 "shiftable_operator"
9518 [(match_operand:SI 3 "s_register_operand" "r")
9519 (match_operand:SI 4 "arm_rhs_operand" "rI")])))]
cffb2a26 9520 "TARGET_ARM"
8a18b90c 9521 "%I6%d5\\t%0, %1, %2\;%I7%D5\\t%0, %3, %4"
8fa3ba89 9522 [(set_attr "conds" "use")
1b7da4ac 9523 (set_attr "length" "8")
9524 (set_attr "type" "multiple")]
8fa3ba89 9525)
8a18b90c 9526
f7fbdd4a 9527(define_insn "*ifcompare_arith_move"
9c08d1fa 9528 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8fa3ba89 9529 (if_then_else:SI (match_operator 6 "arm_comparison_operator"
9c08d1fa 9530 [(match_operand:SI 2 "s_register_operand" "r,r")
5565501b 9531 (match_operand:SI 3 "arm_add_operand" "rIL,rIL")])
9c08d1fa 9532 (match_operator:SI 7 "shiftable_operator"
9533 [(match_operand:SI 4 "s_register_operand" "r,r")
9534 (match_operand:SI 5 "arm_rhs_operand" "rI,rI")])
129a2fe4 9535 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))
bd5b4116 9536 (clobber (reg:CC CC_REGNUM))]
cffb2a26 9537 "TARGET_ARM"
9c08d1fa 9538 "*
9c08d1fa 9539 /* If we have an operation where (op x 0) is the identity operation and
01cc3b75 9540 the conditional operator is LT or GE and we are comparing against zero and
674a8f0b 9541 everything is in registers then we can do this in two instructions. */
9c08d1fa 9542 if (operands[3] == const0_rtx
9543 && GET_CODE (operands[7]) != AND
0438d37f 9544 && REG_P (operands[5])
9545 && REG_P (operands[1])
9c08d1fa 9546 && REGNO (operands[1]) == REGNO (operands[4])
9547 && REGNO (operands[4]) != REGNO (operands[0]))
9548 {
9549 if (GET_CODE (operands[6]) == LT)
40dbec34 9550 return \"and\\t%0, %5, %2, asr #31\;%I7\\t%0, %4, %0\";
9c08d1fa 9551 else if (GET_CODE (operands[6]) == GE)
40dbec34 9552 return \"bic\\t%0, %5, %2, asr #31\;%I7\\t%0, %4, %0\";
9c08d1fa 9553 }
0438d37f 9554 if (CONST_INT_P (operands[3])
9c08d1fa 9555 && !const_ok_for_arm (INTVAL (operands[3])))
e2348bcb 9556 output_asm_insn (\"cmn\\t%2, #%n3\", operands);
9c08d1fa 9557 else
e2348bcb 9558 output_asm_insn (\"cmp\\t%2, %3\", operands);
40dbec34 9559 output_asm_insn (\"%I7%d6\\t%0, %4, %5\", operands);
9c08d1fa 9560 if (which_alternative != 0)
129a2fe4 9561 return \"mov%D6\\t%0, %1\";
9c08d1fa 9562 return \"\";
215b30b3 9563 "
8fa3ba89 9564 [(set_attr "conds" "clob")
1b7da4ac 9565 (set_attr "length" "8,12")
9566 (set_attr "type" "multiple")]
8fa3ba89 9567)
9c08d1fa 9568
8a18b90c 9569(define_insn "*if_arith_move"
129a2fe4 9570 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8fa3ba89 9571 (if_then_else:SI (match_operator 4 "arm_comparison_operator"
8a18b90c 9572 [(match_operand 6 "cc_register" "") (const_int 0)])
9573 (match_operator:SI 5 "shiftable_operator"
129a2fe4 9574 [(match_operand:SI 2 "s_register_operand" "r,r")
9575 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
9576 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))]
cffb2a26 9577 "TARGET_ARM"
8a18b90c 9578 "@
9579 %I5%d4\\t%0, %2, %3
129a2fe4 9580 %I5%d4\\t%0, %2, %3\;mov%D4\\t%0, %1"
8fa3ba89 9581 [(set_attr "conds" "use")
9582 (set_attr "length" "4,8")
282b4c75 9583 (set_attr_alternative "type"
9584 [(if_then_else (match_operand 3 "const_int_operand" "")
9585 (const_string "alu_shift_imm" )
9586 (const_string "alu_shift_reg"))
9587 (const_string "multiple")])]
8fa3ba89 9588)
8a18b90c 9589
f7fbdd4a 9590(define_insn "*ifcompare_move_arith"
9c08d1fa 9591 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8fa3ba89 9592 (if_then_else:SI (match_operator 6 "arm_comparison_operator"
9c08d1fa 9593 [(match_operand:SI 4 "s_register_operand" "r,r")
5565501b 9594 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
129a2fe4 9595 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
9c08d1fa 9596 (match_operator:SI 7 "shiftable_operator"
9597 [(match_operand:SI 2 "s_register_operand" "r,r")
9598 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))
bd5b4116 9599 (clobber (reg:CC CC_REGNUM))]
cffb2a26 9600 "TARGET_ARM"
9c08d1fa 9601 "*
9c08d1fa 9602 /* If we have an operation where (op x 0) is the identity operation and
01cc3b75 9603 the conditional operator is LT or GE and we are comparing against zero and
9c08d1fa 9604 everything is in registers then we can do this in two instructions */
9605 if (operands[5] == const0_rtx
9606 && GET_CODE (operands[7]) != AND
0438d37f 9607 && REG_P (operands[3])
9608 && REG_P (operands[1])
9c08d1fa 9609 && REGNO (operands[1]) == REGNO (operands[2])
9610 && REGNO (operands[2]) != REGNO (operands[0]))
9611 {
9612 if (GET_CODE (operands[6]) == GE)
40dbec34 9613 return \"and\\t%0, %3, %4, asr #31\;%I7\\t%0, %2, %0\";
9c08d1fa 9614 else if (GET_CODE (operands[6]) == LT)
40dbec34 9615 return \"bic\\t%0, %3, %4, asr #31\;%I7\\t%0, %2, %0\";
9c08d1fa 9616 }
40dbec34 9617
0438d37f 9618 if (CONST_INT_P (operands[5])
9c08d1fa 9619 && !const_ok_for_arm (INTVAL (operands[5])))
e2348bcb 9620 output_asm_insn (\"cmn\\t%4, #%n5\", operands);
9c08d1fa 9621 else
e2348bcb 9622 output_asm_insn (\"cmp\\t%4, %5\", operands);
40dbec34 9623
9c08d1fa 9624 if (which_alternative != 0)
129a2fe4 9625 output_asm_insn (\"mov%d6\\t%0, %1\", operands);
40dbec34 9626 return \"%I7%D6\\t%0, %2, %3\";
215b30b3 9627 "
8fa3ba89 9628 [(set_attr "conds" "clob")
1b7da4ac 9629 (set_attr "length" "8,12")
9630 (set_attr "type" "multiple")]
8fa3ba89 9631)
9c08d1fa 9632
8a18b90c 9633(define_insn "*if_move_arith"
129a2fe4 9634 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8a18b90c 9635 (if_then_else:SI
8fa3ba89 9636 (match_operator 4 "arm_comparison_operator"
8a18b90c 9637 [(match_operand 6 "cc_register" "") (const_int 0)])
129a2fe4 9638 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
8a18b90c 9639 (match_operator:SI 5 "shiftable_operator"
129a2fe4 9640 [(match_operand:SI 2 "s_register_operand" "r,r")
9641 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))]
cffb2a26 9642 "TARGET_ARM"
8a18b90c 9643 "@
9644 %I5%D4\\t%0, %2, %3
129a2fe4 9645 %I5%D4\\t%0, %2, %3\;mov%d4\\t%0, %1"
8fa3ba89 9646 [(set_attr "conds" "use")
9647 (set_attr "length" "4,8")
282b4c75 9648 (set_attr_alternative "type"
9649 [(if_then_else (match_operand 3 "const_int_operand" "")
9650 (const_string "alu_shift_imm" )
9651 (const_string "alu_shift_reg"))
9652 (const_string "multiple")])]
8fa3ba89 9653)
8a18b90c 9654
9655(define_insn "*ifcompare_move_not"
9c08d1fa 9656 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8a18b90c 9657 (if_then_else:SI
8fa3ba89 9658 (match_operator 5 "arm_comparison_operator"
8a18b90c 9659 [(match_operand:SI 3 "s_register_operand" "r,r")
9660 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
9661 (match_operand:SI 1 "arm_not_operand" "0,?rIK")
9662 (not:SI
9663 (match_operand:SI 2 "s_register_operand" "r,r"))))
bd5b4116 9664 (clobber (reg:CC CC_REGNUM))]
cffb2a26 9665 "TARGET_ARM"
8a18b90c 9666 "#"
8fa3ba89 9667 [(set_attr "conds" "clob")
1b7da4ac 9668 (set_attr "length" "8,12")
9669 (set_attr "type" "multiple")]
8fa3ba89 9670)
9c08d1fa 9671
8a18b90c 9672(define_insn "*if_move_not"
9673 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9674 (if_then_else:SI
8fa3ba89 9675 (match_operator 4 "arm_comparison_operator"
8a18b90c 9676 [(match_operand 3 "cc_register" "") (const_int 0)])
9677 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")
9678 (not:SI (match_operand:SI 2 "s_register_operand" "r,r,r"))))]
cffb2a26 9679 "TARGET_ARM"
8a18b90c 9680 "@
9681 mvn%D4\\t%0, %2
9682 mov%d4\\t%0, %1\;mvn%D4\\t%0, %2
9683 mvn%d4\\t%0, #%B1\;mvn%D4\\t%0, %2"
8fa3ba89 9684 [(set_attr "conds" "use")
1aed5204 9685 (set_attr "type" "mvn_reg")
1b7da4ac 9686 (set_attr "length" "4,8,8")
9687 (set_attr "type" "mvn_reg,multiple,multiple")]
8fa3ba89 9688)
8a18b90c 9689
9690(define_insn "*ifcompare_not_move"
9c08d1fa 9691 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8a18b90c 9692 (if_then_else:SI
8fa3ba89 9693 (match_operator 5 "arm_comparison_operator"
8a18b90c 9694 [(match_operand:SI 3 "s_register_operand" "r,r")
9695 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
9696 (not:SI
9697 (match_operand:SI 2 "s_register_operand" "r,r"))
9698 (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
bd5b4116 9699 (clobber (reg:CC CC_REGNUM))]
cffb2a26 9700 "TARGET_ARM"
8a18b90c 9701 "#"
8fa3ba89 9702 [(set_attr "conds" "clob")
1b7da4ac 9703 (set_attr "length" "8,12")
9704 (set_attr "type" "multiple")]
8fa3ba89 9705)
9c08d1fa 9706
8a18b90c 9707(define_insn "*if_not_move"
9708 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9709 (if_then_else:SI
8fa3ba89 9710 (match_operator 4 "arm_comparison_operator"
8a18b90c 9711 [(match_operand 3 "cc_register" "") (const_int 0)])
9712 (not:SI (match_operand:SI 2 "s_register_operand" "r,r,r"))
9713 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")))]
cffb2a26 9714 "TARGET_ARM"
8a18b90c 9715 "@
9716 mvn%d4\\t%0, %2
9717 mov%D4\\t%0, %1\;mvn%d4\\t%0, %2
9718 mvn%D4\\t%0, #%B1\;mvn%d4\\t%0, %2"
8fa3ba89 9719 [(set_attr "conds" "use")
1b7da4ac 9720 (set_attr "type" "mvn_reg,multiple,multiple")
8fa3ba89 9721 (set_attr "length" "4,8,8")]
9722)
8a18b90c 9723
9724(define_insn "*ifcompare_shift_move"
9c08d1fa 9725 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8a18b90c 9726 (if_then_else:SI
8fa3ba89 9727 (match_operator 6 "arm_comparison_operator"
8a18b90c 9728 [(match_operand:SI 4 "s_register_operand" "r,r")
9729 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
9730 (match_operator:SI 7 "shift_operator"
9731 [(match_operand:SI 2 "s_register_operand" "r,r")
9732 (match_operand:SI 3 "arm_rhs_operand" "rM,rM")])
9733 (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
bd5b4116 9734 (clobber (reg:CC CC_REGNUM))]
cffb2a26 9735 "TARGET_ARM"
9c08d1fa 9736 "#"
8fa3ba89 9737 [(set_attr "conds" "clob")
1b7da4ac 9738 (set_attr "length" "8,12")
9739 (set_attr "type" "multiple")]
8fa3ba89 9740)
9c08d1fa 9741
8a18b90c 9742(define_insn "*if_shift_move"
9743 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9744 (if_then_else:SI
8fa3ba89 9745 (match_operator 5 "arm_comparison_operator"
8a18b90c 9746 [(match_operand 6 "cc_register" "") (const_int 0)])
9747 (match_operator:SI 4 "shift_operator"
9748 [(match_operand:SI 2 "s_register_operand" "r,r,r")
9749 (match_operand:SI 3 "arm_rhs_operand" "rM,rM,rM")])
9750 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")))]
cffb2a26 9751 "TARGET_ARM"
5565501b 9752 "@
8a18b90c 9753 mov%d5\\t%0, %2%S4
9754 mov%D5\\t%0, %1\;mov%d5\\t%0, %2%S4
9755 mvn%D5\\t%0, #%B1\;mov%d5\\t%0, %2%S4"
8fa3ba89 9756 [(set_attr "conds" "use")
331beb1a 9757 (set_attr "shift" "2")
a2cd141b 9758 (set_attr "length" "4,8,8")
282b4c75 9759 (set_attr_alternative "type"
9760 [(if_then_else (match_operand 3 "const_int_operand" "")
9761 (const_string "mov_shift" )
9762 (const_string "mov_shift_reg"))
9763 (const_string "multiple")
9764 (const_string "multiple")])]
8fa3ba89 9765)
5565501b 9766
8a18b90c 9767(define_insn "*ifcompare_move_shift"
9768 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5565501b 9769 (if_then_else:SI
8fa3ba89 9770 (match_operator 6 "arm_comparison_operator"
8a18b90c 9771 [(match_operand:SI 4 "s_register_operand" "r,r")
9772 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
9773 (match_operand:SI 1 "arm_not_operand" "0,?rIK")
5565501b 9774 (match_operator:SI 7 "shift_operator"
8a18b90c 9775 [(match_operand:SI 2 "s_register_operand" "r,r")
9776 (match_operand:SI 3 "arm_rhs_operand" "rM,rM")])))
bd5b4116 9777 (clobber (reg:CC CC_REGNUM))]
cffb2a26 9778 "TARGET_ARM"
8a18b90c 9779 "#"
8fa3ba89 9780 [(set_attr "conds" "clob")
1b7da4ac 9781 (set_attr "length" "8,12")
9782 (set_attr "type" "multiple")]
8fa3ba89 9783)
5565501b 9784
8a18b90c 9785(define_insn "*if_move_shift"
9786 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
5565501b 9787 (if_then_else:SI
8fa3ba89 9788 (match_operator 5 "arm_comparison_operator"
8a18b90c 9789 [(match_operand 6 "cc_register" "") (const_int 0)])
9790 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")
9791 (match_operator:SI 4 "shift_operator"
9792 [(match_operand:SI 2 "s_register_operand" "r,r,r")
9793 (match_operand:SI 3 "arm_rhs_operand" "rM,rM,rM")])))]
cffb2a26 9794 "TARGET_ARM"
5565501b 9795 "@
8a18b90c 9796 mov%D5\\t%0, %2%S4
9797 mov%d5\\t%0, %1\;mov%D5\\t%0, %2%S4
9798 mvn%d5\\t%0, #%B1\;mov%D5\\t%0, %2%S4"
8fa3ba89 9799 [(set_attr "conds" "use")
331beb1a 9800 (set_attr "shift" "2")
a2cd141b 9801 (set_attr "length" "4,8,8")
282b4c75 9802 (set_attr_alternative "type"
9803 [(if_then_else (match_operand 3 "const_int_operand" "")
9804 (const_string "mov_shift" )
9805 (const_string "mov_shift_reg"))
9806 (const_string "multiple")
9807 (const_string "multiple")])]
8fa3ba89 9808)
9c08d1fa 9809
f7fbdd4a 9810(define_insn "*ifcompare_shift_shift"
8a18b90c 9811 [(set (match_operand:SI 0 "s_register_operand" "=r")
5565501b 9812 (if_then_else:SI
8fa3ba89 9813 (match_operator 7 "arm_comparison_operator"
8a18b90c 9814 [(match_operand:SI 5 "s_register_operand" "r")
9815 (match_operand:SI 6 "arm_add_operand" "rIL")])
5565501b 9816 (match_operator:SI 8 "shift_operator"
8a18b90c 9817 [(match_operand:SI 1 "s_register_operand" "r")
9818 (match_operand:SI 2 "arm_rhs_operand" "rM")])
5565501b 9819 (match_operator:SI 9 "shift_operator"
8a18b90c 9820 [(match_operand:SI 3 "s_register_operand" "r")
9821 (match_operand:SI 4 "arm_rhs_operand" "rM")])))
bd5b4116 9822 (clobber (reg:CC CC_REGNUM))]
cffb2a26 9823 "TARGET_ARM"
8a18b90c 9824 "#"
8fa3ba89 9825 [(set_attr "conds" "clob")
1b7da4ac 9826 (set_attr "length" "12")
9827 (set_attr "type" "multiple")]
8fa3ba89 9828)
9c08d1fa 9829
8a18b90c 9830(define_insn "*if_shift_shift"
9831 [(set (match_operand:SI 0 "s_register_operand" "=r")
9832 (if_then_else:SI
8fa3ba89 9833 (match_operator 5 "arm_comparison_operator"
8a18b90c 9834 [(match_operand 8 "cc_register" "") (const_int 0)])
9835 (match_operator:SI 6 "shift_operator"
9836 [(match_operand:SI 1 "s_register_operand" "r")
9837 (match_operand:SI 2 "arm_rhs_operand" "rM")])
9838 (match_operator:SI 7 "shift_operator"
9839 [(match_operand:SI 3 "s_register_operand" "r")
9840 (match_operand:SI 4 "arm_rhs_operand" "rM")])))]
cffb2a26 9841 "TARGET_ARM"
8a18b90c 9842 "mov%d5\\t%0, %1%S6\;mov%D5\\t%0, %3%S7"
8fa3ba89 9843 [(set_attr "conds" "use")
331beb1a 9844 (set_attr "shift" "1")
a2cd141b 9845 (set_attr "length" "8")
9846 (set (attr "type") (if_then_else
9847 (and (match_operand 2 "const_int_operand" "")
9848 (match_operand 4 "const_int_operand" ""))
1aed5204 9849 (const_string "mov_shift")
9850 (const_string "mov_shift_reg")))]
8fa3ba89 9851)
8a18b90c 9852
f7fbdd4a 9853(define_insn "*ifcompare_not_arith"
8a18b90c 9854 [(set (match_operand:SI 0 "s_register_operand" "=r")
5565501b 9855 (if_then_else:SI
8fa3ba89 9856 (match_operator 6 "arm_comparison_operator"
8a18b90c 9857 [(match_operand:SI 4 "s_register_operand" "r")
9858 (match_operand:SI 5 "arm_add_operand" "rIL")])
9859 (not:SI (match_operand:SI 1 "s_register_operand" "r"))
5565501b 9860 (match_operator:SI 7 "shiftable_operator"
8a18b90c 9861 [(match_operand:SI 2 "s_register_operand" "r")
9862 (match_operand:SI 3 "arm_rhs_operand" "rI")])))
bd5b4116 9863 (clobber (reg:CC CC_REGNUM))]
cffb2a26 9864 "TARGET_ARM"
8a18b90c 9865 "#"
8fa3ba89 9866 [(set_attr "conds" "clob")
1b7da4ac 9867 (set_attr "length" "12")
9868 (set_attr "type" "multiple")]
8fa3ba89 9869)
9c08d1fa 9870
8a18b90c 9871(define_insn "*if_not_arith"
9872 [(set (match_operand:SI 0 "s_register_operand" "=r")
9873 (if_then_else:SI
8fa3ba89 9874 (match_operator 5 "arm_comparison_operator"
8a18b90c 9875 [(match_operand 4 "cc_register" "") (const_int 0)])
9876 (not:SI (match_operand:SI 1 "s_register_operand" "r"))
9877 (match_operator:SI 6 "shiftable_operator"
9878 [(match_operand:SI 2 "s_register_operand" "r")
9879 (match_operand:SI 3 "arm_rhs_operand" "rI")])))]
cffb2a26 9880 "TARGET_ARM"
8a18b90c 9881 "mvn%d5\\t%0, %1\;%I6%D5\\t%0, %2, %3"
8fa3ba89 9882 [(set_attr "conds" "use")
1aed5204 9883 (set_attr "type" "mvn_reg")
8fa3ba89 9884 (set_attr "length" "8")]
9885)
8a18b90c 9886
9887(define_insn "*ifcompare_arith_not"
9888 [(set (match_operand:SI 0 "s_register_operand" "=r")
5565501b 9889 (if_then_else:SI
8fa3ba89 9890 (match_operator 6 "arm_comparison_operator"
8a18b90c 9891 [(match_operand:SI 4 "s_register_operand" "r")
9892 (match_operand:SI 5 "arm_add_operand" "rIL")])
5565501b 9893 (match_operator:SI 7 "shiftable_operator"
8a18b90c 9894 [(match_operand:SI 2 "s_register_operand" "r")
9895 (match_operand:SI 3 "arm_rhs_operand" "rI")])
9896 (not:SI (match_operand:SI 1 "s_register_operand" "r"))))
bd5b4116 9897 (clobber (reg:CC CC_REGNUM))]
cffb2a26 9898 "TARGET_ARM"
8a18b90c 9899 "#"
8fa3ba89 9900 [(set_attr "conds" "clob")
1b7da4ac 9901 (set_attr "length" "12")
9902 (set_attr "type" "multiple")]
8fa3ba89 9903)
9c08d1fa 9904
8a18b90c 9905(define_insn "*if_arith_not"
9906 [(set (match_operand:SI 0 "s_register_operand" "=r")
9907 (if_then_else:SI
8fa3ba89 9908 (match_operator 5 "arm_comparison_operator"
8a18b90c 9909 [(match_operand 4 "cc_register" "") (const_int 0)])
9910 (match_operator:SI 6 "shiftable_operator"
9911 [(match_operand:SI 2 "s_register_operand" "r")
9912 (match_operand:SI 3 "arm_rhs_operand" "rI")])
9913 (not:SI (match_operand:SI 1 "s_register_operand" "r"))))]
cffb2a26 9914 "TARGET_ARM"
8a18b90c 9915 "mvn%D5\\t%0, %1\;%I6%d5\\t%0, %2, %3"
8fa3ba89 9916 [(set_attr "conds" "use")
1b7da4ac 9917 (set_attr "type" "multiple")
8fa3ba89 9918 (set_attr "length" "8")]
9919)
8a18b90c 9920
f7fbdd4a 9921(define_insn "*ifcompare_neg_move"
8a18b90c 9922 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5565501b 9923 (if_then_else:SI
8fa3ba89 9924 (match_operator 5 "arm_comparison_operator"
8a18b90c 9925 [(match_operand:SI 3 "s_register_operand" "r,r")
9926 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
9927 (neg:SI (match_operand:SI 2 "s_register_operand" "r,r"))
9928 (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
bd5b4116 9929 (clobber (reg:CC CC_REGNUM))]
cffb2a26 9930 "TARGET_ARM"
8a18b90c 9931 "#"
8fa3ba89 9932 [(set_attr "conds" "clob")
1b7da4ac 9933 (set_attr "length" "8,12")
9934 (set_attr "type" "multiple")]
8fa3ba89 9935)
8a18b90c 9936
9937(define_insn "*if_neg_move"
9938 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9939 (if_then_else:SI
8fa3ba89 9940 (match_operator 4 "arm_comparison_operator"
8a18b90c 9941 [(match_operand 3 "cc_register" "") (const_int 0)])
9942 (neg:SI (match_operand:SI 2 "s_register_operand" "r,r,r"))
9943 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")))]
cffb2a26 9944 "TARGET_ARM"
8a18b90c 9945 "@
9946 rsb%d4\\t%0, %2, #0
9947 mov%D4\\t%0, %1\;rsb%d4\\t%0, %2, #0
9948 mvn%D4\\t%0, #%B1\;rsb%d4\\t%0, %2, #0"
8fa3ba89 9949 [(set_attr "conds" "use")
1b7da4ac 9950 (set_attr "length" "4,8,8")
9951 (set_attr "type" "logic_shift_imm,multiple,multiple")]
8fa3ba89 9952)
9c08d1fa 9953
f7fbdd4a 9954(define_insn "*ifcompare_move_neg"
8a18b90c 9955 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5565501b 9956 (if_then_else:SI
8fa3ba89 9957 (match_operator 5 "arm_comparison_operator"
8a18b90c 9958 [(match_operand:SI 3 "s_register_operand" "r,r")
9959 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
9960 (match_operand:SI 1 "arm_not_operand" "0,?rIK")
9961 (neg:SI (match_operand:SI 2 "s_register_operand" "r,r"))))
bd5b4116 9962 (clobber (reg:CC CC_REGNUM))]
cffb2a26 9963 "TARGET_ARM"
8a18b90c 9964 "#"
8fa3ba89 9965 [(set_attr "conds" "clob")
1b7da4ac 9966 (set_attr "length" "8,12")
9967 (set_attr "type" "multiple")]
8fa3ba89 9968)
8a18b90c 9969
9970(define_insn "*if_move_neg"
9971 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9972 (if_then_else:SI
8fa3ba89 9973 (match_operator 4 "arm_comparison_operator"
8a18b90c 9974 [(match_operand 3 "cc_register" "") (const_int 0)])
9975 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")
9976 (neg:SI (match_operand:SI 2 "s_register_operand" "r,r,r"))))]
cffb2a26 9977 "TARGET_ARM"
8a18b90c 9978 "@
9979 rsb%D4\\t%0, %2, #0
9980 mov%d4\\t%0, %1\;rsb%D4\\t%0, %2, #0
9981 mvn%d4\\t%0, #%B1\;rsb%D4\\t%0, %2, #0"
0d66636f 9982 [(set_attr "conds" "use")
1b7da4ac 9983 (set_attr "length" "4,8,8")
9984 (set_attr "type" "logic_shift_imm,multiple,multiple")]
0d66636f 9985)
9c08d1fa 9986
f7fbdd4a 9987(define_insn "*arith_adjacentmem"
9c08d1fa 9988 [(set (match_operand:SI 0 "s_register_operand" "=r")
9989 (match_operator:SI 1 "shiftable_operator"
9990 [(match_operand:SI 2 "memory_operand" "m")
9991 (match_operand:SI 3 "memory_operand" "m")]))
9992 (clobber (match_scratch:SI 4 "=r"))]
cffb2a26 9993 "TARGET_ARM && adjacent_mem_locations (operands[2], operands[3])"
9c08d1fa 9994 "*
215b30b3 9995 {
9996 rtx ldm[3];
9997 rtx arith[4];
94dee231 9998 rtx base_reg;
9999 HOST_WIDE_INT val1 = 0, val2 = 0;
9c08d1fa 10000
215b30b3 10001 if (REGNO (operands[0]) > REGNO (operands[4]))
10002 {
10003 ldm[1] = operands[4];
10004 ldm[2] = operands[0];
10005 }
10006 else
10007 {
10008 ldm[1] = operands[0];
10009 ldm[2] = operands[4];
10010 }
94dee231 10011
10012 base_reg = XEXP (operands[2], 0);
10013
10014 if (!REG_P (base_reg))
10015 {
10016 val1 = INTVAL (XEXP (base_reg, 1));
10017 base_reg = XEXP (base_reg, 0);
10018 }
10019
10020 if (!REG_P (XEXP (operands[3], 0)))
215b30b3 10021 val2 = INTVAL (XEXP (XEXP (operands[3], 0), 1));
94dee231 10022
215b30b3 10023 arith[0] = operands[0];
10024 arith[3] = operands[1];
94dee231 10025
215b30b3 10026 if (val1 < val2)
10027 {
10028 arith[1] = ldm[1];
10029 arith[2] = ldm[2];
10030 }
10031 else
10032 {
10033 arith[1] = ldm[2];
10034 arith[2] = ldm[1];
10035 }
94dee231 10036
10037 ldm[0] = base_reg;
10038 if (val1 !=0 && val2 != 0)
215b30b3 10039 {
cdb1295a 10040 rtx ops[3];
10041
94dee231 10042 if (val1 == 4 || val2 == 4)
10043 /* Other val must be 8, since we know they are adjacent and neither
10044 is zero. */
25f905c2 10045 output_asm_insn (\"ldm%(ib%)\\t%0, {%1, %2}\", ldm);
cdb1295a 10046 else if (const_ok_for_arm (val1) || const_ok_for_arm (-val1))
94dee231 10047 {
94dee231 10048 ldm[0] = ops[0] = operands[4];
10049 ops[1] = base_reg;
10050 ops[2] = GEN_INT (val1);
10051 output_add_immediate (ops);
10052 if (val1 < val2)
25f905c2 10053 output_asm_insn (\"ldm%(ia%)\\t%0, {%1, %2}\", ldm);
94dee231 10054 else
25f905c2 10055 output_asm_insn (\"ldm%(da%)\\t%0, {%1, %2}\", ldm);
94dee231 10056 }
cdb1295a 10057 else
10058 {
10059 /* Offset is out of range for a single add, so use two ldr. */
10060 ops[0] = ldm[1];
10061 ops[1] = base_reg;
10062 ops[2] = GEN_INT (val1);
10063 output_asm_insn (\"ldr%?\\t%0, [%1, %2]\", ops);
10064 ops[0] = ldm[2];
10065 ops[2] = GEN_INT (val2);
10066 output_asm_insn (\"ldr%?\\t%0, [%1, %2]\", ops);
10067 }
215b30b3 10068 }
94dee231 10069 else if (val1 != 0)
215b30b3 10070 {
215b30b3 10071 if (val1 < val2)
25f905c2 10072 output_asm_insn (\"ldm%(da%)\\t%0, {%1, %2}\", ldm);
215b30b3 10073 else
25f905c2 10074 output_asm_insn (\"ldm%(ia%)\\t%0, {%1, %2}\", ldm);
215b30b3 10075 }
10076 else
10077 {
215b30b3 10078 if (val1 < val2)
25f905c2 10079 output_asm_insn (\"ldm%(ia%)\\t%0, {%1, %2}\", ldm);
215b30b3 10080 else
25f905c2 10081 output_asm_insn (\"ldm%(da%)\\t%0, {%1, %2}\", ldm);
215b30b3 10082 }
10083 output_asm_insn (\"%I3%?\\t%0, %1, %2\", arith);
10084 return \"\";
10085 }"
10086 [(set_attr "length" "12")
10087 (set_attr "predicable" "yes")
a2cd141b 10088 (set_attr "type" "load1")]
215b30b3 10089)
9c08d1fa 10090
9c08d1fa 10091; This pattern is never tried by combine, so do it as a peephole
10092
a0f94409 10093(define_peephole2
372575c7 10094 [(set (match_operand:SI 0 "arm_general_register_operand" "")
10095 (match_operand:SI 1 "arm_general_register_operand" ""))
bd5b4116 10096 (set (reg:CC CC_REGNUM)
aea4c774 10097 (compare:CC (match_dup 1) (const_int 0)))]
372575c7 10098 "TARGET_ARM"
a0f94409 10099 [(parallel [(set (reg:CC CC_REGNUM) (compare:CC (match_dup 1) (const_int 0)))
10100 (set (match_dup 0) (match_dup 1))])]
10101 ""
0d66636f 10102)
9c08d1fa 10103
9c08d1fa 10104(define_split
10105 [(set (match_operand:SI 0 "s_register_operand" "")
10106 (and:SI (ge:SI (match_operand:SI 1 "s_register_operand" "")
10107 (const_int 0))
8fa3ba89 10108 (neg:SI (match_operator:SI 2 "arm_comparison_operator"
9c08d1fa 10109 [(match_operand:SI 3 "s_register_operand" "")
10110 (match_operand:SI 4 "arm_rhs_operand" "")]))))
10111 (clobber (match_operand:SI 5 "s_register_operand" ""))]
cffb2a26 10112 "TARGET_ARM"
9c08d1fa 10113 [(set (match_dup 5) (not:SI (ashiftrt:SI (match_dup 1) (const_int 31))))
10114 (set (match_dup 0) (and:SI (match_op_dup 2 [(match_dup 3) (match_dup 4)])
10115 (match_dup 5)))]
215b30b3 10116 ""
10117)
9c08d1fa 10118
aea4c774 10119;; This split can be used because CC_Z mode implies that the following
10120;; branch will be an equality, or an unsigned inequality, so the sign
10121;; extension is not needed.
9c08d1fa 10122
aea4c774 10123(define_split
bd5b4116 10124 [(set (reg:CC_Z CC_REGNUM)
aea4c774 10125 (compare:CC_Z
10126 (ashift:SI (subreg:SI (match_operand:QI 0 "memory_operand" "") 0)
9c08d1fa 10127 (const_int 24))
aea4c774 10128 (match_operand 1 "const_int_operand" "")))
10129 (clobber (match_scratch:SI 2 ""))]
cffb2a26 10130 "TARGET_ARM
10131 && (((unsigned HOST_WIDE_INT) INTVAL (operands[1]))
10132 == (((unsigned HOST_WIDE_INT) INTVAL (operands[1])) >> 24) << 24)"
aea4c774 10133 [(set (match_dup 2) (zero_extend:SI (match_dup 0)))
bd5b4116 10134 (set (reg:CC CC_REGNUM) (compare:CC (match_dup 2) (match_dup 1)))]
aea4c774 10135 "
9c08d1fa 10136 operands[1] = GEN_INT (((unsigned long) INTVAL (operands[1])) >> 24);
215b30b3 10137 "
10138)
25f905c2 10139;; ??? Check the patterns above for Thumb-2 usefulness
9c08d1fa 10140
87b22bf7 10141(define_expand "prologue"
10142 [(clobber (const_int 0))]
cffb2a26 10143 "TARGET_EITHER"
25f905c2 10144 "if (TARGET_32BIT)
cffb2a26 10145 arm_expand_prologue ();
10146 else
25f905c2 10147 thumb1_expand_prologue ();
87b22bf7 10148 DONE;
cffb2a26 10149 "
10150)
87b22bf7 10151
56d27660 10152(define_expand "epilogue"
4c44712e 10153 [(clobber (const_int 0))]
cffb2a26 10154 "TARGET_EITHER"
56d27660 10155 "
18d50ae6 10156 if (crtl->calls_eh_return)
fb94f18b 10157 emit_insn (gen_force_register_use (gen_rtx_REG (Pmode, 2)));
25f905c2 10158 if (TARGET_THUMB1)
c3635784 10159 {
10160 thumb1_expand_epilogue ();
10161 emit_jump_insn (gen_rtx_UNSPEC_VOLATILE (VOIDmode,
10162 gen_rtvec (1, ret_rtx), VUNSPEC_EPILOGUE));
10163 }
10164 else if (HAVE_return)
10165 {
10166 /* HAVE_return is testing for USE_RETURN_INSN (FALSE). Hence,
10167 no need for explicit testing again. */
10168 emit_jump_insn (gen_return ());
10169 }
10170 else if (TARGET_32BIT)
10171 {
10172 arm_expand_epilogue (true);
10173 }
cffb2a26 10174 DONE;
10175 "
10176)
56d27660 10177
ef5651d0 10178;; Note - although unspec_volatile's USE all hard registers,
10179;; USEs are ignored after relaod has completed. Thus we need
10180;; to add an unspec of the link register to ensure that flow
10181;; does not think that it is unused by the sibcall branch that
10182;; will replace the standard function epilogue.
c3635784 10183(define_expand "sibcall_epilogue"
fb94f18b 10184 [(parallel [(unspec:SI [(reg:SI LR_REGNUM)] UNSPEC_REGISTER_USE)
c3635784 10185 (unspec_volatile [(return)] VUNSPEC_EPILOGUE)])]
10186 "TARGET_32BIT"
10187 "
10188 arm_expand_epilogue (false);
10189 DONE;
10190 "
1c494086 10191)
10192
cffb2a26 10193(define_expand "eh_epilogue"
7db9af5d 10194 [(use (match_operand:SI 0 "register_operand" ""))
10195 (use (match_operand:SI 1 "register_operand" ""))
10196 (use (match_operand:SI 2 "register_operand" ""))]
cffb2a26 10197 "TARGET_EITHER"
10198 "
215b30b3 10199 {
10200 cfun->machine->eh_epilogue_sp_ofs = operands[1];
0438d37f 10201 if (!REG_P (operands[2]) || REGNO (operands[2]) != 2)
215b30b3 10202 {
10203 rtx ra = gen_rtx_REG (Pmode, 2);
10204
10205 emit_move_insn (ra, operands[2]);
10206 operands[2] = ra;
10207 }
5cf3595a 10208 /* This is a hack -- we may have crystalized the function type too
10209 early. */
10210 cfun->machine->func_type = 0;
215b30b3 10211 }"
10212)
56d27660 10213
9c08d1fa 10214;; This split is only used during output to reduce the number of patterns
10215;; that need assembler instructions adding to them. We allowed the setting
10216;; of the conditions to be implicit during rtl generation so that
10217;; the conditional compare patterns would work. However this conflicts to
8a18b90c 10218;; some extent with the conditional data operations, so we have to split them
9c08d1fa 10219;; up again here.
10220
25f905c2 10221;; ??? Need to audit these splitters for Thumb-2. Why isn't normal
10222;; conditional execution sufficient?
10223
9c08d1fa 10224(define_split
10225 [(set (match_operand:SI 0 "s_register_operand" "")
8fa3ba89 10226 (if_then_else:SI (match_operator 1 "arm_comparison_operator"
10227 [(match_operand 2 "" "") (match_operand 3 "" "")])
10228 (match_dup 0)
10229 (match_operand 4 "" "")))
bd5b4116 10230 (clobber (reg:CC CC_REGNUM))]
ac8b093b 10231 "TARGET_ARM && reload_completed"
8fa3ba89 10232 [(set (match_dup 5) (match_dup 6))
10233 (cond_exec (match_dup 7)
10234 (set (match_dup 0) (match_dup 4)))]
10235 "
10236 {
3754d046 10237 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
8fa3ba89 10238 operands[2], operands[3]);
10239 enum rtx_code rc = GET_CODE (operands[1]);
10240
bd5b4116 10241 operands[5] = gen_rtx_REG (mode, CC_REGNUM);
8fa3ba89 10242 operands[6] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
10243 if (mode == CCFPmode || mode == CCFPEmode)
10244 rc = reverse_condition_maybe_unordered (rc);
10245 else
10246 rc = reverse_condition (rc);
10247
10248 operands[7] = gen_rtx_fmt_ee (rc, VOIDmode, operands[5], const0_rtx);
10249 }"
10250)
10251
10252(define_split
10253 [(set (match_operand:SI 0 "s_register_operand" "")
10254 (if_then_else:SI (match_operator 1 "arm_comparison_operator"
10255 [(match_operand 2 "" "") (match_operand 3 "" "")])
10256 (match_operand 4 "" "")
10257 (match_dup 0)))
bd5b4116 10258 (clobber (reg:CC CC_REGNUM))]
ac8b093b 10259 "TARGET_ARM && reload_completed"
8fa3ba89 10260 [(set (match_dup 5) (match_dup 6))
10261 (cond_exec (match_op_dup 1 [(match_dup 5) (const_int 0)])
10262 (set (match_dup 0) (match_dup 4)))]
10263 "
10264 {
3754d046 10265 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
8fa3ba89 10266 operands[2], operands[3]);
10267
bd5b4116 10268 operands[5] = gen_rtx_REG (mode, CC_REGNUM);
8fa3ba89 10269 operands[6] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
10270 }"
10271)
10272
10273(define_split
10274 [(set (match_operand:SI 0 "s_register_operand" "")
10275 (if_then_else:SI (match_operator 1 "arm_comparison_operator"
9c08d1fa 10276 [(match_operand 2 "" "") (match_operand 3 "" "")])
10277 (match_operand 4 "" "")
10278 (match_operand 5 "" "")))
bd5b4116 10279 (clobber (reg:CC CC_REGNUM))]
ac8b093b 10280 "TARGET_ARM && reload_completed"
8fa3ba89 10281 [(set (match_dup 6) (match_dup 7))
10282 (cond_exec (match_op_dup 1 [(match_dup 6) (const_int 0)])
10283 (set (match_dup 0) (match_dup 4)))
10284 (cond_exec (match_dup 8)
10285 (set (match_dup 0) (match_dup 5)))]
10286 "
10287 {
3754d046 10288 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
8fa3ba89 10289 operands[2], operands[3]);
10290 enum rtx_code rc = GET_CODE (operands[1]);
10291
bd5b4116 10292 operands[6] = gen_rtx_REG (mode, CC_REGNUM);
8fa3ba89 10293 operands[7] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
10294 if (mode == CCFPmode || mode == CCFPEmode)
10295 rc = reverse_condition_maybe_unordered (rc);
10296 else
10297 rc = reverse_condition (rc);
10298
10299 operands[8] = gen_rtx_fmt_ee (rc, VOIDmode, operands[6], const0_rtx);
10300 }"
10301)
10302
cffb2a26 10303(define_split
10304 [(set (match_operand:SI 0 "s_register_operand" "")
8fa3ba89 10305 (if_then_else:SI (match_operator 1 "arm_comparison_operator"
cffb2a26 10306 [(match_operand:SI 2 "s_register_operand" "")
10307 (match_operand:SI 3 "arm_add_operand" "")])
10308 (match_operand:SI 4 "arm_rhs_operand" "")
10309 (not:SI
10310 (match_operand:SI 5 "s_register_operand" ""))))
bd5b4116 10311 (clobber (reg:CC CC_REGNUM))]
ac8b093b 10312 "TARGET_ARM && reload_completed"
cffb2a26 10313 [(set (match_dup 6) (match_dup 7))
f6c53574 10314 (cond_exec (match_op_dup 1 [(match_dup 6) (const_int 0)])
10315 (set (match_dup 0) (match_dup 4)))
10316 (cond_exec (match_dup 8)
10317 (set (match_dup 0) (not:SI (match_dup 5))))]
cffb2a26 10318 "
215b30b3 10319 {
3754d046 10320 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
215b30b3 10321 operands[2], operands[3]);
f6c53574 10322 enum rtx_code rc = GET_CODE (operands[1]);
cffb2a26 10323
bd5b4116 10324 operands[6] = gen_rtx_REG (mode, CC_REGNUM);
1a83b3ff 10325 operands[7] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
f6c53574 10326 if (mode == CCFPmode || mode == CCFPEmode)
10327 rc = reverse_condition_maybe_unordered (rc);
10328 else
10329 rc = reverse_condition (rc);
10330
10331 operands[8] = gen_rtx_fmt_ee (rc, VOIDmode, operands[6], const0_rtx);
215b30b3 10332 }"
10333)
cffb2a26 10334
10335(define_insn "*cond_move_not"
10336 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8fa3ba89 10337 (if_then_else:SI (match_operator 4 "arm_comparison_operator"
cffb2a26 10338 [(match_operand 3 "cc_register" "") (const_int 0)])
10339 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
10340 (not:SI
10341 (match_operand:SI 2 "s_register_operand" "r,r"))))]
10342 "TARGET_ARM"
10343 "@
10344 mvn%D4\\t%0, %2
10345 mov%d4\\t%0, %1\;mvn%D4\\t%0, %2"
0d66636f 10346 [(set_attr "conds" "use")
1b7da4ac 10347 (set_attr "type" "mvn_reg,multiple")
0d66636f 10348 (set_attr "length" "4,8")]
10349)
cffb2a26 10350
9c08d1fa 10351;; The next two patterns occur when an AND operation is followed by a
10352;; scc insn sequence
10353
f7fbdd4a 10354(define_insn "*sign_extract_onebit"
9c08d1fa 10355 [(set (match_operand:SI 0 "s_register_operand" "=r")
10356 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
10357 (const_int 1)
ed750274 10358 (match_operand:SI 2 "const_int_operand" "n")))
10359 (clobber (reg:CC CC_REGNUM))]
cffb2a26 10360 "TARGET_ARM"
9c08d1fa 10361 "*
0d66636f 10362 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
10363 output_asm_insn (\"ands\\t%0, %1, %2\", operands);
10364 return \"mvnne\\t%0, #0\";
10365 "
10366 [(set_attr "conds" "clob")
1b7da4ac 10367 (set_attr "length" "8")
10368 (set_attr "type" "multiple")]
0d66636f 10369)
9c08d1fa 10370
f7fbdd4a 10371(define_insn "*not_signextract_onebit"
9c08d1fa 10372 [(set (match_operand:SI 0 "s_register_operand" "=r")
10373 (not:SI
10374 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
10375 (const_int 1)
ed750274 10376 (match_operand:SI 2 "const_int_operand" "n"))))
10377 (clobber (reg:CC CC_REGNUM))]
cffb2a26 10378 "TARGET_ARM"
9c08d1fa 10379 "*
0d66636f 10380 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
10381 output_asm_insn (\"tst\\t%1, %2\", operands);
10382 output_asm_insn (\"mvneq\\t%0, #0\", operands);
10383 return \"movne\\t%0, #0\";
10384 "
10385 [(set_attr "conds" "clob")
1b7da4ac 10386 (set_attr "length" "12")
10387 (set_attr "type" "multiple")]
0d66636f 10388)
25f905c2 10389;; ??? The above patterns need auditing for Thumb-2
87b22bf7 10390
0d66636f 10391;; Push multiple registers to the stack. Registers are in parallel (use ...)
10392;; expressions. For simplicity, the first register is also in the unspec
10393;; part.
08508cbf 10394;; To avoid the usage of GNU extension, the length attribute is computed
10395;; in a C function arm_attr_length_push_multi.
f7fbdd4a 10396(define_insn "*push_multi"
87b22bf7 10397 [(match_parallel 2 "multi_register_push"
7571d3f7 10398 [(set (match_operand:BLK 0 "push_mult_memory_operand" "")
3cc80a30 10399 (unspec:BLK [(match_operand:SI 1 "s_register_operand" "")]
e1159bbe 10400 UNSPEC_PUSH_MULT))])]
7571d3f7 10401 ""
87b22bf7 10402 "*
215b30b3 10403 {
10404 int num_saves = XVECLEN (operands[2], 0);
ed593f11 10405
215b30b3 10406 /* For the StrongARM at least it is faster to
25f905c2 10407 use STR to store only a single register.
542d5028 10408 In Thumb mode always use push, and the assembler will pick
10409 something appropriate. */
25f905c2 10410 if (num_saves == 1 && TARGET_ARM)
61309563 10411 output_asm_insn (\"str%?\\t%1, [%m0, #-4]!\", operands);
215b30b3 10412 else
10413 {
10414 int i;
10415 char pattern[100];
ed593f11 10416
25f905c2 10417 if (TARGET_ARM)
61309563 10418 strcpy (pattern, \"stm%(fd%)\\t%m0!, {%1\");
10419 else if (TARGET_THUMB2)
10420 strcpy (pattern, \"push%?\\t{%1\");
25f905c2 10421 else
10422 strcpy (pattern, \"push\\t{%1\");
215b30b3 10423
6079f055 10424 for (i = 1; i < num_saves; i++)
215b30b3 10425 {
10426 strcat (pattern, \", %|\");
10427 strcat (pattern,
10428 reg_names[REGNO (XEXP (XVECEXP (operands[2], 0, i), 0))]);
10429 }
10430
10431 strcat (pattern, \"}\");
10432 output_asm_insn (pattern, operands);
10433 }
10434
10435 return \"\";
10436 }"
a6864a24 10437 [(set_attr "type" "store4")
10438 (set (attr "length")
08508cbf 10439 (symbol_ref "arm_attr_length_push_multi (operands[2], operands[1])"))]
215b30b3 10440)
f7fbdd4a 10441
4c58c898 10442(define_insn "stack_tie"
10443 [(set (mem:BLK (scratch))
aaa37ad6 10444 (unspec:BLK [(match_operand:SI 0 "s_register_operand" "rk")
10445 (match_operand:SI 1 "s_register_operand" "rk")]
4c58c898 10446 UNSPEC_PRLG_STK))]
10447 ""
10448 ""
1b7da4ac 10449 [(set_attr "length" "0")
10450 (set_attr "type" "block")]
4c58c898 10451)
10452
426be8c5 10453;; Pop (as used in epilogue RTL)
10454;;
10455(define_insn "*load_multiple_with_writeback"
10456 [(match_parallel 0 "load_multiple_operation"
10457 [(set (match_operand:SI 1 "s_register_operand" "+rk")
10458 (plus:SI (match_dup 1)
809003b3 10459 (match_operand:SI 2 "const_int_I_operand" "I")))
426be8c5 10460 (set (match_operand:SI 3 "s_register_operand" "=rk")
10461 (mem:SI (match_dup 1)))
10462 ])]
10463 "TARGET_32BIT && (reload_in_progress || reload_completed)"
10464 "*
10465 {
10466 arm_output_multireg_pop (operands, /*return_pc=*/false,
10467 /*cond=*/const_true_rtx,
10468 /*reverse=*/false,
10469 /*update=*/true);
10470 return \"\";
10471 }
10472 "
10473 [(set_attr "type" "load4")
10474 (set_attr "predicable" "yes")]
10475)
10476
10477;; Pop with return (as used in epilogue RTL)
10478;;
10479;; This instruction is generated when the registers are popped at the end of
10480;; epilogue. Here, instead of popping the value into LR and then generating
10481;; jump to LR, value is popped into PC directly. Hence, the pattern is combined
10482;; with (return).
10483(define_insn "*pop_multiple_with_writeback_and_return"
10484 [(match_parallel 0 "pop_multiple_return"
10485 [(return)
10486 (set (match_operand:SI 1 "s_register_operand" "+rk")
10487 (plus:SI (match_dup 1)
809003b3 10488 (match_operand:SI 2 "const_int_I_operand" "I")))
426be8c5 10489 (set (match_operand:SI 3 "s_register_operand" "=rk")
10490 (mem:SI (match_dup 1)))
10491 ])]
10492 "TARGET_32BIT && (reload_in_progress || reload_completed)"
10493 "*
10494 {
10495 arm_output_multireg_pop (operands, /*return_pc=*/true,
10496 /*cond=*/const_true_rtx,
10497 /*reverse=*/false,
10498 /*update=*/true);
10499 return \"\";
10500 }
10501 "
10502 [(set_attr "type" "load4")
10503 (set_attr "predicable" "yes")]
10504)
10505
10506(define_insn "*pop_multiple_with_return"
10507 [(match_parallel 0 "pop_multiple_return"
10508 [(return)
10509 (set (match_operand:SI 2 "s_register_operand" "=rk")
10510 (mem:SI (match_operand:SI 1 "s_register_operand" "rk")))
10511 ])]
10512 "TARGET_32BIT && (reload_in_progress || reload_completed)"
10513 "*
10514 {
10515 arm_output_multireg_pop (operands, /*return_pc=*/true,
10516 /*cond=*/const_true_rtx,
10517 /*reverse=*/false,
10518 /*update=*/false);
10519 return \"\";
10520 }
10521 "
10522 [(set_attr "type" "load4")
10523 (set_attr "predicable" "yes")]
10524)
10525
10526;; Load into PC and return
10527(define_insn "*ldr_with_return"
10528 [(return)
10529 (set (reg:SI PC_REGNUM)
10530 (mem:SI (post_inc:SI (match_operand:SI 0 "s_register_operand" "+rk"))))]
10531 "TARGET_32BIT && (reload_in_progress || reload_completed)"
10532 "ldr%?\t%|pc, [%0], #4"
10533 [(set_attr "type" "load1")
10534 (set_attr "predicable" "yes")]
10535)
1a0b0f12 10536;; Pop for floating point registers (as used in epilogue RTL)
10537(define_insn "*vfp_pop_multiple_with_writeback"
10538 [(match_parallel 0 "pop_multiple_fp"
10539 [(set (match_operand:SI 1 "s_register_operand" "+rk")
10540 (plus:SI (match_dup 1)
809003b3 10541 (match_operand:SI 2 "const_int_I_operand" "I")))
2f2163a4 10542 (set (match_operand:DF 3 "vfp_hard_register_operand" "")
1a0b0f12 10543 (mem:DF (match_dup 1)))])]
10544 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
10545 "*
10546 {
10547 int num_regs = XVECLEN (operands[0], 0);
10548 char pattern[100];
10549 rtx op_list[2];
b34d8dac 10550 strcpy (pattern, \"vldm\\t\");
1a0b0f12 10551 strcat (pattern, reg_names[REGNO (SET_DEST (XVECEXP (operands[0], 0, 0)))]);
10552 strcat (pattern, \"!, {\");
10553 op_list[0] = XEXP (XVECEXP (operands[0], 0, 1), 0);
10554 strcat (pattern, \"%P0\");
10555 if ((num_regs - 1) > 1)
10556 {
10557 strcat (pattern, \"-%P1\");
10558 op_list [1] = XEXP (XVECEXP (operands[0], 0, num_regs - 1), 0);
10559 }
10560
10561 strcat (pattern, \"}\");
10562 output_asm_insn (pattern, op_list);
10563 return \"\";
10564 }
10565 "
10566 [(set_attr "type" "load4")
10567 (set_attr "conds" "unconditional")
10568 (set_attr "predicable" "no")]
10569)
10570
f7fbdd4a 10571;; Special patterns for dealing with the constant pool
10572
cffb2a26 10573(define_insn "align_4"
e1159bbe 10574 [(unspec_volatile [(const_int 0)] VUNSPEC_ALIGN)]
cffb2a26 10575 "TARGET_EITHER"
f7fbdd4a 10576 "*
cffb2a26 10577 assemble_align (32);
f7fbdd4a 10578 return \"\";
cffb2a26 10579 "
1b7da4ac 10580 [(set_attr "type" "no_insn")]
cffb2a26 10581)
f7fbdd4a 10582
755eb2b4 10583(define_insn "align_8"
10584 [(unspec_volatile [(const_int 0)] VUNSPEC_ALIGN8)]
f9273c43 10585 "TARGET_EITHER"
755eb2b4 10586 "*
10587 assemble_align (64);
10588 return \"\";
10589 "
1b7da4ac 10590 [(set_attr "type" "no_insn")]
755eb2b4 10591)
10592
cffb2a26 10593(define_insn "consttable_end"
e1159bbe 10594 [(unspec_volatile [(const_int 0)] VUNSPEC_POOL_END)]
cffb2a26 10595 "TARGET_EITHER"
f7fbdd4a 10596 "*
cffb2a26 10597 making_const_table = FALSE;
f7fbdd4a 10598 return \"\";
cffb2a26 10599 "
1b7da4ac 10600 [(set_attr "type" "no_insn")]
cffb2a26 10601)
f7fbdd4a 10602
0e207eb8 10603(define_insn "consttable_1"
10604 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_1)]
10605 "TARGET_EITHER"
10606 "*
10607 making_const_table = TRUE;
10608 assemble_integer (operands[0], 1, BITS_PER_WORD, 1);
10609 assemble_zeros (3);
10610 return \"\";
10611 "
10612 [(set_attr "length" "4")
10613 (set_attr "type" "no_insn")]
10614)
10615
10616(define_insn "consttable_2"
10617 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_2)]
10618 "TARGET_EITHER"
10619 "*
10620 {
10621 rtx x = operands[0];
10622 making_const_table = TRUE;
10623 switch (GET_MODE_CLASS (GET_MODE (x)))
10624 {
10625 case MODE_FLOAT:
10626 arm_emit_fp16_const (x);
10627 break;
10628 default:
10629 assemble_integer (operands[0], 2, BITS_PER_WORD, 1);
10630 assemble_zeros (2);
10631 break;
10632 }
10633 return \"\";
10634 }"
10635 [(set_attr "length" "4")
10636 (set_attr "type" "no_insn")]
10637)
10638
cffb2a26 10639(define_insn "consttable_4"
e1159bbe 10640 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_4)]
cffb2a26 10641 "TARGET_EITHER"
10642 "*
10643 {
9b8516be 10644 rtx x = operands[0];
cffb2a26 10645 making_const_table = TRUE;
9b8516be 10646 switch (GET_MODE_CLASS (GET_MODE (x)))
cffb2a26 10647 {
10648 case MODE_FLOAT:
0e207eb8 10649 {
10650 REAL_VALUE_TYPE r;
10651 REAL_VALUE_FROM_CONST_DOUBLE (r, x);
10652 assemble_real (r, GET_MODE (x), BITS_PER_WORD);
10653 break;
10654 }
cffb2a26 10655 default:
7b04c5d5 10656 /* XXX: Sometimes gcc does something really dumb and ends up with
10657 a HIGH in a constant pool entry, usually because it's trying to
10658 load into a VFP register. We know this will always be used in
10659 combination with a LO_SUM which ignores the high bits, so just
10660 strip off the HIGH. */
10661 if (GET_CODE (x) == HIGH)
10662 x = XEXP (x, 0);
9b8516be 10663 assemble_integer (x, 4, BITS_PER_WORD, 1);
10664 mark_symbol_refs_as_used (x);
cffb2a26 10665 break;
10666 }
10667 return \"\";
10668 }"
1b7da4ac 10669 [(set_attr "length" "4")
10670 (set_attr "type" "no_insn")]
cffb2a26 10671)
10672
10673(define_insn "consttable_8"
e1159bbe 10674 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_8)]
cffb2a26 10675 "TARGET_EITHER"
10676 "*
10677 {
10678 making_const_table = TRUE;
10679 switch (GET_MODE_CLASS (GET_MODE (operands[0])))
10680 {
10681 case MODE_FLOAT:
10682 {
badfe841 10683 REAL_VALUE_TYPE r;
10684 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[0]);
10685 assemble_real (r, GET_MODE (operands[0]), BITS_PER_WORD);
cffb2a26 10686 break;
10687 }
10688 default:
09d688ff 10689 assemble_integer (operands[0], 8, BITS_PER_WORD, 1);
cffb2a26 10690 break;
10691 }
10692 return \"\";
10693 }"
1b7da4ac 10694 [(set_attr "length" "8")
10695 (set_attr "type" "no_insn")]
cffb2a26 10696)
10697
d98a3884 10698(define_insn "consttable_16"
10699 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_16)]
10700 "TARGET_EITHER"
10701 "*
10702 {
10703 making_const_table = TRUE;
10704 switch (GET_MODE_CLASS (GET_MODE (operands[0])))
10705 {
10706 case MODE_FLOAT:
10707 {
10708 REAL_VALUE_TYPE r;
10709 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[0]);
10710 assemble_real (r, GET_MODE (operands[0]), BITS_PER_WORD);
10711 break;
10712 }
10713 default:
10714 assemble_integer (operands[0], 16, BITS_PER_WORD, 1);
10715 break;
10716 }
10717 return \"\";
10718 }"
1b7da4ac 10719 [(set_attr "length" "16")
10720 (set_attr "type" "no_insn")]
d98a3884 10721)
10722
331beb1a 10723;; V5 Instructions,
10724
8f4be2be 10725(define_insn "clzsi2"
10726 [(set (match_operand:SI 0 "s_register_operand" "=r")
10727 (clz:SI (match_operand:SI 1 "s_register_operand" "r")))]
25f905c2 10728 "TARGET_32BIT && arm_arch5"
ee7cbe0e 10729 "clz%?\\t%0, %1"
bcaec148 10730 [(set_attr "predicable" "yes")
4a510717 10731 (set_attr "predicable_short_it" "no")
bebe9bbb 10732 (set_attr "type" "clz")])
331beb1a 10733
099ad98b 10734(define_insn "rbitsi2"
10735 [(set (match_operand:SI 0 "s_register_operand" "=r")
10736 (unspec:SI [(match_operand:SI 1 "s_register_operand" "r")] UNSPEC_RBIT))]
10737 "TARGET_32BIT && arm_arch_thumb2"
10738 "rbit%?\\t%0, %1"
10739 [(set_attr "predicable" "yes")
4a510717 10740 (set_attr "predicable_short_it" "no")
bebe9bbb 10741 (set_attr "type" "clz")])
099ad98b 10742
10743(define_expand "ctzsi2"
10744 [(set (match_operand:SI 0 "s_register_operand" "")
10745 (ctz:SI (match_operand:SI 1 "s_register_operand" "")))]
10746 "TARGET_32BIT && arm_arch_thumb2"
10747 "
30191172 10748 {
10749 rtx tmp = gen_reg_rtx (SImode);
10750 emit_insn (gen_rbitsi2 (tmp, operands[1]));
10751 emit_insn (gen_clzsi2 (operands[0], tmp));
10752 }
099ad98b 10753 DONE;
10754 "
10755)
10756
e1159bbe 10757;; V5E instructions.
331beb1a 10758
10759(define_insn "prefetch"
f4e79814 10760 [(prefetch (match_operand:SI 0 "address_operand" "p")
10761 (match_operand:SI 1 "" "")
10762 (match_operand:SI 2 "" ""))]
25f905c2 10763 "TARGET_32BIT && arm_arch5e"
1b7da4ac 10764 "pld\\t%a0"
10765 [(set_attr "type" "load1")]
10766)
331beb1a 10767
0d66636f 10768;; General predication pattern
10769
10770(define_cond_exec
10771 [(match_operator 0 "arm_comparison_operator"
10772 [(match_operand 1 "cc_register" "")
10773 (const_int 0)])]
580f4c48 10774 "TARGET_32BIT
10775 && (!TARGET_NO_VOLATILE_CE || !volatile_refs_p (PATTERN (insn)))"
0d66636f 10776 ""
c7a58118 10777[(set_attr "predicated" "yes")]
0d66636f 10778)
10779
fb94f18b 10780(define_insn "force_register_use"
10781 [(unspec:SI [(match_operand:SI 0 "register_operand" "")] UNSPEC_REGISTER_USE)]
063a05c7 10782 ""
fb94f18b 10783 "%@ %0 needed"
1b7da4ac 10784 [(set_attr "length" "0")
10785 (set_attr "type" "no_insn")]
063a05c7 10786)
7db9af5d 10787
4c44712e 10788
10789;; Patterns for exception handling
10790
10791(define_expand "eh_return"
10792 [(use (match_operand 0 "general_operand" ""))]
10793 "TARGET_EITHER"
10794 "
10795 {
25f905c2 10796 if (TARGET_32BIT)
4c44712e 10797 emit_insn (gen_arm_eh_return (operands[0]));
10798 else
10799 emit_insn (gen_thumb_eh_return (operands[0]));
10800 DONE;
10801 }"
10802)
10803
10804;; We can't expand this before we know where the link register is stored.
10805(define_insn_and_split "arm_eh_return"
10806 [(unspec_volatile [(match_operand:SI 0 "s_register_operand" "r")]
10807 VUNSPEC_EH_RETURN)
10808 (clobber (match_scratch:SI 1 "=&r"))]
10809 "TARGET_ARM"
10810 "#"
10811 "&& reload_completed"
10812 [(const_int 0)]
10813 "
10814 {
10815 arm_set_return_address (operands[0], operands[1]);
10816 DONE;
10817 }"
10818)
10819
f655717d 10820\f
10821;; TLS support
10822
10823(define_insn "load_tp_hard"
10824 [(set (match_operand:SI 0 "register_operand" "=r")
10825 (unspec:SI [(const_int 0)] UNSPEC_TLS))]
10826 "TARGET_HARD_TP"
10827 "mrc%?\\tp15, 0, %0, c13, c0, 3\\t@ load_tp_hard"
1b7da4ac 10828 [(set_attr "predicable" "yes")
4b5d7374 10829 (set_attr "type" "mrs")]
f655717d 10830)
10831
10832;; Doesn't clobber R1-R3. Must use r0 for the first operand.
10833(define_insn "load_tp_soft"
10834 [(set (reg:SI 0) (unspec:SI [(const_int 0)] UNSPEC_TLS))
10835 (clobber (reg:SI LR_REGNUM))
10836 (clobber (reg:SI IP_REGNUM))
10837 (clobber (reg:CC CC_REGNUM))]
10838 "TARGET_SOFT_TP"
10839 "bl\\t__aeabi_read_tp\\t@ load_tp_soft"
1b7da4ac 10840 [(set_attr "conds" "clob")
10841 (set_attr "type" "branch")]
f655717d 10842)
10843
f41e4452 10844;; tls descriptor call
10845(define_insn "tlscall"
10846 [(set (reg:SI R0_REGNUM)
10847 (unspec:SI [(reg:SI R0_REGNUM)
10848 (match_operand:SI 0 "" "X")
10849 (match_operand 1 "" "")] UNSPEC_TLS))
10850 (clobber (reg:SI R1_REGNUM))
10851 (clobber (reg:SI LR_REGNUM))
10852 (clobber (reg:SI CC_REGNUM))]
10853 "TARGET_GNU2_TLS"
10854 {
10855 targetm.asm_out.internal_label (asm_out_file, "LPIC",
10856 INTVAL (operands[1]));
10857 return "bl\\t%c0(tlscall)";
10858 }
10859 [(set_attr "conds" "clob")
1b7da4ac 10860 (set_attr "length" "4")
10861 (set_attr "type" "branch")]
f41e4452 10862)
10863
1fe0edab 10864;; For thread pointer builtin
10865(define_expand "get_thread_pointersi"
10866 [(match_operand:SI 0 "s_register_operand" "=r")]
10867 ""
10868 "
10869 {
10870 arm_load_tp (operands[0]);
10871 DONE;
10872 }")
10873
f41e4452 10874;;
10875
aabe09ac 10876;; We only care about the lower 16 bits of the constant
10877;; being inserted into the upper 16 bits of the register.
eca5c984 10878(define_insn "*arm_movtas_ze"
10879 [(set (zero_extract:SI (match_operand:SI 0 "s_register_operand" "+r")
10880 (const_int 16)
10881 (const_int 16))
10882 (match_operand:SI 1 "const_int_operand" ""))]
181ab277 10883 "arm_arch_thumb2"
aabe09ac 10884 "movt%?\t%0, %L1"
eca5c984 10885 [(set_attr "predicable" "yes")
7c36fe71 10886 (set_attr "predicable_short_it" "no")
1b7da4ac 10887 (set_attr "length" "4")
282b4c75 10888 (set_attr "type" "alu_sreg")]
eca5c984 10889)
10890
c0fc3696 10891(define_insn "*arm_rev"
a486b499 10892 [(set (match_operand:SI 0 "s_register_operand" "=l,l,r")
10893 (bswap:SI (match_operand:SI 1 "s_register_operand" "l,l,r")))]
10894 "arm_arch6"
10895 "@
10896 rev\t%0, %1
10897 rev%?\t%0, %1
10898 rev%?\t%0, %1"
10899 [(set_attr "arch" "t1,t2,32")
1b7da4ac 10900 (set_attr "length" "2,2,4")
4a510717 10901 (set_attr "predicable" "no,yes,yes")
10902 (set_attr "predicable_short_it" "no")
1b7da4ac 10903 (set_attr "type" "rev")]
ff82f757 10904)
10905
10906(define_expand "arm_legacy_rev"
10907 [(set (match_operand:SI 2 "s_register_operand" "")
10908 (xor:SI (rotatert:SI (match_operand:SI 1 "s_register_operand" "")
10909 (const_int 16))
10910 (match_dup 1)))
10911 (set (match_dup 2)
10912 (lshiftrt:SI (match_dup 2)
10913 (const_int 8)))
10914 (set (match_operand:SI 3 "s_register_operand" "")
10915 (rotatert:SI (match_dup 1)
10916 (const_int 8)))
10917 (set (match_dup 2)
10918 (and:SI (match_dup 2)
10919 (const_int -65281)))
10920 (set (match_operand:SI 0 "s_register_operand" "")
10921 (xor:SI (match_dup 3)
10922 (match_dup 2)))]
10923 "TARGET_32BIT"
10924 ""
10925)
10926
10927;; Reuse temporaries to keep register pressure down.
10928(define_expand "thumb_legacy_rev"
10929 [(set (match_operand:SI 2 "s_register_operand" "")
10930 (ashift:SI (match_operand:SI 1 "s_register_operand" "")
10931 (const_int 24)))
10932 (set (match_operand:SI 3 "s_register_operand" "")
10933 (lshiftrt:SI (match_dup 1)
10934 (const_int 24)))
10935 (set (match_dup 3)
10936 (ior:SI (match_dup 3)
10937 (match_dup 2)))
10938 (set (match_operand:SI 4 "s_register_operand" "")
10939 (const_int 16))
10940 (set (match_operand:SI 5 "s_register_operand" "")
10941 (rotatert:SI (match_dup 1)
10942 (match_dup 4)))
10943 (set (match_dup 2)
10944 (ashift:SI (match_dup 5)
10945 (const_int 24)))
10946 (set (match_dup 5)
10947 (lshiftrt:SI (match_dup 5)
10948 (const_int 24)))
10949 (set (match_dup 5)
10950 (ior:SI (match_dup 5)
10951 (match_dup 2)))
10952 (set (match_dup 5)
10953 (rotatert:SI (match_dup 5)
10954 (match_dup 4)))
10955 (set (match_operand:SI 0 "s_register_operand" "")
10956 (ior:SI (match_dup 5)
10957 (match_dup 3)))]
10958 "TARGET_THUMB"
10959 ""
10960)
10961
10962(define_expand "bswapsi2"
10963 [(set (match_operand:SI 0 "s_register_operand" "=r")
10964 (bswap:SI (match_operand:SI 1 "s_register_operand" "r")))]
8d1af482 10965"TARGET_EITHER && (arm_arch6 || !optimize_size)"
ff82f757 10966"
8d1af482 10967 if (!arm_arch6)
10968 {
10969 rtx op2 = gen_reg_rtx (SImode);
10970 rtx op3 = gen_reg_rtx (SImode);
ff82f757 10971
8d1af482 10972 if (TARGET_THUMB)
10973 {
10974 rtx op4 = gen_reg_rtx (SImode);
10975 rtx op5 = gen_reg_rtx (SImode);
ff82f757 10976
8d1af482 10977 emit_insn (gen_thumb_legacy_rev (operands[0], operands[1],
10978 op2, op3, op4, op5));
10979 }
10980 else
10981 {
10982 emit_insn (gen_arm_legacy_rev (operands[0], operands[1],
10983 op2, op3));
10984 }
ff82f757 10985
8d1af482 10986 DONE;
10987 }
ff82f757 10988 "
10989)
10990
a486b499 10991;; bswap16 patterns: use revsh and rev16 instructions for the signed
10992;; and unsigned variants, respectively. For rev16, expose
10993;; byte-swapping in the lower 16 bits only.
10994(define_insn "*arm_revsh"
10995 [(set (match_operand:SI 0 "s_register_operand" "=l,l,r")
10996 (sign_extend:SI (bswap:HI (match_operand:HI 1 "s_register_operand" "l,l,r"))))]
10997 "arm_arch6"
10998 "@
10999 revsh\t%0, %1
11000 revsh%?\t%0, %1
11001 revsh%?\t%0, %1"
11002 [(set_attr "arch" "t1,t2,32")
1b7da4ac 11003 (set_attr "length" "2,2,4")
11004 (set_attr "type" "rev")]
a486b499 11005)
11006
11007(define_insn "*arm_rev16"
11008 [(set (match_operand:HI 0 "s_register_operand" "=l,l,r")
11009 (bswap:HI (match_operand:HI 1 "s_register_operand" "l,l,r")))]
11010 "arm_arch6"
11011 "@
11012 rev16\t%0, %1
11013 rev16%?\t%0, %1
11014 rev16%?\t%0, %1"
11015 [(set_attr "arch" "t1,t2,32")
1b7da4ac 11016 (set_attr "length" "2,2,4")
11017 (set_attr "type" "rev")]
09f69e55 11018)
11019
11020;; There are no canonicalisation rules for the position of the lshiftrt, ashift
11021;; operations within an IOR/AND RTX, therefore we have two patterns matching
11022;; each valid permutation.
11023
11024(define_insn "arm_rev16si2"
11025 [(set (match_operand:SI 0 "register_operand" "=l,l,r")
11026 (ior:SI (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "l,l,r")
11027 (const_int 8))
11028 (match_operand:SI 3 "const_int_operand" "n,n,n"))
11029 (and:SI (lshiftrt:SI (match_dup 1)
11030 (const_int 8))
11031 (match_operand:SI 2 "const_int_operand" "n,n,n"))))]
11032 "arm_arch6
11033 && aarch_rev16_shleft_mask_imm_p (operands[3], SImode)
11034 && aarch_rev16_shright_mask_imm_p (operands[2], SImode)"
11035 "rev16\\t%0, %1"
11036 [(set_attr "arch" "t1,t2,32")
11037 (set_attr "length" "2,2,4")
11038 (set_attr "type" "rev")]
11039)
11040
11041(define_insn "arm_rev16si2_alt"
11042 [(set (match_operand:SI 0 "register_operand" "=l,l,r")
11043 (ior:SI (and:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" "l,l,r")
11044 (const_int 8))
11045 (match_operand:SI 2 "const_int_operand" "n,n,n"))
11046 (and:SI (ashift:SI (match_dup 1)
11047 (const_int 8))
11048 (match_operand:SI 3 "const_int_operand" "n,n,n"))))]
11049 "arm_arch6
11050 && aarch_rev16_shleft_mask_imm_p (operands[3], SImode)
11051 && aarch_rev16_shright_mask_imm_p (operands[2], SImode)"
11052 "rev16\\t%0, %1"
11053 [(set_attr "arch" "t1,t2,32")
11054 (set_attr "length" "2,2,4")
11055 (set_attr "type" "rev")]
a486b499 11056)
11057
11058(define_expand "bswaphi2"
11059 [(set (match_operand:HI 0 "s_register_operand" "=r")
11060 (bswap:HI (match_operand:HI 1 "s_register_operand" "r")))]
11061"arm_arch6"
11062""
11063)
11064
1653cf17 11065;; Patterns for LDRD/STRD in Thumb2 mode
11066
11067(define_insn "*thumb2_ldrd"
11068 [(set (match_operand:SI 0 "s_register_operand" "=r")
11069 (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "rk")
11070 (match_operand:SI 2 "ldrd_strd_offset_operand" "Do"))))
11071 (set (match_operand:SI 3 "s_register_operand" "=r")
11072 (mem:SI (plus:SI (match_dup 1)
11073 (match_operand:SI 4 "const_int_operand" ""))))]
11074 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11075 && current_tune->prefer_ldrd_strd
11076 && ((INTVAL (operands[2]) + 4) == INTVAL (operands[4]))
11077 && (operands_ok_ldrd_strd (operands[0], operands[3],
11078 operands[1], INTVAL (operands[2]),
11079 false, true))"
11080 "ldrd%?\t%0, %3, [%1, %2]"
11081 [(set_attr "type" "load2")
d952d547 11082 (set_attr "predicable" "yes")
11083 (set_attr "predicable_short_it" "no")])
1653cf17 11084
11085(define_insn "*thumb2_ldrd_base"
11086 [(set (match_operand:SI 0 "s_register_operand" "=r")
11087 (mem:SI (match_operand:SI 1 "s_register_operand" "rk")))
11088 (set (match_operand:SI 2 "s_register_operand" "=r")
11089 (mem:SI (plus:SI (match_dup 1)
11090 (const_int 4))))]
11091 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11092 && current_tune->prefer_ldrd_strd
11093 && (operands_ok_ldrd_strd (operands[0], operands[2],
11094 operands[1], 0, false, true))"
11095 "ldrd%?\t%0, %2, [%1]"
11096 [(set_attr "type" "load2")
d952d547 11097 (set_attr "predicable" "yes")
11098 (set_attr "predicable_short_it" "no")])
1653cf17 11099
11100(define_insn "*thumb2_ldrd_base_neg"
11101 [(set (match_operand:SI 0 "s_register_operand" "=r")
11102 (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "rk")
11103 (const_int -4))))
11104 (set (match_operand:SI 2 "s_register_operand" "=r")
11105 (mem:SI (match_dup 1)))]
11106 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11107 && current_tune->prefer_ldrd_strd
11108 && (operands_ok_ldrd_strd (operands[0], operands[2],
11109 operands[1], -4, false, true))"
11110 "ldrd%?\t%0, %2, [%1, #-4]"
11111 [(set_attr "type" "load2")
d952d547 11112 (set_attr "predicable" "yes")
11113 (set_attr "predicable_short_it" "no")])
1653cf17 11114
11115(define_insn "*thumb2_strd"
11116 [(set (mem:SI (plus:SI (match_operand:SI 0 "s_register_operand" "rk")
11117 (match_operand:SI 1 "ldrd_strd_offset_operand" "Do")))
11118 (match_operand:SI 2 "s_register_operand" "r"))
11119 (set (mem:SI (plus:SI (match_dup 0)
11120 (match_operand:SI 3 "const_int_operand" "")))
11121 (match_operand:SI 4 "s_register_operand" "r"))]
11122 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11123 && current_tune->prefer_ldrd_strd
11124 && ((INTVAL (operands[1]) + 4) == INTVAL (operands[3]))
11125 && (operands_ok_ldrd_strd (operands[2], operands[4],
11126 operands[0], INTVAL (operands[1]),
11127 false, false))"
11128 "strd%?\t%2, %4, [%0, %1]"
11129 [(set_attr "type" "store2")
d952d547 11130 (set_attr "predicable" "yes")
11131 (set_attr "predicable_short_it" "no")])
1653cf17 11132
11133(define_insn "*thumb2_strd_base"
11134 [(set (mem:SI (match_operand:SI 0 "s_register_operand" "rk"))
11135 (match_operand:SI 1 "s_register_operand" "r"))
11136 (set (mem:SI (plus:SI (match_dup 0)
11137 (const_int 4)))
11138 (match_operand:SI 2 "s_register_operand" "r"))]
11139 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11140 && current_tune->prefer_ldrd_strd
11141 && (operands_ok_ldrd_strd (operands[1], operands[2],
11142 operands[0], 0, false, false))"
11143 "strd%?\t%1, %2, [%0]"
11144 [(set_attr "type" "store2")
d952d547 11145 (set_attr "predicable" "yes")
11146 (set_attr "predicable_short_it" "no")])
1653cf17 11147
11148(define_insn "*thumb2_strd_base_neg"
11149 [(set (mem:SI (plus:SI (match_operand:SI 0 "s_register_operand" "rk")
11150 (const_int -4)))
11151 (match_operand:SI 1 "s_register_operand" "r"))
11152 (set (mem:SI (match_dup 0))
11153 (match_operand:SI 2 "s_register_operand" "r"))]
11154 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11155 && current_tune->prefer_ldrd_strd
11156 && (operands_ok_ldrd_strd (operands[1], operands[2],
11157 operands[0], -4, false, false))"
11158 "strd%?\t%1, %2, [%0, #-4]"
11159 [(set_attr "type" "store2")
d952d547 11160 (set_attr "predicable" "yes")
11161 (set_attr "predicable_short_it" "no")])
1653cf17 11162
2a0c73f2 11163;; ARMv8 CRC32 instructions.
11164(define_insn "<crc_variant>"
11165 [(set (match_operand:SI 0 "s_register_operand" "=r")
11166 (unspec:SI [(match_operand:SI 1 "s_register_operand" "r")
11167 (match_operand:<crc_mode> 2 "s_register_operand" "r")]
11168 CRC))]
11169 "TARGET_CRC32"
11170 "<crc_variant>\\t%0, %1, %2"
11171 [(set_attr "type" "crc")
11172 (set_attr "conds" "unconditional")]
11173)
1653cf17 11174
353cf59a 11175;; Load the load/store double peephole optimizations.
11176(include "ldrdstrd.md")
11177
320ea44d 11178;; Load the load/store multiple patterns
11179(include "ldmstm.md")
426be8c5 11180
11181;; Patterns in ldmstm.md don't cover more than 4 registers. This pattern covers
11182;; large lists without explicit writeback generated for APCS_FRAME epilogue.
11183(define_insn "*load_multiple"
11184 [(match_parallel 0 "load_multiple_operation"
11185 [(set (match_operand:SI 2 "s_register_operand" "=rk")
11186 (mem:SI (match_operand:SI 1 "s_register_operand" "rk")))
11187 ])]
11188 "TARGET_32BIT"
11189 "*
11190 {
11191 arm_output_multireg_pop (operands, /*return_pc=*/false,
11192 /*cond=*/const_true_rtx,
11193 /*reverse=*/false,
11194 /*update=*/false);
11195 return \"\";
11196 }
11197 "
11198 [(set_attr "predicable" "yes")]
11199)
11200
84450ddc 11201(define_expand "copysignsf3"
11202 [(match_operand:SF 0 "register_operand")
11203 (match_operand:SF 1 "register_operand")
11204 (match_operand:SF 2 "register_operand")]
11205 "TARGET_SOFT_FLOAT && arm_arch_thumb2"
11206 "{
11207 emit_move_insn (operands[0], operands[2]);
11208 emit_insn (gen_insv_t2 (simplify_gen_subreg (SImode, operands[0], SFmode, 0),
11209 GEN_INT (31), GEN_INT (0),
11210 simplify_gen_subreg (SImode, operands[1], SFmode, 0)));
11211 DONE;
11212 }"
11213)
11214
11215(define_expand "copysigndf3"
11216 [(match_operand:DF 0 "register_operand")
11217 (match_operand:DF 1 "register_operand")
11218 (match_operand:DF 2 "register_operand")]
11219 "TARGET_SOFT_FLOAT && arm_arch_thumb2"
11220 "{
11221 rtx op0_low = gen_lowpart (SImode, operands[0]);
11222 rtx op0_high = gen_highpart (SImode, operands[0]);
11223 rtx op1_low = gen_lowpart (SImode, operands[1]);
11224 rtx op1_high = gen_highpart (SImode, operands[1]);
11225 rtx op2_high = gen_highpart (SImode, operands[2]);
11226
11227 rtx scratch1 = gen_reg_rtx (SImode);
11228 rtx scratch2 = gen_reg_rtx (SImode);
11229 emit_move_insn (scratch1, op2_high);
11230 emit_move_insn (scratch2, op1_high);
11231
d1f9b275 11232 emit_insn(gen_rtx_SET(scratch1,
84450ddc 11233 gen_rtx_LSHIFTRT (SImode, op2_high, GEN_INT(31))));
11234 emit_insn(gen_insv_t2(scratch2, GEN_INT(1), GEN_INT(31), scratch1));
11235 emit_move_insn (op0_low, op1_low);
11236 emit_move_insn (op0_high, scratch2);
11237
11238 DONE;
11239 }"
11240)
11241
d98a3884 11242;; Vector bits common to IWMMXT and Neon
11243(include "vec-common.md")
755eb2b4 11244;; Load the Intel Wireless Multimedia Extension patterns
11245(include "iwmmxt.md")
a2cd141b 11246;; Load the VFP co-processor patterns
11247(include "vfp.md")
bc360af8 11248;; Thumb-1 patterns
11249(include "thumb1.md")
25f905c2 11250;; Thumb-2 patterns
11251(include "thumb2.md")
d98a3884 11252;; Neon patterns
11253(include "neon.md")
e84fdf6e 11254;; Crypto patterns
11255(include "crypto.md")
06df6b17 11256;; Synchronization Primitives
11257(include "sync.md")
bbbe4599 11258;; Fixed-point patterns
11259(include "arm-fixed.md")