]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/config/arm/arm.md
* MAINTAINERS (Write After Approval): Add myself.
[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 {
17202aa5 1171 if (DONT_EARLY_SPLIT_CONSTANT (INTVAL (operands[1]), MINUS))
1172 operands[1] = force_reg (SImode, operands[1]);
1173 else
1174 {
1175 arm_split_constant (MINUS, SImode, NULL_RTX,
1176 INTVAL (operands[1]), operands[0],
1177 operands[2],
1178 optimize && can_create_pseudo_p ());
1179 DONE;
1180 }
cffb2a26 1181 }
25f905c2 1182 else /* TARGET_THUMB1 */
cffb2a26 1183 operands[1] = force_reg (SImode, operands[1]);
87b22bf7 1184 }
cffb2a26 1185 "
1186)
87b22bf7 1187
25f905c2 1188; ??? Check Thumb-2 split length
a0f94409 1189(define_insn_and_split "*arm_subsi3_insn"
3a44c5a9 1190 [(set (match_operand:SI 0 "s_register_operand" "=l,l ,l ,l ,r,r,r,rk,r")
1191 (minus:SI (match_operand:SI 1 "reg_or_int_operand" "l ,0 ,l ,Pz,I,r,r,k ,?n")
1192 (match_operand:SI 2 "reg_or_int_operand" "l ,Py,Pd,l ,r,I,r,r ,r")))]
25f905c2 1193 "TARGET_32BIT"
e2348bcb 1194 "@
7c36fe71 1195 sub%?\\t%0, %1, %2
1196 sub%?\\t%0, %2
1197 sub%?\\t%0, %1, %2
1198 rsb%?\\t%0, %2, %1
87b22bf7 1199 rsb%?\\t%0, %2, %1
aaa37ad6 1200 sub%?\\t%0, %1, %2
080c0b9a 1201 sub%?\\t%0, %1, %2
65f68e55 1202 sub%?\\t%0, %1, %2
87b22bf7 1203 #"
0438d37f 1204 "&& (CONST_INT_P (operands[1])
91a5e339 1205 && !const_ok_for_arm (INTVAL (operands[1])))"
87b22bf7 1206 [(clobber (const_int 0))]
1207 "
96f57e36 1208 arm_split_constant (MINUS, SImode, curr_insn,
1209 INTVAL (operands[1]), operands[0], operands[2], 0);
87b22bf7 1210 DONE;
cffb2a26 1211 "
7c36fe71 1212 [(set_attr "length" "4,4,4,4,4,4,4,4,16")
1213 (set_attr "arch" "t2,t2,t2,t2,*,*,*,*,*")
65f68e55 1214 (set_attr "predicable" "yes")
7c36fe71 1215 (set_attr "predicable_short_it" "yes,yes,yes,yes,no,no,no,no,no")
112eda6f 1216 (set_attr "type" "alu_sreg,alu_sreg,alu_sreg,alu_sreg,alu_imm,alu_imm,alu_sreg,alu_sreg,multiple")]
a0f94409 1217)
1218
1219(define_peephole2
1220 [(match_scratch:SI 3 "r")
372575c7 1221 (set (match_operand:SI 0 "arm_general_register_operand" "")
a0f94409 1222 (minus:SI (match_operand:SI 1 "const_int_operand" "")
372575c7 1223 (match_operand:SI 2 "arm_general_register_operand" "")))]
25f905c2 1224 "TARGET_32BIT
a0f94409 1225 && !const_ok_for_arm (INTVAL (operands[1]))
1226 && const_ok_for_arm (~INTVAL (operands[1]))"
1227 [(set (match_dup 3) (match_dup 1))
1228 (set (match_dup 0) (minus:SI (match_dup 3) (match_dup 2)))]
1229 ""
cffb2a26 1230)
b11cae9e 1231
62e39b06 1232(define_insn "subsi3_compare0"
bd5b4116 1233 [(set (reg:CC_NOOV CC_REGNUM)
215b30b3 1234 (compare:CC_NOOV
65f68e55 1235 (minus:SI (match_operand:SI 1 "arm_rhs_operand" "r,r,I")
1236 (match_operand:SI 2 "arm_rhs_operand" "I,r,r"))
215b30b3 1237 (const_int 0)))
65f68e55 1238 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9c08d1fa 1239 (minus:SI (match_dup 1) (match_dup 2)))]
25f905c2 1240 "TARGET_32BIT"
e2348bcb 1241 "@
65f68e55 1242 sub%.\\t%0, %1, %2
25f905c2 1243 sub%.\\t%0, %1, %2
1244 rsb%.\\t%0, %2, %1"
65f68e55 1245 [(set_attr "conds" "set")
112eda6f 1246 (set_attr "type" "alus_imm,alus_sreg,alus_sreg")]
cffb2a26 1247)
9c08d1fa 1248
190efb17 1249(define_insn "subsi3_compare"
080c0b9a 1250 [(set (reg:CC CC_REGNUM)
65f68e55 1251 (compare:CC (match_operand:SI 1 "arm_rhs_operand" "r,r,I")
1252 (match_operand:SI 2 "arm_rhs_operand" "I,r,r")))
1253 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
2df9477b 1254 (minus:SI (match_dup 1) (match_dup 2)))]
1255 "TARGET_32BIT"
1256 "@
65f68e55 1257 sub%.\\t%0, %1, %2
2df9477b 1258 sub%.\\t%0, %1, %2
1259 rsb%.\\t%0, %2, %1"
65f68e55 1260 [(set_attr "conds" "set")
112eda6f 1261 (set_attr "type" "alus_imm,alus_sreg,alus_sreg")]
2df9477b 1262)
1263
604f3a0a 1264(define_expand "subsf3"
1265 [(set (match_operand:SF 0 "s_register_operand" "")
d86c91f6 1266 (minus:SF (match_operand:SF 1 "s_register_operand" "")
1267 (match_operand:SF 2 "s_register_operand" "")))]
25f905c2 1268 "TARGET_32BIT && TARGET_HARD_FLOAT"
604f3a0a 1269 "
604f3a0a 1270")
1271
604f3a0a 1272(define_expand "subdf3"
1273 [(set (match_operand:DF 0 "s_register_operand" "")
d86c91f6 1274 (minus:DF (match_operand:DF 1 "s_register_operand" "")
1275 (match_operand:DF 2 "s_register_operand" "")))]
a50d7267 1276 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
604f3a0a 1277 "
604f3a0a 1278")
1279
b11cae9e 1280\f
1281;; Multiplication insns
1282
4422d91f 1283(define_expand "mulhi3"
1284 [(set (match_operand:HI 0 "s_register_operand" "")
1285 (mult:HI (match_operand:HI 1 "s_register_operand" "")
1286 (match_operand:HI 2 "s_register_operand" "")))]
1287 "TARGET_DSP_MULTIPLY"
1288 "
1289 {
1290 rtx result = gen_reg_rtx (SImode);
1291 emit_insn (gen_mulhisi3 (result, operands[1], operands[2]));
1292 emit_move_insn (operands[0], gen_lowpart (HImode, result));
1293 DONE;
1294 }"
1295)
1296
cffb2a26 1297(define_expand "mulsi3"
1298 [(set (match_operand:SI 0 "s_register_operand" "")
1299 (mult:SI (match_operand:SI 2 "s_register_operand" "")
1300 (match_operand:SI 1 "s_register_operand" "")))]
1301 "TARGET_EITHER"
1302 ""
1303)
1304
9c08d1fa 1305;; Use `&' and then `0' to prevent the operands 0 and 1 being the same
cffb2a26 1306(define_insn "*arm_mulsi3"
1307 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r")
9c08d1fa 1308 (mult:SI (match_operand:SI 2 "s_register_operand" "r,r")
e5fea38e 1309 (match_operand:SI 1 "s_register_operand" "%0,r")))]
58d7d654 1310 "TARGET_32BIT && !arm_arch6"
f7fbdd4a 1311 "mul%?\\t%0, %2, %1"
9da0ec36 1312 [(set_attr "type" "mul")
0d66636f 1313 (set_attr "predicable" "yes")]
cffb2a26 1314)
1315
58d7d654 1316(define_insn "*arm_mulsi3_v6"
d952d547 1317 [(set (match_operand:SI 0 "s_register_operand" "=l,l,r")
1318 (mult:SI (match_operand:SI 1 "s_register_operand" "0,l,r")
1319 (match_operand:SI 2 "s_register_operand" "l,0,r")))]
58d7d654 1320 "TARGET_32BIT && arm_arch6"
1321 "mul%?\\t%0, %1, %2"
9da0ec36 1322 [(set_attr "type" "mul")
d952d547 1323 (set_attr "predicable" "yes")
1324 (set_attr "arch" "t2,t2,*")
1325 (set_attr "length" "4")
1326 (set_attr "predicable_short_it" "yes,yes,no")]
58d7d654 1327)
1328
f7fbdd4a 1329(define_insn "*mulsi3_compare0"
bd5b4116 1330 [(set (reg:CC_NOOV CC_REGNUM)
9c08d1fa 1331 (compare:CC_NOOV (mult:SI
1332 (match_operand:SI 2 "s_register_operand" "r,r")
e5fea38e 1333 (match_operand:SI 1 "s_register_operand" "%0,r"))
9c08d1fa 1334 (const_int 0)))
1335 (set (match_operand:SI 0 "s_register_operand" "=&r,&r")
1336 (mult:SI (match_dup 2) (match_dup 1)))]
58d7d654 1337 "TARGET_ARM && !arm_arch6"
1338 "mul%.\\t%0, %2, %1"
1339 [(set_attr "conds" "set")
9da0ec36 1340 (set_attr "type" "muls")]
58d7d654 1341)
1342
1343(define_insn "*mulsi3_compare0_v6"
1344 [(set (reg:CC_NOOV CC_REGNUM)
1345 (compare:CC_NOOV (mult:SI
1346 (match_operand:SI 2 "s_register_operand" "r")
1347 (match_operand:SI 1 "s_register_operand" "r"))
1348 (const_int 0)))
1349 (set (match_operand:SI 0 "s_register_operand" "=r")
1350 (mult:SI (match_dup 2) (match_dup 1)))]
1351 "TARGET_ARM && arm_arch6 && optimize_size"
25f905c2 1352 "mul%.\\t%0, %2, %1"
cffb2a26 1353 [(set_attr "conds" "set")
9da0ec36 1354 (set_attr "type" "muls")]
cffb2a26 1355)
9c08d1fa 1356
f7fbdd4a 1357(define_insn "*mulsi_compare0_scratch"
bd5b4116 1358 [(set (reg:CC_NOOV CC_REGNUM)
9c08d1fa 1359 (compare:CC_NOOV (mult:SI
1360 (match_operand:SI 2 "s_register_operand" "r,r")
e5fea38e 1361 (match_operand:SI 1 "s_register_operand" "%0,r"))
9c08d1fa 1362 (const_int 0)))
1363 (clobber (match_scratch:SI 0 "=&r,&r"))]
58d7d654 1364 "TARGET_ARM && !arm_arch6"
1365 "mul%.\\t%0, %2, %1"
1366 [(set_attr "conds" "set")
9da0ec36 1367 (set_attr "type" "muls")]
58d7d654 1368)
1369
1370(define_insn "*mulsi_compare0_scratch_v6"
1371 [(set (reg:CC_NOOV CC_REGNUM)
1372 (compare:CC_NOOV (mult:SI
1373 (match_operand:SI 2 "s_register_operand" "r")
1374 (match_operand:SI 1 "s_register_operand" "r"))
1375 (const_int 0)))
1376 (clobber (match_scratch:SI 0 "=r"))]
1377 "TARGET_ARM && arm_arch6 && optimize_size"
25f905c2 1378 "mul%.\\t%0, %2, %1"
cffb2a26 1379 [(set_attr "conds" "set")
9da0ec36 1380 (set_attr "type" "muls")]
cffb2a26 1381)
9c08d1fa 1382
b11cae9e 1383;; Unnamed templates to match MLA instruction.
1384
f7fbdd4a 1385(define_insn "*mulsi3addsi"
9c08d1fa 1386 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r,&r")
c8f69309 1387 (plus:SI
9c08d1fa 1388 (mult:SI (match_operand:SI 2 "s_register_operand" "r,r,r,r")
e5fea38e 1389 (match_operand:SI 1 "s_register_operand" "%0,r,0,r"))
1390 (match_operand:SI 3 "s_register_operand" "r,r,0,0")))]
58d7d654 1391 "TARGET_32BIT && !arm_arch6"
1392 "mla%?\\t%0, %2, %1, %3"
9da0ec36 1393 [(set_attr "type" "mla")
58d7d654 1394 (set_attr "predicable" "yes")]
1395)
1396
1397(define_insn "*mulsi3addsi_v6"
1398 [(set (match_operand:SI 0 "s_register_operand" "=r")
1399 (plus:SI
1400 (mult:SI (match_operand:SI 2 "s_register_operand" "r")
1401 (match_operand:SI 1 "s_register_operand" "r"))
1402 (match_operand:SI 3 "s_register_operand" "r")))]
1403 "TARGET_32BIT && arm_arch6"
f7fbdd4a 1404 "mla%?\\t%0, %2, %1, %3"
9da0ec36 1405 [(set_attr "type" "mla")
d952d547 1406 (set_attr "predicable" "yes")
1407 (set_attr "predicable_short_it" "no")]
0d66636f 1408)
b11cae9e 1409
f7fbdd4a 1410(define_insn "*mulsi3addsi_compare0"
bd5b4116 1411 [(set (reg:CC_NOOV CC_REGNUM)
215b30b3 1412 (compare:CC_NOOV
1413 (plus:SI (mult:SI
1414 (match_operand:SI 2 "s_register_operand" "r,r,r,r")
e5fea38e 1415 (match_operand:SI 1 "s_register_operand" "%0,r,0,r"))
1416 (match_operand:SI 3 "s_register_operand" "r,r,0,0"))
215b30b3 1417 (const_int 0)))
9c08d1fa 1418 (set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r,&r")
1419 (plus:SI (mult:SI (match_dup 2) (match_dup 1))
1420 (match_dup 3)))]
58d7d654 1421 "TARGET_ARM && arm_arch6"
1422 "mla%.\\t%0, %2, %1, %3"
1423 [(set_attr "conds" "set")
9da0ec36 1424 (set_attr "type" "mlas")]
58d7d654 1425)
1426
1427(define_insn "*mulsi3addsi_compare0_v6"
1428 [(set (reg:CC_NOOV CC_REGNUM)
1429 (compare:CC_NOOV
1430 (plus:SI (mult:SI
1431 (match_operand:SI 2 "s_register_operand" "r")
1432 (match_operand:SI 1 "s_register_operand" "r"))
1433 (match_operand:SI 3 "s_register_operand" "r"))
1434 (const_int 0)))
1435 (set (match_operand:SI 0 "s_register_operand" "=r")
1436 (plus:SI (mult:SI (match_dup 2) (match_dup 1))
1437 (match_dup 3)))]
1438 "TARGET_ARM && arm_arch6 && optimize_size"
25f905c2 1439 "mla%.\\t%0, %2, %1, %3"
0d66636f 1440 [(set_attr "conds" "set")
9da0ec36 1441 (set_attr "type" "mlas")]
0d66636f 1442)
9c08d1fa 1443
f7fbdd4a 1444(define_insn "*mulsi3addsi_compare0_scratch"
bd5b4116 1445 [(set (reg:CC_NOOV CC_REGNUM)
215b30b3 1446 (compare:CC_NOOV
1447 (plus:SI (mult:SI
1448 (match_operand:SI 2 "s_register_operand" "r,r,r,r")
e5fea38e 1449 (match_operand:SI 1 "s_register_operand" "%0,r,0,r"))
215b30b3 1450 (match_operand:SI 3 "s_register_operand" "?r,r,0,0"))
1451 (const_int 0)))
9c08d1fa 1452 (clobber (match_scratch:SI 0 "=&r,&r,&r,&r"))]
58d7d654 1453 "TARGET_ARM && !arm_arch6"
1454 "mla%.\\t%0, %2, %1, %3"
1455 [(set_attr "conds" "set")
9da0ec36 1456 (set_attr "type" "mlas")]
58d7d654 1457)
1458
1459(define_insn "*mulsi3addsi_compare0_scratch_v6"
1460 [(set (reg:CC_NOOV CC_REGNUM)
1461 (compare:CC_NOOV
1462 (plus:SI (mult:SI
1463 (match_operand:SI 2 "s_register_operand" "r")
1464 (match_operand:SI 1 "s_register_operand" "r"))
1465 (match_operand:SI 3 "s_register_operand" "r"))
1466 (const_int 0)))
1467 (clobber (match_scratch:SI 0 "=r"))]
1468 "TARGET_ARM && arm_arch6 && optimize_size"
25f905c2 1469 "mla%.\\t%0, %2, %1, %3"
cffb2a26 1470 [(set_attr "conds" "set")
9da0ec36 1471 (set_attr "type" "mlas")]
cffb2a26 1472)
f7fbdd4a 1473
89545238 1474(define_insn "*mulsi3subsi"
1475 [(set (match_operand:SI 0 "s_register_operand" "=r")
1476 (minus:SI
1477 (match_operand:SI 3 "s_register_operand" "r")
1478 (mult:SI (match_operand:SI 2 "s_register_operand" "r")
1479 (match_operand:SI 1 "s_register_operand" "r"))))]
1480 "TARGET_32BIT && arm_arch_thumb2"
1481 "mls%?\\t%0, %2, %1, %3"
9da0ec36 1482 [(set_attr "type" "mla")
d952d547 1483 (set_attr "predicable" "yes")
1484 (set_attr "predicable_short_it" "no")]
89545238 1485)
1486
5cdca009 1487(define_expand "maddsidi4"
1488 [(set (match_operand:DI 0 "s_register_operand" "")
1489 (plus:DI
1490 (mult:DI
1491 (sign_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1492 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "")))
1493 (match_operand:DI 3 "s_register_operand" "")))]
1494 "TARGET_32BIT && arm_arch3m"
1495 "")
82b85d08 1496
1497(define_insn "*mulsidi3adddi"
fe8dbf85 1498 [(set (match_operand:DI 0 "s_register_operand" "=&r")
82b85d08 1499 (plus:DI
215b30b3 1500 (mult:DI
fe8dbf85 1501 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "%r"))
1502 (sign_extend:DI (match_operand:SI 3 "s_register_operand" "r")))
1503 (match_operand:DI 1 "s_register_operand" "0")))]
58d7d654 1504 "TARGET_32BIT && arm_arch3m && !arm_arch6"
1505 "smlal%?\\t%Q0, %R0, %3, %2"
9da0ec36 1506 [(set_attr "type" "smlal")
58d7d654 1507 (set_attr "predicable" "yes")]
1508)
1509
1510(define_insn "*mulsidi3adddi_v6"
1511 [(set (match_operand:DI 0 "s_register_operand" "=r")
1512 (plus:DI
1513 (mult:DI
1514 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r"))
1515 (sign_extend:DI (match_operand:SI 3 "s_register_operand" "r")))
1516 (match_operand:DI 1 "s_register_operand" "0")))]
1517 "TARGET_32BIT && arm_arch6"
fe8dbf85 1518 "smlal%?\\t%Q0, %R0, %3, %2"
9da0ec36 1519 [(set_attr "type" "smlal")
d952d547 1520 (set_attr "predicable" "yes")
1521 (set_attr "predicable_short_it" "no")]
0d66636f 1522)
82b85d08 1523
957788b0 1524;; 32x32->64 widening multiply.
1525;; As with mulsi3, the only difference between the v3-5 and v6+
1526;; versions of these patterns is the requirement that the output not
1527;; overlap the inputs, but that still means we have to have a named
1528;; expander and two different starred insns.
1529
1530(define_expand "mulsidi3"
1531 [(set (match_operand:DI 0 "s_register_operand" "")
1532 (mult:DI
1533 (sign_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1534 (sign_extend:DI (match_operand:SI 2 "s_register_operand" ""))))]
1535 "TARGET_32BIT && arm_arch3m"
1536 ""
1537)
1538
1539(define_insn "*mulsidi3_nov6"
f7fbdd4a 1540 [(set (match_operand:DI 0 "s_register_operand" "=&r")
215b30b3 1541 (mult:DI
1542 (sign_extend:DI (match_operand:SI 1 "s_register_operand" "%r"))
1543 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))]
58d7d654 1544 "TARGET_32BIT && arm_arch3m && !arm_arch6"
1545 "smull%?\\t%Q0, %R0, %1, %2"
9da0ec36 1546 [(set_attr "type" "smull")
58d7d654 1547 (set_attr "predicable" "yes")]
1548)
1549
957788b0 1550(define_insn "*mulsidi3_v6"
58d7d654 1551 [(set (match_operand:DI 0 "s_register_operand" "=r")
1552 (mult:DI
1553 (sign_extend:DI (match_operand:SI 1 "s_register_operand" "r"))
1554 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))]
1555 "TARGET_32BIT && arm_arch6"
97499065 1556 "smull%?\\t%Q0, %R0, %1, %2"
9da0ec36 1557 [(set_attr "type" "smull")
d952d547 1558 (set_attr "predicable" "yes")
1559 (set_attr "predicable_short_it" "no")]
0d66636f 1560)
f7fbdd4a 1561
957788b0 1562(define_expand "umulsidi3"
1563 [(set (match_operand:DI 0 "s_register_operand" "")
1564 (mult:DI
1565 (zero_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1566 (zero_extend:DI (match_operand:SI 2 "s_register_operand" ""))))]
1567 "TARGET_32BIT && arm_arch3m"
1568 ""
1569)
1570
1571(define_insn "*umulsidi3_nov6"
f7fbdd4a 1572 [(set (match_operand:DI 0 "s_register_operand" "=&r")
215b30b3 1573 (mult:DI
1574 (zero_extend:DI (match_operand:SI 1 "s_register_operand" "%r"))
1575 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))]
58d7d654 1576 "TARGET_32BIT && arm_arch3m && !arm_arch6"
1577 "umull%?\\t%Q0, %R0, %1, %2"
9da0ec36 1578 [(set_attr "type" "umull")
58d7d654 1579 (set_attr "predicable" "yes")]
1580)
1581
957788b0 1582(define_insn "*umulsidi3_v6"
58d7d654 1583 [(set (match_operand:DI 0 "s_register_operand" "=r")
1584 (mult:DI
1585 (zero_extend:DI (match_operand:SI 1 "s_register_operand" "r"))
1586 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))]
1587 "TARGET_32BIT && arm_arch6"
97499065 1588 "umull%?\\t%Q0, %R0, %1, %2"
9da0ec36 1589 [(set_attr "type" "umull")
d952d547 1590 (set_attr "predicable" "yes")
1591 (set_attr "predicable_short_it" "no")]
0d66636f 1592)
b11cae9e 1593
5cdca009 1594(define_expand "umaddsidi4"
1595 [(set (match_operand:DI 0 "s_register_operand" "")
1596 (plus:DI
1597 (mult:DI
1598 (zero_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1599 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "")))
1600 (match_operand:DI 3 "s_register_operand" "")))]
1601 "TARGET_32BIT && arm_arch3m"
1602 "")
82b85d08 1603
1604(define_insn "*umulsidi3adddi"
8ead09f9 1605 [(set (match_operand:DI 0 "s_register_operand" "=&r")
82b85d08 1606 (plus:DI
215b30b3 1607 (mult:DI
fe8dbf85 1608 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "%r"))
1609 (zero_extend:DI (match_operand:SI 3 "s_register_operand" "r")))
1610 (match_operand:DI 1 "s_register_operand" "0")))]
58d7d654 1611 "TARGET_32BIT && arm_arch3m && !arm_arch6"
1612 "umlal%?\\t%Q0, %R0, %3, %2"
9da0ec36 1613 [(set_attr "type" "umlal")
58d7d654 1614 (set_attr "predicable" "yes")]
1615)
1616
1617(define_insn "*umulsidi3adddi_v6"
1618 [(set (match_operand:DI 0 "s_register_operand" "=r")
1619 (plus:DI
1620 (mult:DI
1621 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r"))
1622 (zero_extend:DI (match_operand:SI 3 "s_register_operand" "r")))
1623 (match_operand:DI 1 "s_register_operand" "0")))]
1624 "TARGET_32BIT && arm_arch6"
fe8dbf85 1625 "umlal%?\\t%Q0, %R0, %3, %2"
9da0ec36 1626 [(set_attr "type" "umlal")
d952d547 1627 (set_attr "predicable" "yes")
1628 (set_attr "predicable_short_it" "no")]
0d66636f 1629)
82b85d08 1630
957788b0 1631(define_expand "smulsi3_highpart"
1632 [(parallel
1633 [(set (match_operand:SI 0 "s_register_operand" "")
1634 (truncate:SI
1635 (lshiftrt:DI
1636 (mult:DI
1637 (sign_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1638 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "")))
1639 (const_int 32))))
1640 (clobber (match_scratch:SI 3 ""))])]
1641 "TARGET_32BIT && arm_arch3m"
1642 ""
1643)
1644
1645(define_insn "*smulsi3_highpart_nov6"
f082f1c4 1646 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r")
1647 (truncate:SI
1648 (lshiftrt:DI
215b30b3 1649 (mult:DI
e5fea38e 1650 (sign_extend:DI (match_operand:SI 1 "s_register_operand" "%0,r"))
215b30b3 1651 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r,r")))
f082f1c4 1652 (const_int 32))))
1653 (clobber (match_scratch:SI 3 "=&r,&r"))]
58d7d654 1654 "TARGET_32BIT && arm_arch3m && !arm_arch6"
1655 "smull%?\\t%3, %0, %2, %1"
9da0ec36 1656 [(set_attr "type" "smull")
58d7d654 1657 (set_attr "predicable" "yes")]
1658)
1659
957788b0 1660(define_insn "*smulsi3_highpart_v6"
58d7d654 1661 [(set (match_operand:SI 0 "s_register_operand" "=r")
1662 (truncate:SI
1663 (lshiftrt:DI
1664 (mult:DI
1665 (sign_extend:DI (match_operand:SI 1 "s_register_operand" "r"))
1666 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r")))
1667 (const_int 32))))
1668 (clobber (match_scratch:SI 3 "=r"))]
1669 "TARGET_32BIT && arm_arch6"
f082f1c4 1670 "smull%?\\t%3, %0, %2, %1"
9da0ec36 1671 [(set_attr "type" "smull")
d952d547 1672 (set_attr "predicable" "yes")
1673 (set_attr "predicable_short_it" "no")]
cffb2a26 1674)
f082f1c4 1675
957788b0 1676(define_expand "umulsi3_highpart"
1677 [(parallel
1678 [(set (match_operand:SI 0 "s_register_operand" "")
1679 (truncate:SI
1680 (lshiftrt:DI
1681 (mult:DI
1682 (zero_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1683 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "")))
1684 (const_int 32))))
1685 (clobber (match_scratch:SI 3 ""))])]
1686 "TARGET_32BIT && arm_arch3m"
1687 ""
1688)
1689
1690(define_insn "*umulsi3_highpart_nov6"
f082f1c4 1691 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r")
1692 (truncate:SI
1693 (lshiftrt:DI
215b30b3 1694 (mult:DI
e5fea38e 1695 (zero_extend:DI (match_operand:SI 1 "s_register_operand" "%0,r"))
215b30b3 1696 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r,r")))
f082f1c4 1697 (const_int 32))))
1698 (clobber (match_scratch:SI 3 "=&r,&r"))]
58d7d654 1699 "TARGET_32BIT && arm_arch3m && !arm_arch6"
1700 "umull%?\\t%3, %0, %2, %1"
9da0ec36 1701 [(set_attr "type" "umull")
58d7d654 1702 (set_attr "predicable" "yes")]
1703)
1704
957788b0 1705(define_insn "*umulsi3_highpart_v6"
58d7d654 1706 [(set (match_operand:SI 0 "s_register_operand" "=r")
1707 (truncate:SI
1708 (lshiftrt:DI
1709 (mult:DI
1710 (zero_extend:DI (match_operand:SI 1 "s_register_operand" "r"))
1711 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r")))
1712 (const_int 32))))
1713 (clobber (match_scratch:SI 3 "=r"))]
1714 "TARGET_32BIT && arm_arch6"
f082f1c4 1715 "umull%?\\t%3, %0, %2, %1"
9da0ec36 1716 [(set_attr "type" "umull")
d952d547 1717 (set_attr "predicable" "yes")
1718 (set_attr "predicable_short_it" "no")]
cffb2a26 1719)
f082f1c4 1720
331beb1a 1721(define_insn "mulhisi3"
1722 [(set (match_operand:SI 0 "s_register_operand" "=r")
1723 (mult:SI (sign_extend:SI
1724 (match_operand:HI 1 "s_register_operand" "%r"))
1725 (sign_extend:SI
1726 (match_operand:HI 2 "s_register_operand" "r"))))]
25f905c2 1727 "TARGET_DSP_MULTIPLY"
61a2d04c 1728 "smulbb%?\\t%0, %1, %2"
9da0ec36 1729 [(set_attr "type" "smulxy")
fec538d9 1730 (set_attr "predicable" "yes")]
1731)
1732
1733(define_insn "*mulhisi3tb"
1734 [(set (match_operand:SI 0 "s_register_operand" "=r")
1735 (mult:SI (ashiftrt:SI
1736 (match_operand:SI 1 "s_register_operand" "r")
1737 (const_int 16))
1738 (sign_extend:SI
1739 (match_operand:HI 2 "s_register_operand" "r"))))]
25f905c2 1740 "TARGET_DSP_MULTIPLY"
fec538d9 1741 "smultb%?\\t%0, %1, %2"
9da0ec36 1742 [(set_attr "type" "smulxy")
d952d547 1743 (set_attr "predicable" "yes")
1744 (set_attr "predicable_short_it" "no")]
fec538d9 1745)
1746
1747(define_insn "*mulhisi3bt"
1748 [(set (match_operand:SI 0 "s_register_operand" "=r")
1749 (mult:SI (sign_extend:SI
1750 (match_operand:HI 1 "s_register_operand" "r"))
1751 (ashiftrt:SI
1752 (match_operand:SI 2 "s_register_operand" "r")
1753 (const_int 16))))]
25f905c2 1754 "TARGET_DSP_MULTIPLY"
fec538d9 1755 "smulbt%?\\t%0, %1, %2"
9da0ec36 1756 [(set_attr "type" "smulxy")
d952d547 1757 (set_attr "predicable" "yes")
1758 (set_attr "predicable_short_it" "no")]
fec538d9 1759)
1760
1761(define_insn "*mulhisi3tt"
1762 [(set (match_operand:SI 0 "s_register_operand" "=r")
1763 (mult:SI (ashiftrt:SI
1764 (match_operand:SI 1 "s_register_operand" "r")
1765 (const_int 16))
1766 (ashiftrt:SI
1767 (match_operand:SI 2 "s_register_operand" "r")
1768 (const_int 16))))]
25f905c2 1769 "TARGET_DSP_MULTIPLY"
fec538d9 1770 "smultt%?\\t%0, %1, %2"
9da0ec36 1771 [(set_attr "type" "smulxy")
d952d547 1772 (set_attr "predicable" "yes")
1773 (set_attr "predicable_short_it" "no")]
331beb1a 1774)
1775
5cdca009 1776(define_insn "maddhisi4"
331beb1a 1777 [(set (match_operand:SI 0 "s_register_operand" "=r")
cfa6c608 1778 (plus:SI (mult:SI (sign_extend:SI
1779 (match_operand:HI 1 "s_register_operand" "r"))
331beb1a 1780 (sign_extend:SI
cfa6c608 1781 (match_operand:HI 2 "s_register_operand" "r")))
1782 (match_operand:SI 3 "s_register_operand" "r")))]
25f905c2 1783 "TARGET_DSP_MULTIPLY"
5cdca009 1784 "smlabb%?\\t%0, %1, %2, %3"
9da0ec36 1785 [(set_attr "type" "smlaxy")
d952d547 1786 (set_attr "predicable" "yes")
1787 (set_attr "predicable_short_it" "no")]
331beb1a 1788)
1789
9a92f368 1790;; Note: there is no maddhisi4ibt because this one is canonical form
1791(define_insn "*maddhisi4tb"
1792 [(set (match_operand:SI 0 "s_register_operand" "=r")
1793 (plus:SI (mult:SI (ashiftrt:SI
1794 (match_operand:SI 1 "s_register_operand" "r")
1795 (const_int 16))
1796 (sign_extend:SI
1797 (match_operand:HI 2 "s_register_operand" "r")))
1798 (match_operand:SI 3 "s_register_operand" "r")))]
1799 "TARGET_DSP_MULTIPLY"
1800 "smlatb%?\\t%0, %1, %2, %3"
9da0ec36 1801 [(set_attr "type" "smlaxy")
d952d547 1802 (set_attr "predicable" "yes")
1803 (set_attr "predicable_short_it" "no")]
9a92f368 1804)
1805
1806(define_insn "*maddhisi4tt"
1807 [(set (match_operand:SI 0 "s_register_operand" "=r")
1808 (plus:SI (mult:SI (ashiftrt:SI
1809 (match_operand:SI 1 "s_register_operand" "r")
1810 (const_int 16))
1811 (ashiftrt:SI
1812 (match_operand:SI 2 "s_register_operand" "r")
1813 (const_int 16)))
1814 (match_operand:SI 3 "s_register_operand" "r")))]
1815 "TARGET_DSP_MULTIPLY"
1816 "smlatt%?\\t%0, %1, %2, %3"
9da0ec36 1817 [(set_attr "type" "smlaxy")
d952d547 1818 (set_attr "predicable" "yes")
1819 (set_attr "predicable_short_it" "no")]
9a92f368 1820)
1821
aff5fb4d 1822(define_insn "maddhidi4"
331beb1a 1823 [(set (match_operand:DI 0 "s_register_operand" "=r")
1824 (plus:DI
331beb1a 1825 (mult:DI (sign_extend:DI
d952d547 1826 (match_operand:HI 1 "s_register_operand" "r"))
331beb1a 1827 (sign_extend:DI
cfa6c608 1828 (match_operand:HI 2 "s_register_operand" "r")))
1829 (match_operand:DI 3 "s_register_operand" "0")))]
25f905c2 1830 "TARGET_DSP_MULTIPLY"
5cdca009 1831 "smlalbb%?\\t%Q0, %R0, %1, %2"
9da0ec36 1832 [(set_attr "type" "smlalxy")
d952d547 1833 (set_attr "predicable" "yes")
1834 (set_attr "predicable_short_it" "no")])
331beb1a 1835
9a92f368 1836;; Note: there is no maddhidi4ibt because this one is canonical form
1837(define_insn "*maddhidi4tb"
1838 [(set (match_operand:DI 0 "s_register_operand" "=r")
1839 (plus:DI
1840 (mult:DI (sign_extend:DI
1841 (ashiftrt:SI
1842 (match_operand:SI 1 "s_register_operand" "r")
1843 (const_int 16)))
1844 (sign_extend:DI
1845 (match_operand:HI 2 "s_register_operand" "r")))
1846 (match_operand:DI 3 "s_register_operand" "0")))]
1847 "TARGET_DSP_MULTIPLY"
1848 "smlaltb%?\\t%Q0, %R0, %1, %2"
9da0ec36 1849 [(set_attr "type" "smlalxy")
d952d547 1850 (set_attr "predicable" "yes")
1851 (set_attr "predicable_short_it" "no")])
9a92f368 1852
1853(define_insn "*maddhidi4tt"
1854 [(set (match_operand:DI 0 "s_register_operand" "=r")
1855 (plus:DI
1856 (mult:DI (sign_extend:DI
1857 (ashiftrt:SI
1858 (match_operand:SI 1 "s_register_operand" "r")
1859 (const_int 16)))
1860 (sign_extend:DI
1861 (ashiftrt:SI
1862 (match_operand:SI 2 "s_register_operand" "r")
1863 (const_int 16))))
1864 (match_operand:DI 3 "s_register_operand" "0")))]
1865 "TARGET_DSP_MULTIPLY"
1866 "smlaltt%?\\t%Q0, %R0, %1, %2"
9da0ec36 1867 [(set_attr "type" "smlalxy")
d952d547 1868 (set_attr "predicable" "yes")
1869 (set_attr "predicable_short_it" "no")])
9a92f368 1870
604f3a0a 1871(define_expand "mulsf3"
1872 [(set (match_operand:SF 0 "s_register_operand" "")
1873 (mult:SF (match_operand:SF 1 "s_register_operand" "")
d86c91f6 1874 (match_operand:SF 2 "s_register_operand" "")))]
25f905c2 1875 "TARGET_32BIT && TARGET_HARD_FLOAT"
604f3a0a 1876 "
604f3a0a 1877")
1878
604f3a0a 1879(define_expand "muldf3"
1880 [(set (match_operand:DF 0 "s_register_operand" "")
1881 (mult:DF (match_operand:DF 1 "s_register_operand" "")
d86c91f6 1882 (match_operand:DF 2 "s_register_operand" "")))]
a50d7267 1883 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
604f3a0a 1884 "
604f3a0a 1885")
b11cae9e 1886\f
1887;; Division insns
1888
7db9af5d 1889(define_expand "divsf3"
1890 [(set (match_operand:SF 0 "s_register_operand" "")
d86c91f6 1891 (div:SF (match_operand:SF 1 "s_register_operand" "")
1892 (match_operand:SF 2 "s_register_operand" "")))]
994606f8 1893 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
7db9af5d 1894 "")
9c08d1fa 1895
7db9af5d 1896(define_expand "divdf3"
1897 [(set (match_operand:DF 0 "s_register_operand" "")
d86c91f6 1898 (div:DF (match_operand:DF 1 "s_register_operand" "")
1899 (match_operand:DF 2 "s_register_operand" "")))]
994606f8 1900 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
7db9af5d 1901 "")
b11cae9e 1902\f
1903;; Boolean and,ior,xor insns
1904
f6ebffac 1905;; Split up double word logical operations
1906
1907;; Split up simple DImode logical operations. Simply perform the logical
1908;; operation on the upper and lower halves of the registers.
1909(define_split
1910 [(set (match_operand:DI 0 "s_register_operand" "")
1911 (match_operator:DI 6 "logical_binary_operator"
1912 [(match_operand:DI 1 "s_register_operand" "")
1913 (match_operand:DI 2 "s_register_operand" "")]))]
25f905c2 1914 "TARGET_32BIT && reload_completed
e2669ea7 1915 && ! (TARGET_NEON && IS_VFP_REGNUM (REGNO (operands[0])))
25f905c2 1916 && ! IS_IWMMXT_REGNUM (REGNO (operands[0]))"
f6ebffac 1917 [(set (match_dup 0) (match_op_dup:SI 6 [(match_dup 1) (match_dup 2)]))
1918 (set (match_dup 3) (match_op_dup:SI 6 [(match_dup 4) (match_dup 5)]))]
1919 "
215b30b3 1920 {
1921 operands[3] = gen_highpart (SImode, operands[0]);
1922 operands[0] = gen_lowpart (SImode, operands[0]);
1923 operands[4] = gen_highpart (SImode, operands[1]);
1924 operands[1] = gen_lowpart (SImode, operands[1]);
1925 operands[5] = gen_highpart (SImode, operands[2]);
1926 operands[2] = gen_lowpart (SImode, operands[2]);
1927 }"
1928)
f6ebffac 1929
f6ebffac 1930(define_split
1931 [(set (match_operand:DI 0 "s_register_operand" "")
1932 (match_operator:DI 6 "logical_binary_operator"
1933 [(sign_extend:DI (match_operand:SI 2 "s_register_operand" ""))
1934 (match_operand:DI 1 "s_register_operand" "")]))]
25f905c2 1935 "TARGET_32BIT && reload_completed"
f6ebffac 1936 [(set (match_dup 0) (match_op_dup:SI 6 [(match_dup 1) (match_dup 2)]))
1937 (set (match_dup 3) (match_op_dup:SI 6
1938 [(ashiftrt:SI (match_dup 2) (const_int 31))
1939 (match_dup 4)]))]
1940 "
215b30b3 1941 {
1942 operands[3] = gen_highpart (SImode, operands[0]);
1943 operands[0] = gen_lowpart (SImode, operands[0]);
1944 operands[4] = gen_highpart (SImode, operands[1]);
1945 operands[1] = gen_lowpart (SImode, operands[1]);
1946 operands[5] = gen_highpart (SImode, operands[2]);
1947 operands[2] = gen_lowpart (SImode, operands[2]);
1948 }"
1949)
f6ebffac 1950
f6ebffac 1951;; The zero extend of operand 2 means we can just copy the high part of
1952;; operand1 into operand0.
1953(define_split
1954 [(set (match_operand:DI 0 "s_register_operand" "")
1955 (ior:DI
1956 (zero_extend:DI (match_operand:SI 2 "s_register_operand" ""))
1957 (match_operand:DI 1 "s_register_operand" "")))]
25f905c2 1958 "TARGET_32BIT && operands[0] != operands[1] && reload_completed"
f6ebffac 1959 [(set (match_dup 0) (ior:SI (match_dup 1) (match_dup 2)))
1960 (set (match_dup 3) (match_dup 4))]
1961 "
215b30b3 1962 {
1963 operands[4] = gen_highpart (SImode, operands[1]);
1964 operands[3] = gen_highpart (SImode, operands[0]);
1965 operands[0] = gen_lowpart (SImode, operands[0]);
1966 operands[1] = gen_lowpart (SImode, operands[1]);
1967 }"
1968)
f6ebffac 1969
1970;; The zero extend of operand 2 means we can just copy the high part of
1971;; operand1 into operand0.
1972(define_split
1973 [(set (match_operand:DI 0 "s_register_operand" "")
1974 (xor:DI
1975 (zero_extend:DI (match_operand:SI 2 "s_register_operand" ""))
1976 (match_operand:DI 1 "s_register_operand" "")))]
25f905c2 1977 "TARGET_32BIT && operands[0] != operands[1] && reload_completed"
f6ebffac 1978 [(set (match_dup 0) (xor:SI (match_dup 1) (match_dup 2)))
1979 (set (match_dup 3) (match_dup 4))]
1980 "
215b30b3 1981 {
1982 operands[4] = gen_highpart (SImode, operands[1]);
1983 operands[3] = gen_highpart (SImode, operands[0]);
1984 operands[0] = gen_lowpart (SImode, operands[0]);
1985 operands[1] = gen_lowpart (SImode, operands[1]);
1986 }"
1987)
f6ebffac 1988
e2669ea7 1989(define_expand "anddi3"
1990 [(set (match_operand:DI 0 "s_register_operand" "")
1991 (and:DI (match_operand:DI 1 "s_register_operand" "")
1992 (match_operand:DI 2 "neon_inv_logic_op2" "")))]
1993 "TARGET_32BIT"
1994 ""
1995)
1996
f6bbdcf6 1997(define_insn_and_split "*anddi3_insn"
0a314dcd 1998 [(set (match_operand:DI 0 "s_register_operand" "=w,w ,&r,&r,&r,&r,?w,?w")
1999 (and:DI (match_operand:DI 1 "s_register_operand" "%w,0 ,0 ,r ,0 ,r ,w ,0")
2000 (match_operand:DI 2 "arm_anddi_operand_neon" "w ,DL,r ,r ,De,De,w ,DL")))]
f6bbdcf6 2001 "TARGET_32BIT && !TARGET_IWMMXT"
2002{
2003 switch (which_alternative)
2004 {
0a314dcd 2005 case 0: /* fall through */
2006 case 6: return "vand\t%P0, %P1, %P2";
2007 case 1: /* fall through */
2008 case 7: return neon_output_logic_immediate ("vand", &operands[2],
2009 DImode, 1, VALID_NEON_QREG_MODE (DImode));
f6bbdcf6 2010 case 2:
0a314dcd 2011 case 3:
2012 case 4:
f6bbdcf6 2013 case 5: /* fall through */
0a314dcd 2014 return "#";
f6bbdcf6 2015 default: gcc_unreachable ();
2016 }
2017}
0a314dcd 2018 "TARGET_32BIT && !TARGET_IWMMXT && reload_completed
2019 && !(IS_VFP_REGNUM (REGNO (operands[0])))"
f6bbdcf6 2020 [(set (match_dup 3) (match_dup 4))
2021 (set (match_dup 5) (match_dup 6))]
2022 "
2023 {
2024 operands[3] = gen_lowpart (SImode, operands[0]);
2025 operands[5] = gen_highpart (SImode, operands[0]);
2026
2027 operands[4] = simplify_gen_binary (AND, SImode,
2028 gen_lowpart (SImode, operands[1]),
2029 gen_lowpart (SImode, operands[2]));
2030 operands[6] = simplify_gen_binary (AND, SImode,
2031 gen_highpart (SImode, operands[1]),
2032 gen_highpart_mode (SImode, DImode, operands[2]));
2033
2034 }"
32093010 2035 [(set_attr "type" "neon_logic,neon_logic,multiple,multiple,\
2036 multiple,multiple,neon_logic,neon_logic")
0a314dcd 2037 (set_attr "arch" "neon_for_64bits,neon_for_64bits,*,*,*,*,
f6bbdcf6 2038 avoid_neon_for_64bits,avoid_neon_for_64bits")
0a314dcd 2039 (set_attr "length" "*,*,8,8,8,8,*,*")
2040 ]
215b30b3 2041)
b11cae9e 2042
a0f94409 2043(define_insn_and_split "*anddi_zesidi_di"
9c08d1fa 2044 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2045 (and:DI (zero_extend:DI
2046 (match_operand:SI 2 "s_register_operand" "r,r"))
e5fea38e 2047 (match_operand:DI 1 "s_register_operand" "0,r")))]
25f905c2 2048 "TARGET_32BIT"
f6ebffac 2049 "#"
25f905c2 2050 "TARGET_32BIT && reload_completed"
a0f94409 2051 ; The zero extend of operand 2 clears the high word of the output
2052 ; operand.
2053 [(set (match_dup 0) (and:SI (match_dup 1) (match_dup 2)))
2054 (set (match_dup 3) (const_int 0))]
2055 "
2056 {
2057 operands[3] = gen_highpart (SImode, operands[0]);
2058 operands[0] = gen_lowpart (SImode, operands[0]);
2059 operands[1] = gen_lowpart (SImode, operands[1]);
2060 }"
1b7da4ac 2061 [(set_attr "length" "8")
2062 (set_attr "type" "multiple")]
215b30b3 2063)
b11cae9e 2064
f7fbdd4a 2065(define_insn "*anddi_sesdi_di"
cffb2a26 2066 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
9c08d1fa 2067 (and:DI (sign_extend:DI
2068 (match_operand:SI 2 "s_register_operand" "r,r"))
e5fea38e 2069 (match_operand:DI 1 "s_register_operand" "0,r")))]
25f905c2 2070 "TARGET_32BIT"
f6ebffac 2071 "#"
1b7da4ac 2072 [(set_attr "length" "8")
2073 (set_attr "type" "multiple")]
cffb2a26 2074)
b11cae9e 2075
87b22bf7 2076(define_expand "andsi3"
cffb2a26 2077 [(set (match_operand:SI 0 "s_register_operand" "")
87b22bf7 2078 (and:SI (match_operand:SI 1 "s_register_operand" "")
2079 (match_operand:SI 2 "reg_or_int_operand" "")))]
cffb2a26 2080 "TARGET_EITHER"
87b22bf7 2081 "
25f905c2 2082 if (TARGET_32BIT)
87b22bf7 2083 {
0438d37f 2084 if (CONST_INT_P (operands[2]))
cffb2a26 2085 {
47b5b27b 2086 if (INTVAL (operands[2]) == 255 && arm_arch6)
2087 {
2088 operands[1] = convert_to_mode (QImode, operands[1], 1);
2089 emit_insn (gen_thumb2_zero_extendqisi2_v6 (operands[0],
2090 operands[1]));
17202aa5 2091 DONE;
47b5b27b 2092 }
17202aa5 2093 else if (DONT_EARLY_SPLIT_CONSTANT (INTVAL (operands[2]), AND))
2094 operands[2] = force_reg (SImode, operands[2]);
47b5b27b 2095 else
17202aa5 2096 {
2097 arm_split_constant (AND, SImode, NULL_RTX,
2098 INTVAL (operands[2]), operands[0],
2099 operands[1],
2100 optimize && can_create_pseudo_p ());
615caa51 2101
17202aa5 2102 DONE;
2103 }
cffb2a26 2104 }
87b22bf7 2105 }
25f905c2 2106 else /* TARGET_THUMB1 */
cffb2a26 2107 {
0438d37f 2108 if (!CONST_INT_P (operands[2]))
923ffadb 2109 {
2110 rtx tmp = force_reg (SImode, operands[2]);
2111 if (rtx_equal_p (operands[0], operands[1]))
2112 operands[2] = tmp;
2113 else
2114 {
2115 operands[2] = operands[1];
2116 operands[1] = tmp;
2117 }
2118 }
cffb2a26 2119 else
2120 {
2121 int i;
2122
215b30b3 2123 if (((unsigned HOST_WIDE_INT) ~INTVAL (operands[2])) < 256)
cffb2a26 2124 {
215b30b3 2125 operands[2] = force_reg (SImode,
2126 GEN_INT (~INTVAL (operands[2])));
cffb2a26 2127
747b7458 2128 emit_insn (gen_thumb1_bicsi3 (operands[0], operands[2], operands[1]));
cffb2a26 2129
2130 DONE;
2131 }
87b22bf7 2132
cffb2a26 2133 for (i = 9; i <= 31; i++)
2134 {
2135 if ((((HOST_WIDE_INT) 1) << i) - 1 == INTVAL (operands[2]))
2136 {
2137 emit_insn (gen_extzv (operands[0], operands[1], GEN_INT (i),
2138 const0_rtx));
2139 DONE;
2140 }
215b30b3 2141 else if ((((HOST_WIDE_INT) 1) << i) - 1
2142 == ~INTVAL (operands[2]))
cffb2a26 2143 {
2144 rtx shift = GEN_INT (i);
2145 rtx reg = gen_reg_rtx (SImode);
2146
2147 emit_insn (gen_lshrsi3 (reg, operands[1], shift));
2148 emit_insn (gen_ashlsi3 (operands[0], reg, shift));
2149
2150 DONE;
2151 }
2152 }
2153
2154 operands[2] = force_reg (SImode, operands[2]);
2155 }
215b30b3 2156 }
2157 "
cffb2a26 2158)
2159
25f905c2 2160; ??? Check split length for Thumb-2
a0f94409 2161(define_insn_and_split "*arm_andsi3_insn"
29e234a3 2162 [(set (match_operand:SI 0 "s_register_operand" "=r,l,r,r,r")
2163 (and:SI (match_operand:SI 1 "s_register_operand" "%r,0,r,r,r")
2164 (match_operand:SI 2 "reg_or_int_operand" "I,l,K,r,?n")))]
25f905c2 2165 "TARGET_32BIT"
5565501b 2166 "@
29e234a3 2167 and%?\\t%0, %1, %2
5565501b 2168 and%?\\t%0, %1, %2
87b22bf7 2169 bic%?\\t%0, %1, #%B2
65f68e55 2170 and%?\\t%0, %1, %2
87b22bf7 2171 #"
25f905c2 2172 "TARGET_32BIT
0438d37f 2173 && CONST_INT_P (operands[2])
a0f94409 2174 && !(const_ok_for_arm (INTVAL (operands[2]))
2175 || const_ok_for_arm (~INTVAL (operands[2])))"
2176 [(clobber (const_int 0))]
2177 "
96f57e36 2178 arm_split_constant (AND, SImode, curr_insn,
2179 INTVAL (operands[2]), operands[0], operands[1], 0);
a0f94409 2180 DONE;
2181 "
29e234a3 2182 [(set_attr "length" "4,4,4,4,16")
65f68e55 2183 (set_attr "predicable" "yes")
29e234a3 2184 (set_attr "predicable_short_it" "no,yes,no,no,no")
d82e788e 2185 (set_attr "type" "logic_imm,logic_imm,logic_reg,logic_reg,logic_imm")]
cffb2a26 2186)
2187
f7fbdd4a 2188(define_insn "*andsi3_compare0"
bd5b4116 2189 [(set (reg:CC_NOOV CC_REGNUM)
5565501b 2190 (compare:CC_NOOV
65f68e55 2191 (and:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
2192 (match_operand:SI 2 "arm_not_operand" "I,K,r"))
5565501b 2193 (const_int 0)))
65f68e55 2194 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9c08d1fa 2195 (and:SI (match_dup 1) (match_dup 2)))]
25f905c2 2196 "TARGET_32BIT"
5565501b 2197 "@
25f905c2 2198 and%.\\t%0, %1, %2
65f68e55 2199 bic%.\\t%0, %1, #%B2
2200 and%.\\t%0, %1, %2"
2201 [(set_attr "conds" "set")
d82e788e 2202 (set_attr "type" "logics_imm,logics_imm,logics_reg")]
cffb2a26 2203)
9c08d1fa 2204
f7fbdd4a 2205(define_insn "*andsi3_compare0_scratch"
bd5b4116 2206 [(set (reg:CC_NOOV CC_REGNUM)
5565501b 2207 (compare:CC_NOOV
65f68e55 2208 (and:SI (match_operand:SI 0 "s_register_operand" "r,r,r")
2209 (match_operand:SI 1 "arm_not_operand" "I,K,r"))
5565501b 2210 (const_int 0)))
65f68e55 2211 (clobber (match_scratch:SI 2 "=X,r,X"))]
25f905c2 2212 "TARGET_32BIT"
5565501b 2213 "@
2214 tst%?\\t%0, %1
65f68e55 2215 bic%.\\t%2, %0, #%B1
2216 tst%?\\t%0, %1"
2217 [(set_attr "conds" "set")
d82e788e 2218 (set_attr "type" "logics_imm,logics_imm,logics_reg")]
0d66636f 2219)
9c08d1fa 2220
f7fbdd4a 2221(define_insn "*zeroextractsi_compare0_scratch"
bd5b4116 2222 [(set (reg:CC_NOOV CC_REGNUM)
9c08d1fa 2223 (compare:CC_NOOV (zero_extract:SI
2224 (match_operand:SI 0 "s_register_operand" "r")
d952d547 2225 (match_operand 1 "const_int_operand" "n")
206ee9a2 2226 (match_operand 2 "const_int_operand" "n"))
9c08d1fa 2227 (const_int 0)))]
25f905c2 2228 "TARGET_32BIT
cffb2a26 2229 && (INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) < 32
2230 && INTVAL (operands[1]) > 0
2231 && INTVAL (operands[1]) + (INTVAL (operands[2]) & 1) <= 8
2232 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32)"
9c08d1fa 2233 "*
5c49a439 2234 operands[1] = GEN_INT (((1 << INTVAL (operands[1])) - 1)
2235 << INTVAL (operands[2]));
40dbec34 2236 output_asm_insn (\"tst%?\\t%0, %1\", operands);
e2348bcb 2237 return \"\";
0d66636f 2238 "
596e5e8f 2239 [(set_attr "conds" "set")
65f68e55 2240 (set_attr "predicable" "yes")
d952d547 2241 (set_attr "predicable_short_it" "no")
d82e788e 2242 (set_attr "type" "logics_imm")]
0d66636f 2243)
9c08d1fa 2244
f4462328 2245(define_insn_and_split "*ne_zeroextractsi"
c4034607 2246 [(set (match_operand:SI 0 "s_register_operand" "=r")
2247 (ne:SI (zero_extract:SI
2248 (match_operand:SI 1 "s_register_operand" "r")
2249 (match_operand:SI 2 "const_int_operand" "n")
2250 (match_operand:SI 3 "const_int_operand" "n"))
3b8c7f7a 2251 (const_int 0)))
2252 (clobber (reg:CC CC_REGNUM))]
25f905c2 2253 "TARGET_32BIT
cffb2a26 2254 && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
2255 && INTVAL (operands[2]) > 0
2256 && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
2257 && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)"
f4462328 2258 "#"
25f905c2 2259 "TARGET_32BIT
f4462328 2260 && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
2261 && INTVAL (operands[2]) > 0
2262 && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
2263 && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)"
2264 [(parallel [(set (reg:CC_NOOV CC_REGNUM)
2265 (compare:CC_NOOV (and:SI (match_dup 1) (match_dup 2))
2266 (const_int 0)))
2267 (set (match_dup 0) (and:SI (match_dup 1) (match_dup 2)))])
2268 (set (match_dup 0)
2269 (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
2270 (match_dup 0) (const_int 1)))]
2271 "
2272 operands[2] = GEN_INT (((1 << INTVAL (operands[2])) - 1)
2273 << INTVAL (operands[3]));
2274 "
2275 [(set_attr "conds" "clob")
25f905c2 2276 (set (attr "length")
2277 (if_then_else (eq_attr "is_thumb" "yes")
2278 (const_int 12)
1b7da4ac 2279 (const_int 8)))
2280 (set_attr "type" "multiple")]
f4462328 2281)
2282
2283(define_insn_and_split "*ne_zeroextractsi_shifted"
2284 [(set (match_operand:SI 0 "s_register_operand" "=r")
2285 (ne:SI (zero_extract:SI
2286 (match_operand:SI 1 "s_register_operand" "r")
2287 (match_operand:SI 2 "const_int_operand" "n")
2288 (const_int 0))
2289 (const_int 0)))
2290 (clobber (reg:CC CC_REGNUM))]
2291 "TARGET_ARM"
2292 "#"
2293 "TARGET_ARM"
2294 [(parallel [(set (reg:CC_NOOV CC_REGNUM)
2295 (compare:CC_NOOV (ashift:SI (match_dup 1) (match_dup 2))
2296 (const_int 0)))
2297 (set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 2)))])
2298 (set (match_dup 0)
2299 (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
2300 (match_dup 0) (const_int 1)))]
2301 "
2302 operands[2] = GEN_INT (32 - INTVAL (operands[2]));
2303 "
2304 [(set_attr "conds" "clob")
1b7da4ac 2305 (set_attr "length" "8")
2306 (set_attr "type" "multiple")]
f4462328 2307)
2308
2309(define_insn_and_split "*ite_ne_zeroextractsi"
2310 [(set (match_operand:SI 0 "s_register_operand" "=r")
2311 (if_then_else:SI (ne (zero_extract:SI
2312 (match_operand:SI 1 "s_register_operand" "r")
2313 (match_operand:SI 2 "const_int_operand" "n")
2314 (match_operand:SI 3 "const_int_operand" "n"))
2315 (const_int 0))
2316 (match_operand:SI 4 "arm_not_operand" "rIK")
2317 (const_int 0)))
2318 (clobber (reg:CC CC_REGNUM))]
2319 "TARGET_ARM
2320 && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
2321 && INTVAL (operands[2]) > 0
2322 && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
f8d7bf2f 2323 && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)
2324 && !reg_overlap_mentioned_p (operands[0], operands[4])"
f4462328 2325 "#"
2326 "TARGET_ARM
2327 && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
2328 && INTVAL (operands[2]) > 0
2329 && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
f8d7bf2f 2330 && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)
2331 && !reg_overlap_mentioned_p (operands[0], operands[4])"
f4462328 2332 [(parallel [(set (reg:CC_NOOV CC_REGNUM)
2333 (compare:CC_NOOV (and:SI (match_dup 1) (match_dup 2))
2334 (const_int 0)))
2335 (set (match_dup 0) (and:SI (match_dup 1) (match_dup 2)))])
2336 (set (match_dup 0)
2337 (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
2338 (match_dup 0) (match_dup 4)))]
2339 "
c4034607 2340 operands[2] = GEN_INT (((1 << INTVAL (operands[2])) - 1)
f4462328 2341 << INTVAL (operands[3]));
2342 "
2343 [(set_attr "conds" "clob")
1b7da4ac 2344 (set_attr "length" "8")
2345 (set_attr "type" "multiple")]
f4462328 2346)
2347
2348(define_insn_and_split "*ite_ne_zeroextractsi_shifted"
2349 [(set (match_operand:SI 0 "s_register_operand" "=r")
2350 (if_then_else:SI (ne (zero_extract:SI
2351 (match_operand:SI 1 "s_register_operand" "r")
2352 (match_operand:SI 2 "const_int_operand" "n")
2353 (const_int 0))
2354 (const_int 0))
2355 (match_operand:SI 3 "arm_not_operand" "rIK")
2356 (const_int 0)))
2357 (clobber (reg:CC CC_REGNUM))]
f8d7bf2f 2358 "TARGET_ARM && !reg_overlap_mentioned_p (operands[0], operands[3])"
f4462328 2359 "#"
f8d7bf2f 2360 "TARGET_ARM && !reg_overlap_mentioned_p (operands[0], operands[3])"
f4462328 2361 [(parallel [(set (reg:CC_NOOV CC_REGNUM)
2362 (compare:CC_NOOV (ashift:SI (match_dup 1) (match_dup 2))
2363 (const_int 0)))
2364 (set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 2)))])
2365 (set (match_dup 0)
2366 (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
2367 (match_dup 0) (match_dup 3)))]
2368 "
2369 operands[2] = GEN_INT (32 - INTVAL (operands[2]));
0d66636f 2370 "
2371 [(set_attr "conds" "clob")
1b7da4ac 2372 (set_attr "length" "8")
2373 (set_attr "type" "multiple")]
215b30b3 2374)
9c08d1fa 2375
25f905c2 2376;; ??? Use Thumb-2 has bitfield insert/extract instructions.
d7863cfe 2377(define_split
2378 [(set (match_operand:SI 0 "s_register_operand" "")
2379 (match_operator:SI 1 "shiftable_operator"
2380 [(zero_extract:SI (match_operand:SI 2 "s_register_operand" "")
2381 (match_operand:SI 3 "const_int_operand" "")
2382 (match_operand:SI 4 "const_int_operand" ""))
2383 (match_operand:SI 5 "s_register_operand" "")]))
2384 (clobber (match_operand:SI 6 "s_register_operand" ""))]
2385 "TARGET_ARM"
2386 [(set (match_dup 6) (ashift:SI (match_dup 2) (match_dup 3)))
2387 (set (match_dup 0)
2388 (match_op_dup 1
2389 [(lshiftrt:SI (match_dup 6) (match_dup 4))
2390 (match_dup 5)]))]
2391 "{
2392 HOST_WIDE_INT temp = INTVAL (operands[3]);
2393
2394 operands[3] = GEN_INT (32 - temp - INTVAL (operands[4]));
2395 operands[4] = GEN_INT (32 - temp);
2396 }"
2397)
2398
d7863cfe 2399(define_split
2400 [(set (match_operand:SI 0 "s_register_operand" "")
2401 (match_operator:SI 1 "shiftable_operator"
2402 [(sign_extract:SI (match_operand:SI 2 "s_register_operand" "")
2403 (match_operand:SI 3 "const_int_operand" "")
2404 (match_operand:SI 4 "const_int_operand" ""))
2405 (match_operand:SI 5 "s_register_operand" "")]))
2406 (clobber (match_operand:SI 6 "s_register_operand" ""))]
2407 "TARGET_ARM"
2408 [(set (match_dup 6) (ashift:SI (match_dup 2) (match_dup 3)))
2409 (set (match_dup 0)
2410 (match_op_dup 1
2411 [(ashiftrt:SI (match_dup 6) (match_dup 4))
2412 (match_dup 5)]))]
2413 "{
2414 HOST_WIDE_INT temp = INTVAL (operands[3]);
2415
2416 operands[3] = GEN_INT (32 - temp - INTVAL (operands[4]));
2417 operands[4] = GEN_INT (32 - temp);
2418 }"
2419)
2420
a42059fd 2421;;; ??? This pattern is bogus. If operand3 has bits outside the range
2422;;; represented by the bitfield, then this will produce incorrect results.
2423;;; Somewhere, the value needs to be truncated. On targets like the m68k,
ceb2fe0f 2424;;; which have a real bit-field insert instruction, the truncation happens
2425;;; in the bit-field insert instruction itself. Since arm does not have a
2426;;; bit-field insert instruction, we would have to emit code here to truncate
a42059fd 2427;;; the value before we insert. This loses some of the advantage of having
2428;;; this insv pattern, so this pattern needs to be reevalutated.
2429
8a18b90c 2430(define_expand "insv"
eb04cafb 2431 [(set (zero_extract (match_operand 0 "nonimmediate_operand" "")
2432 (match_operand 1 "general_operand" "")
2433 (match_operand 2 "general_operand" ""))
2434 (match_operand 3 "reg_or_int_operand" ""))]
8b054d5a 2435 "TARGET_ARM || arm_arch_thumb2"
8a18b90c 2436 "
215b30b3 2437 {
2438 int start_bit = INTVAL (operands[2]);
2439 int width = INTVAL (operands[1]);
2440 HOST_WIDE_INT mask = (((HOST_WIDE_INT)1) << width) - 1;
2441 rtx target, subtarget;
2442
8b054d5a 2443 if (arm_arch_thumb2)
2444 {
eb04cafb 2445 if (unaligned_access && MEM_P (operands[0])
2446 && s_register_operand (operands[3], GET_MODE (operands[3]))
2447 && (width == 16 || width == 32) && (start_bit % BITS_PER_UNIT) == 0)
8b054d5a 2448 {
eb04cafb 2449 rtx base_addr;
2450
2451 if (BYTES_BIG_ENDIAN)
2452 start_bit = GET_MODE_BITSIZE (GET_MODE (operands[3])) - width
2453 - start_bit;
8b054d5a 2454
eb04cafb 2455 if (width == 32)
8b054d5a 2456 {
eb04cafb 2457 base_addr = adjust_address (operands[0], SImode,
2458 start_bit / BITS_PER_UNIT);
2459 emit_insn (gen_unaligned_storesi (base_addr, operands[3]));
8b054d5a 2460 }
eb04cafb 2461 else
2462 {
2463 rtx tmp = gen_reg_rtx (HImode);
8b054d5a 2464
eb04cafb 2465 base_addr = adjust_address (operands[0], HImode,
2466 start_bit / BITS_PER_UNIT);
2467 emit_move_insn (tmp, gen_lowpart (HImode, operands[3]));
2468 emit_insn (gen_unaligned_storehi (base_addr, tmp));
2469 }
2470 DONE;
8b054d5a 2471 }
eb04cafb 2472 else if (s_register_operand (operands[0], GET_MODE (operands[0])))
8b054d5a 2473 {
eb04cafb 2474 bool use_bfi = TRUE;
8b054d5a 2475
0438d37f 2476 if (CONST_INT_P (operands[3]))
eb04cafb 2477 {
2478 HOST_WIDE_INT val = INTVAL (operands[3]) & mask;
2479
2480 if (val == 0)
2481 {
2482 emit_insn (gen_insv_zero (operands[0], operands[1],
2483 operands[2]));
2484 DONE;
2485 }
2486
2487 /* See if the set can be done with a single orr instruction. */
2488 if (val == mask && const_ok_for_arm (val << start_bit))
2489 use_bfi = FALSE;
2490 }
2491
2492 if (use_bfi)
2493 {
0438d37f 2494 if (!REG_P (operands[3]))
eb04cafb 2495 operands[3] = force_reg (SImode, operands[3]);
2496
2497 emit_insn (gen_insv_t2 (operands[0], operands[1], operands[2],
2498 operands[3]));
2499 DONE;
2500 }
8b054d5a 2501 }
eb04cafb 2502 else
2503 FAIL;
8b054d5a 2504 }
2505
eb04cafb 2506 if (!s_register_operand (operands[0], GET_MODE (operands[0])))
2507 FAIL;
2508
3f8fde42 2509 target = copy_rtx (operands[0]);
215b30b3 2510 /* Avoid using a subreg as a subtarget, and avoid writing a paradoxical
2511 subreg as the final target. */
2512 if (GET_CODE (target) == SUBREG)
2513 {
2514 subtarget = gen_reg_rtx (SImode);
2515 if (GET_MODE_SIZE (GET_MODE (SUBREG_REG (target)))
2516 < GET_MODE_SIZE (SImode))
2517 target = SUBREG_REG (target);
2518 }
2519 else
2520 subtarget = target;
8a18b90c 2521
0438d37f 2522 if (CONST_INT_P (operands[3]))
215b30b3 2523 {
2524 /* Since we are inserting a known constant, we may be able to
2525 reduce the number of bits that we have to clear so that
2526 the mask becomes simple. */
2527 /* ??? This code does not check to see if the new mask is actually
2528 simpler. It may not be. */
2529 rtx op1 = gen_reg_rtx (SImode);
2530 /* ??? Truncate operand3 to fit in the bitfield. See comment before
2531 start of this pattern. */
2532 HOST_WIDE_INT op3_value = mask & INTVAL (operands[3]);
2533 HOST_WIDE_INT mask2 = ((mask & ~op3_value) << start_bit);
2534
c5b3a71b 2535 emit_insn (gen_andsi3 (op1, operands[0],
2536 gen_int_mode (~mask2, SImode)));
215b30b3 2537 emit_insn (gen_iorsi3 (subtarget, op1,
4292ca6b 2538 gen_int_mode (op3_value << start_bit, SImode)));
215b30b3 2539 }
2540 else if (start_bit == 0
2541 && !(const_ok_for_arm (mask)
2542 || const_ok_for_arm (~mask)))
2543 {
2544 /* A Trick, since we are setting the bottom bits in the word,
2545 we can shift operand[3] up, operand[0] down, OR them together
2546 and rotate the result back again. This takes 3 insns, and
5910bb95 2547 the third might be mergeable into another op. */
215b30b3 2548 /* The shift up copes with the possibility that operand[3] is
2549 wider than the bitfield. */
2550 rtx op0 = gen_reg_rtx (SImode);
2551 rtx op1 = gen_reg_rtx (SImode);
2552
2553 emit_insn (gen_ashlsi3 (op0, operands[3], GEN_INT (32 - width)));
2554 emit_insn (gen_lshrsi3 (op1, operands[0], operands[1]));
2555 emit_insn (gen_iorsi3 (op1, op1, op0));
2556 emit_insn (gen_rotlsi3 (subtarget, op1, operands[1]));
2557 }
2558 else if ((width + start_bit == 32)
2559 && !(const_ok_for_arm (mask)
2560 || const_ok_for_arm (~mask)))
2561 {
2562 /* Similar trick, but slightly less efficient. */
8a18b90c 2563
215b30b3 2564 rtx op0 = gen_reg_rtx (SImode);
2565 rtx op1 = gen_reg_rtx (SImode);
8a18b90c 2566
215b30b3 2567 emit_insn (gen_ashlsi3 (op0, operands[3], GEN_INT (32 - width)));
2568 emit_insn (gen_ashlsi3 (op1, operands[0], operands[1]));
2569 emit_insn (gen_lshrsi3 (op1, op1, operands[1]));
2570 emit_insn (gen_iorsi3 (subtarget, op1, op0));
2571 }
2572 else
2573 {
c5b3a71b 2574 rtx op0 = gen_int_mode (mask, SImode);
215b30b3 2575 rtx op1 = gen_reg_rtx (SImode);
2576 rtx op2 = gen_reg_rtx (SImode);
8a18b90c 2577
215b30b3 2578 if (!(const_ok_for_arm (mask) || const_ok_for_arm (~mask)))
2579 {
2580 rtx tmp = gen_reg_rtx (SImode);
8a18b90c 2581
215b30b3 2582 emit_insn (gen_movsi (tmp, op0));
2583 op0 = tmp;
2584 }
8a18b90c 2585
215b30b3 2586 /* Mask out any bits in operand[3] that are not needed. */
2587 emit_insn (gen_andsi3 (op1, operands[3], op0));
8a18b90c 2588
0438d37f 2589 if (CONST_INT_P (op0)
215b30b3 2590 && (const_ok_for_arm (mask << start_bit)
2591 || const_ok_for_arm (~(mask << start_bit))))
2592 {
c5b3a71b 2593 op0 = gen_int_mode (~(mask << start_bit), SImode);
215b30b3 2594 emit_insn (gen_andsi3 (op2, operands[0], op0));
2595 }
2596 else
2597 {
0438d37f 2598 if (CONST_INT_P (op0))
215b30b3 2599 {
2600 rtx tmp = gen_reg_rtx (SImode);
8a18b90c 2601
215b30b3 2602 emit_insn (gen_movsi (tmp, op0));
2603 op0 = tmp;
2604 }
2605
2606 if (start_bit != 0)
2607 emit_insn (gen_ashlsi3 (op0, op0, operands[2]));
a42059fd 2608
215b30b3 2609 emit_insn (gen_andsi_notsi_si (op2, operands[0], op0));
2610 }
8a18b90c 2611
215b30b3 2612 if (start_bit != 0)
2613 emit_insn (gen_ashlsi3 (op1, op1, operands[2]));
8a18b90c 2614
215b30b3 2615 emit_insn (gen_iorsi3 (subtarget, op1, op2));
2616 }
f082f1c4 2617
215b30b3 2618 if (subtarget != target)
2619 {
2620 /* If TARGET is still a SUBREG, then it must be wider than a word,
2621 so we must be careful only to set the subword we were asked to. */
2622 if (GET_CODE (target) == SUBREG)
2623 emit_move_insn (target, subtarget);
2624 else
2625 emit_move_insn (target, gen_lowpart (GET_MODE (target), subtarget));
2626 }
8a18b90c 2627
215b30b3 2628 DONE;
2629 }"
2630)
8a18b90c 2631
8b054d5a 2632(define_insn "insv_zero"
2633 [(set (zero_extract:SI (match_operand:SI 0 "s_register_operand" "+r")
809003b3 2634 (match_operand:SI 1 "const_int_M_operand" "M")
2635 (match_operand:SI 2 "const_int_M_operand" "M"))
8b054d5a 2636 (const_int 0))]
2637 "arm_arch_thumb2"
2638 "bfc%?\t%0, %2, %1"
2639 [(set_attr "length" "4")
d952d547 2640 (set_attr "predicable" "yes")
d82e788e 2641 (set_attr "predicable_short_it" "no")
2642 (set_attr "type" "bfm")]
8b054d5a 2643)
2644
2645(define_insn "insv_t2"
2646 [(set (zero_extract:SI (match_operand:SI 0 "s_register_operand" "+r")
809003b3 2647 (match_operand:SI 1 "const_int_M_operand" "M")
2648 (match_operand:SI 2 "const_int_M_operand" "M"))
8b054d5a 2649 (match_operand:SI 3 "s_register_operand" "r"))]
2650 "arm_arch_thumb2"
2651 "bfi%?\t%0, %3, %2, %1"
2652 [(set_attr "length" "4")
d952d547 2653 (set_attr "predicable" "yes")
d82e788e 2654 (set_attr "predicable_short_it" "no")
2655 (set_attr "type" "bfm")]
8b054d5a 2656)
2657
215b30b3 2658; constants for op 2 will never be given to these patterns.
a0f94409 2659(define_insn_and_split "*anddi_notdi_di"
9c08d1fa 2660 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
e5fea38e 2661 (and:DI (not:DI (match_operand:DI 1 "s_register_operand" "0,r"))
2662 (match_operand:DI 2 "s_register_operand" "r,0")))]
25f905c2 2663 "TARGET_32BIT"
f6ebffac 2664 "#"
e2669ea7 2665 "TARGET_32BIT && reload_completed
2666 && ! (TARGET_NEON && IS_VFP_REGNUM (REGNO (operands[0])))
2667 && ! IS_IWMMXT_REGNUM (REGNO (operands[0]))"
a0f94409 2668 [(set (match_dup 0) (and:SI (not:SI (match_dup 1)) (match_dup 2)))
2669 (set (match_dup 3) (and:SI (not:SI (match_dup 4)) (match_dup 5)))]
2670 "
2671 {
2672 operands[3] = gen_highpart (SImode, operands[0]);
2673 operands[0] = gen_lowpart (SImode, operands[0]);
2674 operands[4] = gen_highpart (SImode, operands[1]);
2675 operands[1] = gen_lowpart (SImode, operands[1]);
2676 operands[5] = gen_highpart (SImode, operands[2]);
2677 operands[2] = gen_lowpart (SImode, operands[2]);
2678 }"
0d66636f 2679 [(set_attr "length" "8")
1b7da4ac 2680 (set_attr "predicable" "yes")
2681 (set_attr "type" "multiple")]
0d66636f 2682)
d952d547 2683
a0f94409 2684(define_insn_and_split "*anddi_notzesidi_di"
9c08d1fa 2685 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2686 (and:DI (not:DI (zero_extend:DI
2687 (match_operand:SI 2 "s_register_operand" "r,r")))
e2348bcb 2688 (match_operand:DI 1 "s_register_operand" "0,?r")))]
25f905c2 2689 "TARGET_32BIT"
e2348bcb 2690 "@
97499065 2691 bic%?\\t%Q0, %Q1, %2
f6ebffac 2692 #"
a0f94409 2693 ; (not (zero_extend ...)) allows us to just copy the high word from
2694 ; operand1 to operand0.
25f905c2 2695 "TARGET_32BIT
a0f94409 2696 && reload_completed
2697 && operands[0] != operands[1]"
5a097f7d 2698 [(set (match_dup 0) (and:SI (not:SI (match_dup 2)) (match_dup 1)))
a0f94409 2699 (set (match_dup 3) (match_dup 4))]
2700 "
2701 {
2702 operands[3] = gen_highpart (SImode, operands[0]);
2703 operands[0] = gen_lowpart (SImode, operands[0]);
2704 operands[4] = gen_highpart (SImode, operands[1]);
2705 operands[1] = gen_lowpart (SImode, operands[1]);
2706 }"
0d66636f 2707 [(set_attr "length" "4,8")
d952d547 2708 (set_attr "predicable" "yes")
1b7da4ac 2709 (set_attr "predicable_short_it" "no")
2710 (set_attr "type" "multiple")]
0d66636f 2711)
d952d547 2712
d8cd5fa0 2713(define_insn_and_split "*anddi_notdi_zesidi"
2714 [(set (match_operand:DI 0 "s_register_operand" "=r")
2715 (and:DI (not:DI (match_operand:DI 2 "s_register_operand" "r"))
2716 (zero_extend:DI
2717 (match_operand:SI 1 "s_register_operand" "r"))))]
2718 "TARGET_32BIT"
2719 "#"
2720 "TARGET_32BIT && reload_completed"
2721 [(set (match_dup 0) (and:SI (not:SI (match_dup 2)) (match_dup 1)))
2722 (set (match_dup 3) (const_int 0))]
2723 "
2724 {
2725 operands[3] = gen_highpart (SImode, operands[0]);
2726 operands[0] = gen_lowpart (SImode, operands[0]);
2727 operands[2] = gen_lowpart (SImode, operands[2]);
2728 }"
2729 [(set_attr "length" "8")
2730 (set_attr "predicable" "yes")
2731 (set_attr "predicable_short_it" "no")
2732 (set_attr "type" "multiple")]
2733)
2734
a0f94409 2735(define_insn_and_split "*anddi_notsesidi_di"
9c08d1fa 2736 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2737 (and:DI (not:DI (sign_extend:DI
2738 (match_operand:SI 2 "s_register_operand" "r,r")))
5a097f7d 2739 (match_operand:DI 1 "s_register_operand" "0,r")))]
25f905c2 2740 "TARGET_32BIT"
f6ebffac 2741 "#"
25f905c2 2742 "TARGET_32BIT && reload_completed"
5a097f7d 2743 [(set (match_dup 0) (and:SI (not:SI (match_dup 2)) (match_dup 1)))
a0f94409 2744 (set (match_dup 3) (and:SI (not:SI
2745 (ashiftrt:SI (match_dup 2) (const_int 31)))
2746 (match_dup 4)))]
2747 "
2748 {
2749 operands[3] = gen_highpart (SImode, operands[0]);
2750 operands[0] = gen_lowpart (SImode, operands[0]);
2751 operands[4] = gen_highpart (SImode, operands[1]);
2752 operands[1] = gen_lowpart (SImode, operands[1]);
2753 }"
0d66636f 2754 [(set_attr "length" "8")
d952d547 2755 (set_attr "predicable" "yes")
1b7da4ac 2756 (set_attr "predicable_short_it" "no")
2757 (set_attr "type" "multiple")]
0d66636f 2758)
d952d547 2759
8a18b90c 2760(define_insn "andsi_notsi_si"
9c08d1fa 2761 [(set (match_operand:SI 0 "s_register_operand" "=r")
2762 (and:SI (not:SI (match_operand:SI 2 "s_register_operand" "r"))
2763 (match_operand:SI 1 "s_register_operand" "r")))]
25f905c2 2764 "TARGET_32BIT"
0d66636f 2765 "bic%?\\t%0, %1, %2"
d952d547 2766 [(set_attr "predicable" "yes")
1b7da4ac 2767 (set_attr "predicable_short_it" "no")
2768 (set_attr "type" "logic_reg")]
0d66636f 2769)
b11cae9e 2770
8a18b90c 2771(define_insn "andsi_not_shiftsi_si"
a2cd141b 2772 [(set (match_operand:SI 0 "s_register_operand" "=r")
2773 (and:SI (not:SI (match_operator:SI 4 "shift_operator"
2774 [(match_operand:SI 2 "s_register_operand" "r")
2775 (match_operand:SI 3 "arm_rhs_operand" "rM")]))
2776 (match_operand:SI 1 "s_register_operand" "r")))]
cffb2a26 2777 "TARGET_ARM"
6c4c2133 2778 "bic%?\\t%0, %1, %2%S4"
344495ea 2779 [(set_attr "predicable" "yes")
331beb1a 2780 (set_attr "shift" "2")
a2cd141b 2781 (set (attr "type") (if_then_else (match_operand 3 "const_int_operand" "")
d82e788e 2782 (const_string "logic_shift_imm")
2783 (const_string "logic_shift_reg")))]
6c4c2133 2784)
8a18b90c 2785
9ed784d8 2786;; Shifted bics pattern used to set up CC status register and not reusing
2787;; bics output. Pattern restricts Thumb2 shift operand as bics for Thumb2
2788;; does not support shift by register.
2789(define_insn "andsi_not_shiftsi_si_scc_no_reuse"
2790 [(set (reg:CC_NOOV CC_REGNUM)
2791 (compare:CC_NOOV
2792 (and:SI (not:SI (match_operator:SI 0 "shift_operator"
2793 [(match_operand:SI 1 "s_register_operand" "r")
2794 (match_operand:SI 2 "arm_rhs_operand" "rM")]))
2795 (match_operand:SI 3 "s_register_operand" "r"))
2796 (const_int 0)))
2797 (clobber (match_scratch:SI 4 "=r"))]
2798 "TARGET_ARM || (TARGET_THUMB2 && CONST_INT_P (operands[2]))"
2799 "bic%.%?\\t%4, %3, %1%S0"
2800 [(set_attr "predicable" "yes")
2801 (set_attr "predicable_short_it" "no")
2802 (set_attr "conds" "set")
2803 (set_attr "shift" "1")
2804 (set (attr "type") (if_then_else (match_operand 2 "const_int_operand" "")
2805 (const_string "logic_shift_imm")
2806 (const_string "logic_shift_reg")))]
2807)
2808
2809;; Same as andsi_not_shiftsi_si_scc_no_reuse, but the bics result is also
2810;; getting reused later.
2811(define_insn "andsi_not_shiftsi_si_scc"
2812 [(parallel [(set (reg:CC_NOOV CC_REGNUM)
2813 (compare:CC_NOOV
2814 (and:SI (not:SI (match_operator:SI 0 "shift_operator"
2815 [(match_operand:SI 1 "s_register_operand" "r")
2816 (match_operand:SI 2 "arm_rhs_operand" "rM")]))
2817 (match_operand:SI 3 "s_register_operand" "r"))
2818 (const_int 0)))
2819 (set (match_operand:SI 4 "s_register_operand" "=r")
2820 (and:SI (not:SI (match_op_dup 0
2821 [(match_dup 1)
2822 (match_dup 2)]))
2823 (match_dup 3)))])]
2824 "TARGET_ARM || (TARGET_THUMB2 && CONST_INT_P (operands[2]))"
2825 "bic%.%?\\t%4, %3, %1%S0"
2826 [(set_attr "predicable" "yes")
2827 (set_attr "predicable_short_it" "no")
2828 (set_attr "conds" "set")
2829 (set_attr "shift" "1")
2830 (set (attr "type") (if_then_else (match_operand 2 "const_int_operand" "")
2831 (const_string "logic_shift_imm")
2832 (const_string "logic_shift_reg")))]
2833)
2834
f7fbdd4a 2835(define_insn "*andsi_notsi_si_compare0"
bd5b4116 2836 [(set (reg:CC_NOOV CC_REGNUM)
e2348bcb 2837 (compare:CC_NOOV
2838 (and:SI (not:SI (match_operand:SI 2 "s_register_operand" "r"))
2839 (match_operand:SI 1 "s_register_operand" "r"))
2840 (const_int 0)))
9c08d1fa 2841 (set (match_operand:SI 0 "s_register_operand" "=r")
2842 (and:SI (not:SI (match_dup 2)) (match_dup 1)))]
25f905c2 2843 "TARGET_32BIT"
2844 "bic%.\\t%0, %1, %2"
d82e788e 2845 [(set_attr "conds" "set")
2846 (set_attr "type" "logics_shift_reg")]
0d66636f 2847)
9c08d1fa 2848
f7fbdd4a 2849(define_insn "*andsi_notsi_si_compare0_scratch"
bd5b4116 2850 [(set (reg:CC_NOOV CC_REGNUM)
e2348bcb 2851 (compare:CC_NOOV
2852 (and:SI (not:SI (match_operand:SI 2 "s_register_operand" "r"))
2853 (match_operand:SI 1 "s_register_operand" "r"))
2854 (const_int 0)))
9c08d1fa 2855 (clobber (match_scratch:SI 0 "=r"))]
25f905c2 2856 "TARGET_32BIT"
2857 "bic%.\\t%0, %1, %2"
d82e788e 2858 [(set_attr "conds" "set")
2859 (set_attr "type" "logics_shift_reg")]
0d66636f 2860)
9c08d1fa 2861
e2669ea7 2862(define_expand "iordi3"
2863 [(set (match_operand:DI 0 "s_register_operand" "")
2864 (ior:DI (match_operand:DI 1 "s_register_operand" "")
2865 (match_operand:DI 2 "neon_logic_op2" "")))]
2866 "TARGET_32BIT"
2867 ""
2868)
2869
74d6113f 2870(define_insn_and_split "*iordi3_insn"
2871 [(set (match_operand:DI 0 "s_register_operand" "=w,w ,&r,&r,&r,&r,?w,?w")
2872 (ior:DI (match_operand:DI 1 "s_register_operand" "%w,0 ,0 ,r ,0 ,r ,w ,0")
e0fe6977 2873 (match_operand:DI 2 "arm_iordi_operand_neon" "w ,Dl,r ,r ,Df,Df,w ,Dl")))]
74d6113f 2874 "TARGET_32BIT && !TARGET_IWMMXT"
2875 {
2876 switch (which_alternative)
2877 {
2878 case 0: /* fall through */
2879 case 6: return "vorr\t%P0, %P1, %P2";
2880 case 1: /* fall through */
2881 case 7: return neon_output_logic_immediate ("vorr", &operands[2],
2882 DImode, 0, VALID_NEON_QREG_MODE (DImode));
2883 case 2:
2884 case 3:
2885 case 4:
2886 case 5:
2887 return "#";
2888 default: gcc_unreachable ();
2889 }
2890 }
2891 "TARGET_32BIT && !TARGET_IWMMXT && reload_completed
2892 && !(IS_VFP_REGNUM (REGNO (operands[0])))"
2893 [(set (match_dup 3) (match_dup 4))
2894 (set (match_dup 5) (match_dup 6))]
2895 "
2896 {
2897 operands[3] = gen_lowpart (SImode, operands[0]);
2898 operands[5] = gen_highpart (SImode, operands[0]);
2899
2900 operands[4] = simplify_gen_binary (IOR, SImode,
2901 gen_lowpart (SImode, operands[1]),
2902 gen_lowpart (SImode, operands[2]));
2903 operands[6] = simplify_gen_binary (IOR, SImode,
2904 gen_highpart (SImode, operands[1]),
2905 gen_highpart_mode (SImode, DImode, operands[2]));
2906
2907 }"
32093010 2908 [(set_attr "type" "neon_logic,neon_logic,multiple,multiple,multiple,\
2909 multiple,neon_logic,neon_logic")
e0fe6977 2910 (set_attr "length" "*,*,8,8,8,8,*,*")
74d6113f 2911 (set_attr "arch" "neon_for_64bits,neon_for_64bits,*,*,*,*,avoid_neon_for_64bits,avoid_neon_for_64bits")]
cffb2a26 2912)
9c08d1fa 2913
f7fbdd4a 2914(define_insn "*iordi_zesidi_di"
9c08d1fa 2915 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2916 (ior:DI (zero_extend:DI
2917 (match_operand:SI 2 "s_register_operand" "r,r"))
e2348bcb 2918 (match_operand:DI 1 "s_register_operand" "0,?r")))]
25f905c2 2919 "TARGET_32BIT"
e2348bcb 2920 "@
97499065 2921 orr%?\\t%Q0, %Q1, %2
f6ebffac 2922 #"
0d66636f 2923 [(set_attr "length" "4,8")
d952d547 2924 (set_attr "predicable" "yes")
1b7da4ac 2925 (set_attr "predicable_short_it" "no")
2926 (set_attr "type" "logic_reg,multiple")]
cffb2a26 2927)
9c08d1fa 2928
f7fbdd4a 2929(define_insn "*iordi_sesidi_di"
9c08d1fa 2930 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2931 (ior:DI (sign_extend:DI
2932 (match_operand:SI 2 "s_register_operand" "r,r"))
e5fea38e 2933 (match_operand:DI 1 "s_register_operand" "0,r")))]
25f905c2 2934 "TARGET_32BIT"
f6ebffac 2935 "#"
0d66636f 2936 [(set_attr "length" "8")
1b7da4ac 2937 (set_attr "predicable" "yes")
2938 (set_attr "type" "multiple")]
cffb2a26 2939)
9c08d1fa 2940
87b22bf7 2941(define_expand "iorsi3"
cffb2a26 2942 [(set (match_operand:SI 0 "s_register_operand" "")
87b22bf7 2943 (ior:SI (match_operand:SI 1 "s_register_operand" "")
2944 (match_operand:SI 2 "reg_or_int_operand" "")))]
cffb2a26 2945 "TARGET_EITHER"
87b22bf7 2946 "
0438d37f 2947 if (CONST_INT_P (operands[2]))
87b22bf7 2948 {
25f905c2 2949 if (TARGET_32BIT)
cffb2a26 2950 {
17202aa5 2951 if (DONT_EARLY_SPLIT_CONSTANT (INTVAL (operands[2]), IOR))
2952 operands[2] = force_reg (SImode, operands[2]);
2953 else
2954 {
2955 arm_split_constant (IOR, SImode, NULL_RTX,
2956 INTVAL (operands[2]), operands[0],
2957 operands[1],
2958 optimize && can_create_pseudo_p ());
2959 DONE;
2960 }
cffb2a26 2961 }
25f905c2 2962 else /* TARGET_THUMB1 */
923ffadb 2963 {
2964 rtx tmp = force_reg (SImode, operands[2]);
2965 if (rtx_equal_p (operands[0], operands[1]))
2966 operands[2] = tmp;
2967 else
2968 {
2969 operands[2] = operands[1];
2970 operands[1] = tmp;
2971 }
2972 }
87b22bf7 2973 }
cffb2a26 2974 "
2975)
87b22bf7 2976
d5d4dc8d 2977(define_insn_and_split "*iorsi3_insn"
29e234a3 2978 [(set (match_operand:SI 0 "s_register_operand" "=r,l,r,r,r")
2979 (ior:SI (match_operand:SI 1 "s_register_operand" "%r,0,r,r,r")
2980 (match_operand:SI 2 "reg_or_int_operand" "I,l,K,r,?n")))]
d5d4dc8d 2981 "TARGET_32BIT"
87b22bf7 2982 "@
29e234a3 2983 orr%?\\t%0, %1, %2
87b22bf7 2984 orr%?\\t%0, %1, %2
d5d4dc8d 2985 orn%?\\t%0, %1, #%B2
65f68e55 2986 orr%?\\t%0, %1, %2
87b22bf7 2987 #"
d5d4dc8d 2988 "TARGET_32BIT
0438d37f 2989 && CONST_INT_P (operands[2])
d5d4dc8d 2990 && !(const_ok_for_arm (INTVAL (operands[2]))
2991 || (TARGET_THUMB2 && const_ok_for_arm (~INTVAL (operands[2]))))"
a0f94409 2992 [(clobber (const_int 0))]
d5d4dc8d 2993{
29e234a3 2994 arm_split_constant (IOR, SImode, curr_insn,
96f57e36 2995 INTVAL (operands[2]), operands[0], operands[1], 0);
a0f94409 2996 DONE;
d5d4dc8d 2997}
29e234a3 2998 [(set_attr "length" "4,4,4,4,16")
2999 (set_attr "arch" "32,t2,t2,32,32")
65f68e55 3000 (set_attr "predicable" "yes")
29e234a3 3001 (set_attr "predicable_short_it" "no,yes,no,no,no")
d82e788e 3002 (set_attr "type" "logic_imm,logic_reg,logic_imm,logic_reg,logic_reg")]
65f68e55 3003)
cffb2a26 3004
a0f94409 3005(define_peephole2
3006 [(match_scratch:SI 3 "r")
372575c7 3007 (set (match_operand:SI 0 "arm_general_register_operand" "")
3008 (ior:SI (match_operand:SI 1 "arm_general_register_operand" "")
87b22bf7 3009 (match_operand:SI 2 "const_int_operand" "")))]
90560cad 3010 "TARGET_ARM
a0f94409 3011 && !const_ok_for_arm (INTVAL (operands[2]))
3012 && const_ok_for_arm (~INTVAL (operands[2]))"
3013 [(set (match_dup 3) (match_dup 2))
3014 (set (match_dup 0) (ior:SI (match_dup 1) (match_dup 3)))]
3015 ""
215b30b3 3016)
a0f94409 3017
f7fbdd4a 3018(define_insn "*iorsi3_compare0"
bd5b4116 3019 [(set (reg:CC_NOOV CC_REGNUM)
65f68e55 3020 (compare:CC_NOOV (ior:SI (match_operand:SI 1 "s_register_operand" "%r,r")
3021 (match_operand:SI 2 "arm_rhs_operand" "I,r"))
9c08d1fa 3022 (const_int 0)))
65f68e55 3023 (set (match_operand:SI 0 "s_register_operand" "=r,r")
9c08d1fa 3024 (ior:SI (match_dup 1) (match_dup 2)))]
25f905c2 3025 "TARGET_32BIT"
3026 "orr%.\\t%0, %1, %2"
65f68e55 3027 [(set_attr "conds" "set")
d82e788e 3028 (set_attr "type" "logics_imm,logics_reg")]
cffb2a26 3029)
9c08d1fa 3030
f7fbdd4a 3031(define_insn "*iorsi3_compare0_scratch"
bd5b4116 3032 [(set (reg:CC_NOOV CC_REGNUM)
65f68e55 3033 (compare:CC_NOOV (ior:SI (match_operand:SI 1 "s_register_operand" "%r,r")
3034 (match_operand:SI 2 "arm_rhs_operand" "I,r"))
9c08d1fa 3035 (const_int 0)))
65f68e55 3036 (clobber (match_scratch:SI 0 "=r,r"))]
25f905c2 3037 "TARGET_32BIT"
3038 "orr%.\\t%0, %1, %2"
65f68e55 3039 [(set_attr "conds" "set")
d82e788e 3040 (set_attr "type" "logics_imm,logics_reg")]
0d66636f 3041)
9c08d1fa 3042
e2669ea7 3043(define_expand "xordi3"
3044 [(set (match_operand:DI 0 "s_register_operand" "")
3045 (xor:DI (match_operand:DI 1 "s_register_operand" "")
8ee7dc6f 3046 (match_operand:DI 2 "arm_xordi_operand" "")))]
e2669ea7 3047 "TARGET_32BIT"
3048 ""
3049)
3050
8ee7dc6f 3051(define_insn_and_split "*xordi3_insn"
3052 [(set (match_operand:DI 0 "s_register_operand" "=w,&r,&r,&r,&r,?w")
205c3b0a 3053 (xor:DI (match_operand:DI 1 "s_register_operand" "%w ,0,r ,0 ,r ,w")
8ee7dc6f 3054 (match_operand:DI 2 "arm_xordi_operand" "w ,r ,r ,Dg,Dg,w")))]
3055 "TARGET_32BIT && !TARGET_IWMMXT"
3056{
3057 switch (which_alternative)
3058 {
3059 case 1:
3060 case 2:
3061 case 3:
3062 case 4: /* fall through */
3063 return "#";
3064 case 0: /* fall through */
3065 case 5: return "veor\t%P0, %P1, %P2";
3066 default: gcc_unreachable ();
3067 }
3068}
3069 "TARGET_32BIT && !TARGET_IWMMXT && reload_completed
3070 && !(IS_VFP_REGNUM (REGNO (operands[0])))"
3071 [(set (match_dup 3) (match_dup 4))
3072 (set (match_dup 5) (match_dup 6))]
3073 "
3074 {
3075 operands[3] = gen_lowpart (SImode, operands[0]);
3076 operands[5] = gen_highpart (SImode, operands[0]);
3077
3078 operands[4] = simplify_gen_binary (XOR, SImode,
3079 gen_lowpart (SImode, operands[1]),
3080 gen_lowpart (SImode, operands[2]));
3081 operands[6] = simplify_gen_binary (XOR, SImode,
3082 gen_highpart (SImode, operands[1]),
3083 gen_highpart_mode (SImode, DImode, operands[2]));
3084
3085 }"
3086 [(set_attr "length" "*,8,8,8,8,*")
32093010 3087 (set_attr "type" "neon_logic,multiple,multiple,multiple,multiple,neon_logic")
8ee7dc6f 3088 (set_attr "arch" "neon_for_64bits,*,*,*,*,avoid_neon_for_64bits")]
cffb2a26 3089)
9c08d1fa 3090
f7fbdd4a 3091(define_insn "*xordi_zesidi_di"
9c08d1fa 3092 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
3093 (xor:DI (zero_extend:DI
3094 (match_operand:SI 2 "s_register_operand" "r,r"))
e2348bcb 3095 (match_operand:DI 1 "s_register_operand" "0,?r")))]
25f905c2 3096 "TARGET_32BIT"
e2348bcb 3097 "@
97499065 3098 eor%?\\t%Q0, %Q1, %2
f6ebffac 3099 #"
0d66636f 3100 [(set_attr "length" "4,8")
d952d547 3101 (set_attr "predicable" "yes")
1b7da4ac 3102 (set_attr "predicable_short_it" "no")
3103 (set_attr "type" "logic_reg")]
cffb2a26 3104)
9c08d1fa 3105
f7fbdd4a 3106(define_insn "*xordi_sesidi_di"
9c08d1fa 3107 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
3108 (xor:DI (sign_extend:DI
3109 (match_operand:SI 2 "s_register_operand" "r,r"))
e5fea38e 3110 (match_operand:DI 1 "s_register_operand" "0,r")))]
25f905c2 3111 "TARGET_32BIT"
f6ebffac 3112 "#"
0d66636f 3113 [(set_attr "length" "8")
1b7da4ac 3114 (set_attr "predicable" "yes")
3115 (set_attr "type" "multiple")]
cffb2a26 3116)
9c08d1fa 3117
cffb2a26 3118(define_expand "xorsi3"
3119 [(set (match_operand:SI 0 "s_register_operand" "")
3120 (xor:SI (match_operand:SI 1 "s_register_operand" "")
923ffadb 3121 (match_operand:SI 2 "reg_or_int_operand" "")))]
cffb2a26 3122 "TARGET_EITHER"
0438d37f 3123 "if (CONST_INT_P (operands[2]))
923ffadb 3124 {
3125 if (TARGET_32BIT)
3126 {
17202aa5 3127 if (DONT_EARLY_SPLIT_CONSTANT (INTVAL (operands[2]), XOR))
3128 operands[2] = force_reg (SImode, operands[2]);
3129 else
3130 {
3131 arm_split_constant (XOR, SImode, NULL_RTX,
3132 INTVAL (operands[2]), operands[0],
3133 operands[1],
3134 optimize && can_create_pseudo_p ());
3135 DONE;
3136 }
923ffadb 3137 }
3138 else /* TARGET_THUMB1 */
3139 {
3140 rtx tmp = force_reg (SImode, operands[2]);
3141 if (rtx_equal_p (operands[0], operands[1]))
3142 operands[2] = tmp;
3143 else
3144 {
3145 operands[2] = operands[1];
3146 operands[1] = tmp;
3147 }
3148 }
3149 }"
cffb2a26 3150)
3151
5dcb35d9 3152(define_insn_and_split "*arm_xorsi3"
29e234a3 3153 [(set (match_operand:SI 0 "s_register_operand" "=r,l,r,r")
3154 (xor:SI (match_operand:SI 1 "s_register_operand" "%r,0,r,r")
3155 (match_operand:SI 2 "reg_or_int_operand" "I,l,r,?n")))]
25f905c2 3156 "TARGET_32BIT"
5dcb35d9 3157 "@
29e234a3 3158 eor%?\\t%0, %1, %2
65f68e55 3159 eor%?\\t%0, %1, %2
5dcb35d9 3160 eor%?\\t%0, %1, %2
3161 #"
3162 "TARGET_32BIT
0438d37f 3163 && CONST_INT_P (operands[2])
5dcb35d9 3164 && !const_ok_for_arm (INTVAL (operands[2]))"
3165 [(clobber (const_int 0))]
3166{
3167 arm_split_constant (XOR, SImode, curr_insn,
3168 INTVAL (operands[2]), operands[0], operands[1], 0);
3169 DONE;
3170}
29e234a3 3171 [(set_attr "length" "4,4,4,16")
65f68e55 3172 (set_attr "predicable" "yes")
29e234a3 3173 (set_attr "predicable_short_it" "no,yes,no,no")
1b7da4ac 3174 (set_attr "type" "logic_imm,logic_reg,logic_reg,multiple")]
cffb2a26 3175)
3176
f7fbdd4a 3177(define_insn "*xorsi3_compare0"
bd5b4116 3178 [(set (reg:CC_NOOV CC_REGNUM)
65f68e55 3179 (compare:CC_NOOV (xor:SI (match_operand:SI 1 "s_register_operand" "r,r")
3180 (match_operand:SI 2 "arm_rhs_operand" "I,r"))
9c08d1fa 3181 (const_int 0)))
65f68e55 3182 (set (match_operand:SI 0 "s_register_operand" "=r,r")
9c08d1fa 3183 (xor:SI (match_dup 1) (match_dup 2)))]
25f905c2 3184 "TARGET_32BIT"
3185 "eor%.\\t%0, %1, %2"
65f68e55 3186 [(set_attr "conds" "set")
d82e788e 3187 (set_attr "type" "logics_imm,logics_reg")]
0d66636f 3188)
9c08d1fa 3189
f7fbdd4a 3190(define_insn "*xorsi3_compare0_scratch"
bd5b4116 3191 [(set (reg:CC_NOOV CC_REGNUM)
65f68e55 3192 (compare:CC_NOOV (xor:SI (match_operand:SI 0 "s_register_operand" "r,r")
3193 (match_operand:SI 1 "arm_rhs_operand" "I,r"))
9c08d1fa 3194 (const_int 0)))]
25f905c2 3195 "TARGET_32BIT"
40dbec34 3196 "teq%?\\t%0, %1"
65f68e55 3197 [(set_attr "conds" "set")
d82e788e 3198 (set_attr "type" "logics_imm,logics_reg")]
cffb2a26 3199)
9c08d1fa 3200
215b30b3 3201; By splitting (IOR (AND (NOT A) (NOT B)) C) as D = AND (IOR A B) (NOT C),
3202; (NOT D) we can sometimes merge the final NOT into one of the following
3203; insns.
9c08d1fa 3204
3205(define_split
a058e94a 3206 [(set (match_operand:SI 0 "s_register_operand" "")
3207 (ior:SI (and:SI (not:SI (match_operand:SI 1 "s_register_operand" ""))
3208 (not:SI (match_operand:SI 2 "arm_rhs_operand" "")))
3209 (match_operand:SI 3 "arm_rhs_operand" "")))
3210 (clobber (match_operand:SI 4 "s_register_operand" ""))]
25f905c2 3211 "TARGET_32BIT"
9c08d1fa 3212 [(set (match_dup 4) (and:SI (ior:SI (match_dup 1) (match_dup 2))
3213 (not:SI (match_dup 3))))
3214 (set (match_dup 0) (not:SI (match_dup 4)))]
3215 ""
3216)
3217
ba6a3b2f 3218(define_insn_and_split "*andsi_iorsi3_notsi"
9c08d1fa 3219 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r")
e5fea38e 3220 (and:SI (ior:SI (match_operand:SI 1 "s_register_operand" "%0,r,r")
9c08d1fa 3221 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI"))
3222 (not:SI (match_operand:SI 3 "arm_rhs_operand" "rI,rI,rI"))))]
25f905c2 3223 "TARGET_32BIT"
ba6a3b2f 3224 "#" ; "orr%?\\t%0, %1, %2\;bic%?\\t%0, %0, %3"
3225 "&& reload_completed"
3226 [(set (match_dup 0) (ior:SI (match_dup 1) (match_dup 2)))
3227 (set (match_dup 0) (and:SI (not:SI (match_dup 3)) (match_dup 0)))]
3228 ""
0d66636f 3229 [(set_attr "length" "8")
25f905c2 3230 (set_attr "ce_count" "2")
d952d547 3231 (set_attr "predicable" "yes")
1b7da4ac 3232 (set_attr "predicable_short_it" "no")
3233 (set_attr "type" "multiple")]
cffb2a26 3234)
9c08d1fa 3235
25f905c2 3236; ??? Are these four splitters still beneficial when the Thumb-2 bitfield
3237; insns are available?
d7863cfe 3238(define_split
3239 [(set (match_operand:SI 0 "s_register_operand" "")
3240 (match_operator:SI 1 "logical_binary_operator"
3241 [(zero_extract:SI (match_operand:SI 2 "s_register_operand" "")
3242 (match_operand:SI 3 "const_int_operand" "")
3243 (match_operand:SI 4 "const_int_operand" ""))
3244 (match_operator:SI 9 "logical_binary_operator"
3245 [(lshiftrt:SI (match_operand:SI 5 "s_register_operand" "")
3246 (match_operand:SI 6 "const_int_operand" ""))
3247 (match_operand:SI 7 "s_register_operand" "")])]))
3248 (clobber (match_operand:SI 8 "s_register_operand" ""))]
25f905c2 3249 "TARGET_32BIT
d7863cfe 3250 && GET_CODE (operands[1]) == GET_CODE (operands[9])
3251 && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
3252 [(set (match_dup 8)
3253 (match_op_dup 1
3254 [(ashift:SI (match_dup 2) (match_dup 4))
3255 (match_dup 5)]))
3256 (set (match_dup 0)
3257 (match_op_dup 1
3258 [(lshiftrt:SI (match_dup 8) (match_dup 6))
3259 (match_dup 7)]))]
3260 "
3261 operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
3262")
3263
3264(define_split
3265 [(set (match_operand:SI 0 "s_register_operand" "")
3266 (match_operator:SI 1 "logical_binary_operator"
3267 [(match_operator:SI 9 "logical_binary_operator"
3268 [(lshiftrt:SI (match_operand:SI 5 "s_register_operand" "")
3269 (match_operand:SI 6 "const_int_operand" ""))
3270 (match_operand:SI 7 "s_register_operand" "")])
3271 (zero_extract:SI (match_operand:SI 2 "s_register_operand" "")
3272 (match_operand:SI 3 "const_int_operand" "")
3273 (match_operand:SI 4 "const_int_operand" ""))]))
3274 (clobber (match_operand:SI 8 "s_register_operand" ""))]
25f905c2 3275 "TARGET_32BIT
d7863cfe 3276 && GET_CODE (operands[1]) == GET_CODE (operands[9])
3277 && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
3278 [(set (match_dup 8)
3279 (match_op_dup 1
3280 [(ashift:SI (match_dup 2) (match_dup 4))
3281 (match_dup 5)]))
3282 (set (match_dup 0)
3283 (match_op_dup 1
3284 [(lshiftrt:SI (match_dup 8) (match_dup 6))
3285 (match_dup 7)]))]
3286 "
3287 operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
3288")
3289
3290(define_split
3291 [(set (match_operand:SI 0 "s_register_operand" "")
3292 (match_operator:SI 1 "logical_binary_operator"
3293 [(sign_extract:SI (match_operand:SI 2 "s_register_operand" "")
3294 (match_operand:SI 3 "const_int_operand" "")
3295 (match_operand:SI 4 "const_int_operand" ""))
3296 (match_operator:SI 9 "logical_binary_operator"
3297 [(ashiftrt:SI (match_operand:SI 5 "s_register_operand" "")
3298 (match_operand:SI 6 "const_int_operand" ""))
3299 (match_operand:SI 7 "s_register_operand" "")])]))
3300 (clobber (match_operand:SI 8 "s_register_operand" ""))]
25f905c2 3301 "TARGET_32BIT
d7863cfe 3302 && GET_CODE (operands[1]) == GET_CODE (operands[9])
3303 && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
3304 [(set (match_dup 8)
3305 (match_op_dup 1
3306 [(ashift:SI (match_dup 2) (match_dup 4))
3307 (match_dup 5)]))
3308 (set (match_dup 0)
3309 (match_op_dup 1
3310 [(ashiftrt:SI (match_dup 8) (match_dup 6))
3311 (match_dup 7)]))]
3312 "
3313 operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
3314")
3315
3316(define_split
3317 [(set (match_operand:SI 0 "s_register_operand" "")
3318 (match_operator:SI 1 "logical_binary_operator"
3319 [(match_operator:SI 9 "logical_binary_operator"
3320 [(ashiftrt:SI (match_operand:SI 5 "s_register_operand" "")
3321 (match_operand:SI 6 "const_int_operand" ""))
3322 (match_operand:SI 7 "s_register_operand" "")])
3323 (sign_extract:SI (match_operand:SI 2 "s_register_operand" "")
3324 (match_operand:SI 3 "const_int_operand" "")
3325 (match_operand:SI 4 "const_int_operand" ""))]))
3326 (clobber (match_operand:SI 8 "s_register_operand" ""))]
25f905c2 3327 "TARGET_32BIT
d7863cfe 3328 && GET_CODE (operands[1]) == GET_CODE (operands[9])
3329 && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
3330 [(set (match_dup 8)
3331 (match_op_dup 1
3332 [(ashift:SI (match_dup 2) (match_dup 4))
3333 (match_dup 5)]))
3334 (set (match_dup 0)
3335 (match_op_dup 1
3336 [(ashiftrt:SI (match_dup 8) (match_dup 6))
3337 (match_dup 7)]))]
3338 "
3339 operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
3340")
9c08d1fa 3341\f
3342
3343;; Minimum and maximum insns
3344
8b9dc177 3345(define_expand "smaxsi3"
3346 [(parallel [
3347 (set (match_operand:SI 0 "s_register_operand" "")
3348 (smax:SI (match_operand:SI 1 "s_register_operand" "")
3349 (match_operand:SI 2 "arm_rhs_operand" "")))
3350 (clobber (reg:CC CC_REGNUM))])]
25f905c2 3351 "TARGET_32BIT"
8b9dc177 3352 "
8774928b 3353 if (operands[2] == const0_rtx || operands[2] == constm1_rtx)
8b9dc177 3354 {
3355 /* No need for a clobber of the condition code register here. */
d1f9b275 3356 emit_insn (gen_rtx_SET (operands[0],
8b9dc177 3357 gen_rtx_SMAX (SImode, operands[1],
3358 operands[2])));
3359 DONE;
3360 }
3361")
3362
3363(define_insn "*smax_0"
3364 [(set (match_operand:SI 0 "s_register_operand" "=r")
3365 (smax:SI (match_operand:SI 1 "s_register_operand" "r")
3366 (const_int 0)))]
25f905c2 3367 "TARGET_32BIT"
8b9dc177 3368 "bic%?\\t%0, %1, %1, asr #31"
d952d547 3369 [(set_attr "predicable" "yes")
1b7da4ac 3370 (set_attr "predicable_short_it" "no")
3371 (set_attr "type" "logic_shift_reg")]
8b9dc177 3372)
3373
8774928b 3374(define_insn "*smax_m1"
3375 [(set (match_operand:SI 0 "s_register_operand" "=r")
3376 (smax:SI (match_operand:SI 1 "s_register_operand" "r")
3377 (const_int -1)))]
25f905c2 3378 "TARGET_32BIT"
8774928b 3379 "orr%?\\t%0, %1, %1, asr #31"
d952d547 3380 [(set_attr "predicable" "yes")
1b7da4ac 3381 (set_attr "predicable_short_it" "no")
3382 (set_attr "type" "logic_shift_reg")]
8774928b 3383)
3384
3dc953f2 3385(define_insn_and_split "*arm_smax_insn"
8b9dc177 3386 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
3387 (smax:SI (match_operand:SI 1 "s_register_operand" "%0,?r")
3388 (match_operand:SI 2 "arm_rhs_operand" "rI,rI")))
bd5b4116 3389 (clobber (reg:CC CC_REGNUM))]
cffb2a26 3390 "TARGET_ARM"
3dc953f2 3391 "#"
3392 ; cmp\\t%1, %2\;movlt\\t%0, %2
3393 ; cmp\\t%1, %2\;movge\\t%0, %1\;movlt\\t%0, %2"
3394 "TARGET_ARM"
3395 [(set (reg:CC CC_REGNUM)
3396 (compare:CC (match_dup 1) (match_dup 2)))
3397 (set (match_dup 0)
3398 (if_then_else:SI (ge:SI (reg:CC CC_REGNUM) (const_int 0))
3399 (match_dup 1)
3400 (match_dup 2)))]
3401 ""
cffb2a26 3402 [(set_attr "conds" "clob")
1b7da4ac 3403 (set_attr "length" "8,12")
3404 (set_attr "type" "multiple")]
cffb2a26 3405)
9c08d1fa 3406
8b9dc177 3407(define_expand "sminsi3"
3408 [(parallel [
3409 (set (match_operand:SI 0 "s_register_operand" "")
3410 (smin:SI (match_operand:SI 1 "s_register_operand" "")
3411 (match_operand:SI 2 "arm_rhs_operand" "")))
3412 (clobber (reg:CC CC_REGNUM))])]
25f905c2 3413 "TARGET_32BIT"
8b9dc177 3414 "
3415 if (operands[2] == const0_rtx)
3416 {
3417 /* No need for a clobber of the condition code register here. */
d1f9b275 3418 emit_insn (gen_rtx_SET (operands[0],
8b9dc177 3419 gen_rtx_SMIN (SImode, operands[1],
3420 operands[2])));
3421 DONE;
3422 }
3423")
3424
3425(define_insn "*smin_0"
3426 [(set (match_operand:SI 0 "s_register_operand" "=r")
3427 (smin:SI (match_operand:SI 1 "s_register_operand" "r")
3428 (const_int 0)))]
25f905c2 3429 "TARGET_32BIT"
8b9dc177 3430 "and%?\\t%0, %1, %1, asr #31"
d952d547 3431 [(set_attr "predicable" "yes")
1b7da4ac 3432 (set_attr "predicable_short_it" "no")
3433 (set_attr "type" "logic_shift_reg")]
8b9dc177 3434)
3435
3dc953f2 3436(define_insn_and_split "*arm_smin_insn"
8b9dc177 3437 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
3438 (smin:SI (match_operand:SI 1 "s_register_operand" "%0,?r")
3439 (match_operand:SI 2 "arm_rhs_operand" "rI,rI")))
bd5b4116 3440 (clobber (reg:CC CC_REGNUM))]
cffb2a26 3441 "TARGET_ARM"
3dc953f2 3442 "#"
3443 ; cmp\\t%1, %2\;movge\\t%0, %2
3444 ; cmp\\t%1, %2\;movlt\\t%0, %1\;movge\\t%0, %2"
3445 "TARGET_ARM"
3446 [(set (reg:CC CC_REGNUM)
3447 (compare:CC (match_dup 1) (match_dup 2)))
3448 (set (match_dup 0)
3449 (if_then_else:SI (lt:SI (reg:CC CC_REGNUM) (const_int 0))
3450 (match_dup 1)
3451 (match_dup 2)))]
3452 ""
0d66636f 3453 [(set_attr "conds" "clob")
1b7da4ac 3454 (set_attr "length" "8,12")
3455 (set_attr "type" "multiple,multiple")]
0d66636f 3456)
9c08d1fa 3457
3d5db02d 3458;; t = (s/u)min (x, y)
3459;; cc = cmp (t, z)
3460;; is the same as
3461;; cmp x, z
3462;; cmpge(u) y, z
3463
3464(define_insn_and_split "*arm_smin_cmp"
3465 [(set (reg:CC CC_REGNUM)
3466 (compare:CC
3467 (smin:SI (match_operand:SI 0 "s_register_operand" "r")
3468 (match_operand:SI 1 "s_register_operand" "r"))
3469 (match_operand:SI 2 "s_register_operand" "r")))]
3470 "TARGET_32BIT"
3471 "#"
3472 "&& reload_completed"
3473 [(set (reg:CC CC_REGNUM)
3474 (compare:CC (match_dup 0) (match_dup 2)))
3475 (cond_exec (ge:CC (reg:CC CC_REGNUM) (const_int 0))
3476 (set (reg:CC CC_REGNUM)
3477 (compare:CC (match_dup 1) (match_dup 2))))]
3478)
3479
3480(define_insn_and_split "*arm_umin_cmp"
3481 [(set (reg:CC CC_REGNUM)
3482 (compare:CC
3483 (umin:SI (match_operand:SI 0 "s_register_operand" "r")
3484 (match_operand:SI 1 "s_register_operand" "r"))
3485 (match_operand:SI 2 "s_register_operand" "r")))]
3486 "TARGET_32BIT"
3487 "#"
3488 "&& reload_completed"
3489 [(set (reg:CC CC_REGNUM)
3490 (compare:CC (match_dup 0) (match_dup 2)))
3491 (cond_exec (geu:CC (reg:CC CC_REGNUM) (const_int 0))
3492 (set (reg:CC CC_REGNUM)
3493 (compare:CC (match_dup 1) (match_dup 2))))]
3494)
3495
25f905c2 3496(define_expand "umaxsi3"
3497 [(parallel [
3498 (set (match_operand:SI 0 "s_register_operand" "")
3499 (umax:SI (match_operand:SI 1 "s_register_operand" "")
3500 (match_operand:SI 2 "arm_rhs_operand" "")))
3501 (clobber (reg:CC CC_REGNUM))])]
3502 "TARGET_32BIT"
3503 ""
3504)
3505
3dc953f2 3506(define_insn_and_split "*arm_umaxsi3"
9c08d1fa 3507 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
3508 (umax:SI (match_operand:SI 1 "s_register_operand" "0,r,?r")
3509 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
bd5b4116 3510 (clobber (reg:CC CC_REGNUM))]
cffb2a26 3511 "TARGET_ARM"
3dc953f2 3512 "#"
3513 ; cmp\\t%1, %2\;movcc\\t%0, %2
3514 ; cmp\\t%1, %2\;movcs\\t%0, %1
3515 ; cmp\\t%1, %2\;movcs\\t%0, %1\;movcc\\t%0, %2"
3516 "TARGET_ARM"
3517 [(set (reg:CC CC_REGNUM)
3518 (compare:CC (match_dup 1) (match_dup 2)))
3519 (set (match_dup 0)
3520 (if_then_else:SI (geu:SI (reg:CC CC_REGNUM) (const_int 0))
3521 (match_dup 1)
3522 (match_dup 2)))]
3523 ""
0d66636f 3524 [(set_attr "conds" "clob")
1b7da4ac 3525 (set_attr "length" "8,8,12")
3526 (set_attr "type" "store1")]
0d66636f 3527)
9c08d1fa 3528
25f905c2 3529(define_expand "uminsi3"
3530 [(parallel [
3531 (set (match_operand:SI 0 "s_register_operand" "")
3532 (umin:SI (match_operand:SI 1 "s_register_operand" "")
3533 (match_operand:SI 2 "arm_rhs_operand" "")))
3534 (clobber (reg:CC CC_REGNUM))])]
3535 "TARGET_32BIT"
3536 ""
3537)
3538
3dc953f2 3539(define_insn_and_split "*arm_uminsi3"
9c08d1fa 3540 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
3541 (umin:SI (match_operand:SI 1 "s_register_operand" "0,r,?r")
3542 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
bd5b4116 3543 (clobber (reg:CC CC_REGNUM))]
cffb2a26 3544 "TARGET_ARM"
3dc953f2 3545 "#"
3546 ; cmp\\t%1, %2\;movcs\\t%0, %2
3547 ; cmp\\t%1, %2\;movcc\\t%0, %1
3548 ; cmp\\t%1, %2\;movcc\\t%0, %1\;movcs\\t%0, %2"
3549 "TARGET_ARM"
3550 [(set (reg:CC CC_REGNUM)
3551 (compare:CC (match_dup 1) (match_dup 2)))
3552 (set (match_dup 0)
3553 (if_then_else:SI (ltu:SI (reg:CC CC_REGNUM) (const_int 0))
3554 (match_dup 1)
3555 (match_dup 2)))]
3556 ""
0d66636f 3557 [(set_attr "conds" "clob")
1b7da4ac 3558 (set_attr "length" "8,8,12")
3559 (set_attr "type" "store1")]
0d66636f 3560)
9c08d1fa 3561
8a18b90c 3562(define_insn "*store_minmaxsi"
9c08d1fa 3563 [(set (match_operand:SI 0 "memory_operand" "=m")
3564 (match_operator:SI 3 "minmax_operator"
3565 [(match_operand:SI 1 "s_register_operand" "r")
3566 (match_operand:SI 2 "s_register_operand" "r")]))
bd5b4116 3567 (clobber (reg:CC CC_REGNUM))]
b207d152 3568 "TARGET_32BIT && optimize_function_for_size_p (cfun) && !arm_restrict_it"
9c08d1fa 3569 "*
dc55b8a9 3570 operands[3] = gen_rtx_fmt_ee (minmax_code (operands[3]), SImode,
3571 operands[1], operands[2]);
e2348bcb 3572 output_asm_insn (\"cmp\\t%1, %2\", operands);
25f905c2 3573 if (TARGET_THUMB2)
3574 output_asm_insn (\"ite\t%d3\", operands);
e2348bcb 3575 output_asm_insn (\"str%d3\\t%1, %0\", operands);
3576 output_asm_insn (\"str%D3\\t%2, %0\", operands);
3577 return \"\";
0d66636f 3578 "
3579 [(set_attr "conds" "clob")
25f905c2 3580 (set (attr "length")
3581 (if_then_else (eq_attr "is_thumb" "yes")
3582 (const_int 14)
3583 (const_int 12)))
0d66636f 3584 (set_attr "type" "store1")]
3585)
9c08d1fa 3586
8a18b90c 3587; Reject the frame pointer in operand[1], since reloading this after
3588; it has been eliminated can cause carnage.
f7fbdd4a 3589(define_insn "*minmax_arithsi"
9c08d1fa 3590 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
3591 (match_operator:SI 4 "shiftable_operator"
3592 [(match_operator:SI 5 "minmax_operator"
3593 [(match_operand:SI 2 "s_register_operand" "r,r")
3594 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
3595 (match_operand:SI 1 "s_register_operand" "0,?r")]))
bd5b4116 3596 (clobber (reg:CC CC_REGNUM))]
7c36fe71 3597 "TARGET_32BIT && !arm_eliminable_register (operands[1]) && !arm_restrict_it"
9c08d1fa 3598 "*
0d66636f 3599 {
3600 enum rtx_code code = GET_CODE (operands[4]);
25f905c2 3601 bool need_else;
3602
3603 if (which_alternative != 0 || operands[3] != const0_rtx
ca0fc5a2 3604 || (code != PLUS && code != IOR && code != XOR))
25f905c2 3605 need_else = true;
3606 else
3607 need_else = false;
0d66636f 3608
dc55b8a9 3609 operands[5] = gen_rtx_fmt_ee (minmax_code (operands[5]), SImode,
3610 operands[2], operands[3]);
0d66636f 3611 output_asm_insn (\"cmp\\t%2, %3\", operands);
25f905c2 3612 if (TARGET_THUMB2)
3613 {
3614 if (need_else)
3615 output_asm_insn (\"ite\\t%d5\", operands);
3616 else
3617 output_asm_insn (\"it\\t%d5\", operands);
3618 }
0d66636f 3619 output_asm_insn (\"%i4%d5\\t%0, %1, %2\", operands);
25f905c2 3620 if (need_else)
0d66636f 3621 output_asm_insn (\"%i4%D5\\t%0, %1, %3\", operands);
3622 return \"\";
215b30b3 3623 }"
0d66636f 3624 [(set_attr "conds" "clob")
25f905c2 3625 (set (attr "length")
3626 (if_then_else (eq_attr "is_thumb" "yes")
3627 (const_int 14)
1b7da4ac 3628 (const_int 12)))
3629 (set_attr "type" "multiple")]
0d66636f 3630)
9c08d1fa 3631
4164bca1 3632; Reject the frame pointer in operand[1], since reloading this after
3633; it has been eliminated can cause carnage.
3634(define_insn_and_split "*minmax_arithsi_non_canon"
7c36fe71 3635 [(set (match_operand:SI 0 "s_register_operand" "=Ts,Ts")
4164bca1 3636 (minus:SI
7c36fe71 3637 (match_operand:SI 1 "s_register_operand" "0,?Ts")
4164bca1 3638 (match_operator:SI 4 "minmax_operator"
7c36fe71 3639 [(match_operand:SI 2 "s_register_operand" "Ts,Ts")
3640 (match_operand:SI 3 "arm_rhs_operand" "TsI,TsI")])))
4164bca1 3641 (clobber (reg:CC CC_REGNUM))]
7c36fe71 3642 "TARGET_32BIT && !arm_eliminable_register (operands[1])
3643 && !(arm_restrict_it && CONST_INT_P (operands[3]))"
4164bca1 3644 "#"
3645 "TARGET_32BIT && !arm_eliminable_register (operands[1]) && reload_completed"
3646 [(set (reg:CC CC_REGNUM)
3647 (compare:CC (match_dup 2) (match_dup 3)))
3648
3649 (cond_exec (match_op_dup 4 [(reg:CC CC_REGNUM) (const_int 0)])
3650 (set (match_dup 0)
3651 (minus:SI (match_dup 1)
3652 (match_dup 2))))
3653 (cond_exec (match_op_dup 5 [(reg:CC CC_REGNUM) (const_int 0)])
3654 (set (match_dup 0)
36ee0cde 3655 (match_dup 6)))]
4164bca1 3656 {
3754d046 3657 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
4164bca1 3658 operands[2], operands[3]);
3659 enum rtx_code rc = minmax_code (operands[4]);
3660 operands[4] = gen_rtx_fmt_ee (rc, VOIDmode,
3661 operands[2], operands[3]);
3662
3663 if (mode == CCFPmode || mode == CCFPEmode)
3664 rc = reverse_condition_maybe_unordered (rc);
3665 else
3666 rc = reverse_condition (rc);
3667 operands[5] = gen_rtx_fmt_ee (rc, SImode, operands[2], operands[3]);
36ee0cde 3668 if (CONST_INT_P (operands[3]))
3669 operands[6] = plus_constant (SImode, operands[1], -INTVAL (operands[3]));
3670 else
3671 operands[6] = gen_rtx_MINUS (SImode, operands[1], operands[3]);
4164bca1 3672 }
3673 [(set_attr "conds" "clob")
3674 (set (attr "length")
3675 (if_then_else (eq_attr "is_thumb" "yes")
3676 (const_int 14)
1b7da4ac 3677 (const_int 12)))
3678 (set_attr "type" "multiple")]
4164bca1 3679)
3680
b49e3742 3681(define_code_iterator SAT [smin smax])
3682(define_code_iterator SATrev [smin smax])
3683(define_code_attr SATlo [(smin "1") (smax "2")])
3684(define_code_attr SAThi [(smin "2") (smax "1")])
3685
3686(define_insn "*satsi_<SAT:code>"
3687 [(set (match_operand:SI 0 "s_register_operand" "=r")
3688 (SAT:SI (SATrev:SI (match_operand:SI 3 "s_register_operand" "r")
3689 (match_operand:SI 1 "const_int_operand" "i"))
3690 (match_operand:SI 2 "const_int_operand" "i")))]
3691 "TARGET_32BIT && arm_arch6 && <SAT:CODE> != <SATrev:CODE>
3692 && arm_sat_operator_match (operands[<SAT:SATlo>], operands[<SAT:SAThi>], NULL, NULL)"
3693{
3694 int mask;
3695 bool signed_sat;
3696 if (!arm_sat_operator_match (operands[<SAT:SATlo>], operands[<SAT:SAThi>],
3697 &mask, &signed_sat))
3698 gcc_unreachable ();
3699
3700 operands[1] = GEN_INT (mask);
3701 if (signed_sat)
3702 return "ssat%?\t%0, %1, %3";
3703 else
3704 return "usat%?\t%0, %1, %3";
3705}
7c36fe71 3706 [(set_attr "predicable" "yes")
1b7da4ac 3707 (set_attr "predicable_short_it" "no")
3708 (set_attr "type" "alus_imm")]
bebe9bbb 3709)
b49e3742 3710
3711(define_insn "*satsi_<SAT:code>_shift"
3712 [(set (match_operand:SI 0 "s_register_operand" "=r")
3713 (SAT:SI (SATrev:SI (match_operator:SI 3 "sat_shift_operator"
3714 [(match_operand:SI 4 "s_register_operand" "r")
3715 (match_operand:SI 5 "const_int_operand" "i")])
3716 (match_operand:SI 1 "const_int_operand" "i"))
3717 (match_operand:SI 2 "const_int_operand" "i")))]
3718 "TARGET_32BIT && arm_arch6 && <SAT:CODE> != <SATrev:CODE>
3719 && arm_sat_operator_match (operands[<SAT:SATlo>], operands[<SAT:SAThi>], NULL, NULL)"
3720{
3721 int mask;
3722 bool signed_sat;
3723 if (!arm_sat_operator_match (operands[<SAT:SATlo>], operands[<SAT:SAThi>],
3724 &mask, &signed_sat))
3725 gcc_unreachable ();
3726
3727 operands[1] = GEN_INT (mask);
3728 if (signed_sat)
3729 return "ssat%?\t%0, %1, %4%S3";
3730 else
3731 return "usat%?\t%0, %1, %4%S3";
3732}
3733 [(set_attr "predicable" "yes")
7c36fe71 3734 (set_attr "predicable_short_it" "no")
b49e3742 3735 (set_attr "shift" "3")
d82e788e 3736 (set_attr "type" "logic_shift_reg")])
b11cae9e 3737\f
3738;; Shift and rotation insns
3739
a2cd141b 3740(define_expand "ashldi3"
3741 [(set (match_operand:DI 0 "s_register_operand" "")
3742 (ashift:DI (match_operand:DI 1 "s_register_operand" "")
aa06c51c 3743 (match_operand:SI 2 "general_operand" "")))]
25f905c2 3744 "TARGET_32BIT"
a2cd141b 3745 "
aa06c51c 3746 if (TARGET_NEON)
3747 {
3748 /* Delay the decision whether to use NEON or core-regs until
3749 register allocation. */
3750 emit_insn (gen_ashldi3_neon (operands[0], operands[1], operands[2]));
3751 DONE;
3752 }
3753 else
3754 {
3755 /* Only the NEON case can handle in-memory shift counts. */
3756 if (!reg_or_int_operand (operands[2], SImode))
3757 operands[2] = force_reg (SImode, operands[2]);
3758 }
3759
b805622c 3760 if (!CONST_INT_P (operands[2]) && TARGET_REALLY_IWMMXT)
ffcc986d 3761 ; /* No special preparation statements; expand pattern as above. */
3762 else
a2cd141b 3763 {
ffcc986d 3764 rtx scratch1, scratch2;
3765
3766 if (CONST_INT_P (operands[2])
3767 && (HOST_WIDE_INT) INTVAL (operands[2]) == 1)
a2cd141b 3768 {
3769 emit_insn (gen_arm_ashldi3_1bit (operands[0], operands[1]));
3770 DONE;
3771 }
ffcc986d 3772
3773 /* Ideally we should use iwmmxt here if we could know that operands[1]
3774 ends up already living in an iwmmxt register. Otherwise it's
3775 cheaper to have the alternate code being generated than moving
3776 values to iwmmxt regs and back. */
3777
3778 /* If we're optimizing for size, we prefer the libgcc calls. */
3779 if (optimize_function_for_size_p (cfun))
3780 FAIL;
3781
3782 /* Expand operation using core-registers.
3783 'FAIL' would achieve the same thing, but this is a bit smarter. */
3784 scratch1 = gen_reg_rtx (SImode);
3785 scratch2 = gen_reg_rtx (SImode);
3786 arm_emit_coreregs_64bit_shift (ASHIFT, operands[0], operands[1],
3787 operands[2], scratch1, scratch2);
3788 DONE;
a2cd141b 3789 }
a2cd141b 3790 "
3791)
3792
2837e3fb 3793(define_insn "arm_ashldi3_1bit"
50ad1bf9 3794 [(set (match_operand:DI 0 "s_register_operand" "=r,&r")
e5fea38e 3795 (ashift:DI (match_operand:DI 1 "s_register_operand" "0,r")
a2cd141b 3796 (const_int 1)))
3797 (clobber (reg:CC CC_REGNUM))]
25f905c2 3798 "TARGET_32BIT"
2837e3fb 3799 "movs\\t%Q0, %Q1, asl #1\;adc\\t%R0, %R1, %R1"
a2cd141b 3800 [(set_attr "conds" "clob")
1b7da4ac 3801 (set_attr "length" "8")
3802 (set_attr "type" "multiple")]
a2cd141b 3803)
3804
87b22bf7 3805(define_expand "ashlsi3"
cffb2a26 3806 [(set (match_operand:SI 0 "s_register_operand" "")
87b22bf7 3807 (ashift:SI (match_operand:SI 1 "s_register_operand" "")
3808 (match_operand:SI 2 "arm_rhs_operand" "")))]
cffb2a26 3809 "TARGET_EITHER"
87b22bf7 3810 "
0438d37f 3811 if (CONST_INT_P (operands[2])
87b22bf7 3812 && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) > 31)
3813 {
3814 emit_insn (gen_movsi (operands[0], const0_rtx));
3815 DONE;
3816 }
cffb2a26 3817 "
3818)
3819
a2cd141b 3820(define_expand "ashrdi3"
3821 [(set (match_operand:DI 0 "s_register_operand" "")
3822 (ashiftrt:DI (match_operand:DI 1 "s_register_operand" "")
3823 (match_operand:SI 2 "reg_or_int_operand" "")))]
25f905c2 3824 "TARGET_32BIT"
a2cd141b 3825 "
aa06c51c 3826 if (TARGET_NEON)
3827 {
3828 /* Delay the decision whether to use NEON or core-regs until
3829 register allocation. */
3830 emit_insn (gen_ashrdi3_neon (operands[0], operands[1], operands[2]));
3831 DONE;
3832 }
3833
b805622c 3834 if (!CONST_INT_P (operands[2]) && TARGET_REALLY_IWMMXT)
ffcc986d 3835 ; /* No special preparation statements; expand pattern as above. */
3836 else
a2cd141b 3837 {
ffcc986d 3838 rtx scratch1, scratch2;
3839
3840 if (CONST_INT_P (operands[2])
3841 && (HOST_WIDE_INT) INTVAL (operands[2]) == 1)
a2cd141b 3842 {
3843 emit_insn (gen_arm_ashrdi3_1bit (operands[0], operands[1]));
3844 DONE;
3845 }
ffcc986d 3846
3847 /* Ideally we should use iwmmxt here if we could know that operands[1]
3848 ends up already living in an iwmmxt register. Otherwise it's
3849 cheaper to have the alternate code being generated than moving
3850 values to iwmmxt regs and back. */
3851
3852 /* If we're optimizing for size, we prefer the libgcc calls. */
3853 if (optimize_function_for_size_p (cfun))
3854 FAIL;
3855
3856 /* Expand operation using core-registers.
3857 'FAIL' would achieve the same thing, but this is a bit smarter. */
3858 scratch1 = gen_reg_rtx (SImode);
3859 scratch2 = gen_reg_rtx (SImode);
3860 arm_emit_coreregs_64bit_shift (ASHIFTRT, operands[0], operands[1],
3861 operands[2], scratch1, scratch2);
3862 DONE;
a2cd141b 3863 }
a2cd141b 3864 "
3865)
3866
2837e3fb 3867(define_insn "arm_ashrdi3_1bit"
50ad1bf9 3868 [(set (match_operand:DI 0 "s_register_operand" "=r,&r")
e5fea38e 3869 (ashiftrt:DI (match_operand:DI 1 "s_register_operand" "0,r")
a2cd141b 3870 (const_int 1)))
3871 (clobber (reg:CC CC_REGNUM))]
25f905c2 3872 "TARGET_32BIT"
2837e3fb 3873 "movs\\t%R0, %R1, asr #1\;mov\\t%Q0, %Q1, rrx"
a2cd141b 3874 [(set_attr "conds" "clob")
1b7da4ac 3875 (set_attr "length" "8")
3876 (set_attr "type" "multiple")]
a2cd141b 3877)
3878
87b22bf7 3879(define_expand "ashrsi3"
cffb2a26 3880 [(set (match_operand:SI 0 "s_register_operand" "")
87b22bf7 3881 (ashiftrt:SI (match_operand:SI 1 "s_register_operand" "")
3882 (match_operand:SI 2 "arm_rhs_operand" "")))]
cffb2a26 3883 "TARGET_EITHER"
87b22bf7 3884 "
0438d37f 3885 if (CONST_INT_P (operands[2])
87b22bf7 3886 && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) > 31)
3887 operands[2] = GEN_INT (31);
cffb2a26 3888 "
3889)
3890
a2cd141b 3891(define_expand "lshrdi3"
3892 [(set (match_operand:DI 0 "s_register_operand" "")
3893 (lshiftrt:DI (match_operand:DI 1 "s_register_operand" "")
3894 (match_operand:SI 2 "reg_or_int_operand" "")))]
25f905c2 3895 "TARGET_32BIT"
a2cd141b 3896 "
aa06c51c 3897 if (TARGET_NEON)
3898 {
3899 /* Delay the decision whether to use NEON or core-regs until
3900 register allocation. */
3901 emit_insn (gen_lshrdi3_neon (operands[0], operands[1], operands[2]));
3902 DONE;
3903 }
3904
b805622c 3905 if (!CONST_INT_P (operands[2]) && TARGET_REALLY_IWMMXT)
ffcc986d 3906 ; /* No special preparation statements; expand pattern as above. */
3907 else
a2cd141b 3908 {
ffcc986d 3909 rtx scratch1, scratch2;
3910
3911 if (CONST_INT_P (operands[2])
3912 && (HOST_WIDE_INT) INTVAL (operands[2]) == 1)
a2cd141b 3913 {
3914 emit_insn (gen_arm_lshrdi3_1bit (operands[0], operands[1]));
3915 DONE;
3916 }
ffcc986d 3917
3918 /* Ideally we should use iwmmxt here if we could know that operands[1]
3919 ends up already living in an iwmmxt register. Otherwise it's
3920 cheaper to have the alternate code being generated than moving
3921 values to iwmmxt regs and back. */
3922
3923 /* If we're optimizing for size, we prefer the libgcc calls. */
3924 if (optimize_function_for_size_p (cfun))
3925 FAIL;
3926
3927 /* Expand operation using core-registers.
3928 'FAIL' would achieve the same thing, but this is a bit smarter. */
3929 scratch1 = gen_reg_rtx (SImode);
3930 scratch2 = gen_reg_rtx (SImode);
3931 arm_emit_coreregs_64bit_shift (LSHIFTRT, operands[0], operands[1],
3932 operands[2], scratch1, scratch2);
3933 DONE;
a2cd141b 3934 }
a2cd141b 3935 "
3936)
3937
2837e3fb 3938(define_insn "arm_lshrdi3_1bit"
50ad1bf9 3939 [(set (match_operand:DI 0 "s_register_operand" "=r,&r")
e5fea38e 3940 (lshiftrt:DI (match_operand:DI 1 "s_register_operand" "0,r")
a2cd141b 3941 (const_int 1)))
3942 (clobber (reg:CC CC_REGNUM))]
25f905c2 3943 "TARGET_32BIT"
2837e3fb 3944 "movs\\t%R0, %R1, lsr #1\;mov\\t%Q0, %Q1, rrx"
a2cd141b 3945 [(set_attr "conds" "clob")
1b7da4ac 3946 (set_attr "length" "8")
3947 (set_attr "type" "multiple")]
a2cd141b 3948)
3949
87b22bf7 3950(define_expand "lshrsi3"
cffb2a26 3951 [(set (match_operand:SI 0 "s_register_operand" "")
87b22bf7 3952 (lshiftrt:SI (match_operand:SI 1 "s_register_operand" "")
3953 (match_operand:SI 2 "arm_rhs_operand" "")))]
cffb2a26 3954 "TARGET_EITHER"
87b22bf7 3955 "
0438d37f 3956 if (CONST_INT_P (operands[2])
87b22bf7 3957 && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) > 31)
3958 {
3959 emit_insn (gen_movsi (operands[0], const0_rtx));
3960 DONE;
3961 }
cffb2a26 3962 "
3963)
3964
87b22bf7 3965(define_expand "rotlsi3"
cffb2a26 3966 [(set (match_operand:SI 0 "s_register_operand" "")
87b22bf7 3967 (rotatert:SI (match_operand:SI 1 "s_register_operand" "")
3968 (match_operand:SI 2 "reg_or_int_operand" "")))]
25f905c2 3969 "TARGET_32BIT"
87b22bf7 3970 "
0438d37f 3971 if (CONST_INT_P (operands[2]))
87b22bf7 3972 operands[2] = GEN_INT ((32 - INTVAL (operands[2])) % 32);
3973 else
b11cae9e 3974 {
87b22bf7 3975 rtx reg = gen_reg_rtx (SImode);
3976 emit_insn (gen_subsi3 (reg, GEN_INT (32), operands[2]));
3977 operands[2] = reg;
b11cae9e 3978 }
cffb2a26 3979 "
3980)
9c08d1fa 3981
87b22bf7 3982(define_expand "rotrsi3"
cffb2a26 3983 [(set (match_operand:SI 0 "s_register_operand" "")
87b22bf7 3984 (rotatert:SI (match_operand:SI 1 "s_register_operand" "")
3985 (match_operand:SI 2 "arm_rhs_operand" "")))]
cffb2a26 3986 "TARGET_EITHER"
87b22bf7 3987 "
25f905c2 3988 if (TARGET_32BIT)
cffb2a26 3989 {
0438d37f 3990 if (CONST_INT_P (operands[2])
cffb2a26 3991 && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) > 31)
3992 operands[2] = GEN_INT (INTVAL (operands[2]) % 32);
3993 }
25f905c2 3994 else /* TARGET_THUMB1 */
cffb2a26 3995 {
0438d37f 3996 if (CONST_INT_P (operands [2]))
cffb2a26 3997 operands [2] = force_reg (SImode, operands[2]);
3998 }
3999 "
4000)
87b22bf7 4001
cffb2a26 4002(define_insn "*arm_shiftsi3"
88c29385 4003 [(set (match_operand:SI 0 "s_register_operand" "=l,l,r,r")
cffb2a26 4004 (match_operator:SI 3 "shift_operator"
88c29385 4005 [(match_operand:SI 1 "s_register_operand" "0,l,r,r")
4006 (match_operand:SI 2 "reg_or_int_operand" "l,M,M,r")]))]
25f905c2 4007 "TARGET_32BIT"
4008 "* return arm_output_shift(operands, 0);"
344495ea 4009 [(set_attr "predicable" "yes")
88c29385 4010 (set_attr "arch" "t2,t2,*,*")
4011 (set_attr "predicable_short_it" "yes,yes,no,no")
7c36fe71 4012 (set_attr "length" "4")
331beb1a 4013 (set_attr "shift" "1")
88c29385 4014 (set_attr "type" "alu_shift_reg,alu_shift_imm,alu_shift_imm,alu_shift_reg")]
6c4c2133 4015)
87b22bf7 4016
f7fbdd4a 4017(define_insn "*shiftsi3_compare0"
bd5b4116 4018 [(set (reg:CC_NOOV CC_REGNUM)
87b22bf7 4019 (compare:CC_NOOV (match_operator:SI 3 "shift_operator"
6b6abc9c 4020 [(match_operand:SI 1 "s_register_operand" "r,r")
4021 (match_operand:SI 2 "arm_rhs_operand" "M,r")])
9c08d1fa 4022 (const_int 0)))
6b6abc9c 4023 (set (match_operand:SI 0 "s_register_operand" "=r,r")
87b22bf7 4024 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))]
25f905c2 4025 "TARGET_32BIT"
4026 "* return arm_output_shift(operands, 1);"
344495ea 4027 [(set_attr "conds" "set")
331beb1a 4028 (set_attr "shift" "1")
d82e788e 4029 (set_attr "type" "alus_shift_imm,alus_shift_reg")]
0d66636f 4030)
9c08d1fa 4031
f7fbdd4a 4032(define_insn "*shiftsi3_compare0_scratch"
bd5b4116 4033 [(set (reg:CC_NOOV CC_REGNUM)
87b22bf7 4034 (compare:CC_NOOV (match_operator:SI 3 "shift_operator"
6b6abc9c 4035 [(match_operand:SI 1 "s_register_operand" "r,r")
4036 (match_operand:SI 2 "arm_rhs_operand" "M,r")])
9c08d1fa 4037 (const_int 0)))
6b6abc9c 4038 (clobber (match_scratch:SI 0 "=r,r"))]
25f905c2 4039 "TARGET_32BIT"
4040 "* return arm_output_shift(operands, 1);"
344495ea 4041 [(set_attr "conds" "set")
6b6abc9c 4042 (set_attr "shift" "1")
d82e788e 4043 (set_attr "type" "shift_imm,shift_reg")]
0d66636f 4044)
9c08d1fa 4045
d5d4dc8d 4046(define_insn "*not_shiftsi"
4047 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
87b22bf7 4048 (not:SI (match_operator:SI 3 "shift_operator"
d5d4dc8d 4049 [(match_operand:SI 1 "s_register_operand" "r,r")
4050 (match_operand:SI 2 "shift_amount_operand" "M,rM")])))]
4051 "TARGET_32BIT"
6c4c2133 4052 "mvn%?\\t%0, %1%S3"
344495ea 4053 [(set_attr "predicable" "yes")
d952d547 4054 (set_attr "predicable_short_it" "no")
331beb1a 4055 (set_attr "shift" "1")
d5d4dc8d 4056 (set_attr "arch" "32,a")
1aed5204 4057 (set_attr "type" "mvn_shift,mvn_shift_reg")])
9c08d1fa 4058
d5d4dc8d 4059(define_insn "*not_shiftsi_compare0"
bd5b4116 4060 [(set (reg:CC_NOOV CC_REGNUM)
d5d4dc8d 4061 (compare:CC_NOOV
4062 (not:SI (match_operator:SI 3 "shift_operator"
4063 [(match_operand:SI 1 "s_register_operand" "r,r")
4064 (match_operand:SI 2 "shift_amount_operand" "M,rM")]))
4065 (const_int 0)))
4066 (set (match_operand:SI 0 "s_register_operand" "=r,r")
87b22bf7 4067 (not:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)])))]
d5d4dc8d 4068 "TARGET_32BIT"
25f905c2 4069 "mvn%.\\t%0, %1%S3"
344495ea 4070 [(set_attr "conds" "set")
331beb1a 4071 (set_attr "shift" "1")
d5d4dc8d 4072 (set_attr "arch" "32,a")
1aed5204 4073 (set_attr "type" "mvn_shift,mvn_shift_reg")])
9c08d1fa 4074
d5d4dc8d 4075(define_insn "*not_shiftsi_compare0_scratch"
bd5b4116 4076 [(set (reg:CC_NOOV CC_REGNUM)
d5d4dc8d 4077 (compare:CC_NOOV
4078 (not:SI (match_operator:SI 3 "shift_operator"
4079 [(match_operand:SI 1 "s_register_operand" "r,r")
4080 (match_operand:SI 2 "shift_amount_operand" "M,rM")]))
4081 (const_int 0)))
4082 (clobber (match_scratch:SI 0 "=r,r"))]
4083 "TARGET_32BIT"
25f905c2 4084 "mvn%.\\t%0, %1%S3"
344495ea 4085 [(set_attr "conds" "set")
331beb1a 4086 (set_attr "shift" "1")
d5d4dc8d 4087 (set_attr "arch" "32,a")
1aed5204 4088 (set_attr "type" "mvn_shift,mvn_shift_reg")])
9c08d1fa 4089
cffb2a26 4090;; We don't really have extzv, but defining this using shifts helps
4091;; to reduce register pressure later on.
4092
4093(define_expand "extzv"
eb04cafb 4094 [(set (match_operand 0 "s_register_operand" "")
4095 (zero_extract (match_operand 1 "nonimmediate_operand" "")
4096 (match_operand 2 "const_int_operand" "")
4097 (match_operand 3 "const_int_operand" "")))]
8b054d5a 4098 "TARGET_THUMB1 || arm_arch_thumb2"
cffb2a26 4099 "
4100 {
4101 HOST_WIDE_INT lshift = 32 - INTVAL (operands[2]) - INTVAL (operands[3]);
4102 HOST_WIDE_INT rshift = 32 - INTVAL (operands[2]);
4103
8b054d5a 4104 if (arm_arch_thumb2)
4105 {
eb04cafb 4106 HOST_WIDE_INT width = INTVAL (operands[2]);
4107 HOST_WIDE_INT bitpos = INTVAL (operands[3]);
4108
4109 if (unaligned_access && MEM_P (operands[1])
4110 && (width == 16 || width == 32) && (bitpos % BITS_PER_UNIT) == 0)
4111 {
4112 rtx base_addr;
4113
4114 if (BYTES_BIG_ENDIAN)
4115 bitpos = GET_MODE_BITSIZE (GET_MODE (operands[0])) - width
4116 - bitpos;
4117
4118 if (width == 32)
4119 {
4120 base_addr = adjust_address (operands[1], SImode,
4121 bitpos / BITS_PER_UNIT);
4122 emit_insn (gen_unaligned_loadsi (operands[0], base_addr));
4123 }
4124 else
4125 {
4126 rtx dest = operands[0];
4127 rtx tmp = gen_reg_rtx (SImode);
4128
4129 /* We may get a paradoxical subreg here. Strip it off. */
4130 if (GET_CODE (dest) == SUBREG
4131 && GET_MODE (dest) == SImode
4132 && GET_MODE (SUBREG_REG (dest)) == HImode)
4133 dest = SUBREG_REG (dest);
4134
4135 if (GET_MODE_BITSIZE (GET_MODE (dest)) != width)
4136 FAIL;
4137
4138 base_addr = adjust_address (operands[1], HImode,
4139 bitpos / BITS_PER_UNIT);
4140 emit_insn (gen_unaligned_loadhiu (tmp, base_addr));
4141 emit_move_insn (gen_lowpart (SImode, dest), tmp);
4142 }
4143 DONE;
4144 }
4145 else if (s_register_operand (operands[1], GET_MODE (operands[1])))
4146 {
4147 emit_insn (gen_extzv_t2 (operands[0], operands[1], operands[2],
4148 operands[3]));
4149 DONE;
4150 }
4151 else
4152 FAIL;
8b054d5a 4153 }
eb04cafb 4154
4155 if (!s_register_operand (operands[1], GET_MODE (operands[1])))
4156 FAIL;
8b054d5a 4157
cffb2a26 4158 operands[3] = GEN_INT (rshift);
4159
4160 if (lshift == 0)
4161 {
4162 emit_insn (gen_lshrsi3 (operands[0], operands[1], operands[3]));
4163 DONE;
4164 }
4165
eb04cafb 4166 emit_insn (gen_extzv_t1 (operands[0], operands[1], GEN_INT (lshift),
4167 operands[3], gen_reg_rtx (SImode)));
4168 DONE;
215b30b3 4169 }"
cffb2a26 4170)
4171
eb04cafb 4172;; Helper for extzv, for the Thumb-1 register-shifts case.
4173
4174(define_expand "extzv_t1"
4175 [(set (match_operand:SI 4 "s_register_operand" "")
4176 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
4177 (match_operand:SI 2 "const_int_operand" "")))
4178 (set (match_operand:SI 0 "s_register_operand" "")
4179 (lshiftrt:SI (match_dup 4)
4180 (match_operand:SI 3 "const_int_operand" "")))]
4181 "TARGET_THUMB1"
4182 "")
4183
4184(define_expand "extv"
4185 [(set (match_operand 0 "s_register_operand" "")
4186 (sign_extract (match_operand 1 "nonimmediate_operand" "")
4187 (match_operand 2 "const_int_operand" "")
4188 (match_operand 3 "const_int_operand" "")))]
4189 "arm_arch_thumb2"
4190{
4191 HOST_WIDE_INT width = INTVAL (operands[2]);
4192 HOST_WIDE_INT bitpos = INTVAL (operands[3]);
4193
4194 if (unaligned_access && MEM_P (operands[1]) && (width == 16 || width == 32)
4195 && (bitpos % BITS_PER_UNIT) == 0)
4196 {
4197 rtx base_addr;
4198
4199 if (BYTES_BIG_ENDIAN)
4200 bitpos = GET_MODE_BITSIZE (GET_MODE (operands[0])) - width - bitpos;
4201
4202 if (width == 32)
4203 {
4204 base_addr = adjust_address (operands[1], SImode,
4205 bitpos / BITS_PER_UNIT);
4206 emit_insn (gen_unaligned_loadsi (operands[0], base_addr));
4207 }
4208 else
4209 {
4210 rtx dest = operands[0];
4211 rtx tmp = gen_reg_rtx (SImode);
4212
4213 /* We may get a paradoxical subreg here. Strip it off. */
4214 if (GET_CODE (dest) == SUBREG
4215 && GET_MODE (dest) == SImode
4216 && GET_MODE (SUBREG_REG (dest)) == HImode)
4217 dest = SUBREG_REG (dest);
4218
4219 if (GET_MODE_BITSIZE (GET_MODE (dest)) != width)
4220 FAIL;
4221
4222 base_addr = adjust_address (operands[1], HImode,
4223 bitpos / BITS_PER_UNIT);
4224 emit_insn (gen_unaligned_loadhis (tmp, base_addr));
4225 emit_move_insn (gen_lowpart (SImode, dest), tmp);
4226 }
4227
4228 DONE;
4229 }
4230 else if (!s_register_operand (operands[1], GET_MODE (operands[1])))
4231 FAIL;
4232 else if (GET_MODE (operands[0]) == SImode
4233 && GET_MODE (operands[1]) == SImode)
4234 {
4235 emit_insn (gen_extv_regsi (operands[0], operands[1], operands[2],
4236 operands[3]));
4237 DONE;
4238 }
4239
4240 FAIL;
4241})
4242
4243; Helper to expand register forms of extv with the proper modes.
4244
4245(define_expand "extv_regsi"
4246 [(set (match_operand:SI 0 "s_register_operand" "")
4247 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "")
4248 (match_operand 2 "const_int_operand" "")
4249 (match_operand 3 "const_int_operand" "")))]
4250 ""
4251{
4252})
4253
4254; ARMv6+ unaligned load/store instructions (used for packed structure accesses).
4255
4256(define_insn "unaligned_loadsi"
4257 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
4258 (unspec:SI [(match_operand:SI 1 "memory_operand" "Uw,m")]
4259 UNSPEC_UNALIGNED_LOAD))]
4260 "unaligned_access && TARGET_32BIT"
4261 "ldr%?\t%0, %1\t@ unaligned"
4262 [(set_attr "arch" "t2,any")
4263 (set_attr "length" "2,4")
4264 (set_attr "predicable" "yes")
d952d547 4265 (set_attr "predicable_short_it" "yes,no")
eb04cafb 4266 (set_attr "type" "load1")])
4267
4268(define_insn "unaligned_loadhis"
4269 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
4270 (sign_extend:SI
e3f4ccee 4271 (unspec:HI [(match_operand:HI 1 "memory_operand" "Uw,Uh")]
eb04cafb 4272 UNSPEC_UNALIGNED_LOAD)))]
4273 "unaligned_access && TARGET_32BIT"
4274 "ldr%(sh%)\t%0, %1\t@ unaligned"
4275 [(set_attr "arch" "t2,any")
4276 (set_attr "length" "2,4")
4277 (set_attr "predicable" "yes")
d952d547 4278 (set_attr "predicable_short_it" "yes,no")
eb04cafb 4279 (set_attr "type" "load_byte")])
4280
4281(define_insn "unaligned_loadhiu"
4282 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
4283 (zero_extend:SI
4284 (unspec:HI [(match_operand:HI 1 "memory_operand" "Uw,m")]
4285 UNSPEC_UNALIGNED_LOAD)))]
4286 "unaligned_access && TARGET_32BIT"
4287 "ldr%(h%)\t%0, %1\t@ unaligned"
4288 [(set_attr "arch" "t2,any")
4289 (set_attr "length" "2,4")
4290 (set_attr "predicable" "yes")
d952d547 4291 (set_attr "predicable_short_it" "yes,no")
eb04cafb 4292 (set_attr "type" "load_byte")])
4293
4294(define_insn "unaligned_storesi"
4295 [(set (match_operand:SI 0 "memory_operand" "=Uw,m")
4296 (unspec:SI [(match_operand:SI 1 "s_register_operand" "l,r")]
4297 UNSPEC_UNALIGNED_STORE))]
4298 "unaligned_access && TARGET_32BIT"
4299 "str%?\t%1, %0\t@ unaligned"
4300 [(set_attr "arch" "t2,any")
4301 (set_attr "length" "2,4")
4302 (set_attr "predicable" "yes")
d952d547 4303 (set_attr "predicable_short_it" "yes,no")
eb04cafb 4304 (set_attr "type" "store1")])
4305
4306(define_insn "unaligned_storehi"
4307 [(set (match_operand:HI 0 "memory_operand" "=Uw,m")
4308 (unspec:HI [(match_operand:HI 1 "s_register_operand" "l,r")]
4309 UNSPEC_UNALIGNED_STORE))]
4310 "unaligned_access && TARGET_32BIT"
4311 "str%(h%)\t%1, %0\t@ unaligned"
4312 [(set_attr "arch" "t2,any")
4313 (set_attr "length" "2,4")
4314 (set_attr "predicable" "yes")
d952d547 4315 (set_attr "predicable_short_it" "yes,no")
eb04cafb 4316 (set_attr "type" "store1")])
4317
ae51a965 4318;; Unaligned double-word load and store.
4319;; Split after reload into two unaligned single-word accesses.
4320;; It prevents lower_subreg from splitting some other aligned
4321;; double-word accesses too early. Used for internal memcpy.
4322
4323(define_insn_and_split "unaligned_loaddi"
4324 [(set (match_operand:DI 0 "s_register_operand" "=l,r")
4325 (unspec:DI [(match_operand:DI 1 "memory_operand" "o,o")]
4326 UNSPEC_UNALIGNED_LOAD))]
4327 "unaligned_access && TARGET_32BIT"
4328 "#"
4329 "&& reload_completed"
4330 [(set (match_dup 0) (unspec:SI [(match_dup 1)] UNSPEC_UNALIGNED_LOAD))
4331 (set (match_dup 2) (unspec:SI [(match_dup 3)] UNSPEC_UNALIGNED_LOAD))]
4332 {
4333 operands[2] = gen_highpart (SImode, operands[0]);
4334 operands[0] = gen_lowpart (SImode, operands[0]);
4335 operands[3] = gen_highpart (SImode, operands[1]);
4336 operands[1] = gen_lowpart (SImode, operands[1]);
4337
4338 /* If the first destination register overlaps with the base address,
4339 swap the order in which the loads are emitted. */
4340 if (reg_overlap_mentioned_p (operands[0], operands[1]))
4341 {
f145bcba 4342 std::swap (operands[1], operands[3]);
4343 std::swap (operands[0], operands[2]);
ae51a965 4344 }
4345 }
4346 [(set_attr "arch" "t2,any")
4347 (set_attr "length" "4,8")
4348 (set_attr "predicable" "yes")
4349 (set_attr "type" "load2")])
4350
4351(define_insn_and_split "unaligned_storedi"
4352 [(set (match_operand:DI 0 "memory_operand" "=o,o")
4353 (unspec:DI [(match_operand:DI 1 "s_register_operand" "l,r")]
4354 UNSPEC_UNALIGNED_STORE))]
4355 "unaligned_access && TARGET_32BIT"
4356 "#"
4357 "&& reload_completed"
4358 [(set (match_dup 0) (unspec:SI [(match_dup 1)] UNSPEC_UNALIGNED_STORE))
4359 (set (match_dup 2) (unspec:SI [(match_dup 3)] UNSPEC_UNALIGNED_STORE))]
4360 {
4361 operands[2] = gen_highpart (SImode, operands[0]);
4362 operands[0] = gen_lowpart (SImode, operands[0]);
4363 operands[3] = gen_highpart (SImode, operands[1]);
4364 operands[1] = gen_lowpart (SImode, operands[1]);
4365 }
4366 [(set_attr "arch" "t2,any")
4367 (set_attr "length" "4,8")
4368 (set_attr "predicable" "yes")
4369 (set_attr "type" "store2")])
4370
4371
eb04cafb 4372(define_insn "*extv_reg"
8b054d5a 4373 [(set (match_operand:SI 0 "s_register_operand" "=r")
4374 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
809003b3 4375 (match_operand:SI 2 "const_int_M_operand" "M")
4376 (match_operand:SI 3 "const_int_M_operand" "M")))]
8b054d5a 4377 "arm_arch_thumb2"
4378 "sbfx%?\t%0, %1, %3, %2"
4379 [(set_attr "length" "4")
d952d547 4380 (set_attr "predicable" "yes")
d82e788e 4381 (set_attr "predicable_short_it" "no")
4382 (set_attr "type" "bfm")]
8b054d5a 4383)
4384
4385(define_insn "extzv_t2"
4386 [(set (match_operand:SI 0 "s_register_operand" "=r")
4387 (zero_extract:SI (match_operand:SI 1 "s_register_operand" "r")
809003b3 4388 (match_operand:SI 2 "const_int_M_operand" "M")
4389 (match_operand:SI 3 "const_int_M_operand" "M")))]
8b054d5a 4390 "arm_arch_thumb2"
4391 "ubfx%?\t%0, %1, %3, %2"
4392 [(set_attr "length" "4")
d952d547 4393 (set_attr "predicable" "yes")
d82e788e 4394 (set_attr "predicable_short_it" "no")
4395 (set_attr "type" "bfm")]
8b054d5a 4396)
4397
7d3cda8c 4398
4399;; Division instructions
4400(define_insn "divsi3"
4401 [(set (match_operand:SI 0 "s_register_operand" "=r")
4402 (div:SI (match_operand:SI 1 "s_register_operand" "r")
4403 (match_operand:SI 2 "s_register_operand" "r")))]
4404 "TARGET_IDIV"
4405 "sdiv%?\t%0, %1, %2"
4406 [(set_attr "predicable" "yes")
d952d547 4407 (set_attr "predicable_short_it" "no")
9da0ec36 4408 (set_attr "type" "sdiv")]
7d3cda8c 4409)
4410
4411(define_insn "udivsi3"
4412 [(set (match_operand:SI 0 "s_register_operand" "=r")
4413 (udiv:SI (match_operand:SI 1 "s_register_operand" "r")
4414 (match_operand:SI 2 "s_register_operand" "r")))]
4415 "TARGET_IDIV"
4416 "udiv%?\t%0, %1, %2"
4417 [(set_attr "predicable" "yes")
d952d547 4418 (set_attr "predicable_short_it" "no")
9da0ec36 4419 (set_attr "type" "udiv")]
7d3cda8c 4420)
4421
b11cae9e 4422\f
4423;; Unary arithmetic insns
4424
cffb2a26 4425(define_expand "negdi2"
4426 [(parallel
8135a42b 4427 [(set (match_operand:DI 0 "s_register_operand" "")
4428 (neg:DI (match_operand:DI 1 "s_register_operand" "")))
bd5b4116 4429 (clobber (reg:CC CC_REGNUM))])]
cffb2a26 4430 "TARGET_EITHER"
774d2fbb 4431 {
4432 if (TARGET_NEON)
4433 {
4434 emit_insn (gen_negdi2_neon (operands[0], operands[1]));
4435 DONE;
4436 }
4437 }
cffb2a26 4438)
4439
4440;; The constraints here are to prevent a *partial* overlap (where %Q0 == %R1).
e5fea38e 4441;; The first alternative allows the common case of a *full* overlap.
ba6a3b2f 4442(define_insn_and_split "*arm_negdi2"
458a8706 4443 [(set (match_operand:DI 0 "s_register_operand" "=r,&r")
e5fea38e 4444 (neg:DI (match_operand:DI 1 "s_register_operand" "0,r")))
bd5b4116 4445 (clobber (reg:CC CC_REGNUM))]
cffb2a26 4446 "TARGET_ARM"
ba6a3b2f 4447 "#" ; "rsbs\\t%Q0, %Q1, #0\;rsc\\t%R0, %R1, #0"
4448 "&& reload_completed"
4449 [(parallel [(set (reg:CC CC_REGNUM)
4450 (compare:CC (const_int 0) (match_dup 1)))
4451 (set (match_dup 0) (minus:SI (const_int 0) (match_dup 1)))])
4452 (set (match_dup 2) (minus:SI (minus:SI (const_int 0) (match_dup 3))
4453 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
4454 {
4455 operands[2] = gen_highpart (SImode, operands[0]);
4456 operands[0] = gen_lowpart (SImode, operands[0]);
4457 operands[3] = gen_highpart (SImode, operands[1]);
4458 operands[1] = gen_lowpart (SImode, operands[1]);
4459 }
cffb2a26 4460 [(set_attr "conds" "clob")
1b7da4ac 4461 (set_attr "length" "8")
4462 (set_attr "type" "multiple")]
cffb2a26 4463)
b11cae9e 4464
cffb2a26 4465(define_expand "negsi2"
4466 [(set (match_operand:SI 0 "s_register_operand" "")
4467 (neg:SI (match_operand:SI 1 "s_register_operand" "")))]
4468 "TARGET_EITHER"
b11cae9e 4469 ""
cffb2a26 4470)
4471
4472(define_insn "*arm_negsi2"
d952d547 4473 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
4474 (neg:SI (match_operand:SI 1 "s_register_operand" "l,r")))]
25f905c2 4475 "TARGET_32BIT"
cffb2a26 4476 "rsb%?\\t%0, %1, #0"
d952d547 4477 [(set_attr "predicable" "yes")
4478 (set_attr "predicable_short_it" "yes,no")
4479 (set_attr "arch" "t2,*")
1b7da4ac 4480 (set_attr "length" "4")
112eda6f 4481 (set_attr "type" "alu_sreg")]
cffb2a26 4482)
4483
604f3a0a 4484(define_expand "negsf2"
4485 [(set (match_operand:SF 0 "s_register_operand" "")
4486 (neg:SF (match_operand:SF 1 "s_register_operand" "")))]
994606f8 4487 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
604f3a0a 4488 ""
4489)
4490
4491(define_expand "negdf2"
4492 [(set (match_operand:DF 0 "s_register_operand" "")
4493 (neg:DF (match_operand:DF 1 "s_register_operand" "")))]
994606f8 4494 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
604f3a0a 4495 "")
4496
7eaf2be0 4497(define_insn_and_split "*zextendsidi_negsi"
4498 [(set (match_operand:DI 0 "s_register_operand" "=r")
4499 (zero_extend:DI (neg:SI (match_operand:SI 1 "s_register_operand" "r"))))]
4500 "TARGET_32BIT"
4501 "#"
4502 ""
4503 [(set (match_dup 2)
4504 (neg:SI (match_dup 1)))
4505 (set (match_dup 3)
4506 (const_int 0))]
4507 {
4508 operands[2] = gen_lowpart (SImode, operands[0]);
4509 operands[3] = gen_highpart (SImode, operands[0]);
4510 }
4511 [(set_attr "length" "8")
4512 (set_attr "type" "multiple")]
4513)
4514
83e2b922 4515;; Negate an extended 32-bit value.
4516(define_insn_and_split "*negdi_extendsidi"
61fa8ff2 4517 [(set (match_operand:DI 0 "s_register_operand" "=l,r")
4518 (neg:DI (sign_extend:DI
4519 (match_operand:SI 1 "s_register_operand" "l,r"))))
83e2b922 4520 (clobber (reg:CC CC_REGNUM))]
4521 "TARGET_32BIT"
61fa8ff2 4522 "#"
83e2b922 4523 "&& reload_completed"
4524 [(const_int 0)]
4525 {
61fa8ff2 4526 rtx low = gen_lowpart (SImode, operands[0]);
4527 rtx high = gen_highpart (SImode, operands[0]);
4528
4529 if (reg_overlap_mentioned_p (low, operands[1]))
4530 {
4531 /* Input overlaps the low word of the output. Use:
4532 asr Rhi, Rin, #31
4533 rsbs Rlo, Rin, #0
4534 rsc Rhi, Rhi, #0 (thumb2: sbc Rhi, Rhi, Rhi, lsl #1). */
4535 rtx cc_reg = gen_rtx_REG (CC_Cmode, CC_REGNUM);
4536
d1f9b275 4537 emit_insn (gen_rtx_SET (high,
61fa8ff2 4538 gen_rtx_ASHIFTRT (SImode, operands[1],
4539 GEN_INT (31))));
4540
4541 emit_insn (gen_subsi3_compare (low, const0_rtx, operands[1]));
4542 if (TARGET_ARM)
d1f9b275 4543 emit_insn (gen_rtx_SET (high,
61fa8ff2 4544 gen_rtx_MINUS (SImode,
4545 gen_rtx_MINUS (SImode,
4546 const0_rtx,
4547 high),
4548 gen_rtx_LTU (SImode,
4549 cc_reg,
4550 const0_rtx))));
4551 else
4552 {
4553 rtx two_x = gen_rtx_ASHIFT (SImode, high, GEN_INT (1));
d1f9b275 4554 emit_insn (gen_rtx_SET (high,
61fa8ff2 4555 gen_rtx_MINUS (SImode,
4556 gen_rtx_MINUS (SImode,
4557 high,
4558 two_x),
4559 gen_rtx_LTU (SImode,
4560 cc_reg,
4561 const0_rtx))));
4562 }
4563 }
4564 else
4565 {
4566 /* No overlap, or overlap on high word. Use:
4567 rsb Rlo, Rin, #0
4568 bic Rhi, Rlo, Rin
4569 asr Rhi, Rhi, #31
4570 Flags not needed for this sequence. */
d1f9b275 4571 emit_insn (gen_rtx_SET (low, gen_rtx_NEG (SImode, operands[1])));
4572 emit_insn (gen_rtx_SET (high,
61fa8ff2 4573 gen_rtx_AND (SImode,
4574 gen_rtx_NOT (SImode, operands[1]),
4575 low)));
d1f9b275 4576 emit_insn (gen_rtx_SET (high,
61fa8ff2 4577 gen_rtx_ASHIFTRT (SImode, high,
4578 GEN_INT (31))));
4579 }
4580 DONE;
83e2b922 4581 }
61fa8ff2 4582 [(set_attr "length" "12")
4583 (set_attr "arch" "t2,*")
1b7da4ac 4584 (set_attr "type" "multiple")]
83e2b922 4585)
4586
4587(define_insn_and_split "*negdi_zero_extendsidi"
4588 [(set (match_operand:DI 0 "s_register_operand" "=r,&r")
4589 (neg:DI (zero_extend:DI (match_operand:SI 1 "s_register_operand" "0,r"))))
4590 (clobber (reg:CC CC_REGNUM))]
4591 "TARGET_32BIT"
4592 "#" ; "rsbs\\t%Q0, %1, #0\;sbc\\t%R0,%R0,%R0"
4593 ;; Don't care what register is input to sbc,
47ae02b7 4594 ;; since we just need to propagate the carry.
83e2b922 4595 "&& reload_completed"
4596 [(parallel [(set (reg:CC CC_REGNUM)
4597 (compare:CC (const_int 0) (match_dup 1)))
4598 (set (match_dup 0) (minus:SI (const_int 0) (match_dup 1)))])
4599 (set (match_dup 2) (minus:SI (minus:SI (match_dup 2) (match_dup 2))
4600 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
4601 {
4602 operands[2] = gen_highpart (SImode, operands[0]);
4603 operands[0] = gen_lowpart (SImode, operands[0]);
4604 }
4605 [(set_attr "conds" "clob")
1b7da4ac 4606 (set_attr "length" "8")
4607 (set_attr "type" "multiple")] ;; length in thumb is 4
83e2b922 4608)
4609
9c08d1fa 4610;; abssi2 doesn't really clobber the condition codes if a different register
4611;; is being set. To keep things simple, assume during rtl manipulations that
4612;; it does, but tell the final scan operator the truth. Similarly for
4613;; (neg (abs...))
4614
604f3a0a 4615(define_expand "abssi2"
4616 [(parallel
4617 [(set (match_operand:SI 0 "s_register_operand" "")
4618 (abs:SI (match_operand:SI 1 "s_register_operand" "")))
ba156559 4619 (clobber (match_dup 2))])]
4620 "TARGET_EITHER"
4621 "
25f905c2 4622 if (TARGET_THUMB1)
ba156559 4623 operands[2] = gen_rtx_SCRATCH (SImode);
4624 else
4625 operands[2] = gen_rtx_REG (CCmode, CC_REGNUM);
4626")
604f3a0a 4627
ba6a3b2f 4628(define_insn_and_split "*arm_abssi2"
ba156559 4629 [(set (match_operand:SI 0 "s_register_operand" "=r,&r")
9c08d1fa 4630 (abs:SI (match_operand:SI 1 "s_register_operand" "0,r")))
bd5b4116 4631 (clobber (reg:CC CC_REGNUM))]
cffb2a26 4632 "TARGET_ARM"
ba6a3b2f 4633 "#"
4634 "&& reload_completed"
4635 [(const_int 0)]
4636 {
4637 /* if (which_alternative == 0) */
4638 if (REGNO(operands[0]) == REGNO(operands[1]))
4639 {
4640 /* Emit the pattern:
4641 cmp\\t%0, #0\;rsblt\\t%0, %0, #0
4642 [(set (reg:CC CC_REGNUM)
4643 (compare:CC (match_dup 0) (const_int 0)))
4644 (cond_exec (lt:CC (reg:CC CC_REGNUM) (const_int 0))
4645 (set (match_dup 0) (minus:SI (const_int 0) (match_dup 1))))]
4646 */
d1f9b275 4647 emit_insn (gen_rtx_SET (gen_rtx_REG (CCmode, CC_REGNUM),
ba6a3b2f 4648 gen_rtx_COMPARE (CCmode, operands[0], const0_rtx)));
4649 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
4650 (gen_rtx_LT (SImode,
4651 gen_rtx_REG (CCmode, CC_REGNUM),
4652 const0_rtx)),
d1f9b275 4653 (gen_rtx_SET (operands[0],
ba6a3b2f 4654 (gen_rtx_MINUS (SImode,
4655 const0_rtx,
4656 operands[1]))))));
4657 DONE;
4658 }
4659 else
4660 {
4661 /* Emit the pattern:
4662 alt1: eor%?\\t%0, %1, %1, asr #31\;sub%?\\t%0, %0, %1, asr #31
4663 [(set (match_dup 0)
4664 (xor:SI (match_dup 1)
4665 (ashiftrt:SI (match_dup 1) (const_int 31))))
4666 (set (match_dup 0)
4667 (minus:SI (match_dup 0)
4668 (ashiftrt:SI (match_dup 1) (const_int 31))))]
4669 */
d1f9b275 4670 emit_insn (gen_rtx_SET (operands[0],
ba6a3b2f 4671 gen_rtx_XOR (SImode,
4672 gen_rtx_ASHIFTRT (SImode,
4673 operands[1],
4674 GEN_INT (31)),
4675 operands[1])));
d1f9b275 4676 emit_insn (gen_rtx_SET (operands[0],
ba6a3b2f 4677 gen_rtx_MINUS (SImode,
4678 operands[0],
4679 gen_rtx_ASHIFTRT (SImode,
4680 operands[1],
4681 GEN_INT (31)))));
4682 DONE;
4683 }
4684 }
cffb2a26 4685 [(set_attr "conds" "clob,*")
331beb1a 4686 (set_attr "shift" "1")
2ad08b65 4687 (set_attr "predicable" "no, yes")
1b7da4ac 4688 (set_attr "length" "8")
4689 (set_attr "type" "multiple")]
cffb2a26 4690)
9c08d1fa 4691
ba6a3b2f 4692(define_insn_and_split "*arm_neg_abssi2"
9c08d1fa 4693 [(set (match_operand:SI 0 "s_register_operand" "=r,&r")
4694 (neg:SI (abs:SI (match_operand:SI 1 "s_register_operand" "0,r"))))
bd5b4116 4695 (clobber (reg:CC CC_REGNUM))]
cffb2a26 4696 "TARGET_ARM"
ba6a3b2f 4697 "#"
4698 "&& reload_completed"
4699 [(const_int 0)]
4700 {
4701 /* if (which_alternative == 0) */
4702 if (REGNO (operands[0]) == REGNO (operands[1]))
4703 {
4704 /* Emit the pattern:
4705 cmp\\t%0, #0\;rsbgt\\t%0, %0, #0
4706 */
d1f9b275 4707 emit_insn (gen_rtx_SET (gen_rtx_REG (CCmode, CC_REGNUM),
ba6a3b2f 4708 gen_rtx_COMPARE (CCmode, operands[0], const0_rtx)));
4709 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
4710 gen_rtx_GT (SImode,
4711 gen_rtx_REG (CCmode, CC_REGNUM),
4712 const0_rtx),
d1f9b275 4713 gen_rtx_SET (operands[0],
ba6a3b2f 4714 (gen_rtx_MINUS (SImode,
4715 const0_rtx,
4716 operands[1])))));
4717 }
4718 else
4719 {
4720 /* Emit the pattern:
4721 eor%?\\t%0, %1, %1, asr #31\;rsb%?\\t%0, %0, %1, asr #31
4722 */
d1f9b275 4723 emit_insn (gen_rtx_SET (operands[0],
ba6a3b2f 4724 gen_rtx_XOR (SImode,
4725 gen_rtx_ASHIFTRT (SImode,
4726 operands[1],
4727 GEN_INT (31)),
4728 operands[1])));
d1f9b275 4729 emit_insn (gen_rtx_SET (operands[0],
ba6a3b2f 4730 gen_rtx_MINUS (SImode,
4731 gen_rtx_ASHIFTRT (SImode,
4732 operands[1],
4733 GEN_INT (31)),
4734 operands[0])));
4735 }
4736 DONE;
4737 }
cffb2a26 4738 [(set_attr "conds" "clob,*")
331beb1a 4739 (set_attr "shift" "1")
2ad08b65 4740 (set_attr "predicable" "no, yes")
1b7da4ac 4741 (set_attr "length" "8")
4742 (set_attr "type" "multiple")]
cffb2a26 4743)
b11cae9e 4744
604f3a0a 4745(define_expand "abssf2"
4746 [(set (match_operand:SF 0 "s_register_operand" "")
4747 (abs:SF (match_operand:SF 1 "s_register_operand" "")))]
25f905c2 4748 "TARGET_32BIT && TARGET_HARD_FLOAT"
604f3a0a 4749 "")
4750
604f3a0a 4751(define_expand "absdf2"
4752 [(set (match_operand:DF 0 "s_register_operand" "")
4753 (abs:DF (match_operand:DF 1 "s_register_operand" "")))]
a50d7267 4754 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
604f3a0a 4755 "")
4756
7db9af5d 4757(define_expand "sqrtsf2"
4758 [(set (match_operand:SF 0 "s_register_operand" "")
4759 (sqrt:SF (match_operand:SF 1 "s_register_operand" "")))]
994606f8 4760 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
7db9af5d 4761 "")
9c08d1fa 4762
7db9af5d 4763(define_expand "sqrtdf2"
4764 [(set (match_operand:DF 0 "s_register_operand" "")
4765 (sqrt:DF (match_operand:DF 1 "s_register_operand" "")))]
994606f8 4766 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
7db9af5d 4767 "")
9c08d1fa 4768
a0f94409 4769(define_insn_and_split "one_cmpldi2"
10efb95f 4770 [(set (match_operand:DI 0 "s_register_operand" "=w,&r,&r,?w")
4771 (not:DI (match_operand:DI 1 "s_register_operand" " w, 0, r, w")))]
25f905c2 4772 "TARGET_32BIT"
10efb95f 4773 "@
4774 vmvn\t%P0, %P1
4775 #
4776 #
4777 vmvn\t%P0, %P1"
4778 "TARGET_32BIT && reload_completed
4779 && arm_general_register_operand (operands[0], DImode)"
a0f94409 4780 [(set (match_dup 0) (not:SI (match_dup 1)))
4781 (set (match_dup 2) (not:SI (match_dup 3)))]
4782 "
4783 {
4784 operands[2] = gen_highpart (SImode, operands[0]);
4785 operands[0] = gen_lowpart (SImode, operands[0]);
4786 operands[3] = gen_highpart (SImode, operands[1]);
4787 operands[1] = gen_lowpart (SImode, operands[1]);
4788 }"
10efb95f 4789 [(set_attr "length" "*,8,8,*")
4790 (set_attr "predicable" "no,yes,yes,no")
32093010 4791 (set_attr "type" "neon_move,multiple,multiple,neon_move")
b6779ddc 4792 (set_attr "arch" "neon_for_64bits,*,*,avoid_neon_for_64bits")]
cffb2a26 4793)
b11cae9e 4794
cffb2a26 4795(define_expand "one_cmplsi2"
4796 [(set (match_operand:SI 0 "s_register_operand" "")
4797 (not:SI (match_operand:SI 1 "s_register_operand" "")))]
4798 "TARGET_EITHER"
b11cae9e 4799 ""
cffb2a26 4800)
4801
4802(define_insn "*arm_one_cmplsi2"
d952d547 4803 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
4804 (not:SI (match_operand:SI 1 "s_register_operand" "l,r")))]
25f905c2 4805 "TARGET_32BIT"
cffb2a26 4806 "mvn%?\\t%0, %1"
d2a518d1 4807 [(set_attr "predicable" "yes")
d952d547 4808 (set_attr "predicable_short_it" "yes,no")
4809 (set_attr "arch" "t2,*")
4810 (set_attr "length" "4")
1aed5204 4811 (set_attr "type" "mvn_reg")]
cffb2a26 4812)
4813
f7fbdd4a 4814(define_insn "*notsi_compare0"
bd5b4116 4815 [(set (reg:CC_NOOV CC_REGNUM)
9c08d1fa 4816 (compare:CC_NOOV (not:SI (match_operand:SI 1 "s_register_operand" "r"))
4817 (const_int 0)))
4818 (set (match_operand:SI 0 "s_register_operand" "=r")
4819 (not:SI (match_dup 1)))]
25f905c2 4820 "TARGET_32BIT"
4821 "mvn%.\\t%0, %1"
d2a518d1 4822 [(set_attr "conds" "set")
1aed5204 4823 (set_attr "type" "mvn_reg")]
cffb2a26 4824)
9c08d1fa 4825
f7fbdd4a 4826(define_insn "*notsi_compare0_scratch"
bd5b4116 4827 [(set (reg:CC_NOOV CC_REGNUM)
9c08d1fa 4828 (compare:CC_NOOV (not:SI (match_operand:SI 1 "s_register_operand" "r"))
4829 (const_int 0)))
4830 (clobber (match_scratch:SI 0 "=r"))]
25f905c2 4831 "TARGET_32BIT"
4832 "mvn%.\\t%0, %1"
d2a518d1 4833 [(set_attr "conds" "set")
1aed5204 4834 (set_attr "type" "mvn_reg")]
cffb2a26 4835)
b11cae9e 4836\f
4837;; Fixed <--> Floating conversion insns
4838
9b8516be 4839(define_expand "floatsihf2"
4840 [(set (match_operand:HF 0 "general_operand" "")
4841 (float:HF (match_operand:SI 1 "general_operand" "")))]
4842 "TARGET_EITHER"
4843 "
4844 {
4845 rtx op1 = gen_reg_rtx (SFmode);
4846 expand_float (op1, operands[1], 0);
4847 op1 = convert_to_mode (HFmode, op1, 0);
4848 emit_move_insn (operands[0], op1);
4849 DONE;
4850 }"
4851)
4852
4853(define_expand "floatdihf2"
4854 [(set (match_operand:HF 0 "general_operand" "")
4855 (float:HF (match_operand:DI 1 "general_operand" "")))]
4856 "TARGET_EITHER"
4857 "
4858 {
4859 rtx op1 = gen_reg_rtx (SFmode);
4860 expand_float (op1, operands[1], 0);
4861 op1 = convert_to_mode (HFmode, op1, 0);
4862 emit_move_insn (operands[0], op1);
4863 DONE;
4864 }"
4865)
4866
604f3a0a 4867(define_expand "floatsisf2"
4868 [(set (match_operand:SF 0 "s_register_operand" "")
4869 (float:SF (match_operand:SI 1 "s_register_operand" "")))]
25f905c2 4870 "TARGET_32BIT && TARGET_HARD_FLOAT"
604f3a0a 4871 "
604f3a0a 4872")
4873
604f3a0a 4874(define_expand "floatsidf2"
4875 [(set (match_operand:DF 0 "s_register_operand" "")
4876 (float:DF (match_operand:SI 1 "s_register_operand" "")))]
a50d7267 4877 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
604f3a0a 4878 "
604f3a0a 4879")
4880
9b8516be 4881(define_expand "fix_trunchfsi2"
4882 [(set (match_operand:SI 0 "general_operand" "")
4883 (fix:SI (fix:HF (match_operand:HF 1 "general_operand" ""))))]
4884 "TARGET_EITHER"
4885 "
4886 {
4887 rtx op1 = convert_to_mode (SFmode, operands[1], 0);
4888 expand_fix (operands[0], op1, 0);
4889 DONE;
4890 }"
4891)
4892
4893(define_expand "fix_trunchfdi2"
4894 [(set (match_operand:DI 0 "general_operand" "")
4895 (fix:DI (fix:HF (match_operand:HF 1 "general_operand" ""))))]
4896 "TARGET_EITHER"
4897 "
4898 {
4899 rtx op1 = convert_to_mode (SFmode, operands[1], 0);
4900 expand_fix (operands[0], op1, 0);
4901 DONE;
4902 }"
4903)
4904
604f3a0a 4905(define_expand "fix_truncsfsi2"
4906 [(set (match_operand:SI 0 "s_register_operand" "")
a33d5c9c 4907 (fix:SI (fix:SF (match_operand:SF 1 "s_register_operand" ""))))]
25f905c2 4908 "TARGET_32BIT && TARGET_HARD_FLOAT"
604f3a0a 4909 "
604f3a0a 4910")
4911
604f3a0a 4912(define_expand "fix_truncdfsi2"
4913 [(set (match_operand:SI 0 "s_register_operand" "")
a33d5c9c 4914 (fix:SI (fix:DF (match_operand:DF 1 "s_register_operand" ""))))]
a50d7267 4915 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
604f3a0a 4916 "
604f3a0a 4917")
4918
f544c6d2 4919;; Truncation insns
b11cae9e 4920
604f3a0a 4921(define_expand "truncdfsf2"
4922 [(set (match_operand:SF 0 "s_register_operand" "")
4923 (float_truncate:SF
4924 (match_operand:DF 1 "s_register_operand" "")))]
a50d7267 4925 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
604f3a0a 4926 ""
4927)
9b8516be 4928
4929/* DFmode -> HFmode conversions have to go through SFmode. */
4930(define_expand "truncdfhf2"
4931 [(set (match_operand:HF 0 "general_operand" "")
4932 (float_truncate:HF
4933 (match_operand:DF 1 "general_operand" "")))]
4934 "TARGET_EITHER"
4935 "
4936 {
4937 rtx op1;
4938 op1 = convert_to_mode (SFmode, operands[1], 0);
4939 op1 = convert_to_mode (HFmode, op1, 0);
4940 emit_move_insn (operands[0], op1);
4941 DONE;
4942 }"
4943)
b11cae9e 4944\f
9c08d1fa 4945;; Zero and sign extension instructions.
b11cae9e 4946
848e66ac 4947(define_insn "zero_extend<mode>di2"
6aa689e8 4948 [(set (match_operand:DI 0 "s_register_operand" "=w,r,?r,w")
6d97728e 4949 (zero_extend:DI (match_operand:QHSI 1 "<qhs_zextenddi_op>"
4950 "<qhs_zextenddi_cstr>")))]
848e66ac 4951 "TARGET_32BIT <qhs_zextenddi_cond>"
4952 "#"
6aa689e8 4953 [(set_attr "length" "8,4,8,8")
b6779ddc 4954 (set_attr "arch" "neon_for_64bits,*,*,avoid_neon_for_64bits")
848e66ac 4955 (set_attr "ce_count" "2")
efbb5e19 4956 (set_attr "predicable" "yes")
4957 (set_attr "type" "multiple,mov_reg,multiple,multiple")]
25f905c2 4958)
4959
848e66ac 4960(define_insn "extend<mode>di2"
6aa689e8 4961 [(set (match_operand:DI 0 "s_register_operand" "=w,r,?r,?r,w")
63d204a8 4962 (sign_extend:DI (match_operand:QHSI 1 "<qhs_extenddi_op>"
4963 "<qhs_extenddi_cstr>")))]
848e66ac 4964 "TARGET_32BIT <qhs_sextenddi_cond>"
4965 "#"
6aa689e8 4966 [(set_attr "length" "8,4,8,8,8")
848e66ac 4967 (set_attr "ce_count" "2")
4968 (set_attr "shift" "1")
8012d2c2 4969 (set_attr "predicable" "yes")
1b7da4ac 4970 (set_attr "arch" "neon_for_64bits,*,a,t,avoid_neon_for_64bits")
4971 (set_attr "type" "multiple,mov_reg,multiple,multiple,multiple")]
0d66636f 4972)
9c08d1fa 4973
848e66ac 4974;; Splits for all extensions to DImode
4975(define_split
4976 [(set (match_operand:DI 0 "s_register_operand" "")
4977 (zero_extend:DI (match_operand 1 "nonimmediate_operand" "")))]
6aa689e8 4978 "TARGET_32BIT && reload_completed && !IS_VFP_REGNUM (REGNO (operands[0]))"
848e66ac 4979 [(set (match_dup 0) (match_dup 1))]
4980{
848e66ac 4981 rtx lo_part = gen_lowpart (SImode, operands[0]);
3754d046 4982 machine_mode src_mode = GET_MODE (operands[1]);
848e66ac 4983
4984 if (REG_P (operands[0])
4985 && !reg_overlap_mentioned_p (operands[0], operands[1]))
4986 emit_clobber (operands[0]);
4987 if (!REG_P (lo_part) || src_mode != SImode
4988 || !rtx_equal_p (lo_part, operands[1]))
4989 {
4990 if (src_mode == SImode)
4991 emit_move_insn (lo_part, operands[1]);
4992 else
d1f9b275 4993 emit_insn (gen_rtx_SET (lo_part,
848e66ac 4994 gen_rtx_ZERO_EXTEND (SImode, operands[1])));
4995 operands[1] = lo_part;
4996 }
4997 operands[0] = gen_highpart (SImode, operands[0]);
4998 operands[1] = const0_rtx;
4999})
9c08d1fa 5000
848e66ac 5001(define_split
25f905c2 5002 [(set (match_operand:DI 0 "s_register_operand" "")
848e66ac 5003 (sign_extend:DI (match_operand 1 "nonimmediate_operand" "")))]
6aa689e8 5004 "TARGET_32BIT && reload_completed && !IS_VFP_REGNUM (REGNO (operands[0]))"
848e66ac 5005 [(set (match_dup 0) (ashiftrt:SI (match_dup 1) (const_int 31)))]
5006{
5007 rtx lo_part = gen_lowpart (SImode, operands[0]);
3754d046 5008 machine_mode src_mode = GET_MODE (operands[1]);
25f905c2 5009
848e66ac 5010 if (REG_P (operands[0])
5011 && !reg_overlap_mentioned_p (operands[0], operands[1]))
5012 emit_clobber (operands[0]);
5013
5014 if (!REG_P (lo_part) || src_mode != SImode
5015 || !rtx_equal_p (lo_part, operands[1]))
5016 {
5017 if (src_mode == SImode)
5018 emit_move_insn (lo_part, operands[1]);
5019 else
d1f9b275 5020 emit_insn (gen_rtx_SET (lo_part,
848e66ac 5021 gen_rtx_SIGN_EXTEND (SImode, operands[1])));
5022 operands[1] = lo_part;
5023 }
5024 operands[0] = gen_highpart (SImode, operands[0]);
5025})
9c08d1fa 5026
5027(define_expand "zero_extendhisi2"
ef51b8e1 5028 [(set (match_operand:SI 0 "s_register_operand" "")
5029 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
cffb2a26 5030 "TARGET_EITHER"
ef51b8e1 5031{
5032 if (TARGET_ARM && !arm_arch4 && MEM_P (operands[1]))
f7fbdd4a 5033 {
ef51b8e1 5034 emit_insn (gen_movhi_bytes (operands[0], operands[1]));
5035 DONE;
25f7a26e 5036 }
ef51b8e1 5037 if (!arm_arch6 && !MEM_P (operands[1]))
5038 {
5039 rtx t = gen_lowpart (SImode, operands[1]);
5040 rtx tmp = gen_reg_rtx (SImode);
5041 emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (16)));
5042 emit_insn (gen_lshrsi3 (operands[0], tmp, GEN_INT (16)));
5043 DONE;
5044 }
5045})
9c08d1fa 5046
ef51b8e1 5047(define_split
b146458f 5048 [(set (match_operand:SI 0 "s_register_operand" "")
5049 (zero_extend:SI (match_operand:HI 1 "s_register_operand" "")))]
ef51b8e1 5050 "!TARGET_THUMB2 && !arm_arch6"
5051 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
5052 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 16)))]
5053{
5054 operands[2] = gen_lowpart (SImode, operands[1]);
5055})
5056
cffb2a26 5057(define_insn "*arm_zero_extendhisi2"
ef51b8e1 5058 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5059 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
a2cd141b 5060 "TARGET_ARM && arm_arch4 && !arm_arch6"
ef51b8e1 5061 "@
5062 #
5063 ldr%(h%)\\t%0, %1"
d82e788e 5064 [(set_attr "type" "alu_shift_reg,load_byte")
848e66ac 5065 (set_attr "predicable" "yes")]
cffb2a26 5066)
f7fbdd4a 5067
a2cd141b 5068(define_insn "*arm_zero_extendhisi2_v6"
5069 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
e3f4ccee 5070 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,Uh")))]
a2cd141b 5071 "TARGET_ARM && arm_arch6"
5072 "@
5073 uxth%?\\t%0, %1
25f905c2 5074 ldr%(h%)\\t%0, %1"
65f68e55 5075 [(set_attr "predicable" "yes")
6b6abc9c 5076 (set_attr "type" "extend,load_byte")]
a2cd141b 5077)
5078
5079(define_insn "*arm_zero_extendhisi2addsi"
5080 [(set (match_operand:SI 0 "s_register_operand" "=r")
5081 (plus:SI (zero_extend:SI (match_operand:HI 1 "s_register_operand" "r"))
5082 (match_operand:SI 2 "s_register_operand" "r")))]
25f905c2 5083 "TARGET_INT_SIMD"
a2cd141b 5084 "uxtah%?\\t%0, %2, %1"
d82e788e 5085 [(set_attr "type" "alu_shift_reg")
d952d547 5086 (set_attr "predicable" "yes")
5087 (set_attr "predicable_short_it" "no")]
a2cd141b 5088)
5089
87b22bf7 5090(define_expand "zero_extendqisi2"
cffb2a26 5091 [(set (match_operand:SI 0 "s_register_operand" "")
5092 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))]
5093 "TARGET_EITHER"
ef51b8e1 5094{
0438d37f 5095 if (TARGET_ARM && !arm_arch6 && !MEM_P (operands[1]))
87b22bf7 5096 {
ef51b8e1 5097 emit_insn (gen_andsi3 (operands[0],
5098 gen_lowpart (SImode, operands[1]),
5099 GEN_INT (255)));
5100 DONE;
5101 }
5102 if (!arm_arch6 && !MEM_P (operands[1]))
5103 {
5104 rtx t = gen_lowpart (SImode, operands[1]);
5105 rtx tmp = gen_reg_rtx (SImode);
5106 emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (24)));
5107 emit_insn (gen_lshrsi3 (operands[0], tmp, GEN_INT (24)));
5108 DONE;
5109 }
5110})
cffb2a26 5111
ef51b8e1 5112(define_split
b146458f 5113 [(set (match_operand:SI 0 "s_register_operand" "")
5114 (zero_extend:SI (match_operand:QI 1 "s_register_operand" "")))]
ef51b8e1 5115 "!arm_arch6"
5116 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 24)))
5117 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 24)))]
5118{
5119 operands[2] = simplify_gen_subreg (SImode, operands[1], QImode, 0);
5120 if (TARGET_ARM)
5121 {
5122 emit_insn (gen_andsi3 (operands[0], operands[2], GEN_INT (255)));
87b22bf7 5123 DONE;
5124 }
ef51b8e1 5125})
9c08d1fa 5126
cffb2a26 5127(define_insn "*arm_zero_extendqisi2"
ef51b8e1 5128 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5129 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
a2cd141b 5130 "TARGET_ARM && !arm_arch6"
ef51b8e1 5131 "@
5132 #
5133 ldr%(b%)\\t%0, %1\\t%@ zero_extendqisi2"
5134 [(set_attr "length" "8,4")
d82e788e 5135 (set_attr "type" "alu_shift_reg,load_byte")
848e66ac 5136 (set_attr "predicable" "yes")]
cffb2a26 5137)
87b22bf7 5138
a2cd141b 5139(define_insn "*arm_zero_extendqisi2_v6"
5140 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
e3f4ccee 5141 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "r,Uh")))]
a2cd141b 5142 "TARGET_ARM && arm_arch6"
5143 "@
25f905c2 5144 uxtb%(%)\\t%0, %1
5145 ldr%(b%)\\t%0, %1\\t%@ zero_extendqisi2"
6b6abc9c 5146 [(set_attr "type" "extend,load_byte")
848e66ac 5147 (set_attr "predicable" "yes")]
a2cd141b 5148)
5149
5150(define_insn "*arm_zero_extendqisi2addsi"
5151 [(set (match_operand:SI 0 "s_register_operand" "=r")
5152 (plus:SI (zero_extend:SI (match_operand:QI 1 "s_register_operand" "r"))
5153 (match_operand:SI 2 "s_register_operand" "r")))]
25f905c2 5154 "TARGET_INT_SIMD"
a2cd141b 5155 "uxtab%?\\t%0, %2, %1"
5156 [(set_attr "predicable" "yes")
d952d547 5157 (set_attr "predicable_short_it" "no")
d82e788e 5158 (set_attr "type" "alu_shift_reg")]
a2cd141b 5159)
5160
87b22bf7 5161(define_split
5162 [(set (match_operand:SI 0 "s_register_operand" "")
5163 (zero_extend:SI (subreg:QI (match_operand:SI 1 "" "") 0)))
5164 (clobber (match_operand:SI 2 "s_register_operand" ""))]
0438d37f 5165 "TARGET_32BIT && (!MEM_P (operands[1])) && ! BYTES_BIG_ENDIAN"
87b22bf7 5166 [(set (match_dup 2) (match_dup 1))
5167 (set (match_dup 0) (and:SI (match_dup 2) (const_int 255)))]
cffb2a26 5168 ""
5169)
9c08d1fa 5170
8a4d25d6 5171(define_split
5172 [(set (match_operand:SI 0 "s_register_operand" "")
5173 (zero_extend:SI (subreg:QI (match_operand:SI 1 "" "") 3)))
5174 (clobber (match_operand:SI 2 "s_register_operand" ""))]
0438d37f 5175 "TARGET_32BIT && (!MEM_P (operands[1])) && BYTES_BIG_ENDIAN"
8a4d25d6 5176 [(set (match_dup 2) (match_dup 1))
5177 (set (match_dup 0) (and:SI (match_dup 2) (const_int 255)))]
5178 ""
5179)
5180
1c274529 5181
5182(define_split
5183 [(set (match_operand:SI 0 "s_register_operand" "")
9b23f0a7 5184 (IOR_XOR:SI (and:SI (ashift:SI
1c274529 5185 (match_operand:SI 1 "s_register_operand" "")
5186 (match_operand:SI 2 "const_int_operand" ""))
5187 (match_operand:SI 3 "const_int_operand" ""))
5188 (zero_extend:SI
5189 (match_operator 5 "subreg_lowpart_operator"
5190 [(match_operand:SI 4 "s_register_operand" "")]))))]
5191 "TARGET_32BIT
63787642 5192 && ((unsigned HOST_WIDE_INT) INTVAL (operands[3])
1c274529 5193 == (GET_MODE_MASK (GET_MODE (operands[5]))
5194 & (GET_MODE_MASK (GET_MODE (operands[5]))
5195 << (INTVAL (operands[2])))))"
9b23f0a7 5196 [(set (match_dup 0) (IOR_XOR:SI (ashift:SI (match_dup 1) (match_dup 2))
1c274529 5197 (match_dup 4)))
5198 (set (match_dup 0) (zero_extend:SI (match_dup 5)))]
5199 "operands[5] = gen_lowpart (GET_MODE (operands[5]), operands[0]);"
5200)
5201
f7fbdd4a 5202(define_insn "*compareqi_eq0"
bd5b4116 5203 [(set (reg:CC_Z CC_REGNUM)
206ee9a2 5204 (compare:CC_Z (match_operand:QI 0 "s_register_operand" "r")
87b22bf7 5205 (const_int 0)))]
25f905c2 5206 "TARGET_32BIT"
596e5e8f 5207 "tst%?\\t%0, #255"
5208 [(set_attr "conds" "set")
d952d547 5209 (set_attr "predicable" "yes")
1b7da4ac 5210 (set_attr "predicable_short_it" "no")
5211 (set_attr "type" "logic_imm")]
cffb2a26 5212)
b11cae9e 5213
b11cae9e 5214(define_expand "extendhisi2"
ef51b8e1 5215 [(set (match_operand:SI 0 "s_register_operand" "")
5216 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
cffb2a26 5217 "TARGET_EITHER"
ef51b8e1 5218{
5219 if (TARGET_THUMB1)
5220 {
5221 emit_insn (gen_thumb1_extendhisi2 (operands[0], operands[1]));
5222 DONE;
5223 }
5224 if (MEM_P (operands[1]) && TARGET_ARM && !arm_arch4)
5225 {
5226 emit_insn (gen_extendhisi2_mem (operands[0], operands[1]));
5227 DONE;
5228 }
ed29c566 5229
ef51b8e1 5230 if (!arm_arch6 && !MEM_P (operands[1]))
5231 {
5232 rtx t = gen_lowpart (SImode, operands[1]);
5233 rtx tmp = gen_reg_rtx (SImode);
5234 emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (16)));
5235 emit_insn (gen_ashrsi3 (operands[0], tmp, GEN_INT (16)));
5236 DONE;
5237 }
5238})
cffb2a26 5239
ef51b8e1 5240(define_split
5241 [(parallel
5242 [(set (match_operand:SI 0 "register_operand" "")
5243 (sign_extend:SI (match_operand:HI 1 "register_operand" "")))
5244 (clobber (match_scratch:SI 2 ""))])]
5245 "!arm_arch6"
5246 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
5247 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 16)))]
5248{
5249 operands[2] = simplify_gen_subreg (SImode, operands[1], HImode, 0);
5250})
25f7a26e 5251
25f905c2 5252;; This pattern will only be used when ldsh is not available
25f7a26e 5253(define_expand "extendhisi2_mem"
eab14235 5254 [(set (match_dup 2) (zero_extend:SI (match_operand:HI 1 "" "")))
25f7a26e 5255 (set (match_dup 3)
eab14235 5256 (zero_extend:SI (match_dup 7)))
25f7a26e 5257 (set (match_dup 6) (ashift:SI (match_dup 4) (const_int 24)))
5258 (set (match_operand:SI 0 "" "")
5259 (ior:SI (ashiftrt:SI (match_dup 6) (const_int 16)) (match_dup 5)))]
cffb2a26 5260 "TARGET_ARM"
25f7a26e 5261 "
215b30b3 5262 {
5263 rtx mem1, mem2;
5264 rtx addr = copy_to_mode_reg (SImode, XEXP (operands[1], 0));
5265
788fcce0 5266 mem1 = change_address (operands[1], QImode, addr);
29c05e22 5267 mem2 = change_address (operands[1], QImode,
5268 plus_constant (Pmode, addr, 1));
215b30b3 5269 operands[0] = gen_lowpart (SImode, operands[0]);
5270 operands[1] = mem1;
5271 operands[2] = gen_reg_rtx (SImode);
5272 operands[3] = gen_reg_rtx (SImode);
5273 operands[6] = gen_reg_rtx (SImode);
5274 operands[7] = mem2;
25f7a26e 5275
215b30b3 5276 if (BYTES_BIG_ENDIAN)
5277 {
5278 operands[4] = operands[2];
5279 operands[5] = operands[3];
5280 }
5281 else
5282 {
5283 operands[4] = operands[3];
5284 operands[5] = operands[2];
5285 }
5286 }"
5287)
b11cae9e 5288
ef51b8e1 5289(define_split
5290 [(set (match_operand:SI 0 "register_operand" "")
5291 (sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
5292 "!arm_arch6"
5293 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
5294 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 16)))]
5295{
5296 operands[2] = simplify_gen_subreg (SImode, operands[1], HImode, 0);
5297})
5298
a2cd141b 5299(define_insn "*arm_extendhisi2"
ef51b8e1 5300 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
e3f4ccee 5301 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,Uh")))]
a2cd141b 5302 "TARGET_ARM && arm_arch4 && !arm_arch6"
ef51b8e1 5303 "@
5304 #
5305 ldr%(sh%)\\t%0, %1"
5306 [(set_attr "length" "8,4")
d82e788e 5307 (set_attr "type" "alu_shift_reg,load_byte")
e3f4ccee 5308 (set_attr "predicable" "yes")]
cffb2a26 5309)
f7fbdd4a 5310
25f905c2 5311;; ??? Check Thumb-2 pool range
a2cd141b 5312(define_insn "*arm_extendhisi2_v6"
5313 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
e3f4ccee 5314 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,Uh")))]
25f905c2 5315 "TARGET_32BIT && arm_arch6"
a2cd141b 5316 "@
5317 sxth%?\\t%0, %1
25f905c2 5318 ldr%(sh%)\\t%0, %1"
6b6abc9c 5319 [(set_attr "type" "extend,load_byte")
a2cd141b 5320 (set_attr "predicable" "yes")
e3f4ccee 5321 (set_attr "predicable_short_it" "no")]
a2cd141b 5322)
5323
5324(define_insn "*arm_extendhisi2addsi"
5325 [(set (match_operand:SI 0 "s_register_operand" "=r")
5326 (plus:SI (sign_extend:SI (match_operand:HI 1 "s_register_operand" "r"))
5327 (match_operand:SI 2 "s_register_operand" "r")))]
25f905c2 5328 "TARGET_INT_SIMD"
a2cd141b 5329 "sxtah%?\\t%0, %2, %1"
1b7da4ac 5330 [(set_attr "type" "alu_shift_reg")]
a2cd141b 5331)
5332
c8f69309 5333(define_expand "extendqihi2"
5334 [(set (match_dup 2)
bed7d9a5 5335 (ashift:SI (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "")
c8f69309 5336 (const_int 24)))
9c08d1fa 5337 (set (match_operand:HI 0 "s_register_operand" "")
c8f69309 5338 (ashiftrt:SI (match_dup 2)
5339 (const_int 24)))]
cffb2a26 5340 "TARGET_ARM"
c8f69309 5341 "
215b30b3 5342 {
0438d37f 5343 if (arm_arch4 && MEM_P (operands[1]))
215b30b3 5344 {
d1f9b275 5345 emit_insn (gen_rtx_SET (operands[0],
215b30b3 5346 gen_rtx_SIGN_EXTEND (HImode, operands[1])));
5347 DONE;
5348 }
5349 if (!s_register_operand (operands[1], QImode))
5350 operands[1] = copy_to_mode_reg (QImode, operands[1]);
5351 operands[0] = gen_lowpart (SImode, operands[0]);
5352 operands[1] = gen_lowpart (SImode, operands[1]);
5353 operands[2] = gen_reg_rtx (SImode);
5354 }"
5355)
f7fbdd4a 5356
25f905c2 5357(define_insn "*arm_extendqihi_insn"
b4e8a300 5358 [(set (match_operand:HI 0 "s_register_operand" "=r")
bed7d9a5 5359 (sign_extend:HI (match_operand:QI 1 "arm_extendqisi_mem_op" "Uq")))]
cffb2a26 5360 "TARGET_ARM && arm_arch4"
25f905c2 5361 "ldr%(sb%)\\t%0, %1"
a2cd141b 5362 [(set_attr "type" "load_byte")
e3f4ccee 5363 (set_attr "predicable" "yes")]
cffb2a26 5364)
3fc2009e 5365
b11cae9e 5366(define_expand "extendqisi2"
ef51b8e1 5367 [(set (match_operand:SI 0 "s_register_operand" "")
5368 (sign_extend:SI (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "")))]
cffb2a26 5369 "TARGET_EITHER"
ef51b8e1 5370{
5371 if (!arm_arch4 && MEM_P (operands[1]))
5372 operands[1] = copy_to_mode_reg (QImode, operands[1]);
a2cd141b 5373
ef51b8e1 5374 if (!arm_arch6 && !MEM_P (operands[1]))
5375 {
5376 rtx t = gen_lowpart (SImode, operands[1]);
5377 rtx tmp = gen_reg_rtx (SImode);
5378 emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (24)));
5379 emit_insn (gen_ashrsi3 (operands[0], tmp, GEN_INT (24)));
5380 DONE;
5381 }
5382})
a2cd141b 5383
ef51b8e1 5384(define_split
5385 [(set (match_operand:SI 0 "register_operand" "")
5386 (sign_extend:SI (match_operand:QI 1 "register_operand" "")))]
5387 "!arm_arch6"
5388 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 24)))
5389 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 24)))]
5390{
5391 operands[2] = simplify_gen_subreg (SImode, operands[1], QImode, 0);
5392})
f7fbdd4a 5393
a2cd141b 5394(define_insn "*arm_extendqisi"
ef51b8e1 5395 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5396 (sign_extend:SI (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "r,Uq")))]
a2cd141b 5397 "TARGET_ARM && arm_arch4 && !arm_arch6"
ef51b8e1 5398 "@
5399 #
5400 ldr%(sb%)\\t%0, %1"
5401 [(set_attr "length" "8,4")
d82e788e 5402 (set_attr "type" "alu_shift_reg,load_byte")
e3f4ccee 5403 (set_attr "predicable" "yes")]
cffb2a26 5404)
3fc2009e 5405
a2cd141b 5406(define_insn "*arm_extendqisi_v6"
5407 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
bed7d9a5 5408 (sign_extend:SI
5409 (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "r,Uq")))]
a2cd141b 5410 "TARGET_ARM && arm_arch6"
b4e8a300 5411 "@
5412 sxtb%?\\t%0, %1
25f905c2 5413 ldr%(sb%)\\t%0, %1"
6b6abc9c 5414 [(set_attr "type" "extend,load_byte")
e3f4ccee 5415 (set_attr "predicable" "yes")]
a2cd141b 5416)
5417
5418(define_insn "*arm_extendqisi2addsi"
5419 [(set (match_operand:SI 0 "s_register_operand" "=r")
5420 (plus:SI (sign_extend:SI (match_operand:QI 1 "s_register_operand" "r"))
5421 (match_operand:SI 2 "s_register_operand" "r")))]
25f905c2 5422 "TARGET_INT_SIMD"
a2cd141b 5423 "sxtab%?\\t%0, %2, %1"
d82e788e 5424 [(set_attr "type" "alu_shift_reg")
d952d547 5425 (set_attr "predicable" "yes")
5426 (set_attr "predicable_short_it" "no")]
a2cd141b 5427)
5428
caedf871 5429(define_expand "extendsfdf2"
5430 [(set (match_operand:DF 0 "s_register_operand" "")
5431 (float_extend:DF (match_operand:SF 1 "s_register_operand" "")))]
a50d7267 5432 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
caedf871 5433 ""
5434)
9b8516be 5435
5436/* HFmode -> DFmode conversions have to go through SFmode. */
5437(define_expand "extendhfdf2"
5438 [(set (match_operand:DF 0 "general_operand" "")
5439 (float_extend:DF (match_operand:HF 1 "general_operand" "")))]
5440 "TARGET_EITHER"
5441 "
5442 {
5443 rtx op1;
5444 op1 = convert_to_mode (SFmode, operands[1], 0);
5445 op1 = convert_to_mode (DFmode, op1, 0);
5446 emit_insn (gen_movdf (operands[0], op1));
5447 DONE;
5448 }"
5449)
b11cae9e 5450\f
5451;; Move insns (including loads and stores)
5452
5453;; XXX Just some ideas about movti.
9c08d1fa 5454;; I don't think these are a good idea on the arm, there just aren't enough
5455;; registers
b11cae9e 5456;;(define_expand "loadti"
9c08d1fa 5457;; [(set (match_operand:TI 0 "s_register_operand" "")
b11cae9e 5458;; (mem:TI (match_operand:SI 1 "address_operand" "")))]
5459;; "" "")
5460
5461;;(define_expand "storeti"
5462;; [(set (mem:TI (match_operand:TI 0 "address_operand" ""))
9c08d1fa 5463;; (match_operand:TI 1 "s_register_operand" ""))]
b11cae9e 5464;; "" "")
5465
5466;;(define_expand "movti"
5467;; [(set (match_operand:TI 0 "general_operand" "")
5468;; (match_operand:TI 1 "general_operand" ""))]
5469;; ""
5470;; "
5471;;{
5472;; rtx insn;
5473;;
0438d37f 5474;; if (MEM_P (operands[0]) && MEM_P (operands[1]))
b11cae9e 5475;; operands[1] = copy_to_reg (operands[1]);
0438d37f 5476;; if (MEM_P (operands[0]))
b11cae9e 5477;; insn = gen_storeti (XEXP (operands[0], 0), operands[1]);
0438d37f 5478;; else if (MEM_P (operands[1]))
b11cae9e 5479;; insn = gen_loadti (operands[0], XEXP (operands[1], 0));
5480;; else
5481;; FAIL;
5482;;
5483;; emit_insn (insn);
5484;; DONE;
5485;;}")
5486
a2f10574 5487;; Recognize garbage generated above.
b11cae9e 5488
5489;;(define_insn ""
5490;; [(set (match_operand:TI 0 "general_operand" "=r,r,r,<,>,m")
5491;; (match_operand:TI 1 "general_operand" "<,>,m,r,r,r"))]
5492;; ""
5493;; "*
5494;; {
5495;; register mem = (which_alternative < 3);
0d66636f 5496;; register const char *template;
b11cae9e 5497;;
5498;; operands[mem] = XEXP (operands[mem], 0);
5499;; switch (which_alternative)
5500;; {
5501;; case 0: template = \"ldmdb\\t%1!, %M0\"; break;
5502;; case 1: template = \"ldmia\\t%1!, %M0\"; break;
5503;; case 2: template = \"ldmia\\t%1, %M0\"; break;
5504;; case 3: template = \"stmdb\\t%0!, %M1\"; break;
5505;; case 4: template = \"stmia\\t%0!, %M1\"; break;
5506;; case 5: template = \"stmia\\t%0, %M1\"; break;
5507;; }
e2348bcb 5508;; output_asm_insn (template, operands);
5509;; return \"\";
b11cae9e 5510;; }")
5511
cffb2a26 5512(define_expand "movdi"
5513 [(set (match_operand:DI 0 "general_operand" "")
5514 (match_operand:DI 1 "general_operand" ""))]
5515 "TARGET_EITHER"
5516 "
e1ba4a27 5517 if (can_create_pseudo_p ())
cffb2a26 5518 {
0438d37f 5519 if (!REG_P (operands[0]))
b2778788 5520 operands[1] = force_reg (DImode, operands[1]);
cffb2a26 5521 }
6b97fdcc 5522 if (REG_P (operands[0]) && REGNO (operands[0]) <= LAST_ARM_REGNUM
4f0e25ca 5523 && !HARD_REGNO_MODE_OK (REGNO (operands[0]), DImode))
5524 {
5525 /* Avoid LDRD's into an odd-numbered register pair in ARM state
5526 when expanding function calls. */
5527 gcc_assert (can_create_pseudo_p ());
5528 if (MEM_P (operands[1]) && MEM_VOLATILE_P (operands[1]))
5529 {
5530 /* Perform load into legal reg pair first, then move. */
5531 rtx reg = gen_reg_rtx (DImode);
5532 emit_insn (gen_movdi (reg, operands[1]));
5533 operands[1] = reg;
5534 }
5535 emit_move_insn (gen_lowpart (SImode, operands[0]),
5536 gen_lowpart (SImode, operands[1]));
5537 emit_move_insn (gen_highpart (SImode, operands[0]),
5538 gen_highpart (SImode, operands[1]));
5539 DONE;
5540 }
6b97fdcc 5541 else if (REG_P (operands[1]) && REGNO (operands[1]) <= LAST_ARM_REGNUM
4f0e25ca 5542 && !HARD_REGNO_MODE_OK (REGNO (operands[1]), DImode))
5543 {
5544 /* Avoid STRD's from an odd-numbered register pair in ARM state
5545 when expanding function prologue. */
5546 gcc_assert (can_create_pseudo_p ());
5547 rtx split_dest = (MEM_P (operands[0]) && MEM_VOLATILE_P (operands[0]))
5548 ? gen_reg_rtx (DImode)
5549 : operands[0];
5550 emit_move_insn (gen_lowpart (SImode, split_dest),
5551 gen_lowpart (SImode, operands[1]));
5552 emit_move_insn (gen_highpart (SImode, split_dest),
5553 gen_highpart (SImode, operands[1]));
5554 if (split_dest != operands[0])
5555 emit_insn (gen_movdi (operands[0], split_dest));
5556 DONE;
5557 }
cffb2a26 5558 "
5559)
b11cae9e 5560
cffb2a26 5561(define_insn "*arm_movdi"
353cf59a 5562 [(set (match_operand:DI 0 "nonimmediate_di_operand" "=r, r, r, q, m")
5563 (match_operand:DI 1 "di_operand" "rDa,Db,Dc,mi,q"))]
cde1623a 5564 "TARGET_32BIT
b805622c 5565 && !(TARGET_HARD_FLOAT && TARGET_VFP)
b2778788 5566 && !TARGET_IWMMXT
5567 && ( register_operand (operands[0], DImode)
5568 || register_operand (operands[1], DImode))"
b11cae9e 5569 "*
d51f92df 5570 switch (which_alternative)
5571 {
5572 case 0:
5573 case 1:
5574 case 2:
5575 return \"#\";
5576 default:
26ff80c0 5577 return output_move_double (operands, true, NULL);
d51f92df 5578 }
cffb2a26 5579 "
359a6e9f 5580 [(set_attr "length" "8,12,16,8,8")
1b7da4ac 5581 (set_attr "type" "multiple,multiple,multiple,load2,store2")
cde1623a 5582 (set_attr "arm_pool_range" "*,*,*,1020,*")
8848d797 5583 (set_attr "arm_neg_pool_range" "*,*,*,1004,*")
42e1de19 5584 (set_attr "thumb2_pool_range" "*,*,*,4094,*")
cde1623a 5585 (set_attr "thumb2_neg_pool_range" "*,*,*,0,*")]
cffb2a26 5586)
5587
d51f92df 5588(define_split
5589 [(set (match_operand:ANY64 0 "arm_general_register_operand" "")
e6dd3afa 5590 (match_operand:ANY64 1 "immediate_operand" ""))]
25f905c2 5591 "TARGET_32BIT
d51f92df 5592 && reload_completed
5593 && (arm_const_double_inline_cost (operands[1])
861033d5 5594 <= arm_max_const_double_inline_cost ())"
d51f92df 5595 [(const_int 0)]
5596 "
5597 arm_split_constant (SET, SImode, curr_insn,
5598 INTVAL (gen_lowpart (SImode, operands[1])),
5599 gen_lowpart (SImode, operands[0]), NULL_RTX, 0);
5600 arm_split_constant (SET, SImode, curr_insn,
5601 INTVAL (gen_highpart_mode (SImode,
5602 GET_MODE (operands[0]),
5603 operands[1])),
5604 gen_highpart (SImode, operands[0]), NULL_RTX, 0);
5605 DONE;
5606 "
5607)
5608
e5ba9289 5609; If optimizing for size, or if we have load delay slots, then
5610; we want to split the constant into two separate operations.
5611; In both cases this may split a trivial part into a single data op
5612; leaving a single complex constant to load. We can also get longer
5613; offsets in a LDR which means we get better chances of sharing the pool
5614; entries. Finally, we can normally do a better job of scheduling
5615; LDR instructions than we can with LDM.
5616; This pattern will only match if the one above did not.
5617(define_split
5618 [(set (match_operand:ANY64 0 "arm_general_register_operand" "")
5619 (match_operand:ANY64 1 "const_double_operand" ""))]
5620 "TARGET_ARM && reload_completed
5621 && arm_const_double_by_parts (operands[1])"
5622 [(set (match_dup 0) (match_dup 1))
5623 (set (match_dup 2) (match_dup 3))]
5624 "
5625 operands[2] = gen_highpart (SImode, operands[0]);
5626 operands[3] = gen_highpart_mode (SImode, GET_MODE (operands[0]),
5627 operands[1]);
5628 operands[0] = gen_lowpart (SImode, operands[0]);
5629 operands[1] = gen_lowpart (SImode, operands[1]);
5630 "
5631)
5632
d51f92df 5633(define_split
5634 [(set (match_operand:ANY64 0 "arm_general_register_operand" "")
5635 (match_operand:ANY64 1 "arm_general_register_operand" ""))]
5636 "TARGET_EITHER && reload_completed"
5637 [(set (match_dup 0) (match_dup 1))
5638 (set (match_dup 2) (match_dup 3))]
5639 "
5640 operands[2] = gen_highpart (SImode, operands[0]);
5641 operands[3] = gen_highpart (SImode, operands[1]);
5642 operands[0] = gen_lowpart (SImode, operands[0]);
5643 operands[1] = gen_lowpart (SImode, operands[1]);
5644
5645 /* Handle a partial overlap. */
5646 if (rtx_equal_p (operands[0], operands[3]))
5647 {
5648 rtx tmp0 = operands[0];
5649 rtx tmp1 = operands[1];
5650
5651 operands[0] = operands[2];
5652 operands[1] = operands[3];
5653 operands[2] = tmp0;
5654 operands[3] = tmp1;
5655 }
5656 "
5657)
5658
a8a3b539 5659;; We can't actually do base+index doubleword loads if the index and
5660;; destination overlap. Split here so that we at least have chance to
5661;; schedule.
5662(define_split
5663 [(set (match_operand:DI 0 "s_register_operand" "")
5664 (mem:DI (plus:SI (match_operand:SI 1 "s_register_operand" "")
5665 (match_operand:SI 2 "s_register_operand" ""))))]
5666 "TARGET_LDRD
5667 && reg_overlap_mentioned_p (operands[0], operands[1])
5668 && reg_overlap_mentioned_p (operands[0], operands[2])"
5669 [(set (match_dup 4)
5670 (plus:SI (match_dup 1)
5671 (match_dup 2)))
5672 (set (match_dup 0)
5673 (mem:DI (match_dup 4)))]
5674 "
5675 operands[4] = gen_rtx_REG (SImode, REGNO(operands[0]));
5676 "
5677)
5678
9c08d1fa 5679(define_expand "movsi"
5680 [(set (match_operand:SI 0 "general_operand" "")
5681 (match_operand:SI 1 "general_operand" ""))]
cffb2a26 5682 "TARGET_EITHER"
9c08d1fa 5683 "
befb0bac 5684 {
e348ff3e 5685 rtx base, offset, tmp;
5686
25f905c2 5687 if (TARGET_32BIT)
9c08d1fa 5688 {
674a8f0b 5689 /* Everything except mem = const or mem = mem can be done easily. */
0438d37f 5690 if (MEM_P (operands[0]))
cffb2a26 5691 operands[1] = force_reg (SImode, operands[1]);
a2cd141b 5692 if (arm_general_register_operand (operands[0], SImode)
0438d37f 5693 && CONST_INT_P (operands[1])
cffb2a26 5694 && !(const_ok_for_arm (INTVAL (operands[1]))
5695 || const_ok_for_arm (~INTVAL (operands[1]))))
5696 {
17202aa5 5697 if (DONT_EARLY_SPLIT_CONSTANT (INTVAL (operands[1]), SET))
5698 {
5699 emit_insn (gen_rtx_SET (operands[0], operands[1]));
5700 DONE;
5701 }
5702 else
5703 {
5704 arm_split_constant (SET, SImode, NULL_RTX,
5705 INTVAL (operands[1]), operands[0], NULL_RTX,
5706 optimize && can_create_pseudo_p ());
5707 DONE;
5708 }
cffb2a26 5709 }
5710 }
25f905c2 5711 else /* TARGET_THUMB1... */
cffb2a26 5712 {
e1ba4a27 5713 if (can_create_pseudo_p ())
cffb2a26 5714 {
0438d37f 5715 if (!REG_P (operands[0]))
cffb2a26 5716 operands[1] = force_reg (SImode, operands[1]);
5717 }
9c08d1fa 5718 }
f655717d 5719
e348ff3e 5720 if (ARM_OFFSETS_MUST_BE_WITHIN_SECTIONS_P)
5721 {
5722 split_const (operands[1], &base, &offset);
5723 if (GET_CODE (base) == SYMBOL_REF
5724 && !offset_within_block_p (base, INTVAL (offset)))
5725 {
b308ddcf 5726 tmp = can_create_pseudo_p () ? gen_reg_rtx (SImode) : operands[0];
e348ff3e 5727 emit_move_insn (tmp, base);
5728 emit_insn (gen_addsi3 (operands[0], tmp, offset));
5729 DONE;
5730 }
5731 }
5732
f655717d 5733 /* Recognize the case where operand[1] is a reference to thread-local
5734 data and load its address to a register. */
5735 if (arm_tls_referenced_p (operands[1]))
5736 {
5737 rtx tmp = operands[1];
5738 rtx addend = NULL;
5739
5740 if (GET_CODE (tmp) == CONST && GET_CODE (XEXP (tmp, 0)) == PLUS)
5741 {
5742 addend = XEXP (XEXP (tmp, 0), 1);
5743 tmp = XEXP (XEXP (tmp, 0), 0);
5744 }
5745
5746 gcc_assert (GET_CODE (tmp) == SYMBOL_REF);
5747 gcc_assert (SYMBOL_REF_TLS_MODEL (tmp) != 0);
5748
e1ba4a27 5749 tmp = legitimize_tls_address (tmp,
5750 !can_create_pseudo_p () ? operands[0] : 0);
f655717d 5751 if (addend)
5752 {
5753 tmp = gen_rtx_PLUS (SImode, tmp, addend);
5754 tmp = force_operand (tmp, operands[0]);
5755 }
5756 operands[1] = tmp;
5757 }
5758 else if (flag_pic
5759 && (CONSTANT_P (operands[1])
5760 || symbol_mentioned_p (operands[1])
5761 || label_mentioned_p (operands[1])))
5762 operands[1] = legitimize_pic_address (operands[1], SImode,
e1ba4a27 5763 (!can_create_pseudo_p ()
5764 ? operands[0]
5765 : 0));
befb0bac 5766 }
215b30b3 5767 "
5768)
9c08d1fa 5769
d0e6a121 5770;; The ARM LO_SUM and HIGH are backwards - HIGH sets the low bits, and
5771;; LO_SUM adds in the high bits. Fortunately these are opaque operations
5772;; so this does not matter.
5773(define_insn "*arm_movt"
5774 [(set (match_operand:SI 0 "nonimmediate_operand" "=r")
5775 (lo_sum:SI (match_operand:SI 1 "nonimmediate_operand" "0")
5776 (match_operand:SI 2 "general_operand" "i")))]
ac528743 5777 "arm_arch_thumb2 && arm_valid_symbolic_address_p (operands[2])"
d0e6a121 5778 "movt%?\t%0, #:upper16:%c2"
5779 [(set_attr "predicable" "yes")
d952d547 5780 (set_attr "predicable_short_it" "no")
1b7da4ac 5781 (set_attr "length" "4")
282b4c75 5782 (set_attr "type" "alu_sreg")]
d0e6a121 5783)
5784
cffb2a26 5785(define_insn "*arm_movsi_insn"
aaa37ad6 5786 [(set (match_operand:SI 0 "nonimmediate_operand" "=rk,r,r,r,rk,m")
110eae03 5787 (match_operand:SI 1 "general_operand" "rk, I,K,j,mi,rk"))]
755eb2b4 5788 "TARGET_ARM && ! TARGET_IWMMXT
a2cd141b 5789 && !(TARGET_HARD_FLOAT && TARGET_VFP)
cffb2a26 5790 && ( register_operand (operands[0], SImode)
5791 || register_operand (operands[1], SImode))"
f7fbdd4a 5792 "@
aaa37ad6 5793 mov%?\\t%0, %1
f7fbdd4a 5794 mov%?\\t%0, %1
5795 mvn%?\\t%0, #%B1
25f905c2 5796 movw%?\\t%0, %1
f7fbdd4a 5797 ldr%?\\t%0, %1
5798 str%?\\t%1, %0"
1aed5204 5799 [(set_attr "type" "mov_reg,mov_imm,mvn_imm,mov_imm,load1,store1")
0d66636f 5800 (set_attr "predicable" "yes")
aaa37ad6 5801 (set_attr "pool_range" "*,*,*,*,4096,*")
5802 (set_attr "neg_pool_range" "*,*,*,*,4084,*")]
cffb2a26 5803)
87b22bf7 5804
5805(define_split
a2cd141b 5806 [(set (match_operand:SI 0 "arm_general_register_operand" "")
87b22bf7 5807 (match_operand:SI 1 "const_int_operand" ""))]
25f905c2 5808 "TARGET_32BIT
215b30b3 5809 && (!(const_ok_for_arm (INTVAL (operands[1]))
5810 || const_ok_for_arm (~INTVAL (operands[1]))))"
87b22bf7 5811 [(clobber (const_int 0))]
5812 "
96f57e36 5813 arm_split_constant (SET, SImode, NULL_RTX,
5814 INTVAL (operands[1]), operands[0], NULL_RTX, 0);
87b22bf7 5815 DONE;
215b30b3 5816 "
5817)
9c08d1fa 5818
861033d5 5819;; A normal way to do (symbol + offset) requires three instructions at least
5820;; (depends on how big the offset is) as below:
5821;; movw r0, #:lower16:g
5822;; movw r0, #:upper16:g
5823;; adds r0, #4
5824;;
5825;; A better way would be:
5826;; movw r0, #:lower16:g+4
5827;; movw r0, #:upper16:g+4
5828;;
5829;; The limitation of this way is that the length of offset should be a 16-bit
5830;; signed value, because current assembler only supports REL type relocation for
5831;; such case. If the more powerful RELA type is supported in future, we should
5832;; update this pattern to go with better way.
5833(define_split
5834 [(set (match_operand:SI 0 "arm_general_register_operand" "")
5835 (const:SI (plus:SI (match_operand:SI 1 "general_operand" "")
5836 (match_operand:SI 2 "const_int_operand" ""))))]
5837 "TARGET_THUMB2
5838 && arm_disable_literal_pool
5839 && reload_completed
5840 && GET_CODE (operands[1]) == SYMBOL_REF"
5841 [(clobber (const_int 0))]
5842 "
5843 int offset = INTVAL (operands[2]);
5844
5845 if (offset < -0x8000 || offset > 0x7fff)
5846 {
5847 arm_emit_movpair (operands[0], operands[1]);
d1f9b275 5848 emit_insn (gen_rtx_SET (operands[0],
861033d5 5849 gen_rtx_PLUS (SImode, operands[0], operands[2])));
5850 }
5851 else
5852 {
5853 rtx op = gen_rtx_CONST (SImode,
5854 gen_rtx_PLUS (SImode, operands[1], operands[2]));
5855 arm_emit_movpair (operands[0], op);
5856 }
5857 "
5858)
5859
b8d5d078 5860;; Split symbol_refs at the later stage (after cprop), instead of generating
5861;; movt/movw pair directly at expand. Otherwise corresponding high_sum
5862;; and lo_sum would be merged back into memory load at cprop. However,
5863;; if the default is to prefer movt/movw rather than a load from the constant
5864;; pool, the performance is better.
5865(define_split
5866 [(set (match_operand:SI 0 "arm_general_register_operand" "")
5867 (match_operand:SI 1 "general_operand" ""))]
5868 "TARGET_32BIT
5869 && TARGET_USE_MOVT && GET_CODE (operands[1]) == SYMBOL_REF
5870 && !flag_pic && !target_word_relocations
5871 && !arm_tls_referenced_p (operands[1])"
5872 [(clobber (const_int 0))]
5873{
5874 arm_emit_movpair (operands[0], operands[1]);
5875 DONE;
5876})
5877
bc360af8 5878;; When generating pic, we need to load the symbol offset into a register.
5879;; So that the optimizer does not confuse this with a normal symbol load
5880;; we use an unspec. The offset will be loaded from a constant pool entry,
5881;; since that is the only type of relocation we can use.
cffb2a26 5882
bc360af8 5883;; Wrap calculation of the whole PIC address in a single pattern for the
5884;; benefit of optimizers, particularly, PRE and HOIST. Calculation of
5885;; a PIC address involves two loads from memory, so we want to CSE it
5886;; as often as possible.
5887;; This pattern will be split into one of the pic_load_addr_* patterns
5888;; and a move after GCSE optimizations.
5889;;
5890;; Note: Update arm.c: legitimize_pic_address() when changing this pattern.
5891(define_expand "calculate_pic_address"
94f8caca 5892 [(set (match_operand:SI 0 "register_operand" "")
5893 (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "")
5894 (unspec:SI [(match_operand:SI 2 "" "")]
5895 UNSPEC_PIC_SYM))))]
5896 "flag_pic"
5897)
5898
5899;; Split calculate_pic_address into pic_load_addr_* and a move.
5900(define_split
5901 [(set (match_operand:SI 0 "register_operand" "")
5902 (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "")
5903 (unspec:SI [(match_operand:SI 2 "" "")]
5904 UNSPEC_PIC_SYM))))]
5905 "flag_pic"
5906 [(set (match_dup 3) (unspec:SI [(match_dup 2)] UNSPEC_PIC_SYM))
5907 (set (match_dup 0) (mem:SI (plus:SI (match_dup 1) (match_dup 3))))]
5908 "operands[3] = can_create_pseudo_p () ? gen_reg_rtx (SImode) : operands[0];"
5909)
5910
350ccca5 5911;; operand1 is the memory address to go into
5912;; pic_load_addr_32bit.
5913;; operand2 is the PIC label to be emitted
5914;; from pic_add_dot_plus_eight.
5915;; We do this to allow hoisting of the entire insn.
5916(define_insn_and_split "pic_load_addr_unified"
5917 [(set (match_operand:SI 0 "s_register_operand" "=r,r,l")
5918 (unspec:SI [(match_operand:SI 1 "" "mX,mX,mX")
5919 (match_operand:SI 2 "" "")]
5920 UNSPEC_PIC_UNIFIED))]
5921 "flag_pic"
5922 "#"
5923 "&& reload_completed"
5924 [(set (match_dup 0) (unspec:SI [(match_dup 1)] UNSPEC_PIC_SYM))
5925 (set (match_dup 0) (unspec:SI [(match_dup 0) (match_dup 3)
5926 (match_dup 2)] UNSPEC_PIC_BASE))]
5927 "operands[3] = TARGET_THUMB ? GEN_INT (4) : GEN_INT (8);"
5928 [(set_attr "type" "load1,load1,load1")
42e1de19 5929 (set_attr "pool_range" "4096,4094,1022")
350ccca5 5930 (set_attr "neg_pool_range" "4084,0,0")
5931 (set_attr "arch" "a,t2,t1")
5932 (set_attr "length" "8,6,4")]
5933)
5934
67336bcf 5935;; The rather odd constraints on the following are to force reload to leave
5936;; the insn alone, and to force the minipool generation pass to then move
5937;; the GOT symbol to memory.
849170fd 5938
b3cd5f55 5939(define_insn "pic_load_addr_32bit"
849170fd 5940 [(set (match_operand:SI 0 "s_register_operand" "=r")
e1159bbe 5941 (unspec:SI [(match_operand:SI 1 "" "mX")] UNSPEC_PIC_SYM))]
b3cd5f55 5942 "TARGET_32BIT && flag_pic"
67336bcf 5943 "ldr%?\\t%0, %1"
a2cd141b 5944 [(set_attr "type" "load1")
42e1de19 5945 (set (attr "pool_range")
5946 (if_then_else (eq_attr "is_thumb" "no")
5947 (const_int 4096)
5948 (const_int 4094)))
b3cd5f55 5949 (set (attr "neg_pool_range")
5950 (if_then_else (eq_attr "is_thumb" "no")
5951 (const_int 4084)
5952 (const_int 0)))]
8c4d8060 5953)
5954
25f905c2 5955(define_insn "pic_load_addr_thumb1"
8c4d8060 5956 [(set (match_operand:SI 0 "s_register_operand" "=l")
e1159bbe 5957 (unspec:SI [(match_operand:SI 1 "" "mX")] UNSPEC_PIC_SYM))]
25f905c2 5958 "TARGET_THUMB1 && flag_pic"
8c4d8060 5959 "ldr\\t%0, %1"
a2cd141b 5960 [(set_attr "type" "load1")
42e1de19 5961 (set (attr "pool_range") (const_int 1018))]
cffb2a26 5962)
849170fd 5963
cffb2a26 5964(define_insn "pic_add_dot_plus_four"
15d5d060 5965 [(set (match_operand:SI 0 "register_operand" "=r")
c0c1fba5 5966 (unspec:SI [(match_operand:SI 1 "register_operand" "0")
5967 (const_int 4)
beef0fb5 5968 (match_operand 2 "" "")]
5969 UNSPEC_PIC_BASE))]
b3cd5f55 5970 "TARGET_THUMB"
cffb2a26 5971 "*
6cdcb15c 5972 (*targetm.asm_out.internal_label) (asm_out_file, \"LPIC\",
5973 INTVAL (operands[2]));
cffb2a26 5974 return \"add\\t%0, %|pc\";
5975 "
1b7da4ac 5976 [(set_attr "length" "2")
112eda6f 5977 (set_attr "type" "alu_sreg")]
cffb2a26 5978)
849170fd 5979
5980(define_insn "pic_add_dot_plus_eight"
15d5d060 5981 [(set (match_operand:SI 0 "register_operand" "=r")
c0c1fba5 5982 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
5983 (const_int 8)
beef0fb5 5984 (match_operand 2 "" "")]
5985 UNSPEC_PIC_BASE))]
f655717d 5986 "TARGET_ARM"
c4034607 5987 "*
6cdcb15c 5988 (*targetm.asm_out.internal_label) (asm_out_file, \"LPIC\",
5989 INTVAL (operands[2]));
15d5d060 5990 return \"add%?\\t%0, %|pc, %1\";
cffb2a26 5991 "
1b7da4ac 5992 [(set_attr "predicable" "yes")
112eda6f 5993 (set_attr "type" "alu_sreg")]
cffb2a26 5994)
849170fd 5995
f655717d 5996(define_insn "tls_load_dot_plus_eight"
cc071db6 5997 [(set (match_operand:SI 0 "register_operand" "=r")
c0c1fba5 5998 (mem:SI (unspec:SI [(match_operand:SI 1 "register_operand" "r")
5999 (const_int 8)
beef0fb5 6000 (match_operand 2 "" "")]
6001 UNSPEC_PIC_BASE)))]
f655717d 6002 "TARGET_ARM"
6003 "*
6cdcb15c 6004 (*targetm.asm_out.internal_label) (asm_out_file, \"LPIC\",
6005 INTVAL (operands[2]));
f655717d 6006 return \"ldr%?\\t%0, [%|pc, %1]\t\t@ tls_load_dot_plus_eight\";
6007 "
1b7da4ac 6008 [(set_attr "predicable" "yes")
6009 (set_attr "type" "load1")]
f655717d 6010)
6011
6012;; PIC references to local variables can generate pic_add_dot_plus_eight
6013;; followed by a load. These sequences can be crunched down to
6014;; tls_load_dot_plus_eight by a peephole.
6015
6016(define_peephole2
c0c1fba5 6017 [(set (match_operand:SI 0 "register_operand" "")
6018 (unspec:SI [(match_operand:SI 3 "register_operand" "")
6019 (const_int 8)
6020 (match_operand 1 "" "")]
6021 UNSPEC_PIC_BASE))
2d05dfad 6022 (set (match_operand:SI 2 "arm_general_register_operand" "")
6023 (mem:SI (match_dup 0)))]
f655717d 6024 "TARGET_ARM && peep2_reg_dead_p (2, operands[0])"
c0c1fba5 6025 [(set (match_dup 2)
6026 (mem:SI (unspec:SI [(match_dup 3)
6027 (const_int 8)
6028 (match_dup 1)]
6029 UNSPEC_PIC_BASE)))]
f655717d 6030 ""
6031)
6032
bac7fc85 6033(define_insn "pic_offset_arm"
6034 [(set (match_operand:SI 0 "register_operand" "=r")
6035 (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
6036 (unspec:SI [(match_operand:SI 2 "" "X")]
6037 UNSPEC_PIC_OFFSET))))]
6038 "TARGET_VXWORKS_RTP && TARGET_ARM && flag_pic"
6039 "ldr%?\\t%0, [%1,%2]"
6040 [(set_attr "type" "load1")]
6041)
6042
95373f08 6043(define_expand "builtin_setjmp_receiver"
6044 [(label_ref (match_operand 0 "" ""))]
6045 "flag_pic"
6046 "
6047{
b935b306 6048 /* r3 is clobbered by set/longjmp, so we can use it as a scratch
6049 register. */
2cb7d577 6050 if (arm_pic_register != INVALID_REGNUM)
6051 arm_load_pic_register (1UL << 3);
95373f08 6052 DONE;
6053}")
6054
9c08d1fa 6055;; If copying one reg to another we can set the condition codes according to
6056;; its value. Such a move is common after a return from subroutine and the
6057;; result is being tested against zero.
6058
f7fbdd4a 6059(define_insn "*movsi_compare0"
bd5b4116 6060 [(set (reg:CC CC_REGNUM)
cffb2a26 6061 (compare:CC (match_operand:SI 1 "s_register_operand" "0,r")
6062 (const_int 0)))
6063 (set (match_operand:SI 0 "s_register_operand" "=r,r")
6064 (match_dup 1))]
25f905c2 6065 "TARGET_32BIT"
e2348bcb 6066 "@
40dbec34 6067 cmp%?\\t%0, #0
25f905c2 6068 sub%.\\t%0, %1, #0"
65f68e55 6069 [(set_attr "conds" "set")
d82e788e 6070 (set_attr "type" "alus_imm,alus_imm")]
cffb2a26 6071)
b11cae9e 6072
b11cae9e 6073;; Subroutine to store a half word from a register into memory.
6074;; Operand 0 is the source register (HImode)
c8f69309 6075;; Operand 1 is the destination address in a register (SImode)
b11cae9e 6076
9c08d1fa 6077;; In both this routine and the next, we must be careful not to spill
01cc3b75 6078;; a memory address of reg+large_const into a separate PLUS insn, since this
9c08d1fa 6079;; can generate unrecognizable rtl.
6080
b11cae9e 6081(define_expand "storehi"
c8f69309 6082 [;; store the low byte
f082f1c4 6083 (set (match_operand 1 "" "") (match_dup 3))
b11cae9e 6084 ;; extract the high byte
c8f69309 6085 (set (match_dup 2)
6086 (ashiftrt:SI (match_operand 0 "" "") (const_int 8)))
b11cae9e 6087 ;; store the high byte
787f8210 6088 (set (match_dup 4) (match_dup 5))]
cffb2a26 6089 "TARGET_ARM"
b11cae9e 6090 "
215b30b3 6091 {
537ffcfc 6092 rtx op1 = operands[1];
6093 rtx addr = XEXP (op1, 0);
215b30b3 6094 enum rtx_code code = GET_CODE (addr);
6095
0438d37f 6096 if ((code == PLUS && !CONST_INT_P (XEXP (addr, 1)))
215b30b3 6097 || code == MINUS)
537ffcfc 6098 op1 = replace_equiv_address (operands[1], force_reg (SImode, addr));
215b30b3 6099
537ffcfc 6100 operands[4] = adjust_address (op1, QImode, 1);
e513d163 6101 operands[1] = adjust_address (operands[1], QImode, 0);
215b30b3 6102 operands[3] = gen_lowpart (QImode, operands[0]);
6103 operands[0] = gen_lowpart (SImode, operands[0]);
787f8210 6104 operands[2] = gen_reg_rtx (SImode);
6105 operands[5] = gen_lowpart (QImode, operands[2]);
215b30b3 6106 }"
6107)
b11cae9e 6108
c7597b5d 6109(define_expand "storehi_bigend"
f082f1c4 6110 [(set (match_dup 4) (match_dup 3))
c7597b5d 6111 (set (match_dup 2)
6112 (ashiftrt:SI (match_operand 0 "" "") (const_int 8)))
787f8210 6113 (set (match_operand 1 "" "") (match_dup 5))]
cffb2a26 6114 "TARGET_ARM"
b11cae9e 6115 "
215b30b3 6116 {
537ffcfc 6117 rtx op1 = operands[1];
6118 rtx addr = XEXP (op1, 0);
215b30b3 6119 enum rtx_code code = GET_CODE (addr);
6120
0438d37f 6121 if ((code == PLUS && !CONST_INT_P (XEXP (addr, 1)))
215b30b3 6122 || code == MINUS)
537ffcfc 6123 op1 = replace_equiv_address (op1, force_reg (SImode, addr));
215b30b3 6124
537ffcfc 6125 operands[4] = adjust_address (op1, QImode, 1);
e513d163 6126 operands[1] = adjust_address (operands[1], QImode, 0);
215b30b3 6127 operands[3] = gen_lowpart (QImode, operands[0]);
6128 operands[0] = gen_lowpart (SImode, operands[0]);
6129 operands[2] = gen_reg_rtx (SImode);
787f8210 6130 operands[5] = gen_lowpart (QImode, operands[2]);
215b30b3 6131 }"
6132)
c7597b5d 6133
6134;; Subroutine to store a half word integer constant into memory.
6135(define_expand "storeinthi"
f082f1c4 6136 [(set (match_operand 0 "" "")
787f8210 6137 (match_operand 1 "" ""))
9e8503e6 6138 (set (match_dup 3) (match_dup 2))]
cffb2a26 6139 "TARGET_ARM"
c7597b5d 6140 "
215b30b3 6141 {
6142 HOST_WIDE_INT value = INTVAL (operands[1]);
6143 rtx addr = XEXP (operands[0], 0);
537ffcfc 6144 rtx op0 = operands[0];
215b30b3 6145 enum rtx_code code = GET_CODE (addr);
c7597b5d 6146
0438d37f 6147 if ((code == PLUS && !CONST_INT_P (XEXP (addr, 1)))
215b30b3 6148 || code == MINUS)
537ffcfc 6149 op0 = replace_equiv_address (op0, force_reg (SImode, addr));
c7597b5d 6150
215b30b3 6151 operands[1] = gen_reg_rtx (SImode);
6152 if (BYTES_BIG_ENDIAN)
6153 {
6154 emit_insn (gen_movsi (operands[1], GEN_INT ((value >> 8) & 255)));
6155 if ((value & 255) == ((value >> 8) & 255))
6156 operands[2] = operands[1];
6157 else
6158 {
6159 operands[2] = gen_reg_rtx (SImode);
6160 emit_insn (gen_movsi (operands[2], GEN_INT (value & 255)));
6161 }
6162 }
6163 else
6164 {
6165 emit_insn (gen_movsi (operands[1], GEN_INT (value & 255)));
6166 if ((value & 255) == ((value >> 8) & 255))
6167 operands[2] = operands[1];
6168 else
6169 {
6170 operands[2] = gen_reg_rtx (SImode);
6171 emit_insn (gen_movsi (operands[2], GEN_INT ((value >> 8) & 255)));
6172 }
6173 }
c7597b5d 6174
537ffcfc 6175 operands[3] = adjust_address (op0, QImode, 1);
e513d163 6176 operands[0] = adjust_address (operands[0], QImode, 0);
9e8503e6 6177 operands[2] = gen_lowpart (QImode, operands[2]);
787f8210 6178 operands[1] = gen_lowpart (QImode, operands[1]);
215b30b3 6179 }"
6180)
b11cae9e 6181
f7fbdd4a 6182(define_expand "storehi_single_op"
6183 [(set (match_operand:HI 0 "memory_operand" "")
6184 (match_operand:HI 1 "general_operand" ""))]
25f905c2 6185 "TARGET_32BIT && arm_arch4"
f7fbdd4a 6186 "
215b30b3 6187 if (!s_register_operand (operands[1], HImode))
f7fbdd4a 6188 operands[1] = copy_to_mode_reg (HImode, operands[1]);
215b30b3 6189 "
6190)
f7fbdd4a 6191
b11cae9e 6192(define_expand "movhi"
6193 [(set (match_operand:HI 0 "general_operand" "")
c8f69309 6194 (match_operand:HI 1 "general_operand" ""))]
cffb2a26 6195 "TARGET_EITHER"
b11cae9e 6196 "
cffb2a26 6197 if (TARGET_ARM)
b11cae9e 6198 {
e1ba4a27 6199 if (can_create_pseudo_p ())
cffb2a26 6200 {
0438d37f 6201 if (MEM_P (operands[0]))
b11cae9e 6202 {
cffb2a26 6203 if (arm_arch4)
6204 {
6205 emit_insn (gen_storehi_single_op (operands[0], operands[1]));
6206 DONE;
6207 }
0438d37f 6208 if (CONST_INT_P (operands[1]))
cffb2a26 6209 emit_insn (gen_storeinthi (operands[0], operands[1]));
c7597b5d 6210 else
cffb2a26 6211 {
0438d37f 6212 if (MEM_P (operands[1]))
cffb2a26 6213 operands[1] = force_reg (HImode, operands[1]);
6214 if (BYTES_BIG_ENDIAN)
6215 emit_insn (gen_storehi_bigend (operands[1], operands[0]));
6216 else
6217 emit_insn (gen_storehi (operands[1], operands[0]));
6218 }
6219 DONE;
b11cae9e 6220 }
cffb2a26 6221 /* Sign extend a constant, and keep it in an SImode reg. */
0438d37f 6222 else if (CONST_INT_P (operands[1]))
9c08d1fa 6223 {
cffb2a26 6224 rtx reg = gen_reg_rtx (SImode);
6225 HOST_WIDE_INT val = INTVAL (operands[1]) & 0xffff;
6226
6227 /* If the constant is already valid, leave it alone. */
215b30b3 6228 if (!const_ok_for_arm (val))
cffb2a26 6229 {
6230 /* If setting all the top bits will make the constant
6231 loadable in a single instruction, then set them.
6232 Otherwise, sign extend the number. */
6233
215b30b3 6234 if (const_ok_for_arm (~(val | ~0xffff)))
cffb2a26 6235 val |= ~0xffff;
6236 else if (val & 0x8000)
6237 val |= ~0xffff;
6238 }
6239
6240 emit_insn (gen_movsi (reg, GEN_INT (val)));
9e8503e6 6241 operands[1] = gen_lowpart (HImode, reg);
9c08d1fa 6242 }
e1ba4a27 6243 else if (arm_arch4 && optimize && can_create_pseudo_p ()
0438d37f 6244 && MEM_P (operands[1]))
0045890a 6245 {
6246 rtx reg = gen_reg_rtx (SImode);
6247
6248 emit_insn (gen_zero_extendhisi2 (reg, operands[1]));
6249 operands[1] = gen_lowpart (HImode, reg);
6250 }
215b30b3 6251 else if (!arm_arch4)
f7fbdd4a 6252 {
0438d37f 6253 if (MEM_P (operands[1]))
cffb2a26 6254 {
c1a66faf 6255 rtx base;
6256 rtx offset = const0_rtx;
6257 rtx reg = gen_reg_rtx (SImode);
6258
0438d37f 6259 if ((REG_P (base = XEXP (operands[1], 0))
c1a66faf 6260 || (GET_CODE (base) == PLUS
0438d37f 6261 && (CONST_INT_P (offset = XEXP (base, 1)))
c1a66faf 6262 && ((INTVAL(offset) & 1) != 1)
0438d37f 6263 && REG_P (base = XEXP (base, 0))))
c1a66faf 6264 && REGNO_POINTER_ALIGN (REGNO (base)) >= 32)
206ee9a2 6265 {
8deb3959 6266 rtx new_rtx;
c1a66faf 6267
8deb3959 6268 new_rtx = widen_memory_access (operands[1], SImode,
6269 ((INTVAL (offset) & ~3)
6270 - INTVAL (offset)));
6271 emit_insn (gen_movsi (reg, new_rtx));
c1a66faf 6272 if (((INTVAL (offset) & 2) != 0)
6273 ^ (BYTES_BIG_ENDIAN ? 1 : 0))
6274 {
6275 rtx reg2 = gen_reg_rtx (SImode);
6276
6277 emit_insn (gen_lshrsi3 (reg2, reg, GEN_INT (16)));
6278 reg = reg2;
6279 }
206ee9a2 6280 }
c1a66faf 6281 else
6282 emit_insn (gen_movhi_bytes (reg, operands[1]));
6283
6284 operands[1] = gen_lowpart (HImode, reg);
cffb2a26 6285 }
6286 }
6287 }
674a8f0b 6288 /* Handle loading a large integer during reload. */
0438d37f 6289 else if (CONST_INT_P (operands[1])
215b30b3 6290 && !const_ok_for_arm (INTVAL (operands[1]))
6291 && !const_ok_for_arm (~INTVAL (operands[1])))
cffb2a26 6292 {
6293 /* Writing a constant to memory needs a scratch, which should
6294 be handled with SECONDARY_RELOADs. */
0438d37f 6295 gcc_assert (REG_P (operands[0]));
cffb2a26 6296
6297 operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
6298 emit_insn (gen_movsi (operands[0], operands[1]));
6299 DONE;
6300 }
6301 }
25f905c2 6302 else if (TARGET_THUMB2)
6303 {
6304 /* Thumb-2 can do everything except mem=mem and mem=const easily. */
e1ba4a27 6305 if (can_create_pseudo_p ())
25f905c2 6306 {
0438d37f 6307 if (!REG_P (operands[0]))
25f905c2 6308 operands[1] = force_reg (HImode, operands[1]);
6309 /* Zero extend a constant, and keep it in an SImode reg. */
0438d37f 6310 else if (CONST_INT_P (operands[1]))
25f905c2 6311 {
6312 rtx reg = gen_reg_rtx (SImode);
6313 HOST_WIDE_INT val = INTVAL (operands[1]) & 0xffff;
6314
6315 emit_insn (gen_movsi (reg, GEN_INT (val)));
6316 operands[1] = gen_lowpart (HImode, reg);
6317 }
6318 }
6319 }
6320 else /* TARGET_THUMB1 */
cffb2a26 6321 {
e1ba4a27 6322 if (can_create_pseudo_p ())
cffb2a26 6323 {
0438d37f 6324 if (CONST_INT_P (operands[1]))
6cffc037 6325 {
6326 rtx reg = gen_reg_rtx (SImode);
6327
6328 emit_insn (gen_movsi (reg, operands[1]));
6329 operands[1] = gen_lowpart (HImode, reg);
6330 }
cffb2a26 6331
6332 /* ??? We shouldn't really get invalid addresses here, but this can
215b30b3 6333 happen if we are passed a SP (never OK for HImode/QImode) or
bc409cb4 6334 virtual register (also rejected as illegitimate for HImode/QImode)
6335 relative address. */
cffb2a26 6336 /* ??? This should perhaps be fixed elsewhere, for instance, in
6337 fixup_stack_1, by checking for other kinds of invalid addresses,
6338 e.g. a bare reference to a virtual register. This may confuse the
6339 alpha though, which must handle this case differently. */
0438d37f 6340 if (MEM_P (operands[0])
215b30b3 6341 && !memory_address_p (GET_MODE (operands[0]),
6342 XEXP (operands[0], 0)))
537ffcfc 6343 operands[0]
6344 = replace_equiv_address (operands[0],
6345 copy_to_reg (XEXP (operands[0], 0)));
cffb2a26 6346
0438d37f 6347 if (MEM_P (operands[1])
215b30b3 6348 && !memory_address_p (GET_MODE (operands[1]),
6349 XEXP (operands[1], 0)))
537ffcfc 6350 operands[1]
6351 = replace_equiv_address (operands[1],
6352 copy_to_reg (XEXP (operands[1], 0)));
6cffc037 6353
0438d37f 6354 if (MEM_P (operands[1]) && optimize > 0)
6cffc037 6355 {
6356 rtx reg = gen_reg_rtx (SImode);
6357
6358 emit_insn (gen_zero_extendhisi2 (reg, operands[1]));
6359 operands[1] = gen_lowpart (HImode, reg);
6360 }
6361
0438d37f 6362 if (MEM_P (operands[0]))
6cffc037 6363 operands[1] = force_reg (HImode, operands[1]);
cffb2a26 6364 }
0438d37f 6365 else if (CONST_INT_P (operands[1])
234f6557 6366 && !satisfies_constraint_I (operands[1]))
cffb2a26 6367 {
6cffc037 6368 /* Handle loading a large integer during reload. */
6369
cffb2a26 6370 /* Writing a constant to memory needs a scratch, which should
6371 be handled with SECONDARY_RELOADs. */
0438d37f 6372 gcc_assert (REG_P (operands[0]));
cffb2a26 6373
1a83b3ff 6374 operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
cffb2a26 6375 emit_insn (gen_movsi (operands[0], operands[1]));
6376 DONE;
6377 }
b11cae9e 6378 }
cffb2a26 6379 "
6380)
6381
25f7a26e 6382(define_expand "movhi_bytes"
eab14235 6383 [(set (match_dup 2) (zero_extend:SI (match_operand:HI 1 "" "")))
25f7a26e 6384 (set (match_dup 3)
eab14235 6385 (zero_extend:SI (match_dup 6)))
25f7a26e 6386 (set (match_operand:SI 0 "" "")
6387 (ior:SI (ashift:SI (match_dup 4) (const_int 8)) (match_dup 5)))]
cffb2a26 6388 "TARGET_ARM"
25f7a26e 6389 "
215b30b3 6390 {
6391 rtx mem1, mem2;
6392 rtx addr = copy_to_mode_reg (SImode, XEXP (operands[1], 0));
6393
788fcce0 6394 mem1 = change_address (operands[1], QImode, addr);
29c05e22 6395 mem2 = change_address (operands[1], QImode,
6396 plus_constant (Pmode, addr, 1));
215b30b3 6397 operands[0] = gen_lowpart (SImode, operands[0]);
6398 operands[1] = mem1;
6399 operands[2] = gen_reg_rtx (SImode);
6400 operands[3] = gen_reg_rtx (SImode);
6401 operands[6] = mem2;
25f7a26e 6402
215b30b3 6403 if (BYTES_BIG_ENDIAN)
6404 {
6405 operands[4] = operands[2];
6406 operands[5] = operands[3];
6407 }
6408 else
6409 {
6410 operands[4] = operands[3];
6411 operands[5] = operands[2];
6412 }
6413 }"
6414)
25f7a26e 6415
c7597b5d 6416(define_expand "movhi_bigend"
6417 [(set (match_dup 2)
6418 (rotate:SI (subreg:SI (match_operand:HI 1 "memory_operand" "") 0)
6419 (const_int 16)))
6420 (set (match_dup 3)
6421 (ashiftrt:SI (match_dup 2) (const_int 16)))
6422 (set (match_operand:HI 0 "s_register_operand" "")
787f8210 6423 (match_dup 4))]
cffb2a26 6424 "TARGET_ARM"
c7597b5d 6425 "
6426 operands[2] = gen_reg_rtx (SImode);
6427 operands[3] = gen_reg_rtx (SImode);
787f8210 6428 operands[4] = gen_lowpart (HImode, operands[3]);
215b30b3 6429 "
6430)
b11cae9e 6431
a2f10574 6432;; Pattern to recognize insn generated default case above
f7fbdd4a 6433(define_insn "*movhi_insn_arch4"
e4585731 6434 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m,r")
6435 (match_operand:HI 1 "general_operand" "rIk,K,n,r,mi"))]
cffb2a26 6436 "TARGET_ARM
6437 && arm_arch4
85e02ccb 6438 && (register_operand (operands[0], HImode)
6439 || register_operand (operands[1], HImode))"
f7fbdd4a 6440 "@
6441 mov%?\\t%0, %1\\t%@ movhi
6442 mvn%?\\t%0, #%B1\\t%@ movhi
b1c1a101 6443 movw%?\\t%0, %L1\\t%@ movhi
25f905c2 6444 str%(h%)\\t%1, %0\\t%@ movhi
6445 ldr%(h%)\\t%0, %1\\t%@ movhi"
65f68e55 6446 [(set_attr "predicable" "yes")
e4585731 6447 (set_attr "pool_range" "*,*,*,*,256")
6448 (set_attr "neg_pool_range" "*,*,*,*,244")
6449 (set_attr "arch" "*,*,v6t2,*,*")
65f68e55 6450 (set_attr_alternative "type"
6451 [(if_then_else (match_operand 1 "const_int_operand" "")
1aed5204 6452 (const_string "mov_imm" )
6453 (const_string "mov_reg"))
6454 (const_string "mvn_imm")
e4585731 6455 (const_string "mov_imm")
65f68e55 6456 (const_string "store1")
6457 (const_string "load1")])]
cffb2a26 6458)
f7fbdd4a 6459
f7fbdd4a 6460(define_insn "*movhi_bytes"
65f68e55 6461 [(set (match_operand:HI 0 "s_register_operand" "=r,r,r")
5fd254ed 6462 (match_operand:HI 1 "arm_rhs_operand" "I,rk,K"))]
c1a66faf 6463 "TARGET_ARM"
25f7a26e 6464 "@
65f68e55 6465 mov%?\\t%0, %1\\t%@ movhi
25f7a26e 6466 mov%?\\t%0, %1\\t%@ movhi
0d66636f 6467 mvn%?\\t%0, #%B1\\t%@ movhi"
d2a518d1 6468 [(set_attr "predicable" "yes")
1aed5204 6469 (set_attr "type" "mov_imm,mov_reg,mvn_imm")]
0d66636f 6470)
cffb2a26 6471
bc5c7e08 6472;; We use a DImode scratch because we may occasionally need an additional
6473;; temporary if the address isn't offsettable -- push_reload doesn't seem
6474;; to take any notice of the "o" constraints on reload_memory_operand operand.
d3373b54 6475(define_expand "reload_outhi"
cffb2a26 6476 [(parallel [(match_operand:HI 0 "arm_reload_memory_operand" "=o")
215b30b3 6477 (match_operand:HI 1 "s_register_operand" "r")
6478 (match_operand:DI 2 "s_register_operand" "=&l")])]
cffb2a26 6479 "TARGET_EITHER"
6480 "if (TARGET_ARM)
6481 arm_reload_out_hi (operands);
6482 else
6483 thumb_reload_out_hi (operands);
d3373b54 6484 DONE;
cffb2a26 6485 "
6486)
d3373b54 6487
25f7a26e 6488(define_expand "reload_inhi"
6489 [(parallel [(match_operand:HI 0 "s_register_operand" "=r")
cffb2a26 6490 (match_operand:HI 1 "arm_reload_memory_operand" "o")
bc5c7e08 6491 (match_operand:DI 2 "s_register_operand" "=&r")])]
c1a66faf 6492 "TARGET_EITHER"
25f7a26e 6493 "
cffb2a26 6494 if (TARGET_ARM)
6495 arm_reload_in_hi (operands);
6496 else
6497 thumb_reload_out_hi (operands);
25f7a26e 6498 DONE;
6499")
6500
9c08d1fa 6501(define_expand "movqi"
6502 [(set (match_operand:QI 0 "general_operand" "")
6503 (match_operand:QI 1 "general_operand" ""))]
cffb2a26 6504 "TARGET_EITHER"
9c08d1fa 6505 "
6cffc037 6506 /* Everything except mem = const or mem = mem can be done easily */
0045890a 6507
e1ba4a27 6508 if (can_create_pseudo_p ())
cffb2a26 6509 {
0438d37f 6510 if (CONST_INT_P (operands[1]))
6cffc037 6511 {
6512 rtx reg = gen_reg_rtx (SImode);
6513
03770691 6514 /* For thumb we want an unsigned immediate, then we are more likely
6515 to be able to use a movs insn. */
6516 if (TARGET_THUMB)
6517 operands[1] = GEN_INT (INTVAL (operands[1]) & 255);
6518
6cffc037 6519 emit_insn (gen_movsi (reg, operands[1]));
6520 operands[1] = gen_lowpart (QImode, reg);
6521 }
cffb2a26 6522
6cffc037 6523 if (TARGET_THUMB)
6524 {
cffb2a26 6525 /* ??? We shouldn't really get invalid addresses here, but this can
215b30b3 6526 happen if we are passed a SP (never OK for HImode/QImode) or
bc409cb4 6527 virtual register (also rejected as illegitimate for HImode/QImode)
6528 relative address. */
cffb2a26 6529 /* ??? This should perhaps be fixed elsewhere, for instance, in
6530 fixup_stack_1, by checking for other kinds of invalid addresses,
6531 e.g. a bare reference to a virtual register. This may confuse the
6532 alpha though, which must handle this case differently. */
0438d37f 6533 if (MEM_P (operands[0])
215b30b3 6534 && !memory_address_p (GET_MODE (operands[0]),
cffb2a26 6535 XEXP (operands[0], 0)))
537ffcfc 6536 operands[0]
6537 = replace_equiv_address (operands[0],
6538 copy_to_reg (XEXP (operands[0], 0)));
0438d37f 6539 if (MEM_P (operands[1])
215b30b3 6540 && !memory_address_p (GET_MODE (operands[1]),
cffb2a26 6541 XEXP (operands[1], 0)))
537ffcfc 6542 operands[1]
6543 = replace_equiv_address (operands[1],
6544 copy_to_reg (XEXP (operands[1], 0)));
6cffc037 6545 }
6546
0438d37f 6547 if (MEM_P (operands[1]) && optimize > 0)
6cffc037 6548 {
6549 rtx reg = gen_reg_rtx (SImode);
6550
6551 emit_insn (gen_zero_extendqisi2 (reg, operands[1]));
6552 operands[1] = gen_lowpart (QImode, reg);
6553 }
6554
0438d37f 6555 if (MEM_P (operands[0]))
6cffc037 6556 operands[1] = force_reg (QImode, operands[1]);
6557 }
6558 else if (TARGET_THUMB
0438d37f 6559 && CONST_INT_P (operands[1])
234f6557 6560 && !satisfies_constraint_I (operands[1]))
6cffc037 6561 {
674a8f0b 6562 /* Handle loading a large integer during reload. */
cffb2a26 6563
6cffc037 6564 /* Writing a constant to memory needs a scratch, which should
6565 be handled with SECONDARY_RELOADs. */
0438d37f 6566 gcc_assert (REG_P (operands[0]));
6cffc037 6567
6568 operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
6569 emit_insn (gen_movsi (operands[0], operands[1]));
6570 DONE;
cffb2a26 6571 }
6572 "
6573)
b11cae9e 6574
cffb2a26 6575(define_insn "*arm_movqi_insn"
fd711051 6576 [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,r,l,r,l,Uu,r,m")
490f62ca 6577 (match_operand:QI 1 "general_operand" "rk,rk,I,Py,K,Uu,l,Uh,r"))]
25f905c2 6578 "TARGET_32BIT
cffb2a26 6579 && ( register_operand (operands[0], QImode)
6580 || register_operand (operands[1], QImode))"
5565501b 6581 "@
fd711051 6582 mov%?\\t%0, %1
6583 mov%?\\t%0, %1
65f68e55 6584 mov%?\\t%0, %1
5565501b 6585 mov%?\\t%0, %1
6586 mvn%?\\t%0, #%B1
25f905c2 6587 ldr%(b%)\\t%0, %1
a54e3e7b 6588 str%(b%)\\t%1, %0
6589 ldr%(b%)\\t%0, %1
25f905c2 6590 str%(b%)\\t%1, %0"
1aed5204 6591 [(set_attr "type" "mov_reg,mov_reg,mov_imm,mov_imm,mvn_imm,load1,store1,load1,store1")
a54e3e7b 6592 (set_attr "predicable" "yes")
fd711051 6593 (set_attr "predicable_short_it" "yes,yes,yes,no,no,no,no,no,no")
6594 (set_attr "arch" "t2,any,any,t2,any,t2,t2,any,any")
6595 (set_attr "length" "2,4,4,2,4,2,2,4,4")]
cffb2a26 6596)
6597
9b8516be 6598;; HFmode moves
6599(define_expand "movhf"
6600 [(set (match_operand:HF 0 "general_operand" "")
6601 (match_operand:HF 1 "general_operand" ""))]
6602 "TARGET_EITHER"
6603 "
6604 if (TARGET_32BIT)
6605 {
0438d37f 6606 if (MEM_P (operands[0]))
9b8516be 6607 operands[1] = force_reg (HFmode, operands[1]);
6608 }
6609 else /* TARGET_THUMB1 */
6610 {
6611 if (can_create_pseudo_p ())
6612 {
0438d37f 6613 if (!REG_P (operands[0]))
9b8516be 6614 operands[1] = force_reg (HFmode, operands[1]);
6615 }
6616 }
6617 "
6618)
6619
6620(define_insn "*arm32_movhf"
6621 [(set (match_operand:HF 0 "nonimmediate_operand" "=r,m,r,r")
6622 (match_operand:HF 1 "general_operand" " m,r,r,F"))]
ea501323 6623 "TARGET_32BIT && !(TARGET_HARD_FLOAT && TARGET_FP16)
9b8516be 6624 && ( s_register_operand (operands[0], HFmode)
6625 || s_register_operand (operands[1], HFmode))"
6626 "*
6627 switch (which_alternative)
6628 {
6629 case 0: /* ARM register from memory */
6630 return \"ldr%(h%)\\t%0, %1\\t%@ __fp16\";
6631 case 1: /* memory from ARM register */
6632 return \"str%(h%)\\t%1, %0\\t%@ __fp16\";
6633 case 2: /* ARM register from ARM register */
6634 return \"mov%?\\t%0, %1\\t%@ __fp16\";
6635 case 3: /* ARM register from constant */
6636 {
9b8516be 6637 long bits;
6638 rtx ops[4];
6639
945f7b03 6640 bits = real_to_target (NULL, CONST_DOUBLE_REAL_VALUE (operands[1]),
6641 HFmode);
9b8516be 6642 ops[0] = operands[0];
6643 ops[1] = GEN_INT (bits);
6644 ops[2] = GEN_INT (bits & 0xff00);
6645 ops[3] = GEN_INT (bits & 0x00ff);
6646
6647 if (arm_arch_thumb2)
6648 output_asm_insn (\"movw%?\\t%0, %1\", ops);
6649 else
6650 output_asm_insn (\"mov%?\\t%0, %2\;orr%?\\t%0, %0, %3\", ops);
6651 return \"\";
6652 }
6653 default:
6654 gcc_unreachable ();
6655 }
6656 "
6657 [(set_attr "conds" "unconditional")
ad4fc3c0 6658 (set_attr "type" "load1,store1,mov_reg,multiple")
9b8516be 6659 (set_attr "length" "4,4,4,8")
ea501323 6660 (set_attr "predicable" "yes")
6661 (set_attr "predicable_short_it" "no")]
9b8516be 6662)
6663
87b22bf7 6664(define_expand "movsf"
6665 [(set (match_operand:SF 0 "general_operand" "")
6666 (match_operand:SF 1 "general_operand" ""))]
cffb2a26 6667 "TARGET_EITHER"
87b22bf7 6668 "
25f905c2 6669 if (TARGET_32BIT)
cffb2a26 6670 {
0438d37f 6671 if (MEM_P (operands[0]))
cffb2a26 6672 operands[1] = force_reg (SFmode, operands[1]);
6673 }
25f905c2 6674 else /* TARGET_THUMB1 */
cffb2a26 6675 {
e1ba4a27 6676 if (can_create_pseudo_p ())
cffb2a26 6677 {
0438d37f 6678 if (!REG_P (operands[0]))
cffb2a26 6679 operands[1] = force_reg (SFmode, operands[1]);
6680 }
6681 }
6682 "
6683)
6684
03d440a6 6685;; Transform a floating-point move of a constant into a core register into
6686;; an SImode operation.
cffb2a26 6687(define_split
03d440a6 6688 [(set (match_operand:SF 0 "arm_general_register_operand" "")
cffb2a26 6689 (match_operand:SF 1 "immediate_operand" ""))]
339034d0 6690 "TARGET_EITHER
cffb2a26 6691 && reload_completed
0438d37f 6692 && CONST_DOUBLE_P (operands[1])"
cffb2a26 6693 [(set (match_dup 2) (match_dup 3))]
6694 "
6695 operands[2] = gen_lowpart (SImode, operands[0]);
6696 operands[3] = gen_lowpart (SImode, operands[1]);
6697 if (operands[2] == 0 || operands[3] == 0)
6698 FAIL;
215b30b3 6699 "
6700)
87b22bf7 6701
cffb2a26 6702(define_insn "*arm_movsf_soft_insn"
6703 [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,m")
6704 (match_operand:SF 1 "general_operand" "r,mE,r"))]
cde1623a 6705 "TARGET_32BIT
cffb2a26 6706 && TARGET_SOFT_FLOAT
0438d37f 6707 && (!MEM_P (operands[0])
215b30b3 6708 || register_operand (operands[1], SFmode))"
9a1112d7 6709 "@
6710 mov%?\\t%0, %1
6711 ldr%?\\t%0, %1\\t%@ float
6712 str%?\\t%1, %0\\t%@ float"
cde1623a 6713 [(set_attr "predicable" "yes")
7c36fe71 6714 (set_attr "predicable_short_it" "no")
1aed5204 6715 (set_attr "type" "mov_reg,load1,store1")
42e1de19 6716 (set_attr "arm_pool_range" "*,4096,*")
6717 (set_attr "thumb2_pool_range" "*,4094,*")
cde1623a 6718 (set_attr "arm_neg_pool_range" "*,4084,*")
6719 (set_attr "thumb2_neg_pool_range" "*,0,*")]
cffb2a26 6720)
6721
9c08d1fa 6722(define_expand "movdf"
87b22bf7 6723 [(set (match_operand:DF 0 "general_operand" "")
6724 (match_operand:DF 1 "general_operand" ""))]
cffb2a26 6725 "TARGET_EITHER"
9c08d1fa 6726 "
25f905c2 6727 if (TARGET_32BIT)
cffb2a26 6728 {
0438d37f 6729 if (MEM_P (operands[0]))
cffb2a26 6730 operands[1] = force_reg (DFmode, operands[1]);
6731 }
6732 else /* TARGET_THUMB */
6733 {
e1ba4a27 6734 if (can_create_pseudo_p ())
cffb2a26 6735 {
0438d37f 6736 if (!REG_P (operands[0]))
cffb2a26 6737 operands[1] = force_reg (DFmode, operands[1]);
6738 }
6739 }
6740 "
6741)
b11cae9e 6742
9c08d1fa 6743;; Reloading a df mode value stored in integer regs to memory can require a
6744;; scratch reg.
6745(define_expand "reload_outdf"
cffb2a26 6746 [(match_operand:DF 0 "arm_reload_memory_operand" "=o")
87b22bf7 6747 (match_operand:DF 1 "s_register_operand" "r")
6748 (match_operand:SI 2 "s_register_operand" "=&r")]
06adefdc 6749 "TARGET_THUMB2"
87b22bf7 6750 "
215b30b3 6751 {
6752 enum rtx_code code = GET_CODE (XEXP (operands[0], 0));
f7fbdd4a 6753
215b30b3 6754 if (code == REG)
6755 operands[2] = XEXP (operands[0], 0);
6756 else if (code == POST_INC || code == PRE_DEC)
6757 {
6758 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
6759 operands[1] = gen_rtx_SUBREG (DImode, operands[1], 0);
6760 emit_insn (gen_movdi (operands[0], operands[1]));
6761 DONE;
6762 }
6763 else if (code == PRE_INC)
6764 {
6765 rtx reg = XEXP (XEXP (operands[0], 0), 0);
f7fbdd4a 6766
215b30b3 6767 emit_insn (gen_addsi3 (reg, reg, GEN_INT (8)));
6768 operands[2] = reg;
6769 }
6770 else if (code == POST_DEC)
6771 operands[2] = XEXP (XEXP (operands[0], 0), 0);
6772 else
6773 emit_insn (gen_addsi3 (operands[2], XEXP (XEXP (operands[0], 0), 0),
6774 XEXP (XEXP (operands[0], 0), 1)));
f7fbdd4a 6775
d1f9b275 6776 emit_insn (gen_rtx_SET (replace_equiv_address (operands[0], operands[2]),
215b30b3 6777 operands[1]));
f7fbdd4a 6778
215b30b3 6779 if (code == POST_DEC)
6780 emit_insn (gen_addsi3 (operands[2], operands[2], GEN_INT (-8)));
6781
6782 DONE;
6783 }"
6784)
9c08d1fa 6785
9a1112d7 6786(define_insn "*movdf_soft_insn"
353cf59a 6787 [(set (match_operand:DF 0 "nonimmediate_soft_df_operand" "=r,r,r,q,m")
6788 (match_operand:DF 1 "soft_df_operand" "rDa,Db,Dc,mF,q"))]
cde1623a 6789 "TARGET_32BIT && TARGET_SOFT_FLOAT
b2778788 6790 && ( register_operand (operands[0], DFmode)
6791 || register_operand (operands[1], DFmode))"
d51f92df 6792 "*
6793 switch (which_alternative)
6794 {
6795 case 0:
6796 case 1:
6797 case 2:
6798 return \"#\";
6799 default:
26ff80c0 6800 return output_move_double (operands, true, NULL);
d51f92df 6801 }
6802 "
359a6e9f 6803 [(set_attr "length" "8,12,16,8,8")
1b7da4ac 6804 (set_attr "type" "multiple,multiple,multiple,load2,store2")
42e1de19 6805 (set_attr "arm_pool_range" "*,*,*,1020,*")
6806 (set_attr "thumb2_pool_range" "*,*,*,1018,*")
8848d797 6807 (set_attr "arm_neg_pool_range" "*,*,*,1004,*")
cde1623a 6808 (set_attr "thumb2_neg_pool_range" "*,*,*,0,*")]
cffb2a26 6809)
b11cae9e 6810\f
b11cae9e 6811
9c08d1fa 6812;; load- and store-multiple insns
6813;; The arm can load/store any set of registers, provided that they are in
320ea44d 6814;; ascending order, but these expanders assume a contiguous set.
b11cae9e 6815
9c08d1fa 6816(define_expand "load_multiple"
6817 [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
6818 (match_operand:SI 1 "" ""))
6819 (use (match_operand:SI 2 "" ""))])]
25f905c2 6820 "TARGET_32BIT"
9580c25f 6821{
6822 HOST_WIDE_INT offset = 0;
6823
bd5b4116 6824 /* Support only fixed point registers. */
0438d37f 6825 if (!CONST_INT_P (operands[2])
6e628811 6826 || INTVAL (operands[2]) > MAX_LDM_STM_OPS
9c08d1fa 6827 || INTVAL (operands[2]) < 2
0438d37f 6828 || !MEM_P (operands[1])
6829 || !REG_P (operands[0])
bd5b4116 6830 || REGNO (operands[0]) > (LAST_ARM_REGNUM - 1)
6831 || REGNO (operands[0]) + INTVAL (operands[2]) > LAST_ARM_REGNUM)
9c08d1fa 6832 FAIL;
6833
6834 operands[3]
320ea44d 6835 = arm_gen_load_multiple (arm_regs_in_sequence + REGNO (operands[0]),
6836 INTVAL (operands[2]),
f082f1c4 6837 force_reg (SImode, XEXP (operands[1], 0)),
320ea44d 6838 FALSE, operands[1], &offset);
9580c25f 6839})
b11cae9e 6840
9c08d1fa 6841(define_expand "store_multiple"
6842 [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
6843 (match_operand:SI 1 "" ""))
6844 (use (match_operand:SI 2 "" ""))])]
25f905c2 6845 "TARGET_32BIT"
9580c25f 6846{
6847 HOST_WIDE_INT offset = 0;
6848
674a8f0b 6849 /* Support only fixed point registers. */
0438d37f 6850 if (!CONST_INT_P (operands[2])
6e628811 6851 || INTVAL (operands[2]) > MAX_LDM_STM_OPS
9c08d1fa 6852 || INTVAL (operands[2]) < 2
0438d37f 6853 || !REG_P (operands[1])
6854 || !MEM_P (operands[0])
bd5b4116 6855 || REGNO (operands[1]) > (LAST_ARM_REGNUM - 1)
6856 || REGNO (operands[1]) + INTVAL (operands[2]) > LAST_ARM_REGNUM)
9c08d1fa 6857 FAIL;
6858
6859 operands[3]
320ea44d 6860 = arm_gen_store_multiple (arm_regs_in_sequence + REGNO (operands[1]),
6861 INTVAL (operands[2]),
f082f1c4 6862 force_reg (SImode, XEXP (operands[0], 0)),
320ea44d 6863 FALSE, operands[0], &offset);
9580c25f 6864})
b11cae9e 6865
9c08d1fa 6866
e34ebfca 6867(define_expand "setmemsi"
6868 [(match_operand:BLK 0 "general_operand" "")
6869 (match_operand:SI 1 "const_int_operand" "")
6870 (match_operand:SI 2 "const_int_operand" "")
6871 (match_operand:SI 3 "const_int_operand" "")]
6872 "TARGET_32BIT"
6873{
6874 if (arm_gen_setmem (operands))
6875 DONE;
6876
6877 FAIL;
6878})
6879
6880
9c08d1fa 6881;; Move a block of memory if it is word aligned and MORE than 2 words long.
6882;; We could let this apply for blocks of less than this, but it clobbers so
6883;; many registers that there is then probably a better way.
6884
008c057d 6885(define_expand "movmemqi"
34191dd1 6886 [(match_operand:BLK 0 "general_operand" "")
6887 (match_operand:BLK 1 "general_operand" "")
6888 (match_operand:SI 2 "const_int_operand" "")
6889 (match_operand:SI 3 "const_int_operand" "")]
ae51a965 6890 ""
9c08d1fa 6891 "
25f905c2 6892 if (TARGET_32BIT)
cffb2a26 6893 {
ae51a965 6894 if (TARGET_LDRD && current_tune->prefer_ldrd_strd
6895 && !optimize_function_for_size_p (cfun))
6896 {
6897 if (gen_movmem_ldrd_strd (operands))
6898 DONE;
6899 FAIL;
6900 }
6901
008c057d 6902 if (arm_gen_movmemqi (operands))
cffb2a26 6903 DONE;
6904 FAIL;
6905 }
25f905c2 6906 else /* TARGET_THUMB1 */
cffb2a26 6907 {
6908 if ( INTVAL (operands[3]) != 4
6909 || INTVAL (operands[2]) > 48)
6910 FAIL;
6911
008c057d 6912 thumb_expand_movmemqi (operands);
cffb2a26 6913 DONE;
6914 }
6915 "
6916)
9c08d1fa 6917\f
b11cae9e 6918
341940e8 6919;; Compare & branch insns
8d232dc7 6920;; The range calculations are based as follows:
341940e8 6921;; For forward branches, the address calculation returns the address of
6922;; the next instruction. This is 2 beyond the branch instruction.
6923;; For backward branches, the address calculation returns the address of
6924;; the first instruction in this pattern (cmp). This is 2 before the branch
6925;; instruction for the shortest sequence, and 4 before the branch instruction
6926;; if we have to jump around an unconditional branch.
6927;; To the basic branch range the PC offset must be added (this is +4).
6928;; So for forward branches we have
6929;; (pos_range - pos_base_offs + pc_offs) = (pos_range - 2 + 4).
6930;; And for backward branches we have
6931;; (neg_range - neg_base_offs + pc_offs) = (neg_range - (-2 or -4) + 4).
6932;;
6933;; For a 'b' pos_range = 2046, neg_range = -2048 giving (-2040->2048).
6934;; For a 'b<cond>' pos_range = 254, neg_range = -256 giving (-250 ->256).
cffb2a26 6935
aeac46d4 6936(define_expand "cbranchsi4"
6937 [(set (pc) (if_then_else
aa06947a 6938 (match_operator 0 "expandable_comparison_operator"
aeac46d4 6939 [(match_operand:SI 1 "s_register_operand" "")
6940 (match_operand:SI 2 "nonmemory_operand" "")])
6941 (label_ref (match_operand 3 "" ""))
6942 (pc)))]
f9aa4160 6943 "TARGET_EITHER"
aeac46d4 6944 "
74f4459c 6945 if (!TARGET_THUMB1)
6946 {
f9aa4160 6947 if (!arm_validize_comparison (&operands[0], &operands[1], &operands[2]))
6948 FAIL;
74f4459c 6949 emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
6950 operands[3]));
6951 DONE;
6952 }
25f905c2 6953 if (thumb1_cmpneg_operand (operands[2], SImode))
aeac46d4 6954 {
6955 emit_jump_insn (gen_cbranchsi4_scratch (NULL, operands[1], operands[2],
6956 operands[3], operands[0]));
6957 DONE;
6958 }
25f905c2 6959 if (!thumb1_cmp_operand (operands[2], SImode))
aeac46d4 6960 operands[2] = force_reg (SImode, operands[2]);
6961 ")
6962
74f4459c 6963(define_expand "cbranchsf4"
6964 [(set (pc) (if_then_else
aa06947a 6965 (match_operator 0 "expandable_comparison_operator"
74f4459c 6966 [(match_operand:SF 1 "s_register_operand" "")
6967 (match_operand:SF 2 "arm_float_compare_operand" "")])
6968 (label_ref (match_operand 3 "" ""))
6969 (pc)))]
6970 "TARGET_32BIT && TARGET_HARD_FLOAT"
6971 "emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
6972 operands[3])); DONE;"
6973)
6974
6975(define_expand "cbranchdf4"
6976 [(set (pc) (if_then_else
aa06947a 6977 (match_operator 0 "expandable_comparison_operator"
74f4459c 6978 [(match_operand:DF 1 "s_register_operand" "")
6979 (match_operand:DF 2 "arm_float_compare_operand" "")])
6980 (label_ref (match_operand 3 "" ""))
6981 (pc)))]
a50d7267 6982 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
74f4459c 6983 "emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
6984 operands[3])); DONE;"
6985)
6986
74f4459c 6987(define_expand "cbranchdi4"
6988 [(set (pc) (if_then_else
aa06947a 6989 (match_operator 0 "expandable_comparison_operator"
b8eae306 6990 [(match_operand:DI 1 "s_register_operand" "")
a8045a4f 6991 (match_operand:DI 2 "cmpdi_operand" "")])
74f4459c 6992 (label_ref (match_operand 3 "" ""))
6993 (pc)))]
a8045a4f 6994 "TARGET_32BIT"
6995 "{
0438d37f 6996 if (!arm_validize_comparison (&operands[0], &operands[1], &operands[2]))
f9aa4160 6997 FAIL;
6998 emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
a8045a4f 6999 operands[3]));
7000 DONE;
7001 }"
74f4459c 7002)
7003
9c08d1fa 7004;; Comparison and test insns
7005
cffb2a26 7006(define_insn "*arm_cmpsi_insn"
bd5b4116 7007 [(set (reg:CC CC_REGNUM)
f9f234ec 7008 (compare:CC (match_operand:SI 0 "s_register_operand" "l,r,r,r,r")
7009 (match_operand:SI 1 "arm_add_operand" "Py,r,r,I,L")))]
25f905c2 7010 "TARGET_32BIT"
5565501b 7011 "@
a6864a24 7012 cmp%?\\t%0, %1
7013 cmp%?\\t%0, %1
aea4c774 7014 cmp%?\\t%0, %1
f9f234ec 7015 cmp%?\\t%0, %1
aea4c774 7016 cmn%?\\t%0, #%n1"
a6864a24 7017 [(set_attr "conds" "set")
f9f234ec 7018 (set_attr "arch" "t2,t2,any,any,any")
7019 (set_attr "length" "2,2,4,4,4")
65f68e55 7020 (set_attr "predicable" "yes")
f9f234ec 7021 (set_attr "predicable_short_it" "yes,yes,yes,no,no")
112eda6f 7022 (set_attr "type" "alus_imm,alus_sreg,alus_sreg,alus_imm,alus_imm")]
cffb2a26 7023)
b11cae9e 7024
d5d4dc8d 7025(define_insn "*cmpsi_shiftsi"
bd5b4116 7026 [(set (reg:CC CC_REGNUM)
d82e788e 7027 (compare:CC (match_operand:SI 0 "s_register_operand" "r,r,r")
cffb2a26 7028 (match_operator:SI 3 "shift_operator"
d82e788e 7029 [(match_operand:SI 1 "s_register_operand" "r,r,r")
7030 (match_operand:SI 2 "shift_amount_operand" "M,r,M")])))]
d5d4dc8d 7031 "TARGET_32BIT"
f9f234ec 7032 "cmp\\t%0, %1%S3"
344495ea 7033 [(set_attr "conds" "set")
331beb1a 7034 (set_attr "shift" "1")
d82e788e 7035 (set_attr "arch" "32,a,a")
282b4c75 7036 (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")])
b11cae9e 7037
d5d4dc8d 7038(define_insn "*cmpsi_shiftsi_swp"
bd5b4116 7039 [(set (reg:CC_SWP CC_REGNUM)
aea4c774 7040 (compare:CC_SWP (match_operator:SI 3 "shift_operator"
d82e788e 7041 [(match_operand:SI 1 "s_register_operand" "r,r,r")
7042 (match_operand:SI 2 "shift_amount_operand" "M,r,M")])
7043 (match_operand:SI 0 "s_register_operand" "r,r,r")))]
d5d4dc8d 7044 "TARGET_32BIT"
aea4c774 7045 "cmp%?\\t%0, %1%S3"
344495ea 7046 [(set_attr "conds" "set")
331beb1a 7047 (set_attr "shift" "1")
d82e788e 7048 (set_attr "arch" "32,a,a")
282b4c75 7049 (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")])
b11cae9e 7050
25f905c2 7051(define_insn "*arm_cmpsi_negshiftsi_si"
aed179ae 7052 [(set (reg:CC_Z CC_REGNUM)
7053 (compare:CC_Z
7054 (neg:SI (match_operator:SI 1 "shift_operator"
7055 [(match_operand:SI 2 "s_register_operand" "r")
7056 (match_operand:SI 3 "reg_or_int_operand" "rM")]))
7057 (match_operand:SI 0 "s_register_operand" "r")))]
cffb2a26 7058 "TARGET_ARM"
aed179ae 7059 "cmn%?\\t%0, %2%S1"
344495ea 7060 [(set_attr "conds" "set")
aed179ae 7061 (set (attr "type") (if_then_else (match_operand 3 "const_int_operand" "")
d82e788e 7062 (const_string "alus_shift_imm")
7063 (const_string "alus_shift_reg")))
596e5e8f 7064 (set_attr "predicable" "yes")]
0d66636f 7065)
b11cae9e 7066
a8045a4f 7067;; DImode comparisons. The generic code generates branches that
7068;; if-conversion can not reduce to a conditional compare, so we do
7069;; that directly.
7070
ba6a3b2f 7071(define_insn_and_split "*arm_cmpdi_insn"
a8045a4f 7072 [(set (reg:CC_NCV CC_REGNUM)
7073 (compare:CC_NCV (match_operand:DI 0 "s_register_operand" "r")
7074 (match_operand:DI 1 "arm_di_operand" "rDi")))
7075 (clobber (match_scratch:SI 2 "=r"))]
b805622c 7076 "TARGET_32BIT"
ba6a3b2f 7077 "#" ; "cmp\\t%Q0, %Q1\;sbcs\\t%2, %R0, %R1"
7078 "&& reload_completed"
7079 [(set (reg:CC CC_REGNUM)
7080 (compare:CC (match_dup 0) (match_dup 1)))
7081 (parallel [(set (reg:CC CC_REGNUM)
7082 (compare:CC (match_dup 3) (match_dup 4)))
7083 (set (match_dup 2)
7084 (minus:SI (match_dup 5)
7085 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))])]
7086 {
7087 operands[3] = gen_highpart (SImode, operands[0]);
7088 operands[0] = gen_lowpart (SImode, operands[0]);
7089 if (CONST_INT_P (operands[1]))
7090 {
7091 operands[4] = GEN_INT (~INTVAL (gen_highpart_mode (SImode,
7092 DImode,
7093 operands[1])));
7094 operands[5] = gen_rtx_PLUS (SImode, operands[3], operands[4]);
7095 }
7096 else
7097 {
7098 operands[4] = gen_highpart (SImode, operands[1]);
7099 operands[5] = gen_rtx_MINUS (SImode, operands[3], operands[4]);
7100 }
7101 operands[1] = gen_lowpart (SImode, operands[1]);
7102 operands[2] = gen_lowpart (SImode, operands[2]);
7103 }
a8045a4f 7104 [(set_attr "conds" "set")
1b7da4ac 7105 (set_attr "length" "8")
7106 (set_attr "type" "multiple")]
a8045a4f 7107)
7108
ba6a3b2f 7109(define_insn_and_split "*arm_cmpdi_unsigned"
a8045a4f 7110 [(set (reg:CC_CZ CC_REGNUM)
1a86364b 7111 (compare:CC_CZ (match_operand:DI 0 "s_register_operand" "l,r,r,r")
7112 (match_operand:DI 1 "arm_di_operand" "Py,r,Di,rDi")))]
7c36fe71 7113
48a98053 7114 "TARGET_32BIT"
ba6a3b2f 7115 "#" ; "cmp\\t%R0, %R1\;it eq\;cmpeq\\t%Q0, %Q1"
7116 "&& reload_completed"
7117 [(set (reg:CC CC_REGNUM)
7118 (compare:CC (match_dup 2) (match_dup 3)))
7119 (cond_exec (eq:SI (reg:CC CC_REGNUM) (const_int 0))
7120 (set (reg:CC CC_REGNUM)
7121 (compare:CC (match_dup 0) (match_dup 1))))]
7122 {
7123 operands[2] = gen_highpart (SImode, operands[0]);
7124 operands[0] = gen_lowpart (SImode, operands[0]);
7125 if (CONST_INT_P (operands[1]))
7126 operands[3] = gen_highpart_mode (SImode, DImode, operands[1]);
7127 else
7128 operands[3] = gen_highpart (SImode, operands[1]);
7129 operands[1] = gen_lowpart (SImode, operands[1]);
7130 }
a8045a4f 7131 [(set_attr "conds" "set")
1a86364b 7132 (set_attr "enabled_for_depr_it" "yes,yes,no,*")
7133 (set_attr "arch" "t2,t2,t2,a")
7134 (set_attr "length" "6,6,10,8")
1b7da4ac 7135 (set_attr "type" "multiple")]
a8045a4f 7136)
7137
7138(define_insn "*arm_cmpdi_zero"
7139 [(set (reg:CC_Z CC_REGNUM)
7140 (compare:CC_Z (match_operand:DI 0 "s_register_operand" "r")
7141 (const_int 0)))
7142 (clobber (match_scratch:SI 1 "=r"))]
7143 "TARGET_32BIT"
7144 "orr%.\\t%1, %Q0, %R0"
1b7da4ac 7145 [(set_attr "conds" "set")
7146 (set_attr "type" "logics_reg")]
a8045a4f 7147)
7148
9c08d1fa 7149; This insn allows redundant compares to be removed by cse, nothing should
7150; ever appear in the output file since (set (reg x) (reg x)) is a no-op that
7151; is deleted later on. The match_dup will match the mode here, so that
7152; mode changes of the condition codes aren't lost by this even though we don't
7153; specify what they are.
7154
8a18b90c 7155(define_insn "*deleted_compare"
9c08d1fa 7156 [(set (match_operand 0 "cc_register" "") (match_dup 0))]
25f905c2 7157 "TARGET_32BIT"
40dbec34 7158 "\\t%@ deleted compare"
cffb2a26 7159 [(set_attr "conds" "set")
1b7da4ac 7160 (set_attr "length" "0")
7161 (set_attr "type" "no_insn")]
cffb2a26 7162)
9c08d1fa 7163
7164\f
7165;; Conditional branch insns
7166
74f4459c 7167(define_expand "cbranch_cc"
9c08d1fa 7168 [(set (pc)
74f4459c 7169 (if_then_else (match_operator 0 "" [(match_operand 1 "" "")
7170 (match_operand 2 "" "")])
7171 (label_ref (match_operand 3 "" ""))
9c08d1fa 7172 (pc)))]
25f905c2 7173 "TARGET_32BIT"
74f4459c 7174 "operands[1] = arm_gen_compare_reg (GET_CODE (operands[0]),
e1b93706 7175 operands[1], operands[2], NULL_RTX);
74f4459c 7176 operands[2] = const0_rtx;"
8fa3ba89 7177)
7178
7179;;
7180;; Patterns to match conditional branch insns.
7181;;
7182
ffcc986d 7183(define_insn "arm_cond_branch"
9c08d1fa 7184 [(set (pc)
8fa3ba89 7185 (if_then_else (match_operator 1 "arm_comparison_operator"
8a18b90c 7186 [(match_operand 2 "cc_register" "") (const_int 0)])
9c08d1fa 7187 (label_ref (match_operand 0 "" ""))
7188 (pc)))]
25f905c2 7189 "TARGET_32BIT"
d75350ce 7190 "*
9c08d1fa 7191 if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
cffb2a26 7192 {
7193 arm_ccfsm_state += 2;
7194 return \"\";
7195 }
e2348bcb 7196 return \"b%d1\\t%l0\";
cffb2a26 7197 "
a2cd141b 7198 [(set_attr "conds" "use")
a6864a24 7199 (set_attr "type" "branch")
7200 (set (attr "length")
7201 (if_then_else
0bf497f5 7202 (and (match_test "TARGET_THUMB2")
a6864a24 7203 (and (ge (minus (match_dup 0) (pc)) (const_int -250))
7204 (le (minus (match_dup 0) (pc)) (const_int 256))))
7205 (const_int 2)
7206 (const_int 4)))]
cffb2a26 7207)
d75350ce 7208
cffb2a26 7209(define_insn "*arm_cond_branch_reversed"
9c08d1fa 7210 [(set (pc)
8fa3ba89 7211 (if_then_else (match_operator 1 "arm_comparison_operator"
8a18b90c 7212 [(match_operand 2 "cc_register" "") (const_int 0)])
9c08d1fa 7213 (pc)
7214 (label_ref (match_operand 0 "" ""))))]
25f905c2 7215 "TARGET_32BIT"
d75350ce 7216 "*
9c08d1fa 7217 if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
cffb2a26 7218 {
7219 arm_ccfsm_state += 2;
7220 return \"\";
7221 }
e2348bcb 7222 return \"b%D1\\t%l0\";
cffb2a26 7223 "
a2cd141b 7224 [(set_attr "conds" "use")
a6864a24 7225 (set_attr "type" "branch")
7226 (set (attr "length")
7227 (if_then_else
0bf497f5 7228 (and (match_test "TARGET_THUMB2")
a6864a24 7229 (and (ge (minus (match_dup 0) (pc)) (const_int -250))
7230 (le (minus (match_dup 0) (pc)) (const_int 256))))
7231 (const_int 2)
7232 (const_int 4)))]
cffb2a26 7233)
7234
b11cae9e 7235\f
9c08d1fa 7236
7237; scc insns
7238
74f4459c 7239(define_expand "cstore_cc"
7db9af5d 7240 [(set (match_operand:SI 0 "s_register_operand" "")
74f4459c 7241 (match_operator:SI 1 "" [(match_operand 2 "" "")
7242 (match_operand 3 "" "")]))]
25f905c2 7243 "TARGET_32BIT"
74f4459c 7244 "operands[2] = arm_gen_compare_reg (GET_CODE (operands[1]),
e1b93706 7245 operands[2], operands[3], NULL_RTX);
74f4459c 7246 operands[3] = const0_rtx;"
8fa3ba89 7247)
7248
a3b84066 7249(define_insn_and_split "*mov_scc"
9c08d1fa 7250 [(set (match_operand:SI 0 "s_register_operand" "=r")
8fa3ba89 7251 (match_operator:SI 1 "arm_comparison_operator"
8a18b90c 7252 [(match_operand 2 "cc_register" "") (const_int 0)]))]
cffb2a26 7253 "TARGET_ARM"
a3b84066 7254 "#" ; "mov%D1\\t%0, #0\;mov%d1\\t%0, #1"
7255 "TARGET_ARM"
7256 [(set (match_dup 0)
7257 (if_then_else:SI (match_dup 1)
7258 (const_int 1)
7259 (const_int 0)))]
7260 ""
cffb2a26 7261 [(set_attr "conds" "use")
1b7da4ac 7262 (set_attr "length" "8")
7263 (set_attr "type" "multiple")]
cffb2a26 7264)
9c08d1fa 7265
a3b84066 7266(define_insn_and_split "*mov_negscc"
9c08d1fa 7267 [(set (match_operand:SI 0 "s_register_operand" "=r")
8fa3ba89 7268 (neg:SI (match_operator:SI 1 "arm_comparison_operator"
8a18b90c 7269 [(match_operand 2 "cc_register" "") (const_int 0)])))]
cffb2a26 7270 "TARGET_ARM"
a3b84066 7271 "#" ; "mov%D1\\t%0, #0\;mvn%d1\\t%0, #0"
7272 "TARGET_ARM"
7273 [(set (match_dup 0)
7274 (if_then_else:SI (match_dup 1)
7275 (match_dup 3)
7276 (const_int 0)))]
7277 {
7278 operands[3] = GEN_INT (~0);
7279 }
cffb2a26 7280 [(set_attr "conds" "use")
1b7da4ac 7281 (set_attr "length" "8")
7282 (set_attr "type" "multiple")]
cffb2a26 7283)
9c08d1fa 7284
a3b84066 7285(define_insn_and_split "*mov_notscc"
9c08d1fa 7286 [(set (match_operand:SI 0 "s_register_operand" "=r")
8fa3ba89 7287 (not:SI (match_operator:SI 1 "arm_comparison_operator"
8a18b90c 7288 [(match_operand 2 "cc_register" "") (const_int 0)])))]
cffb2a26 7289 "TARGET_ARM"
a3b84066 7290 "#" ; "mvn%D1\\t%0, #0\;mvn%d1\\t%0, #1"
7291 "TARGET_ARM"
7292 [(set (match_dup 0)
7293 (if_then_else:SI (match_dup 1)
7294 (match_dup 3)
7295 (match_dup 4)))]
7296 {
7297 operands[3] = GEN_INT (~1);
7298 operands[4] = GEN_INT (~0);
7299 }
cffb2a26 7300 [(set_attr "conds" "use")
1b7da4ac 7301 (set_attr "length" "8")
7302 (set_attr "type" "multiple")]
cffb2a26 7303)
9c08d1fa 7304
595d88b5 7305(define_expand "cstoresi4"
7306 [(set (match_operand:SI 0 "s_register_operand" "")
aa06947a 7307 (match_operator:SI 1 "expandable_comparison_operator"
595d88b5 7308 [(match_operand:SI 2 "s_register_operand" "")
7309 (match_operand:SI 3 "reg_or_int_operand" "")]))]
74f4459c 7310 "TARGET_32BIT || TARGET_THUMB1"
595d88b5 7311 "{
7312 rtx op3, scratch, scratch2;
7313
74f4459c 7314 if (!TARGET_THUMB1)
7315 {
7316 if (!arm_add_operand (operands[3], SImode))
7317 operands[3] = force_reg (SImode, operands[3]);
7318 emit_insn (gen_cstore_cc (operands[0], operands[1],
7319 operands[2], operands[3]));
7320 DONE;
7321 }
7322
595d88b5 7323 if (operands[3] == const0_rtx)
7324 {
7325 switch (GET_CODE (operands[1]))
7326 {
7327 case EQ:
25f905c2 7328 emit_insn (gen_cstoresi_eq0_thumb1 (operands[0], operands[2]));
595d88b5 7329 break;
7330
7331 case NE:
25f905c2 7332 emit_insn (gen_cstoresi_ne0_thumb1 (operands[0], operands[2]));
595d88b5 7333 break;
7334
7335 case LE:
7336 scratch = expand_binop (SImode, add_optab, operands[2], constm1_rtx,
7337 NULL_RTX, 0, OPTAB_WIDEN);
7338 scratch = expand_binop (SImode, ior_optab, operands[2], scratch,
7339 NULL_RTX, 0, OPTAB_WIDEN);
7340 expand_binop (SImode, lshr_optab, scratch, GEN_INT (31),
7341 operands[0], 1, OPTAB_WIDEN);
7342 break;
7343
7344 case GE:
7345 scratch = expand_unop (SImode, one_cmpl_optab, operands[2],
7346 NULL_RTX, 1);
7347 expand_binop (SImode, lshr_optab, scratch, GEN_INT (31),
7348 NULL_RTX, 1, OPTAB_WIDEN);
7349 break;
7350
7351 case GT:
7352 scratch = expand_binop (SImode, ashr_optab, operands[2],
7353 GEN_INT (31), NULL_RTX, 0, OPTAB_WIDEN);
7354 scratch = expand_binop (SImode, sub_optab, scratch, operands[2],
7355 NULL_RTX, 0, OPTAB_WIDEN);
7356 expand_binop (SImode, lshr_optab, scratch, GEN_INT (31), operands[0],
7357 0, OPTAB_WIDEN);
7358 break;
7359
7360 /* LT is handled by generic code. No need for unsigned with 0. */
7361 default:
7362 FAIL;
7363 }
7364 DONE;
7365 }
7366
7367 switch (GET_CODE (operands[1]))
7368 {
7369 case EQ:
7370 scratch = expand_binop (SImode, sub_optab, operands[2], operands[3],
7371 NULL_RTX, 0, OPTAB_WIDEN);
25f905c2 7372 emit_insn (gen_cstoresi_eq0_thumb1 (operands[0], scratch));
595d88b5 7373 break;
7374
7375 case NE:
7376 scratch = expand_binop (SImode, sub_optab, operands[2], operands[3],
7377 NULL_RTX, 0, OPTAB_WIDEN);
25f905c2 7378 emit_insn (gen_cstoresi_ne0_thumb1 (operands[0], scratch));
595d88b5 7379 break;
7380
7381 case LE:
7382 op3 = force_reg (SImode, operands[3]);
7383
7384 scratch = expand_binop (SImode, lshr_optab, operands[2], GEN_INT (31),
7385 NULL_RTX, 1, OPTAB_WIDEN);
7386 scratch2 = expand_binop (SImode, ashr_optab, op3, GEN_INT (31),
7387 NULL_RTX, 0, OPTAB_WIDEN);
25f905c2 7388 emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch2,
595d88b5 7389 op3, operands[2]));
7390 break;
7391
7392 case GE:
7393 op3 = operands[3];
25f905c2 7394 if (!thumb1_cmp_operand (op3, SImode))
595d88b5 7395 op3 = force_reg (SImode, op3);
7396 scratch = expand_binop (SImode, ashr_optab, operands[2], GEN_INT (31),
7397 NULL_RTX, 0, OPTAB_WIDEN);
7398 scratch2 = expand_binop (SImode, lshr_optab, op3, GEN_INT (31),
7399 NULL_RTX, 1, OPTAB_WIDEN);
25f905c2 7400 emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch2,
595d88b5 7401 operands[2], op3));
7402 break;
7403
7404 case LEU:
7405 op3 = force_reg (SImode, operands[3]);
7406 scratch = force_reg (SImode, const0_rtx);
25f905c2 7407 emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch,
595d88b5 7408 op3, operands[2]));
7409 break;
7410
7411 case GEU:
7412 op3 = operands[3];
25f905c2 7413 if (!thumb1_cmp_operand (op3, SImode))
595d88b5 7414 op3 = force_reg (SImode, op3);
7415 scratch = force_reg (SImode, const0_rtx);
25f905c2 7416 emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch,
595d88b5 7417 operands[2], op3));
7418 break;
7419
7420 case LTU:
7421 op3 = operands[3];
25f905c2 7422 if (!thumb1_cmp_operand (op3, SImode))
595d88b5 7423 op3 = force_reg (SImode, op3);
7424 scratch = gen_reg_rtx (SImode);
408b7ae5 7425 emit_insn (gen_cstoresi_ltu_thumb1 (operands[0], operands[2], op3));
595d88b5 7426 break;
7427
7428 case GTU:
7429 op3 = force_reg (SImode, operands[3]);
7430 scratch = gen_reg_rtx (SImode);
408b7ae5 7431 emit_insn (gen_cstoresi_ltu_thumb1 (operands[0], op3, operands[2]));
595d88b5 7432 break;
7433
7434 /* No good sequences for GT, LT. */
7435 default:
7436 FAIL;
7437 }
7438 DONE;
7439}")
7440
74f4459c 7441(define_expand "cstoresf4"
7442 [(set (match_operand:SI 0 "s_register_operand" "")
aa06947a 7443 (match_operator:SI 1 "expandable_comparison_operator"
74f4459c 7444 [(match_operand:SF 2 "s_register_operand" "")
7445 (match_operand:SF 3 "arm_float_compare_operand" "")]))]
7446 "TARGET_32BIT && TARGET_HARD_FLOAT"
7447 "emit_insn (gen_cstore_cc (operands[0], operands[1],
7448 operands[2], operands[3])); DONE;"
7449)
7450
7451(define_expand "cstoredf4"
7452 [(set (match_operand:SI 0 "s_register_operand" "")
aa06947a 7453 (match_operator:SI 1 "expandable_comparison_operator"
74f4459c 7454 [(match_operand:DF 2 "s_register_operand" "")
7455 (match_operand:DF 3 "arm_float_compare_operand" "")]))]
d63ed457 7456 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
74f4459c 7457 "emit_insn (gen_cstore_cc (operands[0], operands[1],
7458 operands[2], operands[3])); DONE;"
7459)
7460
74f4459c 7461(define_expand "cstoredi4"
7462 [(set (match_operand:SI 0 "s_register_operand" "")
aa06947a 7463 (match_operator:SI 1 "expandable_comparison_operator"
b8eae306 7464 [(match_operand:DI 2 "s_register_operand" "")
a8045a4f 7465 (match_operand:DI 3 "cmpdi_operand" "")]))]
7466 "TARGET_32BIT"
7467 "{
f9aa4160 7468 if (!arm_validize_comparison (&operands[1],
7469 &operands[2],
7470 &operands[3]))
7471 FAIL;
7472 emit_insn (gen_cstore_cc (operands[0], operands[1], operands[2],
a8045a4f 7473 operands[3]));
7474 DONE;
7475 }"
74f4459c 7476)
7477
9c08d1fa 7478\f
39b5e676 7479;; Conditional move insns
7480
7481(define_expand "movsicc"
8a18b90c 7482 [(set (match_operand:SI 0 "s_register_operand" "")
aa06947a 7483 (if_then_else:SI (match_operand 1 "expandable_comparison_operator" "")
aea4c774 7484 (match_operand:SI 2 "arm_not_operand" "")
8a18b90c 7485 (match_operand:SI 3 "arm_not_operand" "")))]
25f905c2 7486 "TARGET_32BIT"
39b5e676 7487 "
215b30b3 7488 {
f9aa4160 7489 enum rtx_code code;
278b301d 7490 rtx ccreg;
7491
f9aa4160 7492 if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0),
7493 &XEXP (operands[1], 1)))
278b301d 7494 FAIL;
f9aa4160 7495
7496 code = GET_CODE (operands[1]);
74f4459c 7497 ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
e1b93706 7498 XEXP (operands[1], 1), NULL_RTX);
29bb088d 7499 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
215b30b3 7500 }"
7501)
39b5e676 7502
7503(define_expand "movsfcc"
8a18b90c 7504 [(set (match_operand:SF 0 "s_register_operand" "")
4df97ffc 7505 (if_then_else:SF (match_operand 1 "arm_cond_move_operator" "")
8a18b90c 7506 (match_operand:SF 2 "s_register_operand" "")
d86c91f6 7507 (match_operand:SF 3 "s_register_operand" "")))]
19f6bf8d 7508 "TARGET_32BIT && TARGET_HARD_FLOAT"
39b5e676 7509 "
215b30b3 7510 {
7511 enum rtx_code code = GET_CODE (operands[1]);
7512 rtx ccreg;
f082f1c4 7513
f9aa4160 7514 if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0),
7515 &XEXP (operands[1], 1)))
7516 FAIL;
39b5e676 7517
f9aa4160 7518 code = GET_CODE (operands[1]);
74f4459c 7519 ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
e1b93706 7520 XEXP (operands[1], 1), NULL_RTX);
29bb088d 7521 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
215b30b3 7522 }"
7523)
39b5e676 7524
7525(define_expand "movdfcc"
8a18b90c 7526 [(set (match_operand:DF 0 "s_register_operand" "")
4df97ffc 7527 (if_then_else:DF (match_operand 1 "arm_cond_move_operator" "")
8a18b90c 7528 (match_operand:DF 2 "s_register_operand" "")
d86c91f6 7529 (match_operand:DF 3 "s_register_operand" "")))]
994606f8 7530 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
39b5e676 7531 "
215b30b3 7532 {
7533 enum rtx_code code = GET_CODE (operands[1]);
278b301d 7534 rtx ccreg;
39b5e676 7535
f9aa4160 7536 if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0),
7537 &XEXP (operands[1], 1)))
7538 FAIL;
7539 code = GET_CODE (operands[1]);
74f4459c 7540 ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
e1b93706 7541 XEXP (operands[1], 1), NULL_RTX);
29bb088d 7542 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
215b30b3 7543 }"
7544)
39b5e676 7545
91cb50d2 7546(define_insn "*cmov<mode>"
7547 [(set (match_operand:SDF 0 "s_register_operand" "=<F_constraint>")
7548 (if_then_else:SDF (match_operator 1 "arm_vsel_comparison_operator"
7549 [(match_operand 2 "cc_register" "") (const_int 0)])
7550 (match_operand:SDF 3 "s_register_operand"
7551 "<F_constraint>")
7552 (match_operand:SDF 4 "s_register_operand"
7553 "<F_constraint>")))]
7554 "TARGET_HARD_FLOAT && TARGET_FPU_ARMV8 <vfp_double_cond>"
7555 "*
7556 {
7557 enum arm_cond_code code = maybe_get_arm_condition_code (operands[1]);
7558 switch (code)
7559 {
7560 case ARM_GE:
7561 case ARM_GT:
7562 case ARM_EQ:
7563 case ARM_VS:
7564 return \"vsel%d1.<V_if_elem>\\t%<V_reg>0, %<V_reg>3, %<V_reg>4\";
7565 case ARM_LT:
7566 case ARM_LE:
7567 case ARM_NE:
7568 case ARM_VC:
7569 return \"vsel%D1.<V_if_elem>\\t%<V_reg>0, %<V_reg>4, %<V_reg>3\";
7570 default:
7571 gcc_unreachable ();
7572 }
7573 return \"\";
7574 }"
7575 [(set_attr "conds" "use")
6664d308 7576 (set_attr "type" "fcsel")]
91cb50d2 7577)
7578
190efb17 7579(define_insn_and_split "*movsicc_insn"
f082f1c4 7580 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r,r,r,r,r")
8a18b90c 7581 (if_then_else:SI
8fa3ba89 7582 (match_operator 3 "arm_comparison_operator"
8a18b90c 7583 [(match_operand 4 "cc_register" "") (const_int 0)])
f082f1c4 7584 (match_operand:SI 1 "arm_not_operand" "0,0,rI,K,rI,rI,K,K")
7585 (match_operand:SI 2 "arm_not_operand" "rI,K,0,0,rI,K,rI,K")))]
cffb2a26 7586 "TARGET_ARM"
39b5e676 7587 "@
8a18b90c 7588 mov%D3\\t%0, %2
7589 mvn%D3\\t%0, #%B2
f082f1c4 7590 mov%d3\\t%0, %1
7591 mvn%d3\\t%0, #%B1
190efb17 7592 #
7593 #
7594 #
7595 #"
7596 ; alt4: mov%d3\\t%0, %1\;mov%D3\\t%0, %2
7597 ; alt5: mov%d3\\t%0, %1\;mvn%D3\\t%0, #%B2
7598 ; alt6: mvn%d3\\t%0, #%B1\;mov%D3\\t%0, %2
7599 ; alt7: mvn%d3\\t%0, #%B1\;mvn%D3\\t%0, #%B2"
7600 "&& reload_completed"
7601 [(const_int 0)]
7602 {
7603 enum rtx_code rev_code;
3754d046 7604 machine_mode mode;
190efb17 7605 rtx rev_cond;
7606
7607 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
7608 operands[3],
d1f9b275 7609 gen_rtx_SET (operands[0], operands[1])));
190efb17 7610
7611 rev_code = GET_CODE (operands[3]);
7612 mode = GET_MODE (operands[4]);
7613 if (mode == CCFPmode || mode == CCFPEmode)
7614 rev_code = reverse_condition_maybe_unordered (rev_code);
7615 else
7616 rev_code = reverse_condition (rev_code);
7617
7618 rev_cond = gen_rtx_fmt_ee (rev_code,
7619 VOIDmode,
7620 operands[4],
7621 const0_rtx);
7622 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
7623 rev_cond,
d1f9b275 7624 gen_rtx_SET (operands[0], operands[2])));
190efb17 7625 DONE;
7626 }
f082f1c4 7627 [(set_attr "length" "4,4,4,4,8,8,8,8")
d2a518d1 7628 (set_attr "conds" "use")
65f68e55 7629 (set_attr_alternative "type"
7630 [(if_then_else (match_operand 2 "const_int_operand" "")
1aed5204 7631 (const_string "mov_imm")
7632 (const_string "mov_reg"))
7633 (const_string "mvn_imm")
65f68e55 7634 (if_then_else (match_operand 1 "const_int_operand" "")
1aed5204 7635 (const_string "mov_imm")
7636 (const_string "mov_reg"))
7637 (const_string "mvn_imm")
282b4c75 7638 (const_string "multiple")
7639 (const_string "multiple")
7640 (const_string "multiple")
7641 (const_string "multiple")])]
215b30b3 7642)
39b5e676 7643
39b5e676 7644(define_insn "*movsfcc_soft_insn"
f082f1c4 7645 [(set (match_operand:SF 0 "s_register_operand" "=r,r")
8fa3ba89 7646 (if_then_else:SF (match_operator 3 "arm_comparison_operator"
8a18b90c 7647 [(match_operand 4 "cc_register" "") (const_int 0)])
f082f1c4 7648 (match_operand:SF 1 "s_register_operand" "0,r")
7649 (match_operand:SF 2 "s_register_operand" "r,0")))]
cffb2a26 7650 "TARGET_ARM && TARGET_SOFT_FLOAT"
f082f1c4 7651 "@
7652 mov%D3\\t%0, %2
7653 mov%d3\\t%0, %1"
d2a518d1 7654 [(set_attr "conds" "use")
1aed5204 7655 (set_attr "type" "mov_reg")]
8fa3ba89 7656)
39b5e676 7657
39b5e676 7658\f
9c08d1fa 7659;; Jump and linkage insns
7660
cffb2a26 7661(define_expand "jump"
9c08d1fa 7662 [(set (pc)
7663 (label_ref (match_operand 0 "" "")))]
cffb2a26 7664 "TARGET_EITHER"
9c08d1fa 7665 ""
cffb2a26 7666)
7667
7668(define_insn "*arm_jump"
7669 [(set (pc)
7670 (label_ref (match_operand 0 "" "")))]
25f905c2 7671 "TARGET_32BIT"
9c08d1fa 7672 "*
0d66636f 7673 {
7674 if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
7675 {
7676 arm_ccfsm_state += 2;
7677 return \"\";
7678 }
7679 return \"b%?\\t%l0\";
7680 }
7681 "
a6864a24 7682 [(set_attr "predicable" "yes")
7683 (set (attr "length")
7684 (if_then_else
0bf497f5 7685 (and (match_test "TARGET_THUMB2")
a6864a24 7686 (and (ge (minus (match_dup 0) (pc)) (const_int -2044))
7687 (le (minus (match_dup 0) (pc)) (const_int 2048))))
7688 (const_int 2)
1b7da4ac 7689 (const_int 4)))
7690 (set_attr "type" "branch")]
0d66636f 7691)
9c08d1fa 7692
d3373b54 7693(define_expand "call"
7694 [(parallel [(call (match_operand 0 "memory_operand" "")
7695 (match_operand 1 "general_operand" ""))
cffb2a26 7696 (use (match_operand 2 "" ""))
bd5b4116 7697 (clobber (reg:SI LR_REGNUM))])]
cffb2a26 7698 "TARGET_EITHER"
6c4c2133 7699 "
7700 {
bac7fc85 7701 rtx callee, pat;
bbe777ea 7702
bbe777ea 7703 /* In an untyped call, we can get NULL for operand 2. */
7704 if (operands[2] == NULL_RTX)
7705 operands[2] = const0_rtx;
7706
de55252a 7707 /* Decide if we should generate indirect calls by loading the
85c36fd1 7708 32-bit address of the callee into a register before performing the
de55252a 7709 branch and link. */
7710 callee = XEXP (operands[0], 0);
7711 if (GET_CODE (callee) == SYMBOL_REF
7712 ? arm_is_long_call_p (SYMBOL_REF_DECL (callee))
7713 : !REG_P (callee))
bbe777ea 7714 XEXP (operands[0], 0) = force_reg (Pmode, callee);
bac7fc85 7715
7716 pat = gen_call_internal (operands[0], operands[1], operands[2]);
ca373797 7717 arm_emit_call_insn (pat, XEXP (operands[0], 0), false);
bac7fc85 7718 DONE;
6c4c2133 7719 }"
7720)
d3373b54 7721
bac7fc85 7722(define_expand "call_internal"
7723 [(parallel [(call (match_operand 0 "memory_operand" "")
7724 (match_operand 1 "general_operand" ""))
7725 (use (match_operand 2 "" ""))
7726 (clobber (reg:SI LR_REGNUM))])])
7727
f1039640 7728(define_insn "*call_reg_armv5"
d3373b54 7729 [(call (mem:SI (match_operand:SI 0 "s_register_operand" "r"))
cffb2a26 7730 (match_operand 1 "" ""))
7731 (use (match_operand 2 "" ""))
bd5b4116 7732 (clobber (reg:SI LR_REGNUM))]
33ae7c4b 7733 "TARGET_ARM && arm_arch5 && !SIBLING_CALL_P (insn)"
f1039640 7734 "blx%?\\t%0"
7735 [(set_attr "type" "call")]
7736)
7737
7738(define_insn "*call_reg_arm"
7739 [(call (mem:SI (match_operand:SI 0 "s_register_operand" "r"))
7740 (match_operand 1 "" ""))
7741 (use (match_operand 2 "" ""))
7742 (clobber (reg:SI LR_REGNUM))]
33ae7c4b 7743 "TARGET_ARM && !arm_arch5 && !SIBLING_CALL_P (insn)"
9c08d1fa 7744 "*
5565501b 7745 return output_call (operands);
cffb2a26 7746 "
7747 ;; length is worst case, normally it is only two
7748 [(set_attr "length" "12")
7749 (set_attr "type" "call")]
7750)
9c08d1fa 7751
89504fc1 7752
7753;; Note: not used for armv5+ because the sequence used (ldr pc, ...) is not
7754;; considered a function call by the branch predictor of some cores (PR40887).
7755;; Falls back to blx rN (*call_reg_armv5).
7756
f7fbdd4a 7757(define_insn "*call_mem"
a3c63a9d 7758 [(call (mem:SI (match_operand:SI 0 "call_memory_operand" "m"))
cffb2a26 7759 (match_operand 1 "" ""))
7760 (use (match_operand 2 "" ""))
bd5b4116 7761 (clobber (reg:SI LR_REGNUM))]
33ae7c4b 7762 "TARGET_ARM && !arm_arch5 && !SIBLING_CALL_P (insn)"
9c08d1fa 7763 "*
5565501b 7764 return output_call_mem (operands);
cffb2a26 7765 "
7766 [(set_attr "length" "12")
7767 (set_attr "type" "call")]
7768)
7769
d3373b54 7770(define_expand "call_value"
e0698af7 7771 [(parallel [(set (match_operand 0 "" "")
7772 (call (match_operand 1 "memory_operand" "")
7773 (match_operand 2 "general_operand" "")))
cffb2a26 7774 (use (match_operand 3 "" ""))
bd5b4116 7775 (clobber (reg:SI LR_REGNUM))])]
cffb2a26 7776 "TARGET_EITHER"
6c4c2133 7777 "
7778 {
bac7fc85 7779 rtx pat, callee;
bbe777ea 7780
7781 /* In an untyped call, we can get NULL for operand 2. */
7782 if (operands[3] == 0)
7783 operands[3] = const0_rtx;
7784
de55252a 7785 /* Decide if we should generate indirect calls by loading the
7786 32-bit address of the callee into a register before performing the
7787 branch and link. */
7788 callee = XEXP (operands[1], 0);
7789 if (GET_CODE (callee) == SYMBOL_REF
7790 ? arm_is_long_call_p (SYMBOL_REF_DECL (callee))
7791 : !REG_P (callee))
78fe751b 7792 XEXP (operands[1], 0) = force_reg (Pmode, callee);
bac7fc85 7793
7794 pat = gen_call_value_internal (operands[0], operands[1],
7795 operands[2], operands[3]);
ca373797 7796 arm_emit_call_insn (pat, XEXP (operands[1], 0), false);
bac7fc85 7797 DONE;
6c4c2133 7798 }"
7799)
d3373b54 7800
bac7fc85 7801(define_expand "call_value_internal"
7802 [(parallel [(set (match_operand 0 "" "")
7803 (call (match_operand 1 "memory_operand" "")
7804 (match_operand 2 "general_operand" "")))
7805 (use (match_operand 3 "" ""))
7806 (clobber (reg:SI LR_REGNUM))])])
7807
f1039640 7808(define_insn "*call_value_reg_armv5"
27ed6835 7809 [(set (match_operand 0 "" "")
755eb2b4 7810 (call (mem:SI (match_operand:SI 1 "s_register_operand" "r"))
cffb2a26 7811 (match_operand 2 "" "")))
bbe777ea 7812 (use (match_operand 3 "" ""))
bd5b4116 7813 (clobber (reg:SI LR_REGNUM))]
33ae7c4b 7814 "TARGET_ARM && arm_arch5 && !SIBLING_CALL_P (insn)"
f1039640 7815 "blx%?\\t%1"
7816 [(set_attr "type" "call")]
7817)
7818
7819(define_insn "*call_value_reg_arm"
7820 [(set (match_operand 0 "" "")
7821 (call (mem:SI (match_operand:SI 1 "s_register_operand" "r"))
7822 (match_operand 2 "" "")))
7823 (use (match_operand 3 "" ""))
7824 (clobber (reg:SI LR_REGNUM))]
33ae7c4b 7825 "TARGET_ARM && !arm_arch5 && !SIBLING_CALL_P (insn)"
9c08d1fa 7826 "*
215b30b3 7827 return output_call (&operands[1]);
cffb2a26 7828 "
7829 [(set_attr "length" "12")
7830 (set_attr "type" "call")]
7831)
9c08d1fa 7832
89504fc1 7833;; Note: see *call_mem
7834
f7fbdd4a 7835(define_insn "*call_value_mem"
27ed6835 7836 [(set (match_operand 0 "" "")
a3c63a9d 7837 (call (mem:SI (match_operand:SI 1 "call_memory_operand" "m"))
cffb2a26 7838 (match_operand 2 "" "")))
bbe777ea 7839 (use (match_operand 3 "" ""))
bd5b4116 7840 (clobber (reg:SI LR_REGNUM))]
33ae7c4b 7841 "TARGET_ARM && !arm_arch5 && (!CONSTANT_ADDRESS_P (XEXP (operands[1], 0)))
7842 && !SIBLING_CALL_P (insn)"
9c08d1fa 7843 "*
215b30b3 7844 return output_call_mem (&operands[1]);
cffb2a26 7845 "
7846 [(set_attr "length" "12")
7847 (set_attr "type" "call")]
7848)
9c08d1fa 7849
7850;; Allow calls to SYMBOL_REFs specially as they are not valid general addresses
7851;; The 'a' causes the operand to be treated as an address, i.e. no '#' output.
7852
f7fbdd4a 7853(define_insn "*call_symbol"
27ed6835 7854 [(call (mem:SI (match_operand:SI 0 "" ""))
cffb2a26 7855 (match_operand 1 "" ""))
bbe777ea 7856 (use (match_operand 2 "" ""))
bd5b4116 7857 (clobber (reg:SI LR_REGNUM))]
d68c2c10 7858 "TARGET_32BIT
33ae7c4b 7859 && !SIBLING_CALL_P (insn)
cffb2a26 7860 && (GET_CODE (operands[0]) == SYMBOL_REF)
de55252a 7861 && !arm_is_long_call_p (SYMBOL_REF_DECL (operands[0]))"
6ebaa29d 7862 "*
7863 {
95f1e0d1 7864 rtx op = operands[0];
7865
7866 /* Switch mode now when possible. */
7867 if (SYMBOL_REF_DECL (op) && !TREE_PUBLIC (SYMBOL_REF_DECL (op))
7868 && arm_arch5 && arm_change_mode_p (SYMBOL_REF_DECL (op)))
7869 return NEED_PLT_RELOC ? \"blx%?\\t%a0(PLT)\" : \"blx%?\\t(%a0)\";
7870
55c1e470 7871 return NEED_PLT_RELOC ? \"bl%?\\t%a0(PLT)\" : \"bl%?\\t%a0\";
6ebaa29d 7872 }"
cffb2a26 7873 [(set_attr "type" "call")]
7874)
9c08d1fa 7875
f7fbdd4a 7876(define_insn "*call_value_symbol"
ccd90aaa 7877 [(set (match_operand 0 "" "")
27ed6835 7878 (call (mem:SI (match_operand:SI 1 "" ""))
dd6d7504 7879 (match_operand:SI 2 "" "")))
bbe777ea 7880 (use (match_operand 3 "" ""))
bd5b4116 7881 (clobber (reg:SI LR_REGNUM))]
d68c2c10 7882 "TARGET_32BIT
33ae7c4b 7883 && !SIBLING_CALL_P (insn)
cffb2a26 7884 && (GET_CODE (operands[1]) == SYMBOL_REF)
de55252a 7885 && !arm_is_long_call_p (SYMBOL_REF_DECL (operands[1]))"
6ebaa29d 7886 "*
7887 {
95f1e0d1 7888 rtx op = operands[1];
7889
7890 /* Switch mode now when possible. */
7891 if (SYMBOL_REF_DECL (op) && !TREE_PUBLIC (SYMBOL_REF_DECL (op))
7892 && arm_arch5 && arm_change_mode_p (SYMBOL_REF_DECL (op)))
3f6b66fa 7893 return NEED_PLT_RELOC ? \"blx%?\\t%a1(PLT)\" : \"blx%?\\t(%a1)\";
95f1e0d1 7894
55c1e470 7895 return NEED_PLT_RELOC ? \"bl%?\\t%a1(PLT)\" : \"bl%?\\t%a1\";
6ebaa29d 7896 }"
cffb2a26 7897 [(set_attr "type" "call")]
7898)
7899
ca373797 7900(define_expand "sibcall_internal"
7901 [(parallel [(call (match_operand 0 "memory_operand" "")
7902 (match_operand 1 "general_operand" ""))
7903 (return)
7904 (use (match_operand 2 "" ""))])])
7905
1c494086 7906;; We may also be able to do sibcalls for Thumb, but it's much harder...
7907(define_expand "sibcall"
7908 [(parallel [(call (match_operand 0 "memory_operand" "")
7909 (match_operand 1 "general_operand" ""))
2ba80634 7910 (return)
7911 (use (match_operand 2 "" ""))])]
d68c2c10 7912 "TARGET_32BIT"
1c494086 7913 "
7914 {
ca373797 7915 rtx pat;
7916
3112c3f7 7917 if ((!REG_P (XEXP (operands[0], 0))
7918 && GET_CODE (XEXP (operands[0], 0)) != SYMBOL_REF)
7919 || (GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
7920 && arm_is_long_call_p (SYMBOL_REF_DECL (XEXP (operands[0], 0)))))
33ae7c4b 7921 XEXP (operands[0], 0) = force_reg (SImode, XEXP (operands[0], 0));
7922
1c494086 7923 if (operands[2] == NULL_RTX)
7924 operands[2] = const0_rtx;
ca373797 7925
7926 pat = gen_sibcall_internal (operands[0], operands[1], operands[2]);
7927 arm_emit_call_insn (pat, operands[0], true);
7928 DONE;
1c494086 7929 }"
7930)
7931
ca373797 7932(define_expand "sibcall_value_internal"
7933 [(parallel [(set (match_operand 0 "" "")
7934 (call (match_operand 1 "memory_operand" "")
7935 (match_operand 2 "general_operand" "")))
7936 (return)
7937 (use (match_operand 3 "" ""))])])
7938
1c494086 7939(define_expand "sibcall_value"
ccd90aaa 7940 [(parallel [(set (match_operand 0 "" "")
1c494086 7941 (call (match_operand 1 "memory_operand" "")
7942 (match_operand 2 "general_operand" "")))
2ba80634 7943 (return)
7944 (use (match_operand 3 "" ""))])]
d68c2c10 7945 "TARGET_32BIT"
1c494086 7946 "
7947 {
ca373797 7948 rtx pat;
7949
3112c3f7 7950 if ((!REG_P (XEXP (operands[1], 0))
7951 && GET_CODE (XEXP (operands[1], 0)) != SYMBOL_REF)
7952 || (GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
7953 && arm_is_long_call_p (SYMBOL_REF_DECL (XEXP (operands[1], 0)))))
33ae7c4b 7954 XEXP (operands[1], 0) = force_reg (SImode, XEXP (operands[1], 0));
7955
1c494086 7956 if (operands[3] == NULL_RTX)
7957 operands[3] = const0_rtx;
ca373797 7958
7959 pat = gen_sibcall_value_internal (operands[0], operands[1],
7960 operands[2], operands[3]);
7961 arm_emit_call_insn (pat, operands[1], true);
7962 DONE;
1c494086 7963 }"
7964)
7965
7966(define_insn "*sibcall_insn"
84ce8e5c 7967 [(call (mem:SI (match_operand:SI 0 "call_insn_operand" "Cs, US"))
1c494086 7968 (match_operand 1 "" ""))
2ba80634 7969 (return)
7970 (use (match_operand 2 "" ""))]
33ae7c4b 7971 "TARGET_32BIT && SIBLING_CALL_P (insn)"
1c494086 7972 "*
33ae7c4b 7973 if (which_alternative == 1)
7974 return NEED_PLT_RELOC ? \"b%?\\t%a0(PLT)\" : \"b%?\\t%a0\";
7975 else
7976 {
7977 if (arm_arch5 || arm_arch4t)
947d113e 7978 return \"bx%?\\t%0\\t%@ indirect register sibling call\";
33ae7c4b 7979 else
7980 return \"mov%?\\t%|pc, %0\\t%@ indirect register sibling call\";
7981 }
1c494086 7982 "
7983 [(set_attr "type" "call")]
7984)
7985
7986(define_insn "*sibcall_value_insn"
84ce8e5c 7987 [(set (match_operand 0 "" "")
7988 (call (mem:SI (match_operand:SI 1 "call_insn_operand" "Cs,US"))
1c494086 7989 (match_operand 2 "" "")))
2ba80634 7990 (return)
7991 (use (match_operand 3 "" ""))]
33ae7c4b 7992 "TARGET_32BIT && SIBLING_CALL_P (insn)"
1c494086 7993 "*
33ae7c4b 7994 if (which_alternative == 1)
7995 return NEED_PLT_RELOC ? \"b%?\\t%a1(PLT)\" : \"b%?\\t%a1\";
7996 else
7997 {
7998 if (arm_arch5 || arm_arch4t)
84ce8e5c 7999 return \"bx%?\\t%1\";
33ae7c4b 8000 else
8001 return \"mov%?\\t%|pc, %1\\t@ indirect sibling call \";
8002 }
1c494086 8003 "
8004 [(set_attr "type" "call")]
8005)
8006
0686440e 8007(define_expand "<return_str>return"
9b23f0a7 8008 [(RETURNS)]
8cba51a5 8009 "(TARGET_ARM || (TARGET_THUMB2
8010 && ARM_FUNC_TYPE (arm_current_func_type ()) == ARM_FT_NORMAL
8011 && !IS_STACKALIGN (arm_current_func_type ())))
0686440e 8012 <return_cond_false>"
8cba51a5 8013 "
8014 {
8015 if (TARGET_THUMB2)
8016 {
0686440e 8017 thumb2_expand_return (<return_simple_p>);
8cba51a5 8018 DONE;
8019 }
8020 }
8021 "
8022)
d68c2c10 8023
9c08d1fa 8024;; Often the return insn will be the same as loading from memory, so set attr
d68c2c10 8025(define_insn "*arm_return"
9c08d1fa 8026 [(return)]
cffb2a26 8027 "TARGET_ARM && USE_RETURN_INSN (FALSE)"
9c08d1fa 8028 "*
9c08d1fa 8029 {
cffb2a26 8030 if (arm_ccfsm_state == 2)
8031 {
8032 arm_ccfsm_state += 2;
8033 return \"\";
8034 }
e2549f81 8035 return output_return_instruction (const_true_rtx, true, false, false);
cffb2a26 8036 }"
a2cd141b 8037 [(set_attr "type" "load1")
755eb2b4 8038 (set_attr "length" "12")
0d66636f 8039 (set_attr "predicable" "yes")]
cffb2a26 8040)
9c08d1fa 8041
0686440e 8042(define_insn "*cond_<return_str>return"
9c08d1fa 8043 [(set (pc)
8fa3ba89 8044 (if_then_else (match_operator 0 "arm_comparison_operator"
8a18b90c 8045 [(match_operand 1 "cc_register" "") (const_int 0)])
9b23f0a7 8046 (RETURNS)
9c08d1fa 8047 (pc)))]
0686440e 8048 "TARGET_ARM <return_cond_true>"
9c08d1fa 8049 "*
8fa3ba89 8050 {
8051 if (arm_ccfsm_state == 2)
8052 {
8053 arm_ccfsm_state += 2;
8054 return \"\";
8055 }
0686440e 8056 return output_return_instruction (operands[0], true, false,
8057 <return_simple_p>);
8fa3ba89 8058 }"
8059 [(set_attr "conds" "use")
755eb2b4 8060 (set_attr "length" "12")
a2cd141b 8061 (set_attr "type" "load1")]
8fa3ba89 8062)
9c08d1fa 8063
0686440e 8064(define_insn "*cond_<return_str>return_inverted"
9c08d1fa 8065 [(set (pc)
8fa3ba89 8066 (if_then_else (match_operator 0 "arm_comparison_operator"
8a18b90c 8067 [(match_operand 1 "cc_register" "") (const_int 0)])
9c08d1fa 8068 (pc)
9b23f0a7 8069 (RETURNS)))]
0686440e 8070 "TARGET_ARM <return_cond_true>"
9c08d1fa 8071 "*
8fa3ba89 8072 {
8073 if (arm_ccfsm_state == 2)
8074 {
8075 arm_ccfsm_state += 2;
8076 return \"\";
8077 }
0686440e 8078 return output_return_instruction (operands[0], true, true,
8079 <return_simple_p>);
8fa3ba89 8080 }"
8081 [(set_attr "conds" "use")
37a1317b 8082 (set_attr "length" "12")
a2cd141b 8083 (set_attr "type" "load1")]
8fa3ba89 8084)
9c08d1fa 8085
e2549f81 8086(define_insn "*arm_simple_return"
8087 [(simple_return)]
8088 "TARGET_ARM"
8089 "*
8090 {
8091 if (arm_ccfsm_state == 2)
8092 {
8093 arm_ccfsm_state += 2;
8094 return \"\";
8095 }
8096 return output_return_instruction (const_true_rtx, true, false, true);
8097 }"
8098 [(set_attr "type" "branch")
8099 (set_attr "length" "4")
8100 (set_attr "predicable" "yes")]
8101)
8102
68121397 8103;; Generate a sequence of instructions to determine if the processor is
8104;; in 26-bit or 32-bit mode, and return the appropriate return address
8105;; mask.
8106
8107(define_expand "return_addr_mask"
8108 [(set (match_dup 1)
8109 (compare:CC_NOOV (unspec [(const_int 0)] UNSPEC_CHECK_ARCH)
8110 (const_int 0)))
8111 (set (match_operand:SI 0 "s_register_operand" "")
8112 (if_then_else:SI (eq (match_dup 1) (const_int 0))
8113 (const_int -1)
8114 (const_int 67108860)))] ; 0x03fffffc
8115 "TARGET_ARM"
8116 "
62eddbd4 8117 operands[1] = gen_rtx_REG (CC_NOOVmode, CC_REGNUM);
68121397 8118 ")
8119
8120(define_insn "*check_arch2"
8121 [(set (match_operand:CC_NOOV 0 "cc_register" "")
8122 (compare:CC_NOOV (unspec [(const_int 0)] UNSPEC_CHECK_ARCH)
8123 (const_int 0)))]
8124 "TARGET_ARM"
8125 "teq\\t%|r0, %|r0\;teq\\t%|pc, %|pc"
8126 [(set_attr "length" "8")
1b7da4ac 8127 (set_attr "conds" "set")
8128 (set_attr "type" "multiple")]
68121397 8129)
8130
9c08d1fa 8131;; Call subroutine returning any type.
8132
8133(define_expand "untyped_call"
8134 [(parallel [(call (match_operand 0 "" "")
8135 (const_int 0))
8136 (match_operand 1 "" "")
8137 (match_operand 2 "" "")])]
ccd90aaa 8138 "TARGET_EITHER"
9c08d1fa 8139 "
215b30b3 8140 {
8141 int i;
ccd90aaa 8142 rtx par = gen_rtx_PARALLEL (VOIDmode,
8143 rtvec_alloc (XVECLEN (operands[2], 0)));
8144 rtx addr = gen_reg_rtx (Pmode);
8145 rtx mem;
8146 int size = 0;
9c08d1fa 8147
ccd90aaa 8148 emit_move_insn (addr, XEXP (operands[1], 0));
8149 mem = change_address (operands[1], BLKmode, addr);
9c08d1fa 8150
215b30b3 8151 for (i = 0; i < XVECLEN (operands[2], 0); i++)
8152 {
ccd90aaa 8153 rtx src = SET_SRC (XVECEXP (operands[2], 0, i));
9c08d1fa 8154
ccd90aaa 8155 /* Default code only uses r0 as a return value, but we could
8156 be using anything up to 4 registers. */
8157 if (REGNO (src) == R0_REGNUM)
8158 src = gen_rtx_REG (TImode, R0_REGNUM);
8159
8160 XVECEXP (par, 0, i) = gen_rtx_EXPR_LIST (VOIDmode, src,
8161 GEN_INT (size));
8162 size += GET_MODE_SIZE (GET_MODE (src));
8163 }
8164
7f265a08 8165 emit_call_insn (gen_call_value (par, operands[0], const0_rtx, NULL));
ccd90aaa 8166
8167 size = 0;
8168
8169 for (i = 0; i < XVECLEN (par, 0); i++)
8170 {
8171 HOST_WIDE_INT offset = 0;
8172 rtx reg = XEXP (XVECEXP (par, 0, i), 0);
8173
8174 if (size != 0)
29c05e22 8175 emit_move_insn (addr, plus_constant (Pmode, addr, size));
ccd90aaa 8176
8177 mem = change_address (mem, GET_MODE (reg), NULL);
8178 if (REGNO (reg) == R0_REGNUM)
8179 {
8180 /* On thumb we have to use a write-back instruction. */
320ea44d 8181 emit_insn (arm_gen_store_multiple (arm_regs_in_sequence, 4, addr,
8182 TARGET_THUMB ? TRUE : FALSE, mem, &offset));
ccd90aaa 8183 size = TARGET_ARM ? 16 : 0;
8184 }
8185 else
8186 {
8187 emit_move_insn (mem, reg);
8188 size = GET_MODE_SIZE (GET_MODE (reg));
8189 }
215b30b3 8190 }
9c08d1fa 8191
215b30b3 8192 /* The optimizer does not know that the call sets the function value
8193 registers we stored in the result block. We avoid problems by
8194 claiming that all hard registers are used and clobbered at this
8195 point. */
8196 emit_insn (gen_blockage ());
8197
8198 DONE;
8199 }"
8200)
9c08d1fa 8201
ccd90aaa 8202(define_expand "untyped_return"
8203 [(match_operand:BLK 0 "memory_operand" "")
8204 (match_operand 1 "" "")]
8205 "TARGET_EITHER"
8206 "
8207 {
8208 int i;
8209 rtx addr = gen_reg_rtx (Pmode);
8210 rtx mem;
8211 int size = 0;
8212
8213 emit_move_insn (addr, XEXP (operands[0], 0));
8214 mem = change_address (operands[0], BLKmode, addr);
8215
8216 for (i = 0; i < XVECLEN (operands[1], 0); i++)
8217 {
8218 HOST_WIDE_INT offset = 0;
8219 rtx reg = SET_DEST (XVECEXP (operands[1], 0, i));
8220
8221 if (size != 0)
29c05e22 8222 emit_move_insn (addr, plus_constant (Pmode, addr, size));
ccd90aaa 8223
8224 mem = change_address (mem, GET_MODE (reg), NULL);
8225 if (REGNO (reg) == R0_REGNUM)
8226 {
8227 /* On thumb we have to use a write-back instruction. */
320ea44d 8228 emit_insn (arm_gen_load_multiple (arm_regs_in_sequence, 4, addr,
8229 TARGET_THUMB ? TRUE : FALSE, mem, &offset));
ccd90aaa 8230 size = TARGET_ARM ? 16 : 0;
8231 }
8232 else
8233 {
8234 emit_move_insn (reg, mem);
8235 size = GET_MODE_SIZE (GET_MODE (reg));
8236 }
8237 }
8238
8239 /* Emit USE insns before the return. */
8240 for (i = 0; i < XVECLEN (operands[1], 0); i++)
18b42941 8241 emit_use (SET_DEST (XVECEXP (operands[1], 0, i)));
ccd90aaa 8242
8243 /* Construct the return. */
8244 expand_naked_return ();
8245
8246 DONE;
8247 }"
8248)
8249
9c08d1fa 8250;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
8251;; all of memory. This blocks insns from being moved across this point.
8252
8253(define_insn "blockage"
e1159bbe 8254 [(unspec_volatile [(const_int 0)] VUNSPEC_BLOCKAGE)]
cffb2a26 8255 "TARGET_EITHER"
9c08d1fa 8256 ""
cffb2a26 8257 [(set_attr "length" "0")
8258 (set_attr "type" "block")]
8259)
9c08d1fa 8260
706dca65 8261(define_insn "probe_stack"
8262 [(set (match_operand 0 "memory_operand" "=m")
8263 (unspec [(const_int 0)] UNSPEC_PROBE_STACK))]
8264 "TARGET_32BIT"
154ae8e6 8265 "str%?\\tr0, %0"
706dca65 8266 [(set_attr "type" "store1")
8267 (set_attr "predicable" "yes")]
8268)
8269
8270(define_insn "probe_stack_range"
8271 [(set (match_operand:SI 0 "register_operand" "=r")
8272 (unspec_volatile:SI [(match_operand:SI 1 "register_operand" "0")
8273 (match_operand:SI 2 "register_operand" "r")]
8274 UNSPEC_PROBE_STACK_RANGE))]
8275 "TARGET_32BIT"
8276{
8277 return output_probe_stack_range (operands[0], operands[2]);
8278}
8279 [(set_attr "type" "multiple")
8280 (set_attr "conds" "clob")]
8281)
8282
f7fbdd4a 8283(define_expand "casesi"
8284 [(match_operand:SI 0 "s_register_operand" "") ; index to jump on
aea4c774 8285 (match_operand:SI 1 "const_int_operand" "") ; lower bound
8286 (match_operand:SI 2 "const_int_operand" "") ; total range
f7fbdd4a 8287 (match_operand:SI 3 "" "") ; table label
8288 (match_operand:SI 4 "" "")] ; Out of range label
e6ac8414 8289 "TARGET_32BIT || optimize_size || flag_pic"
f7fbdd4a 8290 "
215b30b3 8291 {
e6ac8414 8292 enum insn_code code;
215b30b3 8293 if (operands[1] != const0_rtx)
8294 {
e6ac8414 8295 rtx reg = gen_reg_rtx (SImode);
f7fbdd4a 8296
215b30b3 8297 emit_insn (gen_addsi3 (reg, operands[0],
d022fa24 8298 gen_int_mode (-INTVAL (operands[1]),
8299 SImode)));
215b30b3 8300 operands[0] = reg;
8301 }
9c08d1fa 8302
25f905c2 8303 if (TARGET_ARM)
e6ac8414 8304 code = CODE_FOR_arm_casesi_internal;
3db2019b 8305 else if (TARGET_THUMB1)
e6ac8414 8306 code = CODE_FOR_thumb1_casesi_internal_pic;
25f905c2 8307 else if (flag_pic)
e6ac8414 8308 code = CODE_FOR_thumb2_casesi_internal_pic;
25f905c2 8309 else
e6ac8414 8310 code = CODE_FOR_thumb2_casesi_internal;
8311
8312 if (!insn_data[(int) code].operand[1].predicate(operands[2], SImode))
8313 operands[2] = force_reg (SImode, operands[2]);
8314
8315 emit_jump_insn (GEN_FCN ((int) code) (operands[0], operands[2],
8316 operands[3], operands[4]));
215b30b3 8317 DONE;
8318 }"
8319)
f7fbdd4a 8320
f082f1c4 8321;; The USE in this pattern is needed to tell flow analysis that this is
8322;; a CASESI insn. It has no other purpose.
25f905c2 8323(define_insn "arm_casesi_internal"
f082f1c4 8324 [(parallel [(set (pc)
8325 (if_then_else
8326 (leu (match_operand:SI 0 "s_register_operand" "r")
8327 (match_operand:SI 1 "arm_rhs_operand" "rI"))
8328 (mem:SI (plus:SI (mult:SI (match_dup 0) (const_int 4))
8329 (label_ref (match_operand 2 "" ""))))
8330 (label_ref (match_operand 3 "" ""))))
bd5b4116 8331 (clobber (reg:CC CC_REGNUM))
f082f1c4 8332 (use (label_ref (match_dup 2)))])]
cffb2a26 8333 "TARGET_ARM"
f7fbdd4a 8334 "*
0d66636f 8335 if (flag_pic)
8336 return \"cmp\\t%0, %1\;addls\\t%|pc, %|pc, %0, asl #2\;b\\t%l3\";
8337 return \"cmp\\t%0, %1\;ldrls\\t%|pc, [%|pc, %0, asl #2]\;b\\t%l3\";
8338 "
8339 [(set_attr "conds" "clob")
1b7da4ac 8340 (set_attr "length" "12")
8341 (set_attr "type" "multiple")]
0d66636f 8342)
9c08d1fa 8343
cffb2a26 8344(define_expand "indirect_jump"
9c08d1fa 8345 [(set (pc)
cffb2a26 8346 (match_operand:SI 0 "s_register_operand" ""))]
8347 "TARGET_EITHER"
25f905c2 8348 "
8349 /* Thumb-2 doesn't have mov pc, reg. Explicitly set the low bit of the
8350 address and use bx. */
8351 if (TARGET_THUMB2)
8352 {
8353 rtx tmp;
8354 tmp = gen_reg_rtx (SImode);
8355 emit_insn (gen_iorsi3 (tmp, operands[0], GEN_INT(1)));
8356 operands[0] = tmp;
8357 }
8358 "
cffb2a26 8359)
8360
f1039640 8361;; NB Never uses BX.
cffb2a26 8362(define_insn "*arm_indirect_jump"
8363 [(set (pc)
8364 (match_operand:SI 0 "s_register_operand" "r"))]
8365 "TARGET_ARM"
8366 "mov%?\\t%|pc, %0\\t%@ indirect register jump"
1b7da4ac 8367 [(set_attr "predicable" "yes")
8368 (set_attr "type" "branch")]
cffb2a26 8369)
9c08d1fa 8370
f7fbdd4a 8371(define_insn "*load_indirect_jump"
9c08d1fa 8372 [(set (pc)
8373 (match_operand:SI 0 "memory_operand" "m"))]
cffb2a26 8374 "TARGET_ARM"
8375 "ldr%?\\t%|pc, %0\\t%@ indirect memory jump"
a2cd141b 8376 [(set_attr "type" "load1")
61a2d04c 8377 (set_attr "pool_range" "4096")
8378 (set_attr "neg_pool_range" "4084")
0d66636f 8379 (set_attr "predicable" "yes")]
cffb2a26 8380)
8381
9c08d1fa 8382\f
8383;; Misc insns
8384
8385(define_insn "nop"
8386 [(const_int 0)]
cffb2a26 8387 "TARGET_EITHER"
8388 "*
25f905c2 8389 if (TARGET_UNIFIED_ASM)
8390 return \"nop\";
cffb2a26 8391 if (TARGET_ARM)
8392 return \"mov%?\\t%|r0, %|r0\\t%@ nop\";
8393 return \"mov\\tr8, r8\";
8394 "
8395 [(set (attr "length")
8396 (if_then_else (eq_attr "is_thumb" "yes")
8397 (const_int 2)
1b7da4ac 8398 (const_int 4)))
8399 (set_attr "type" "mov_reg")]
cffb2a26 8400)
8401
ad9d4399 8402(define_insn "trap"
8403 [(trap_if (const_int 1) (const_int 0))]
8404 ""
8405 "*
8406 if (TARGET_ARM)
8407 return \".inst\\t0xe7f000f0\";
8408 else
8409 return \".inst\\t0xdeff\";
8410 "
8411 [(set (attr "length")
8412 (if_then_else (eq_attr "is_thumb" "yes")
8413 (const_int 2)
8414 (const_int 4)))
8415 (set_attr "type" "trap")
8416 (set_attr "conds" "unconditional")]
8417)
8418
9c08d1fa 8419\f
8420;; Patterns to allow combination of arithmetic, cond code and shifts
8421
0abea32c 8422(define_insn "*<arith_shift_insn>_multsi"
8423 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9b23f0a7 8424 (SHIFTABLE_OPS:SI
0abea32c 8425 (mult:SI (match_operand:SI 2 "s_register_operand" "r,r")
8426 (match_operand:SI 3 "power_of_two_operand" ""))
8427 (match_operand:SI 1 "s_register_operand" "rk,<t2_binop0>")))]
d5d4dc8d 8428 "TARGET_32BIT"
0abea32c 8429 "<arith_shift_insn>%?\\t%0, %1, %2, lsl %b3"
8430 [(set_attr "predicable" "yes")
8431 (set_attr "predicable_short_it" "no")
753d9835 8432 (set_attr "shift" "2")
0abea32c 8433 (set_attr "arch" "a,t2")
8434 (set_attr "type" "alu_shift_imm")])
8435
8436(define_insn "*<arith_shift_insn>_shiftsi"
8437 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9b23f0a7 8438 (SHIFTABLE_OPS:SI
0abea32c 8439 (match_operator:SI 2 "shift_nomul_operator"
8440 [(match_operand:SI 3 "s_register_operand" "r,r,r")
8441 (match_operand:SI 4 "shift_amount_operand" "M,M,r")])
8442 (match_operand:SI 1 "s_register_operand" "rk,<t2_binop0>,rk")))]
a021b821 8443 "TARGET_32BIT && GET_CODE (operands[2]) != MULT"
0abea32c 8444 "<arith_shift_insn>%?\\t%0, %1, %3%S2"
344495ea 8445 [(set_attr "predicable" "yes")
74ef923b 8446 (set_attr "predicable_short_it" "no")
753d9835 8447 (set_attr "shift" "3")
0abea32c 8448 (set_attr "arch" "a,t2,a")
8449 (set_attr "type" "alu_shift_imm,alu_shift_imm,alu_shift_reg")])
9c08d1fa 8450
d7863cfe 8451(define_split
8452 [(set (match_operand:SI 0 "s_register_operand" "")
8453 (match_operator:SI 1 "shiftable_operator"
8454 [(match_operator:SI 2 "shiftable_operator"
8455 [(match_operator:SI 3 "shift_operator"
8456 [(match_operand:SI 4 "s_register_operand" "")
8457 (match_operand:SI 5 "reg_or_int_operand" "")])
8458 (match_operand:SI 6 "s_register_operand" "")])
8459 (match_operand:SI 7 "arm_rhs_operand" "")]))
8460 (clobber (match_operand:SI 8 "s_register_operand" ""))]
d5d4dc8d 8461 "TARGET_32BIT"
d7863cfe 8462 [(set (match_dup 8)
8463 (match_op_dup 2 [(match_op_dup 3 [(match_dup 4) (match_dup 5)])
8464 (match_dup 6)]))
8465 (set (match_dup 0)
8466 (match_op_dup 1 [(match_dup 8) (match_dup 7)]))]
8467 "")
8468
f7fbdd4a 8469(define_insn "*arith_shiftsi_compare0"
bd5b4116 8470 [(set (reg:CC_NOOV CC_REGNUM)
d5d4dc8d 8471 (compare:CC_NOOV
8472 (match_operator:SI 1 "shiftable_operator"
8473 [(match_operator:SI 3 "shift_operator"
8474 [(match_operand:SI 4 "s_register_operand" "r,r")
8475 (match_operand:SI 5 "shift_amount_operand" "M,r")])
8476 (match_operand:SI 2 "s_register_operand" "r,r")])
8477 (const_int 0)))
8478 (set (match_operand:SI 0 "s_register_operand" "=r,r")
9c08d1fa 8479 (match_op_dup 1 [(match_op_dup 3 [(match_dup 4) (match_dup 5)])
8480 (match_dup 2)]))]
d5d4dc8d 8481 "TARGET_32BIT"
25f905c2 8482 "%i1%.\\t%0, %2, %4%S3"
344495ea 8483 [(set_attr "conds" "set")
331beb1a 8484 (set_attr "shift" "4")
d5d4dc8d 8485 (set_attr "arch" "32,a")
d82e788e 8486 (set_attr "type" "alus_shift_imm,alus_shift_reg")])
9c08d1fa 8487
f7fbdd4a 8488(define_insn "*arith_shiftsi_compare0_scratch"
bd5b4116 8489 [(set (reg:CC_NOOV CC_REGNUM)
d5d4dc8d 8490 (compare:CC_NOOV
8491 (match_operator:SI 1 "shiftable_operator"
8492 [(match_operator:SI 3 "shift_operator"
8493 [(match_operand:SI 4 "s_register_operand" "r,r")
8494 (match_operand:SI 5 "shift_amount_operand" "M,r")])
8495 (match_operand:SI 2 "s_register_operand" "r,r")])
8496 (const_int 0)))
8497 (clobber (match_scratch:SI 0 "=r,r"))]
8498 "TARGET_32BIT"
25f905c2 8499 "%i1%.\\t%0, %2, %4%S3"
344495ea 8500 [(set_attr "conds" "set")
331beb1a 8501 (set_attr "shift" "4")
d5d4dc8d 8502 (set_attr "arch" "32,a")
d82e788e 8503 (set_attr "type" "alus_shift_imm,alus_shift_reg")])
9c08d1fa 8504
f7fbdd4a 8505(define_insn "*sub_shiftsi"
d5d4dc8d 8506 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8507 (minus:SI (match_operand:SI 1 "s_register_operand" "r,r")
9c08d1fa 8508 (match_operator:SI 2 "shift_operator"
d5d4dc8d 8509 [(match_operand:SI 3 "s_register_operand" "r,r")
8510 (match_operand:SI 4 "shift_amount_operand" "M,r")])))]
8511 "TARGET_32BIT"
6c4c2133 8512 "sub%?\\t%0, %1, %3%S2"
344495ea 8513 [(set_attr "predicable" "yes")
331beb1a 8514 (set_attr "shift" "3")
d5d4dc8d 8515 (set_attr "arch" "32,a")
d82e788e 8516 (set_attr "type" "alus_shift_imm,alus_shift_reg")])
9c08d1fa 8517
f7fbdd4a 8518(define_insn "*sub_shiftsi_compare0"
bd5b4116 8519 [(set (reg:CC_NOOV CC_REGNUM)
40dbec34 8520 (compare:CC_NOOV
d82e788e 8521 (minus:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
40dbec34 8522 (match_operator:SI 2 "shift_operator"
d82e788e 8523 [(match_operand:SI 3 "s_register_operand" "r,r,r")
8524 (match_operand:SI 4 "shift_amount_operand" "M,r,M")]))
40dbec34 8525 (const_int 0)))
d82e788e 8526 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
d5d4dc8d 8527 (minus:SI (match_dup 1)
8528 (match_op_dup 2 [(match_dup 3) (match_dup 4)])))]
8529 "TARGET_32BIT"
25f905c2 8530 "sub%.\\t%0, %1, %3%S2"
344495ea 8531 [(set_attr "conds" "set")
a2cd141b 8532 (set_attr "shift" "3")
d82e788e 8533 (set_attr "arch" "32,a,a")
8534 (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")])
9c08d1fa 8535
f7fbdd4a 8536(define_insn "*sub_shiftsi_compare0_scratch"
bd5b4116 8537 [(set (reg:CC_NOOV CC_REGNUM)
40dbec34 8538 (compare:CC_NOOV
d82e788e 8539 (minus:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
40dbec34 8540 (match_operator:SI 2 "shift_operator"
d82e788e 8541 [(match_operand:SI 3 "s_register_operand" "r,r,r")
8542 (match_operand:SI 4 "shift_amount_operand" "M,r,M")]))
40dbec34 8543 (const_int 0)))
d82e788e 8544 (clobber (match_scratch:SI 0 "=r,r,r"))]
d5d4dc8d 8545 "TARGET_32BIT"
25f905c2 8546 "sub%.\\t%0, %1, %3%S2"
344495ea 8547 [(set_attr "conds" "set")
a2cd141b 8548 (set_attr "shift" "3")
d82e788e 8549 (set_attr "arch" "32,a,a")
8550 (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")])
9c08d1fa 8551\f
8552
190efb17 8553(define_insn_and_split "*and_scc"
9c08d1fa 8554 [(set (match_operand:SI 0 "s_register_operand" "=r")
8fa3ba89 8555 (and:SI (match_operator:SI 1 "arm_comparison_operator"
190efb17 8556 [(match_operand 2 "cc_register" "") (const_int 0)])
8557 (match_operand:SI 3 "s_register_operand" "r")))]
cffb2a26 8558 "TARGET_ARM"
190efb17 8559 "#" ; "mov%D1\\t%0, #0\;and%d1\\t%0, %3, #1"
8560 "&& reload_completed"
8561 [(cond_exec (match_dup 5) (set (match_dup 0) (const_int 0)))
8562 (cond_exec (match_dup 4) (set (match_dup 0)
8563 (and:SI (match_dup 3) (const_int 1))))]
8564 {
3754d046 8565 machine_mode mode = GET_MODE (operands[2]);
190efb17 8566 enum rtx_code rc = GET_CODE (operands[1]);
8567
8568 /* Note that operands[4] is the same as operands[1],
8569 but with VOIDmode as the result. */
8570 operands[4] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
8571 if (mode == CCFPmode || mode == CCFPEmode)
8572 rc = reverse_condition_maybe_unordered (rc);
8573 else
8574 rc = reverse_condition (rc);
8575 operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
8576 }
8fa3ba89 8577 [(set_attr "conds" "use")
1b7da4ac 8578 (set_attr "type" "multiple")
8fa3ba89 8579 (set_attr "length" "8")]
8580)
9c08d1fa 8581
190efb17 8582(define_insn_and_split "*ior_scc"
9c08d1fa 8583 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
190efb17 8584 (ior:SI (match_operator:SI 1 "arm_comparison_operator"
8585 [(match_operand 2 "cc_register" "") (const_int 0)])
8586 (match_operand:SI 3 "s_register_operand" "0,?r")))]
cffb2a26 8587 "TARGET_ARM"
e2348bcb 8588 "@
190efb17 8589 orr%d1\\t%0, %3, #1
8590 #"
8591 "&& reload_completed
8592 && REGNO (operands [0]) != REGNO (operands[3])"
8593 ;; && which_alternative == 1
8594 ; mov%D1\\t%0, %3\;orr%d1\\t%0, %3, #1
8595 [(cond_exec (match_dup 5) (set (match_dup 0) (match_dup 3)))
8596 (cond_exec (match_dup 4) (set (match_dup 0)
8597 (ior:SI (match_dup 3) (const_int 1))))]
8598 {
3754d046 8599 machine_mode mode = GET_MODE (operands[2]);
190efb17 8600 enum rtx_code rc = GET_CODE (operands[1]);
8601
8602 /* Note that operands[4] is the same as operands[1],
8603 but with VOIDmode as the result. */
8604 operands[4] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
8605 if (mode == CCFPmode || mode == CCFPEmode)
8606 rc = reverse_condition_maybe_unordered (rc);
8607 else
8608 rc = reverse_condition (rc);
8609 operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
8610 }
8fa3ba89 8611 [(set_attr "conds" "use")
1b7da4ac 8612 (set_attr "length" "4,8")
8613 (set_attr "type" "logic_imm,multiple")]
8fa3ba89 8614)
9c08d1fa 8615
2df9477b 8616; A series of splitters for the compare_scc pattern below. Note that
8617; order is important.
8618(define_split
8619 [(set (match_operand:SI 0 "s_register_operand" "")
8620 (lt:SI (match_operand:SI 1 "s_register_operand" "")
8621 (const_int 0)))
8622 (clobber (reg:CC CC_REGNUM))]
8623 "TARGET_32BIT && reload_completed"
8624 [(set (match_dup 0) (lshiftrt:SI (match_dup 1) (const_int 31)))])
8625
8626(define_split
8627 [(set (match_operand:SI 0 "s_register_operand" "")
8628 (ge:SI (match_operand:SI 1 "s_register_operand" "")
8629 (const_int 0)))
8630 (clobber (reg:CC CC_REGNUM))]
8631 "TARGET_32BIT && reload_completed"
8632 [(set (match_dup 0) (not:SI (match_dup 1)))
8633 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 31)))])
8634
98562479 8635(define_split
8636 [(set (match_operand:SI 0 "s_register_operand" "")
8637 (eq:SI (match_operand:SI 1 "s_register_operand" "")
8638 (const_int 0)))
8639 (clobber (reg:CC CC_REGNUM))]
8640 "arm_arch5 && TARGET_32BIT"
8641 [(set (match_dup 0) (clz:SI (match_dup 1)))
8642 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 5)))]
8643)
8644
2df9477b 8645(define_split
8646 [(set (match_operand:SI 0 "s_register_operand" "")
8647 (eq:SI (match_operand:SI 1 "s_register_operand" "")
8648 (const_int 0)))
8649 (clobber (reg:CC CC_REGNUM))]
8650 "TARGET_32BIT && reload_completed"
8651 [(parallel
080c0b9a 8652 [(set (reg:CC CC_REGNUM)
8653 (compare:CC (const_int 1) (match_dup 1)))
2df9477b 8654 (set (match_dup 0)
8655 (minus:SI (const_int 1) (match_dup 1)))])
080c0b9a 8656 (cond_exec (ltu:CC (reg:CC CC_REGNUM) (const_int 0))
2df9477b 8657 (set (match_dup 0) (const_int 0)))])
8658
8659(define_split
8660 [(set (match_operand:SI 0 "s_register_operand" "")
8661 (ne:SI (match_operand:SI 1 "s_register_operand" "")
8662 (match_operand:SI 2 "const_int_operand" "")))
8663 (clobber (reg:CC CC_REGNUM))]
8664 "TARGET_32BIT && reload_completed"
8665 [(parallel
8666 [(set (reg:CC CC_REGNUM)
8667 (compare:CC (match_dup 1) (match_dup 2)))
8668 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 3)))])
8669 (cond_exec (ne:CC (reg:CC CC_REGNUM) (const_int 0))
8670 (set (match_dup 0) (const_int 1)))]
8671{
8672 operands[3] = GEN_INT (-INTVAL (operands[2]));
8673})
8674
8675(define_split
8676 [(set (match_operand:SI 0 "s_register_operand" "")
8677 (ne:SI (match_operand:SI 1 "s_register_operand" "")
8678 (match_operand:SI 2 "arm_add_operand" "")))
8679 (clobber (reg:CC CC_REGNUM))]
8680 "TARGET_32BIT && reload_completed"
8681 [(parallel
8682 [(set (reg:CC_NOOV CC_REGNUM)
8683 (compare:CC_NOOV (minus:SI (match_dup 1) (match_dup 2))
8684 (const_int 0)))
8685 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
8686 (cond_exec (ne:CC_NOOV (reg:CC_NOOV CC_REGNUM) (const_int 0))
8687 (set (match_dup 0) (const_int 1)))])
8688
8689(define_insn_and_split "*compare_scc"
fd711051 8690 [(set (match_operand:SI 0 "s_register_operand" "=Ts,Ts")
8fa3ba89 8691 (match_operator:SI 1 "arm_comparison_operator"
5565501b 8692 [(match_operand:SI 2 "s_register_operand" "r,r")
8693 (match_operand:SI 3 "arm_add_operand" "rI,L")]))
bd5b4116 8694 (clobber (reg:CC CC_REGNUM))]
2df9477b 8695 "TARGET_32BIT"
8696 "#"
8697 "&& reload_completed"
8698 [(set (reg:CC CC_REGNUM) (compare:CC (match_dup 2) (match_dup 3)))
8699 (cond_exec (match_dup 4) (set (match_dup 0) (const_int 0)))
8700 (cond_exec (match_dup 5) (set (match_dup 0) (const_int 1)))]
8701{
8702 rtx tmp1;
3754d046 8703 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
2df9477b 8704 operands[2], operands[3]);
8705 enum rtx_code rc = GET_CODE (operands[1]);
e2348bcb 8706
2df9477b 8707 tmp1 = gen_rtx_REG (mode, CC_REGNUM);
080c0b9a 8708
2df9477b 8709 operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, tmp1, const0_rtx);
8710 if (mode == CCFPmode || mode == CCFPEmode)
8711 rc = reverse_condition_maybe_unordered (rc);
8712 else
8713 rc = reverse_condition (rc);
8714 operands[4] = gen_rtx_fmt_ee (rc, VOIDmode, tmp1, const0_rtx);
1b7da4ac 8715}
8716 [(set_attr "type" "multiple")]
8717)
9c08d1fa 8718
080c0b9a 8719;; Attempt to improve the sequence generated by the compare_scc splitters
8720;; not to use conditional execution.
98562479 8721
8722;; Rd = (eq (reg1) (const_int0)) // ARMv5
8723;; clz Rd, reg1
8724;; lsr Rd, Rd, #5
080c0b9a 8725(define_peephole2
8726 [(set (reg:CC CC_REGNUM)
8727 (compare:CC (match_operand:SI 1 "register_operand" "")
98562479 8728 (const_int 0)))
8729 (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
8730 (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
8731 (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
8732 (set (match_dup 0) (const_int 1)))]
8733 "arm_arch5 && TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)"
8734 [(set (match_dup 0) (clz:SI (match_dup 1)))
8735 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 5)))]
8736)
8737
8738;; Rd = (eq (reg1) (const_int0)) // !ARMv5
8739;; negs Rd, reg1
8740;; adc Rd, Rd, reg1
8741(define_peephole2
8742 [(set (reg:CC CC_REGNUM)
8743 (compare:CC (match_operand:SI 1 "register_operand" "")
8744 (const_int 0)))
080c0b9a 8745 (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
8746 (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
8747 (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
8748 (set (match_dup 0) (const_int 1)))
98562479 8749 (match_scratch:SI 2 "r")]
8750 "TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)"
922b6913 8751 [(parallel
8752 [(set (reg:CC CC_REGNUM)
98562479 8753 (compare:CC (const_int 0) (match_dup 1)))
8754 (set (match_dup 2) (minus:SI (const_int 0) (match_dup 1)))])
8755 (set (match_dup 0)
8756 (plus:SI (plus:SI (match_dup 1) (match_dup 2))
8757 (geu:SI (reg:CC CC_REGNUM) (const_int 0))))]
8758)
8759
31991287 8760;; Rd = (eq (reg1) (reg2/imm)) // ARMv5 and optimising for speed.
98562479 8761;; sub Rd, Reg1, reg2
8762;; clz Rd, Rd
8763;; lsr Rd, Rd, #5
8764(define_peephole2
8765 [(set (reg:CC CC_REGNUM)
8766 (compare:CC (match_operand:SI 1 "register_operand" "")
8767 (match_operand:SI 2 "arm_rhs_operand" "")))
8768 (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
8769 (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
8770 (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
8771 (set (match_dup 0) (const_int 1)))]
31991287 8772 "arm_arch5 && TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)
8773 && !(TARGET_THUMB2 && optimize_insn_for_size_p ())"
98562479 8774 [(set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))
8775 (set (match_dup 0) (clz:SI (match_dup 0)))
8776 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 5)))]
8777)
8778
8779
31991287 8780;; Rd = (eq (reg1) (reg2)) // ! ARMv5 or optimising for size.
98562479 8781;; sub T1, Reg1, reg2
8782;; negs Rd, T1
8783;; adc Rd, Rd, T1
8784(define_peephole2
8785 [(set (reg:CC CC_REGNUM)
8786 (compare:CC (match_operand:SI 1 "register_operand" "")
8787 (match_operand:SI 2 "arm_rhs_operand" "")))
8788 (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
8789 (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
8790 (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
8791 (set (match_dup 0) (const_int 1)))
8792 (match_scratch:SI 3 "r")]
8793 "TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)"
31991287 8794 [(set (match_dup 3) (match_dup 4))
080c0b9a 8795 (parallel
8796 [(set (reg:CC CC_REGNUM)
8797 (compare:CC (const_int 0) (match_dup 3)))
8798 (set (match_dup 0) (minus:SI (const_int 0) (match_dup 3)))])
98562479 8799 (set (match_dup 0)
8800 (plus:SI (plus:SI (match_dup 0) (match_dup 3))
8801 (geu:SI (reg:CC CC_REGNUM) (const_int 0))))]
31991287 8802 "
8803 if (CONST_INT_P (operands[2]))
8804 operands[4] = plus_constant (SImode, operands[1], -INTVAL (operands[2]));
8805 else
8806 operands[4] = gen_rtx_MINUS (SImode, operands[1], operands[2]);
8807 ")
080c0b9a 8808
f7fbdd4a 8809(define_insn "*cond_move"
9c08d1fa 8810 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
aea4c774 8811 (if_then_else:SI (match_operator 3 "equality_operator"
8fa3ba89 8812 [(match_operator 4 "arm_comparison_operator"
8a18b90c 8813 [(match_operand 5 "cc_register" "") (const_int 0)])
aea4c774 8814 (const_int 0)])
8815 (match_operand:SI 1 "arm_rhs_operand" "0,rI,?rI")
8816 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))]
cffb2a26 8817 "TARGET_ARM"
9c08d1fa 8818 "*
8fa3ba89 8819 if (GET_CODE (operands[3]) == NE)
8820 {
8821 if (which_alternative != 1)
8822 output_asm_insn (\"mov%D4\\t%0, %2\", operands);
8823 if (which_alternative != 0)
8824 output_asm_insn (\"mov%d4\\t%0, %1\", operands);
8825 return \"\";
8826 }
8827 if (which_alternative != 0)
8828 output_asm_insn (\"mov%D4\\t%0, %1\", operands);
8829 if (which_alternative != 1)
8830 output_asm_insn (\"mov%d4\\t%0, %2\", operands);
8831 return \"\";
8832 "
8833 [(set_attr "conds" "use")
282b4c75 8834 (set_attr_alternative "type"
8835 [(if_then_else (match_operand 2 "const_int_operand" "")
8836 (const_string "mov_imm")
8837 (const_string "mov_reg"))
8838 (if_then_else (match_operand 1 "const_int_operand" "")
8839 (const_string "mov_imm")
8840 (const_string "mov_reg"))
8841 (const_string "multiple")])
8fa3ba89 8842 (set_attr "length" "4,4,8")]
8843)
9c08d1fa 8844
f7fbdd4a 8845(define_insn "*cond_arith"
9c08d1fa 8846 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8847 (match_operator:SI 5 "shiftable_operator"
8fa3ba89 8848 [(match_operator:SI 4 "arm_comparison_operator"
9c08d1fa 8849 [(match_operand:SI 2 "s_register_operand" "r,r")
8850 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
8851 (match_operand:SI 1 "s_register_operand" "0,?r")]))
bd5b4116 8852 (clobber (reg:CC CC_REGNUM))]
cffb2a26 8853 "TARGET_ARM"
9c08d1fa 8854 "*
8fa3ba89 8855 if (GET_CODE (operands[4]) == LT && operands[3] == const0_rtx)
8856 return \"%i5\\t%0, %1, %2, lsr #31\";
40dbec34 8857
8fa3ba89 8858 output_asm_insn (\"cmp\\t%2, %3\", operands);
8859 if (GET_CODE (operands[5]) == AND)
8860 output_asm_insn (\"mov%D4\\t%0, #0\", operands);
8861 else if (GET_CODE (operands[5]) == MINUS)
8862 output_asm_insn (\"rsb%D4\\t%0, %1, #0\", operands);
8863 else if (which_alternative != 0)
8864 output_asm_insn (\"mov%D4\\t%0, %1\", operands);
8865 return \"%i5%d4\\t%0, %1, #1\";
8866 "
8867 [(set_attr "conds" "clob")
1b7da4ac 8868 (set_attr "length" "12")
8869 (set_attr "type" "multiple")]
8fa3ba89 8870)
9c08d1fa 8871
f7fbdd4a 8872(define_insn "*cond_sub"
9c08d1fa 8873 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8874 (minus:SI (match_operand:SI 1 "s_register_operand" "0,?r")
8fa3ba89 8875 (match_operator:SI 4 "arm_comparison_operator"
9c08d1fa 8876 [(match_operand:SI 2 "s_register_operand" "r,r")
8877 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))
bd5b4116 8878 (clobber (reg:CC CC_REGNUM))]
cffb2a26 8879 "TARGET_ARM"
9c08d1fa 8880 "*
8fa3ba89 8881 output_asm_insn (\"cmp\\t%2, %3\", operands);
8882 if (which_alternative != 0)
8883 output_asm_insn (\"mov%D4\\t%0, %1\", operands);
8884 return \"sub%d4\\t%0, %1, #1\";
8885 "
8886 [(set_attr "conds" "clob")
1b7da4ac 8887 (set_attr "length" "8,12")
8888 (set_attr "type" "multiple")]
8fa3ba89 8889)
9c08d1fa 8890
aea4c774 8891(define_insn "*cmp_ite0"
cffb2a26 8892 [(set (match_operand 6 "dominant_cc_register" "")
aea4c774 8893 (compare
8894 (if_then_else:SI
8fa3ba89 8895 (match_operator 4 "arm_comparison_operator"
2ff91fec 8896 [(match_operand:SI 0 "s_register_operand"
8897 "l,l,l,r,r,r,r,r,r")
8898 (match_operand:SI 1 "arm_add_operand"
8899 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
8fa3ba89 8900 (match_operator:SI 5 "arm_comparison_operator"
2ff91fec 8901 [(match_operand:SI 2 "s_register_operand"
8902 "l,r,r,l,l,r,r,r,r")
8903 (match_operand:SI 3 "arm_add_operand"
8904 "lPy,rI,L,lPy,lPy,rI,rI,L,L")])
aea4c774 8905 (const_int 0))
8906 (const_int 0)))]
2ff91fec 8907 "TARGET_32BIT"
9c08d1fa 8908 "*
aea4c774 8909 {
2ff91fec 8910 static const char * const cmp1[NUM_OF_COND_CMP][2] =
8911 {
8912 {\"cmp%d5\\t%0, %1\",
8913 \"cmp%d4\\t%2, %3\"},
8914 {\"cmn%d5\\t%0, #%n1\",
8915 \"cmp%d4\\t%2, %3\"},
8916 {\"cmp%d5\\t%0, %1\",
8917 \"cmn%d4\\t%2, #%n3\"},
8918 {\"cmn%d5\\t%0, #%n1\",
8919 \"cmn%d4\\t%2, #%n3\"}
8920 };
8921 static const char * const cmp2[NUM_OF_COND_CMP][2] =
8922 {
8923 {\"cmp\\t%2, %3\",
8924 \"cmp\\t%0, %1\"},
8925 {\"cmp\\t%2, %3\",
8926 \"cmn\\t%0, #%n1\"},
8927 {\"cmn\\t%2, #%n3\",
8928 \"cmp\\t%0, %1\"},
8929 {\"cmn\\t%2, #%n3\",
8930 \"cmn\\t%0, #%n1\"}
8931 };
8932 static const char * const ite[2] =
8fa3ba89 8933 {
2ff91fec 8934 \"it\\t%d5\",
8935 \"it\\t%d4\"
8fa3ba89 8936 };
2ff91fec 8937 static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
8938 CMP_CMP, CMN_CMP, CMP_CMP,
8939 CMN_CMP, CMP_CMN, CMN_CMN};
8fa3ba89 8940 int swap =
8941 comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4]));
8942
2ff91fec 8943 output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
8944 if (TARGET_THUMB2) {
8945 output_asm_insn (ite[swap], operands);
8946 }
8947 output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
8948 return \"\";
8fa3ba89 8949 }"
8950 [(set_attr "conds" "set")
2ff91fec 8951 (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
1b7da4ac 8952 (set_attr "type" "multiple")
2ff91fec 8953 (set_attr_alternative "length"
8954 [(const_int 6)
8955 (const_int 8)
8956 (const_int 8)
8957 (const_int 8)
8958 (const_int 8)
8959 (if_then_else (eq_attr "is_thumb" "no")
8960 (const_int 8)
8961 (const_int 10))
8962 (if_then_else (eq_attr "is_thumb" "no")
8963 (const_int 8)
8964 (const_int 10))
8965 (if_then_else (eq_attr "is_thumb" "no")
8966 (const_int 8)
8967 (const_int 10))
8968 (if_then_else (eq_attr "is_thumb" "no")
8969 (const_int 8)
8970 (const_int 10))])]
8fa3ba89 8971)
9c08d1fa 8972
aea4c774 8973(define_insn "*cmp_ite1"
cffb2a26 8974 [(set (match_operand 6 "dominant_cc_register" "")
aea4c774 8975 (compare
8976 (if_then_else:SI
8fa3ba89 8977 (match_operator 4 "arm_comparison_operator"
2ff91fec 8978 [(match_operand:SI 0 "s_register_operand"
8979 "l,l,l,r,r,r,r,r,r")
8980 (match_operand:SI 1 "arm_add_operand"
8981 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
8fa3ba89 8982 (match_operator:SI 5 "arm_comparison_operator"
2ff91fec 8983 [(match_operand:SI 2 "s_register_operand"
8984 "l,r,r,l,l,r,r,r,r")
8985 (match_operand:SI 3 "arm_add_operand"
8986 "lPy,rI,L,lPy,lPy,rI,rI,L,L")])
aea4c774 8987 (const_int 1))
8988 (const_int 0)))]
2ff91fec 8989 "TARGET_32BIT"
9c08d1fa 8990 "*
9c08d1fa 8991 {
2ff91fec 8992 static const char * const cmp1[NUM_OF_COND_CMP][2] =
8993 {
8994 {\"cmp\\t%0, %1\",
8995 \"cmp\\t%2, %3\"},
8996 {\"cmn\\t%0, #%n1\",
8997 \"cmp\\t%2, %3\"},
8998 {\"cmp\\t%0, %1\",
8999 \"cmn\\t%2, #%n3\"},
9000 {\"cmn\\t%0, #%n1\",
9001 \"cmn\\t%2, #%n3\"}
9002 };
9003 static const char * const cmp2[NUM_OF_COND_CMP][2] =
215b30b3 9004 {
2ff91fec 9005 {\"cmp%d4\\t%2, %3\",
9006 \"cmp%D5\\t%0, %1\"},
9007 {\"cmp%d4\\t%2, %3\",
9008 \"cmn%D5\\t%0, #%n1\"},
9009 {\"cmn%d4\\t%2, #%n3\",
9010 \"cmp%D5\\t%0, %1\"},
9011 {\"cmn%d4\\t%2, #%n3\",
9012 \"cmn%D5\\t%0, #%n1\"}
215b30b3 9013 };
2ff91fec 9014 static const char * const ite[2] =
9015 {
9016 \"it\\t%d4\",
9017 \"it\\t%D5\"
9018 };
9019 static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
9020 CMP_CMP, CMN_CMP, CMP_CMP,
9021 CMN_CMP, CMP_CMN, CMN_CMN};
215b30b3 9022 int swap =
9023 comparison_dominates_p (GET_CODE (operands[5]),
9024 reverse_condition (GET_CODE (operands[4])));
9025
2ff91fec 9026 output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
9027 if (TARGET_THUMB2) {
9028 output_asm_insn (ite[swap], operands);
9029 }
9030 output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
9031 return \"\";
215b30b3 9032 }"
8fa3ba89 9033 [(set_attr "conds" "set")
2ff91fec 9034 (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
9035 (set_attr_alternative "length"
9036 [(const_int 6)
9037 (const_int 8)
9038 (const_int 8)
9039 (const_int 8)
9040 (const_int 8)
9041 (if_then_else (eq_attr "is_thumb" "no")
9042 (const_int 8)
9043 (const_int 10))
9044 (if_then_else (eq_attr "is_thumb" "no")
9045 (const_int 8)
9046 (const_int 10))
9047 (if_then_else (eq_attr "is_thumb" "no")
9048 (const_int 8)
9049 (const_int 10))
9050 (if_then_else (eq_attr "is_thumb" "no")
9051 (const_int 8)
1b7da4ac 9052 (const_int 10))])
9053 (set_attr "type" "multiple")]
8fa3ba89 9054)
9c08d1fa 9055
f6c53574 9056(define_insn "*cmp_and"
9057 [(set (match_operand 6 "dominant_cc_register" "")
9058 (compare
9059 (and:SI
9060 (match_operator 4 "arm_comparison_operator"
2ff91fec 9061 [(match_operand:SI 0 "s_register_operand"
9062 "l,l,l,r,r,r,r,r,r")
9063 (match_operand:SI 1 "arm_add_operand"
9064 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
f6c53574 9065 (match_operator:SI 5 "arm_comparison_operator"
2ff91fec 9066 [(match_operand:SI 2 "s_register_operand"
9067 "l,r,r,l,l,r,r,r,r")
9068 (match_operand:SI 3 "arm_add_operand"
9069 "lPy,rI,L,lPy,lPy,rI,rI,L,L")]))
f6c53574 9070 (const_int 0)))]
2ff91fec 9071 "TARGET_32BIT"
f6c53574 9072 "*
9073 {
2ff91fec 9074 static const char *const cmp1[NUM_OF_COND_CMP][2] =
f6c53574 9075 {
2ff91fec 9076 {\"cmp%d5\\t%0, %1\",
9077 \"cmp%d4\\t%2, %3\"},
9078 {\"cmn%d5\\t%0, #%n1\",
9079 \"cmp%d4\\t%2, %3\"},
9080 {\"cmp%d5\\t%0, %1\",
9081 \"cmn%d4\\t%2, #%n3\"},
9082 {\"cmn%d5\\t%0, #%n1\",
9083 \"cmn%d4\\t%2, #%n3\"}
f6c53574 9084 };
2ff91fec 9085 static const char *const cmp2[NUM_OF_COND_CMP][2] =
9086 {
9087 {\"cmp\\t%2, %3\",
9088 \"cmp\\t%0, %1\"},
9089 {\"cmp\\t%2, %3\",
9090 \"cmn\\t%0, #%n1\"},
9091 {\"cmn\\t%2, #%n3\",
9092 \"cmp\\t%0, %1\"},
9093 {\"cmn\\t%2, #%n3\",
9094 \"cmn\\t%0, #%n1\"}
9095 };
9096 static const char *const ite[2] =
9097 {
9098 \"it\\t%d5\",
9099 \"it\\t%d4\"
9100 };
9101 static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
9102 CMP_CMP, CMN_CMP, CMP_CMP,
9103 CMN_CMP, CMP_CMN, CMN_CMN};
f6c53574 9104 int swap =
9105 comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4]));
9106
2ff91fec 9107 output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
9108 if (TARGET_THUMB2) {
9109 output_asm_insn (ite[swap], operands);
9110 }
9111 output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
9112 return \"\";
f6c53574 9113 }"
9114 [(set_attr "conds" "set")
9115 (set_attr "predicable" "no")
2ff91fec 9116 (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
9117 (set_attr_alternative "length"
9118 [(const_int 6)
9119 (const_int 8)
9120 (const_int 8)
9121 (const_int 8)
9122 (const_int 8)
9123 (if_then_else (eq_attr "is_thumb" "no")
9124 (const_int 8)
9125 (const_int 10))
9126 (if_then_else (eq_attr "is_thumb" "no")
9127 (const_int 8)
9128 (const_int 10))
9129 (if_then_else (eq_attr "is_thumb" "no")
9130 (const_int 8)
9131 (const_int 10))
9132 (if_then_else (eq_attr "is_thumb" "no")
9133 (const_int 8)
1b7da4ac 9134 (const_int 10))])
9135 (set_attr "type" "multiple")]
f6c53574 9136)
9137
9138(define_insn "*cmp_ior"
9139 [(set (match_operand 6 "dominant_cc_register" "")
9140 (compare
9141 (ior:SI
9142 (match_operator 4 "arm_comparison_operator"
2ff91fec 9143 [(match_operand:SI 0 "s_register_operand"
9144 "l,l,l,r,r,r,r,r,r")
9145 (match_operand:SI 1 "arm_add_operand"
9146 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
f6c53574 9147 (match_operator:SI 5 "arm_comparison_operator"
2ff91fec 9148 [(match_operand:SI 2 "s_register_operand"
9149 "l,r,r,l,l,r,r,r,r")
9150 (match_operand:SI 3 "arm_add_operand"
9151 "lPy,rI,L,lPy,lPy,rI,rI,L,L")]))
f6c53574 9152 (const_int 0)))]
2ff91fec 9153 "TARGET_32BIT"
f6c53574 9154 "*
f6c53574 9155 {
2ff91fec 9156 static const char *const cmp1[NUM_OF_COND_CMP][2] =
9157 {
9158 {\"cmp\\t%0, %1\",
9159 \"cmp\\t%2, %3\"},
9160 {\"cmn\\t%0, #%n1\",
9161 \"cmp\\t%2, %3\"},
9162 {\"cmp\\t%0, %1\",
9163 \"cmn\\t%2, #%n3\"},
9164 {\"cmn\\t%0, #%n1\",
9165 \"cmn\\t%2, #%n3\"}
9166 };
9167 static const char *const cmp2[NUM_OF_COND_CMP][2] =
9168 {
9169 {\"cmp%D4\\t%2, %3\",
9170 \"cmp%D5\\t%0, %1\"},
9171 {\"cmp%D4\\t%2, %3\",
9172 \"cmn%D5\\t%0, #%n1\"},
9173 {\"cmn%D4\\t%2, #%n3\",
9174 \"cmp%D5\\t%0, %1\"},
9175 {\"cmn%D4\\t%2, #%n3\",
9176 \"cmn%D5\\t%0, #%n1\"}
9177 };
9178 static const char *const ite[2] =
9179 {
9180 \"it\\t%D4\",
9181 \"it\\t%D5\"
9182 };
9183 static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
9184 CMP_CMP, CMN_CMP, CMP_CMP,
9185 CMN_CMP, CMP_CMN, CMN_CMN};
9186 int swap =
9187 comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4]));
9188
9189 output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
9190 if (TARGET_THUMB2) {
9191 output_asm_insn (ite[swap], operands);
9192 }
9193 output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
9194 return \"\";
9195 }
9196 "
f6c53574 9197 [(set_attr "conds" "set")
2ff91fec 9198 (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
9199 (set_attr_alternative "length"
9200 [(const_int 6)
9201 (const_int 8)
9202 (const_int 8)
9203 (const_int 8)
9204 (const_int 8)
9205 (if_then_else (eq_attr "is_thumb" "no")
9206 (const_int 8)
9207 (const_int 10))
9208 (if_then_else (eq_attr "is_thumb" "no")
9209 (const_int 8)
9210 (const_int 10))
9211 (if_then_else (eq_attr "is_thumb" "no")
9212 (const_int 8)
9213 (const_int 10))
9214 (if_then_else (eq_attr "is_thumb" "no")
9215 (const_int 8)
1b7da4ac 9216 (const_int 10))])
9217 (set_attr "type" "multiple")]
f6c53574 9218)
9219
3c5afce6 9220(define_insn_and_split "*ior_scc_scc"
fd711051 9221 [(set (match_operand:SI 0 "s_register_operand" "=Ts")
3c5afce6 9222 (ior:SI (match_operator:SI 3 "arm_comparison_operator"
9223 [(match_operand:SI 1 "s_register_operand" "r")
9224 (match_operand:SI 2 "arm_add_operand" "rIL")])
9225 (match_operator:SI 6 "arm_comparison_operator"
9226 [(match_operand:SI 4 "s_register_operand" "r")
9227 (match_operand:SI 5 "arm_add_operand" "rIL")])))
9228 (clobber (reg:CC CC_REGNUM))]
2ff91fec 9229 "TARGET_32BIT
3c5afce6 9230 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_OR_Y)
9231 != CCmode)"
9232 "#"
2ff91fec 9233 "TARGET_32BIT && reload_completed"
3c5afce6 9234 [(set (match_dup 7)
9235 (compare
9236 (ior:SI
9237 (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9238 (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9239 (const_int 0)))
9240 (set (match_dup 0) (ne:SI (match_dup 7) (const_int 0)))]
9241 "operands[7]
9242 = gen_rtx_REG (arm_select_dominance_cc_mode (operands[3], operands[6],
9243 DOM_CC_X_OR_Y),
601f584c 9244 CC_REGNUM);"
9245 [(set_attr "conds" "clob")
1b7da4ac 9246 (set_attr "length" "16")
9247 (set_attr "type" "multiple")]
9248)
601f584c 9249
9250; If the above pattern is followed by a CMP insn, then the compare is
9251; redundant, since we can rework the conditional instruction that follows.
9252(define_insn_and_split "*ior_scc_scc_cmp"
9253 [(set (match_operand 0 "dominant_cc_register" "")
9254 (compare (ior:SI (match_operator:SI 3 "arm_comparison_operator"
9255 [(match_operand:SI 1 "s_register_operand" "r")
9256 (match_operand:SI 2 "arm_add_operand" "rIL")])
9257 (match_operator:SI 6 "arm_comparison_operator"
9258 [(match_operand:SI 4 "s_register_operand" "r")
9259 (match_operand:SI 5 "arm_add_operand" "rIL")]))
9260 (const_int 0)))
fd711051 9261 (set (match_operand:SI 7 "s_register_operand" "=Ts")
601f584c 9262 (ior:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9263 (match_op_dup 6 [(match_dup 4) (match_dup 5)])))]
2ff91fec 9264 "TARGET_32BIT"
601f584c 9265 "#"
2ff91fec 9266 "TARGET_32BIT && reload_completed"
601f584c 9267 [(set (match_dup 0)
9268 (compare
9269 (ior:SI
9270 (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9271 (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9272 (const_int 0)))
9273 (set (match_dup 7) (ne:SI (match_dup 0) (const_int 0)))]
9274 ""
9275 [(set_attr "conds" "set")
1b7da4ac 9276 (set_attr "length" "16")
9277 (set_attr "type" "multiple")]
9278)
3c5afce6 9279
9280(define_insn_and_split "*and_scc_scc"
fd711051 9281 [(set (match_operand:SI 0 "s_register_operand" "=Ts")
3c5afce6 9282 (and:SI (match_operator:SI 3 "arm_comparison_operator"
9283 [(match_operand:SI 1 "s_register_operand" "r")
9284 (match_operand:SI 2 "arm_add_operand" "rIL")])
9285 (match_operator:SI 6 "arm_comparison_operator"
9286 [(match_operand:SI 4 "s_register_operand" "r")
9287 (match_operand:SI 5 "arm_add_operand" "rIL")])))
9288 (clobber (reg:CC CC_REGNUM))]
2ff91fec 9289 "TARGET_32BIT
3c5afce6 9290 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y)
9291 != CCmode)"
9292 "#"
2ff91fec 9293 "TARGET_32BIT && reload_completed
601f584c 9294 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y)
9295 != CCmode)"
3c5afce6 9296 [(set (match_dup 7)
9297 (compare
9298 (and:SI
9299 (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9300 (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9301 (const_int 0)))
9302 (set (match_dup 0) (ne:SI (match_dup 7) (const_int 0)))]
9303 "operands[7]
9304 = gen_rtx_REG (arm_select_dominance_cc_mode (operands[3], operands[6],
9305 DOM_CC_X_AND_Y),
601f584c 9306 CC_REGNUM);"
9307 [(set_attr "conds" "clob")
1b7da4ac 9308 (set_attr "length" "16")
9309 (set_attr "type" "multiple")]
9310)
601f584c 9311
9312; If the above pattern is followed by a CMP insn, then the compare is
9313; redundant, since we can rework the conditional instruction that follows.
9314(define_insn_and_split "*and_scc_scc_cmp"
9315 [(set (match_operand 0 "dominant_cc_register" "")
9316 (compare (and:SI (match_operator:SI 3 "arm_comparison_operator"
9317 [(match_operand:SI 1 "s_register_operand" "r")
9318 (match_operand:SI 2 "arm_add_operand" "rIL")])
9319 (match_operator:SI 6 "arm_comparison_operator"
9320 [(match_operand:SI 4 "s_register_operand" "r")
9321 (match_operand:SI 5 "arm_add_operand" "rIL")]))
9322 (const_int 0)))
fd711051 9323 (set (match_operand:SI 7 "s_register_operand" "=Ts")
601f584c 9324 (and:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9325 (match_op_dup 6 [(match_dup 4) (match_dup 5)])))]
2ff91fec 9326 "TARGET_32BIT"
601f584c 9327 "#"
2ff91fec 9328 "TARGET_32BIT && reload_completed"
601f584c 9329 [(set (match_dup 0)
9330 (compare
9331 (and:SI
9332 (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9333 (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9334 (const_int 0)))
9335 (set (match_dup 7) (ne:SI (match_dup 0) (const_int 0)))]
9336 ""
9337 [(set_attr "conds" "set")
1b7da4ac 9338 (set_attr "length" "16")
9339 (set_attr "type" "multiple")]
9340)
601f584c 9341
9342;; If there is no dominance in the comparison, then we can still save an
9343;; instruction in the AND case, since we can know that the second compare
9344;; need only zero the value if false (if true, then the value is already
9345;; correct).
9346(define_insn_and_split "*and_scc_scc_nodom"
fd711051 9347 [(set (match_operand:SI 0 "s_register_operand" "=&Ts,&Ts,&Ts")
601f584c 9348 (and:SI (match_operator:SI 3 "arm_comparison_operator"
9349 [(match_operand:SI 1 "s_register_operand" "r,r,0")
9350 (match_operand:SI 2 "arm_add_operand" "rIL,0,rIL")])
9351 (match_operator:SI 6 "arm_comparison_operator"
9352 [(match_operand:SI 4 "s_register_operand" "r,r,r")
9353 (match_operand:SI 5 "arm_add_operand" "rIL,rIL,rIL")])))
9354 (clobber (reg:CC CC_REGNUM))]
2ff91fec 9355 "TARGET_32BIT
601f584c 9356 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y)
9357 == CCmode)"
9358 "#"
2ff91fec 9359 "TARGET_32BIT && reload_completed"
601f584c 9360 [(parallel [(set (match_dup 0)
9361 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
9362 (clobber (reg:CC CC_REGNUM))])
9363 (set (match_dup 7) (match_op_dup 8 [(match_dup 4) (match_dup 5)]))
9364 (set (match_dup 0)
9365 (if_then_else:SI (match_op_dup 6 [(match_dup 7) (const_int 0)])
9366 (match_dup 0)
9367 (const_int 0)))]
9368 "operands[7] = gen_rtx_REG (SELECT_CC_MODE (GET_CODE (operands[6]),
9369 operands[4], operands[5]),
9370 CC_REGNUM);
9371 operands[8] = gen_rtx_COMPARE (GET_MODE (operands[7]), operands[4],
9372 operands[5]);"
9373 [(set_attr "conds" "clob")
1b7da4ac 9374 (set_attr "length" "20")
9375 (set_attr "type" "multiple")]
9376)
3c5afce6 9377
3a0bdee0 9378(define_split
9379 [(set (reg:CC_NOOV CC_REGNUM)
9380 (compare:CC_NOOV (ior:SI
9381 (and:SI (match_operand:SI 0 "s_register_operand" "")
9382 (const_int 1))
b0694be0 9383 (match_operator:SI 1 "arm_comparison_operator"
3a0bdee0 9384 [(match_operand:SI 2 "s_register_operand" "")
9385 (match_operand:SI 3 "arm_add_operand" "")]))
9386 (const_int 0)))
9387 (clobber (match_operand:SI 4 "s_register_operand" ""))]
9388 "TARGET_ARM"
9389 [(set (match_dup 4)
9390 (ior:SI (match_op_dup 1 [(match_dup 2) (match_dup 3)])
9391 (match_dup 0)))
9392 (set (reg:CC_NOOV CC_REGNUM)
9393 (compare:CC_NOOV (and:SI (match_dup 4) (const_int 1))
9394 (const_int 0)))]
9395 "")
9396
9397(define_split
9398 [(set (reg:CC_NOOV CC_REGNUM)
9399 (compare:CC_NOOV (ior:SI
b0694be0 9400 (match_operator:SI 1 "arm_comparison_operator"
3a0bdee0 9401 [(match_operand:SI 2 "s_register_operand" "")
9402 (match_operand:SI 3 "arm_add_operand" "")])
9403 (and:SI (match_operand:SI 0 "s_register_operand" "")
9404 (const_int 1)))
9405 (const_int 0)))
9406 (clobber (match_operand:SI 4 "s_register_operand" ""))]
9407 "TARGET_ARM"
9408 [(set (match_dup 4)
9409 (ior:SI (match_op_dup 1 [(match_dup 2) (match_dup 3)])
9410 (match_dup 0)))
9411 (set (reg:CC_NOOV CC_REGNUM)
9412 (compare:CC_NOOV (and:SI (match_dup 4) (const_int 1))
9413 (const_int 0)))]
9414 "")
25f905c2 9415;; ??? The conditional patterns above need checking for Thumb-2 usefulness
3a0bdee0 9416
190efb17 9417(define_insn_and_split "*negscc"
9c08d1fa 9418 [(set (match_operand:SI 0 "s_register_operand" "=r")
8fa3ba89 9419 (neg:SI (match_operator 3 "arm_comparison_operator"
9c08d1fa 9420 [(match_operand:SI 1 "s_register_operand" "r")
9421 (match_operand:SI 2 "arm_rhs_operand" "rI")])))
bd5b4116 9422 (clobber (reg:CC CC_REGNUM))]
cffb2a26 9423 "TARGET_ARM"
190efb17 9424 "#"
9425 "&& reload_completed"
9426 [(const_int 0)]
9427 {
9428 rtx cc_reg = gen_rtx_REG (CCmode, CC_REGNUM);
e2348bcb 9429
190efb17 9430 if (GET_CODE (operands[3]) == LT && operands[2] == const0_rtx)
9431 {
9432 /* Emit mov\\t%0, %1, asr #31 */
d1f9b275 9433 emit_insn (gen_rtx_SET (operands[0],
190efb17 9434 gen_rtx_ASHIFTRT (SImode,
9435 operands[1],
9436 GEN_INT (31))));
9437 DONE;
9438 }
9439 else if (GET_CODE (operands[3]) == NE)
9440 {
9441 /* Emit subs\\t%0, %1, %2\;mvnne\\t%0, #0 */
9442 if (CONST_INT_P (operands[2]))
9443 emit_insn (gen_cmpsi2_addneg (operands[0], operands[1], operands[2],
9444 GEN_INT (- INTVAL (operands[2]))));
9445 else
9446 emit_insn (gen_subsi3_compare (operands[0], operands[1], operands[2]));
9447
9448 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
9449 gen_rtx_NE (SImode,
9450 cc_reg,
9451 const0_rtx),
d1f9b275 9452 gen_rtx_SET (operands[0],
190efb17 9453 GEN_INT (~0))));
9454 DONE;
9455 }
9456 else
9457 {
9458 /* Emit: cmp\\t%1, %2\;mov%D3\\t%0, #0\;mvn%d3\\t%0, #0 */
d1f9b275 9459 emit_insn (gen_rtx_SET (cc_reg,
190efb17 9460 gen_rtx_COMPARE (CCmode, operands[1], operands[2])));
9461 enum rtx_code rc = GET_CODE (operands[3]);
9462
9463 rc = reverse_condition (rc);
9464 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
9465 gen_rtx_fmt_ee (rc,
9466 VOIDmode,
9467 cc_reg,
9468 const0_rtx),
d1f9b275 9469 gen_rtx_SET (operands[0], const0_rtx)));
190efb17 9470 rc = GET_CODE (operands[3]);
9471 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
9472 gen_rtx_fmt_ee (rc,
9473 VOIDmode,
9474 cc_reg,
9475 const0_rtx),
d1f9b275 9476 gen_rtx_SET (operands[0],
190efb17 9477 GEN_INT (~0))));
9478 DONE;
9479 }
9480 FAIL;
9481 }
8fa3ba89 9482 [(set_attr "conds" "clob")
1b7da4ac 9483 (set_attr "length" "12")
9484 (set_attr "type" "multiple")]
8fa3ba89 9485)
9c08d1fa 9486
90404b57 9487(define_insn_and_split "movcond_addsi"
9488 [(set (match_operand:SI 0 "s_register_operand" "=r,l,r")
9489 (if_then_else:SI
9490 (match_operator 5 "comparison_operator"
9491 [(plus:SI (match_operand:SI 3 "s_register_operand" "r,r,r")
9492 (match_operand:SI 4 "arm_add_operand" "rIL,rIL,rIL"))
9493 (const_int 0)])
9494 (match_operand:SI 1 "arm_rhs_operand" "rI,rPy,r")
9495 (match_operand:SI 2 "arm_rhs_operand" "rI,rPy,r")))
9496 (clobber (reg:CC CC_REGNUM))]
9497 "TARGET_32BIT"
9498 "#"
9499 "&& reload_completed"
9500 [(set (reg:CC_NOOV CC_REGNUM)
9501 (compare:CC_NOOV
9502 (plus:SI (match_dup 3)
9503 (match_dup 4))
9504 (const_int 0)))
9505 (set (match_dup 0) (match_dup 1))
9506 (cond_exec (match_dup 6)
9507 (set (match_dup 0) (match_dup 2)))]
9508 "
9509 {
3754d046 9510 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[5]),
90404b57 9511 operands[3], operands[4]);
9512 enum rtx_code rc = GET_CODE (operands[5]);
90404b57 9513 operands[6] = gen_rtx_REG (mode, CC_REGNUM);
9514 gcc_assert (!(mode == CCFPmode || mode == CCFPEmode));
22440aeb 9515 if (!REG_P (operands[2]) || REGNO (operands[2]) != REGNO (operands[0]))
4d01ce2f 9516 rc = reverse_condition (rc);
f145bcba 9517 else
9518 std::swap (operands[1], operands[2]);
90404b57 9519
9520 operands[6] = gen_rtx_fmt_ee (rc, VOIDmode, operands[6], const0_rtx);
9521 }
9522 "
9523 [(set_attr "conds" "clob")
1b7da4ac 9524 (set_attr "enabled_for_depr_it" "no,yes,yes")
9525 (set_attr "type" "multiple")]
90404b57 9526)
9527
9c08d1fa 9528(define_insn "movcond"
9529 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
5565501b 9530 (if_then_else:SI
8fa3ba89 9531 (match_operator 5 "arm_comparison_operator"
5565501b 9532 [(match_operand:SI 3 "s_register_operand" "r,r,r")
9533 (match_operand:SI 4 "arm_add_operand" "rIL,rIL,rIL")])
9534 (match_operand:SI 1 "arm_rhs_operand" "0,rI,?rI")
9535 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
bd5b4116 9536 (clobber (reg:CC CC_REGNUM))]
cffb2a26 9537 "TARGET_ARM"
9c08d1fa 9538 "*
9539 if (GET_CODE (operands[5]) == LT
9540 && (operands[4] == const0_rtx))
9541 {
0438d37f 9542 if (which_alternative != 1 && REG_P (operands[1]))
9c08d1fa 9543 {
9c08d1fa 9544 if (operands[2] == const0_rtx)
e2348bcb 9545 return \"and\\t%0, %1, %3, asr #31\";
9546 return \"ands\\t%0, %1, %3, asr #32\;movcc\\t%0, %2\";
9c08d1fa 9547 }
0438d37f 9548 else if (which_alternative != 0 && REG_P (operands[2]))
9c08d1fa 9549 {
9c08d1fa 9550 if (operands[1] == const0_rtx)
e2348bcb 9551 return \"bic\\t%0, %2, %3, asr #31\";
9552 return \"bics\\t%0, %2, %3, asr #32\;movcs\\t%0, %1\";
9c08d1fa 9553 }
9554 /* The only case that falls through to here is when both ops 1 & 2
674a8f0b 9555 are constants. */
9c08d1fa 9556 }
e2348bcb 9557
9c08d1fa 9558 if (GET_CODE (operands[5]) == GE
9559 && (operands[4] == const0_rtx))
9560 {
0438d37f 9561 if (which_alternative != 1 && REG_P (operands[1]))
9c08d1fa 9562 {
9c08d1fa 9563 if (operands[2] == const0_rtx)
e2348bcb 9564 return \"bic\\t%0, %1, %3, asr #31\";
9565 return \"bics\\t%0, %1, %3, asr #32\;movcs\\t%0, %2\";
9c08d1fa 9566 }
0438d37f 9567 else if (which_alternative != 0 && REG_P (operands[2]))
9c08d1fa 9568 {
9c08d1fa 9569 if (operands[1] == const0_rtx)
e2348bcb 9570 return \"and\\t%0, %2, %3, asr #31\";
9571 return \"ands\\t%0, %2, %3, asr #32\;movcc\\t%0, %1\";
9c08d1fa 9572 }
9573 /* The only case that falls through to here is when both ops 1 & 2
674a8f0b 9574 are constants. */
9c08d1fa 9575 }
0438d37f 9576 if (CONST_INT_P (operands[4])
9c08d1fa 9577 && !const_ok_for_arm (INTVAL (operands[4])))
e2348bcb 9578 output_asm_insn (\"cmn\\t%3, #%n4\", operands);
9c08d1fa 9579 else
e2348bcb 9580 output_asm_insn (\"cmp\\t%3, %4\", operands);
9c08d1fa 9581 if (which_alternative != 0)
e2348bcb 9582 output_asm_insn (\"mov%d5\\t%0, %1\", operands);
9c08d1fa 9583 if (which_alternative != 1)
e2348bcb 9584 output_asm_insn (\"mov%D5\\t%0, %2\", operands);
9c08d1fa 9585 return \"\";
215b30b3 9586 "
8fa3ba89 9587 [(set_attr "conds" "clob")
1b7da4ac 9588 (set_attr "length" "8,8,12")
9589 (set_attr "type" "multiple")]
8fa3ba89 9590)
9c08d1fa 9591
25f905c2 9592;; ??? The patterns below need checking for Thumb-2 usefulness.
9593
8a18b90c 9594(define_insn "*ifcompare_plus_move"
9595 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8fa3ba89 9596 (if_then_else:SI (match_operator 6 "arm_comparison_operator"
8a18b90c 9597 [(match_operand:SI 4 "s_register_operand" "r,r")
9598 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
9599 (plus:SI
9600 (match_operand:SI 2 "s_register_operand" "r,r")
9601 (match_operand:SI 3 "arm_add_operand" "rIL,rIL"))
129a2fe4 9602 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))
bd5b4116 9603 (clobber (reg:CC CC_REGNUM))]
cffb2a26 9604 "TARGET_ARM"
8a18b90c 9605 "#"
8fa3ba89 9606 [(set_attr "conds" "clob")
1b7da4ac 9607 (set_attr "length" "8,12")
9608 (set_attr "type" "multiple")]
8fa3ba89 9609)
8a18b90c 9610
9611(define_insn "*if_plus_move"
129a2fe4 9612 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r")
8a18b90c 9613 (if_then_else:SI
8fa3ba89 9614 (match_operator 4 "arm_comparison_operator"
8a18b90c 9615 [(match_operand 5 "cc_register" "") (const_int 0)])
9616 (plus:SI
129a2fe4 9617 (match_operand:SI 2 "s_register_operand" "r,r,r,r")
9618 (match_operand:SI 3 "arm_add_operand" "rI,L,rI,L"))
9619 (match_operand:SI 1 "arm_rhs_operand" "0,0,?rI,?rI")))]
cffb2a26 9620 "TARGET_ARM"
8a18b90c 9621 "@
9622 add%d4\\t%0, %2, %3
9623 sub%d4\\t%0, %2, #%n3
9624 add%d4\\t%0, %2, %3\;mov%D4\\t%0, %1
129a2fe4 9625 sub%d4\\t%0, %2, #%n3\;mov%D4\\t%0, %1"
8fa3ba89 9626 [(set_attr "conds" "use")
9627 (set_attr "length" "4,4,8,8")
65f68e55 9628 (set_attr_alternative "type"
9629 [(if_then_else (match_operand 3 "const_int_operand" "")
d82e788e 9630 (const_string "alu_imm" )
112eda6f 9631 (const_string "alu_sreg"))
d82e788e 9632 (const_string "alu_imm")
282b4c75 9633 (const_string "multiple")
9634 (const_string "multiple")])]
8fa3ba89 9635)
8a18b90c 9636
9637(define_insn "*ifcompare_move_plus"
5565501b 9638 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8fa3ba89 9639 (if_then_else:SI (match_operator 6 "arm_comparison_operator"
8a18b90c 9640 [(match_operand:SI 4 "s_register_operand" "r,r")
9641 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
129a2fe4 9642 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
8a18b90c 9643 (plus:SI
9644 (match_operand:SI 2 "s_register_operand" "r,r")
9645 (match_operand:SI 3 "arm_add_operand" "rIL,rIL"))))
bd5b4116 9646 (clobber (reg:CC CC_REGNUM))]
cffb2a26 9647 "TARGET_ARM"
8a18b90c 9648 "#"
8fa3ba89 9649 [(set_attr "conds" "clob")
1b7da4ac 9650 (set_attr "length" "8,12")
9651 (set_attr "type" "multiple")]
8fa3ba89 9652)
8a18b90c 9653
9654(define_insn "*if_move_plus"
129a2fe4 9655 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r")
8a18b90c 9656 (if_then_else:SI
8fa3ba89 9657 (match_operator 4 "arm_comparison_operator"
8a18b90c 9658 [(match_operand 5 "cc_register" "") (const_int 0)])
129a2fe4 9659 (match_operand:SI 1 "arm_rhs_operand" "0,0,?rI,?rI")
8a18b90c 9660 (plus:SI
129a2fe4 9661 (match_operand:SI 2 "s_register_operand" "r,r,r,r")
9662 (match_operand:SI 3 "arm_add_operand" "rI,L,rI,L"))))]
cffb2a26 9663 "TARGET_ARM"
8a18b90c 9664 "@
9665 add%D4\\t%0, %2, %3
9666 sub%D4\\t%0, %2, #%n3
9667 add%D4\\t%0, %2, %3\;mov%d4\\t%0, %1
129a2fe4 9668 sub%D4\\t%0, %2, #%n3\;mov%d4\\t%0, %1"
8fa3ba89 9669 [(set_attr "conds" "use")
9670 (set_attr "length" "4,4,8,8")
282b4c75 9671 (set_attr_alternative "type"
9672 [(if_then_else (match_operand 3 "const_int_operand" "")
9673 (const_string "alu_imm" )
9674 (const_string "alu_sreg"))
9675 (const_string "alu_imm")
9676 (const_string "multiple")
9677 (const_string "multiple")])]
8fa3ba89 9678)
8a18b90c 9679
9680(define_insn "*ifcompare_arith_arith"
9681 [(set (match_operand:SI 0 "s_register_operand" "=r")
8fa3ba89 9682 (if_then_else:SI (match_operator 9 "arm_comparison_operator"
8a18b90c 9683 [(match_operand:SI 5 "s_register_operand" "r")
9684 (match_operand:SI 6 "arm_add_operand" "rIL")])
9c08d1fa 9685 (match_operator:SI 8 "shiftable_operator"
8a18b90c 9686 [(match_operand:SI 1 "s_register_operand" "r")
9687 (match_operand:SI 2 "arm_rhs_operand" "rI")])
9c08d1fa 9688 (match_operator:SI 7 "shiftable_operator"
8a18b90c 9689 [(match_operand:SI 3 "s_register_operand" "r")
9690 (match_operand:SI 4 "arm_rhs_operand" "rI")])))
bd5b4116 9691 (clobber (reg:CC CC_REGNUM))]
cffb2a26 9692 "TARGET_ARM"
8a18b90c 9693 "#"
8fa3ba89 9694 [(set_attr "conds" "clob")
1b7da4ac 9695 (set_attr "length" "12")
9696 (set_attr "type" "multiple")]
8fa3ba89 9697)
9c08d1fa 9698
8a18b90c 9699(define_insn "*if_arith_arith"
9700 [(set (match_operand:SI 0 "s_register_operand" "=r")
8fa3ba89 9701 (if_then_else:SI (match_operator 5 "arm_comparison_operator"
8a18b90c 9702 [(match_operand 8 "cc_register" "") (const_int 0)])
9703 (match_operator:SI 6 "shiftable_operator"
9704 [(match_operand:SI 1 "s_register_operand" "r")
9705 (match_operand:SI 2 "arm_rhs_operand" "rI")])
9706 (match_operator:SI 7 "shiftable_operator"
9707 [(match_operand:SI 3 "s_register_operand" "r")
9708 (match_operand:SI 4 "arm_rhs_operand" "rI")])))]
cffb2a26 9709 "TARGET_ARM"
8a18b90c 9710 "%I6%d5\\t%0, %1, %2\;%I7%D5\\t%0, %3, %4"
8fa3ba89 9711 [(set_attr "conds" "use")
1b7da4ac 9712 (set_attr "length" "8")
9713 (set_attr "type" "multiple")]
8fa3ba89 9714)
8a18b90c 9715
f7fbdd4a 9716(define_insn "*ifcompare_arith_move"
9c08d1fa 9717 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8fa3ba89 9718 (if_then_else:SI (match_operator 6 "arm_comparison_operator"
9c08d1fa 9719 [(match_operand:SI 2 "s_register_operand" "r,r")
5565501b 9720 (match_operand:SI 3 "arm_add_operand" "rIL,rIL")])
9c08d1fa 9721 (match_operator:SI 7 "shiftable_operator"
9722 [(match_operand:SI 4 "s_register_operand" "r,r")
9723 (match_operand:SI 5 "arm_rhs_operand" "rI,rI")])
129a2fe4 9724 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))
bd5b4116 9725 (clobber (reg:CC CC_REGNUM))]
cffb2a26 9726 "TARGET_ARM"
9c08d1fa 9727 "*
9c08d1fa 9728 /* If we have an operation where (op x 0) is the identity operation and
01cc3b75 9729 the conditional operator is LT or GE and we are comparing against zero and
674a8f0b 9730 everything is in registers then we can do this in two instructions. */
9c08d1fa 9731 if (operands[3] == const0_rtx
9732 && GET_CODE (operands[7]) != AND
0438d37f 9733 && REG_P (operands[5])
9734 && REG_P (operands[1])
9c08d1fa 9735 && REGNO (operands[1]) == REGNO (operands[4])
9736 && REGNO (operands[4]) != REGNO (operands[0]))
9737 {
9738 if (GET_CODE (operands[6]) == LT)
40dbec34 9739 return \"and\\t%0, %5, %2, asr #31\;%I7\\t%0, %4, %0\";
9c08d1fa 9740 else if (GET_CODE (operands[6]) == GE)
40dbec34 9741 return \"bic\\t%0, %5, %2, asr #31\;%I7\\t%0, %4, %0\";
9c08d1fa 9742 }
0438d37f 9743 if (CONST_INT_P (operands[3])
9c08d1fa 9744 && !const_ok_for_arm (INTVAL (operands[3])))
e2348bcb 9745 output_asm_insn (\"cmn\\t%2, #%n3\", operands);
9c08d1fa 9746 else
e2348bcb 9747 output_asm_insn (\"cmp\\t%2, %3\", operands);
40dbec34 9748 output_asm_insn (\"%I7%d6\\t%0, %4, %5\", operands);
9c08d1fa 9749 if (which_alternative != 0)
129a2fe4 9750 return \"mov%D6\\t%0, %1\";
9c08d1fa 9751 return \"\";
215b30b3 9752 "
8fa3ba89 9753 [(set_attr "conds" "clob")
1b7da4ac 9754 (set_attr "length" "8,12")
9755 (set_attr "type" "multiple")]
8fa3ba89 9756)
9c08d1fa 9757
8a18b90c 9758(define_insn "*if_arith_move"
129a2fe4 9759 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8fa3ba89 9760 (if_then_else:SI (match_operator 4 "arm_comparison_operator"
8a18b90c 9761 [(match_operand 6 "cc_register" "") (const_int 0)])
9762 (match_operator:SI 5 "shiftable_operator"
129a2fe4 9763 [(match_operand:SI 2 "s_register_operand" "r,r")
9764 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
9765 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))]
cffb2a26 9766 "TARGET_ARM"
8a18b90c 9767 "@
9768 %I5%d4\\t%0, %2, %3
129a2fe4 9769 %I5%d4\\t%0, %2, %3\;mov%D4\\t%0, %1"
8fa3ba89 9770 [(set_attr "conds" "use")
9771 (set_attr "length" "4,8")
282b4c75 9772 (set_attr_alternative "type"
9773 [(if_then_else (match_operand 3 "const_int_operand" "")
9774 (const_string "alu_shift_imm" )
9775 (const_string "alu_shift_reg"))
9776 (const_string "multiple")])]
8fa3ba89 9777)
8a18b90c 9778
f7fbdd4a 9779(define_insn "*ifcompare_move_arith"
9c08d1fa 9780 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8fa3ba89 9781 (if_then_else:SI (match_operator 6 "arm_comparison_operator"
9c08d1fa 9782 [(match_operand:SI 4 "s_register_operand" "r,r")
5565501b 9783 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
129a2fe4 9784 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
9c08d1fa 9785 (match_operator:SI 7 "shiftable_operator"
9786 [(match_operand:SI 2 "s_register_operand" "r,r")
9787 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))
bd5b4116 9788 (clobber (reg:CC CC_REGNUM))]
cffb2a26 9789 "TARGET_ARM"
9c08d1fa 9790 "*
9c08d1fa 9791 /* If we have an operation where (op x 0) is the identity operation and
01cc3b75 9792 the conditional operator is LT or GE and we are comparing against zero and
9c08d1fa 9793 everything is in registers then we can do this in two instructions */
9794 if (operands[5] == const0_rtx
9795 && GET_CODE (operands[7]) != AND
0438d37f 9796 && REG_P (operands[3])
9797 && REG_P (operands[1])
9c08d1fa 9798 && REGNO (operands[1]) == REGNO (operands[2])
9799 && REGNO (operands[2]) != REGNO (operands[0]))
9800 {
9801 if (GET_CODE (operands[6]) == GE)
40dbec34 9802 return \"and\\t%0, %3, %4, asr #31\;%I7\\t%0, %2, %0\";
9c08d1fa 9803 else if (GET_CODE (operands[6]) == LT)
40dbec34 9804 return \"bic\\t%0, %3, %4, asr #31\;%I7\\t%0, %2, %0\";
9c08d1fa 9805 }
40dbec34 9806
0438d37f 9807 if (CONST_INT_P (operands[5])
9c08d1fa 9808 && !const_ok_for_arm (INTVAL (operands[5])))
e2348bcb 9809 output_asm_insn (\"cmn\\t%4, #%n5\", operands);
9c08d1fa 9810 else
e2348bcb 9811 output_asm_insn (\"cmp\\t%4, %5\", operands);
40dbec34 9812
9c08d1fa 9813 if (which_alternative != 0)
129a2fe4 9814 output_asm_insn (\"mov%d6\\t%0, %1\", operands);
40dbec34 9815 return \"%I7%D6\\t%0, %2, %3\";
215b30b3 9816 "
8fa3ba89 9817 [(set_attr "conds" "clob")
1b7da4ac 9818 (set_attr "length" "8,12")
9819 (set_attr "type" "multiple")]
8fa3ba89 9820)
9c08d1fa 9821
8a18b90c 9822(define_insn "*if_move_arith"
129a2fe4 9823 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8a18b90c 9824 (if_then_else:SI
8fa3ba89 9825 (match_operator 4 "arm_comparison_operator"
8a18b90c 9826 [(match_operand 6 "cc_register" "") (const_int 0)])
129a2fe4 9827 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
8a18b90c 9828 (match_operator:SI 5 "shiftable_operator"
129a2fe4 9829 [(match_operand:SI 2 "s_register_operand" "r,r")
9830 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))]
cffb2a26 9831 "TARGET_ARM"
8a18b90c 9832 "@
9833 %I5%D4\\t%0, %2, %3
129a2fe4 9834 %I5%D4\\t%0, %2, %3\;mov%d4\\t%0, %1"
8fa3ba89 9835 [(set_attr "conds" "use")
9836 (set_attr "length" "4,8")
282b4c75 9837 (set_attr_alternative "type"
9838 [(if_then_else (match_operand 3 "const_int_operand" "")
9839 (const_string "alu_shift_imm" )
9840 (const_string "alu_shift_reg"))
9841 (const_string "multiple")])]
8fa3ba89 9842)
8a18b90c 9843
9844(define_insn "*ifcompare_move_not"
9c08d1fa 9845 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8a18b90c 9846 (if_then_else:SI
8fa3ba89 9847 (match_operator 5 "arm_comparison_operator"
8a18b90c 9848 [(match_operand:SI 3 "s_register_operand" "r,r")
9849 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
9850 (match_operand:SI 1 "arm_not_operand" "0,?rIK")
9851 (not:SI
9852 (match_operand:SI 2 "s_register_operand" "r,r"))))
bd5b4116 9853 (clobber (reg:CC CC_REGNUM))]
cffb2a26 9854 "TARGET_ARM"
8a18b90c 9855 "#"
8fa3ba89 9856 [(set_attr "conds" "clob")
1b7da4ac 9857 (set_attr "length" "8,12")
9858 (set_attr "type" "multiple")]
8fa3ba89 9859)
9c08d1fa 9860
8a18b90c 9861(define_insn "*if_move_not"
9862 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9863 (if_then_else:SI
8fa3ba89 9864 (match_operator 4 "arm_comparison_operator"
8a18b90c 9865 [(match_operand 3 "cc_register" "") (const_int 0)])
9866 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")
9867 (not:SI (match_operand:SI 2 "s_register_operand" "r,r,r"))))]
cffb2a26 9868 "TARGET_ARM"
8a18b90c 9869 "@
9870 mvn%D4\\t%0, %2
9871 mov%d4\\t%0, %1\;mvn%D4\\t%0, %2
9872 mvn%d4\\t%0, #%B1\;mvn%D4\\t%0, %2"
8fa3ba89 9873 [(set_attr "conds" "use")
1aed5204 9874 (set_attr "type" "mvn_reg")
1b7da4ac 9875 (set_attr "length" "4,8,8")
9876 (set_attr "type" "mvn_reg,multiple,multiple")]
8fa3ba89 9877)
8a18b90c 9878
9879(define_insn "*ifcompare_not_move"
9c08d1fa 9880 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8a18b90c 9881 (if_then_else:SI
8fa3ba89 9882 (match_operator 5 "arm_comparison_operator"
8a18b90c 9883 [(match_operand:SI 3 "s_register_operand" "r,r")
9884 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
9885 (not:SI
9886 (match_operand:SI 2 "s_register_operand" "r,r"))
9887 (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
bd5b4116 9888 (clobber (reg:CC CC_REGNUM))]
cffb2a26 9889 "TARGET_ARM"
8a18b90c 9890 "#"
8fa3ba89 9891 [(set_attr "conds" "clob")
1b7da4ac 9892 (set_attr "length" "8,12")
9893 (set_attr "type" "multiple")]
8fa3ba89 9894)
9c08d1fa 9895
8a18b90c 9896(define_insn "*if_not_move"
9897 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9898 (if_then_else:SI
8fa3ba89 9899 (match_operator 4 "arm_comparison_operator"
8a18b90c 9900 [(match_operand 3 "cc_register" "") (const_int 0)])
9901 (not:SI (match_operand:SI 2 "s_register_operand" "r,r,r"))
9902 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")))]
cffb2a26 9903 "TARGET_ARM"
8a18b90c 9904 "@
9905 mvn%d4\\t%0, %2
9906 mov%D4\\t%0, %1\;mvn%d4\\t%0, %2
9907 mvn%D4\\t%0, #%B1\;mvn%d4\\t%0, %2"
8fa3ba89 9908 [(set_attr "conds" "use")
1b7da4ac 9909 (set_attr "type" "mvn_reg,multiple,multiple")
8fa3ba89 9910 (set_attr "length" "4,8,8")]
9911)
8a18b90c 9912
9913(define_insn "*ifcompare_shift_move"
9c08d1fa 9914 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8a18b90c 9915 (if_then_else:SI
8fa3ba89 9916 (match_operator 6 "arm_comparison_operator"
8a18b90c 9917 [(match_operand:SI 4 "s_register_operand" "r,r")
9918 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
9919 (match_operator:SI 7 "shift_operator"
9920 [(match_operand:SI 2 "s_register_operand" "r,r")
9921 (match_operand:SI 3 "arm_rhs_operand" "rM,rM")])
9922 (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
bd5b4116 9923 (clobber (reg:CC CC_REGNUM))]
cffb2a26 9924 "TARGET_ARM"
9c08d1fa 9925 "#"
8fa3ba89 9926 [(set_attr "conds" "clob")
1b7da4ac 9927 (set_attr "length" "8,12")
9928 (set_attr "type" "multiple")]
8fa3ba89 9929)
9c08d1fa 9930
8a18b90c 9931(define_insn "*if_shift_move"
9932 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9933 (if_then_else:SI
8fa3ba89 9934 (match_operator 5 "arm_comparison_operator"
8a18b90c 9935 [(match_operand 6 "cc_register" "") (const_int 0)])
9936 (match_operator:SI 4 "shift_operator"
9937 [(match_operand:SI 2 "s_register_operand" "r,r,r")
9938 (match_operand:SI 3 "arm_rhs_operand" "rM,rM,rM")])
9939 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")))]
cffb2a26 9940 "TARGET_ARM"
5565501b 9941 "@
8a18b90c 9942 mov%d5\\t%0, %2%S4
9943 mov%D5\\t%0, %1\;mov%d5\\t%0, %2%S4
9944 mvn%D5\\t%0, #%B1\;mov%d5\\t%0, %2%S4"
8fa3ba89 9945 [(set_attr "conds" "use")
331beb1a 9946 (set_attr "shift" "2")
a2cd141b 9947 (set_attr "length" "4,8,8")
282b4c75 9948 (set_attr_alternative "type"
9949 [(if_then_else (match_operand 3 "const_int_operand" "")
9950 (const_string "mov_shift" )
9951 (const_string "mov_shift_reg"))
9952 (const_string "multiple")
9953 (const_string "multiple")])]
8fa3ba89 9954)
5565501b 9955
8a18b90c 9956(define_insn "*ifcompare_move_shift"
9957 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5565501b 9958 (if_then_else:SI
8fa3ba89 9959 (match_operator 6 "arm_comparison_operator"
8a18b90c 9960 [(match_operand:SI 4 "s_register_operand" "r,r")
9961 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
9962 (match_operand:SI 1 "arm_not_operand" "0,?rIK")
5565501b 9963 (match_operator:SI 7 "shift_operator"
8a18b90c 9964 [(match_operand:SI 2 "s_register_operand" "r,r")
9965 (match_operand:SI 3 "arm_rhs_operand" "rM,rM")])))
bd5b4116 9966 (clobber (reg:CC CC_REGNUM))]
cffb2a26 9967 "TARGET_ARM"
8a18b90c 9968 "#"
8fa3ba89 9969 [(set_attr "conds" "clob")
1b7da4ac 9970 (set_attr "length" "8,12")
9971 (set_attr "type" "multiple")]
8fa3ba89 9972)
5565501b 9973
8a18b90c 9974(define_insn "*if_move_shift"
9975 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
5565501b 9976 (if_then_else:SI
8fa3ba89 9977 (match_operator 5 "arm_comparison_operator"
8a18b90c 9978 [(match_operand 6 "cc_register" "") (const_int 0)])
9979 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")
9980 (match_operator:SI 4 "shift_operator"
9981 [(match_operand:SI 2 "s_register_operand" "r,r,r")
9982 (match_operand:SI 3 "arm_rhs_operand" "rM,rM,rM")])))]
cffb2a26 9983 "TARGET_ARM"
5565501b 9984 "@
8a18b90c 9985 mov%D5\\t%0, %2%S4
9986 mov%d5\\t%0, %1\;mov%D5\\t%0, %2%S4
9987 mvn%d5\\t%0, #%B1\;mov%D5\\t%0, %2%S4"
8fa3ba89 9988 [(set_attr "conds" "use")
331beb1a 9989 (set_attr "shift" "2")
a2cd141b 9990 (set_attr "length" "4,8,8")
282b4c75 9991 (set_attr_alternative "type"
9992 [(if_then_else (match_operand 3 "const_int_operand" "")
9993 (const_string "mov_shift" )
9994 (const_string "mov_shift_reg"))
9995 (const_string "multiple")
9996 (const_string "multiple")])]
8fa3ba89 9997)
9c08d1fa 9998
f7fbdd4a 9999(define_insn "*ifcompare_shift_shift"
8a18b90c 10000 [(set (match_operand:SI 0 "s_register_operand" "=r")
5565501b 10001 (if_then_else:SI
8fa3ba89 10002 (match_operator 7 "arm_comparison_operator"
8a18b90c 10003 [(match_operand:SI 5 "s_register_operand" "r")
10004 (match_operand:SI 6 "arm_add_operand" "rIL")])
5565501b 10005 (match_operator:SI 8 "shift_operator"
8a18b90c 10006 [(match_operand:SI 1 "s_register_operand" "r")
10007 (match_operand:SI 2 "arm_rhs_operand" "rM")])
5565501b 10008 (match_operator:SI 9 "shift_operator"
8a18b90c 10009 [(match_operand:SI 3 "s_register_operand" "r")
10010 (match_operand:SI 4 "arm_rhs_operand" "rM")])))
bd5b4116 10011 (clobber (reg:CC CC_REGNUM))]
cffb2a26 10012 "TARGET_ARM"
8a18b90c 10013 "#"
8fa3ba89 10014 [(set_attr "conds" "clob")
1b7da4ac 10015 (set_attr "length" "12")
10016 (set_attr "type" "multiple")]
8fa3ba89 10017)
9c08d1fa 10018
8a18b90c 10019(define_insn "*if_shift_shift"
10020 [(set (match_operand:SI 0 "s_register_operand" "=r")
10021 (if_then_else:SI
8fa3ba89 10022 (match_operator 5 "arm_comparison_operator"
8a18b90c 10023 [(match_operand 8 "cc_register" "") (const_int 0)])
10024 (match_operator:SI 6 "shift_operator"
10025 [(match_operand:SI 1 "s_register_operand" "r")
10026 (match_operand:SI 2 "arm_rhs_operand" "rM")])
10027 (match_operator:SI 7 "shift_operator"
10028 [(match_operand:SI 3 "s_register_operand" "r")
10029 (match_operand:SI 4 "arm_rhs_operand" "rM")])))]
cffb2a26 10030 "TARGET_ARM"
8a18b90c 10031 "mov%d5\\t%0, %1%S6\;mov%D5\\t%0, %3%S7"
8fa3ba89 10032 [(set_attr "conds" "use")
331beb1a 10033 (set_attr "shift" "1")
a2cd141b 10034 (set_attr "length" "8")
10035 (set (attr "type") (if_then_else
10036 (and (match_operand 2 "const_int_operand" "")
10037 (match_operand 4 "const_int_operand" ""))
1aed5204 10038 (const_string "mov_shift")
10039 (const_string "mov_shift_reg")))]
8fa3ba89 10040)
8a18b90c 10041
f7fbdd4a 10042(define_insn "*ifcompare_not_arith"
8a18b90c 10043 [(set (match_operand:SI 0 "s_register_operand" "=r")
5565501b 10044 (if_then_else:SI
8fa3ba89 10045 (match_operator 6 "arm_comparison_operator"
8a18b90c 10046 [(match_operand:SI 4 "s_register_operand" "r")
10047 (match_operand:SI 5 "arm_add_operand" "rIL")])
10048 (not:SI (match_operand:SI 1 "s_register_operand" "r"))
5565501b 10049 (match_operator:SI 7 "shiftable_operator"
8a18b90c 10050 [(match_operand:SI 2 "s_register_operand" "r")
10051 (match_operand:SI 3 "arm_rhs_operand" "rI")])))
bd5b4116 10052 (clobber (reg:CC CC_REGNUM))]
cffb2a26 10053 "TARGET_ARM"
8a18b90c 10054 "#"
8fa3ba89 10055 [(set_attr "conds" "clob")
1b7da4ac 10056 (set_attr "length" "12")
10057 (set_attr "type" "multiple")]
8fa3ba89 10058)
9c08d1fa 10059
8a18b90c 10060(define_insn "*if_not_arith"
10061 [(set (match_operand:SI 0 "s_register_operand" "=r")
10062 (if_then_else:SI
8fa3ba89 10063 (match_operator 5 "arm_comparison_operator"
8a18b90c 10064 [(match_operand 4 "cc_register" "") (const_int 0)])
10065 (not:SI (match_operand:SI 1 "s_register_operand" "r"))
10066 (match_operator:SI 6 "shiftable_operator"
10067 [(match_operand:SI 2 "s_register_operand" "r")
10068 (match_operand:SI 3 "arm_rhs_operand" "rI")])))]
cffb2a26 10069 "TARGET_ARM"
8a18b90c 10070 "mvn%d5\\t%0, %1\;%I6%D5\\t%0, %2, %3"
8fa3ba89 10071 [(set_attr "conds" "use")
1aed5204 10072 (set_attr "type" "mvn_reg")
8fa3ba89 10073 (set_attr "length" "8")]
10074)
8a18b90c 10075
10076(define_insn "*ifcompare_arith_not"
10077 [(set (match_operand:SI 0 "s_register_operand" "=r")
5565501b 10078 (if_then_else:SI
8fa3ba89 10079 (match_operator 6 "arm_comparison_operator"
8a18b90c 10080 [(match_operand:SI 4 "s_register_operand" "r")
10081 (match_operand:SI 5 "arm_add_operand" "rIL")])
5565501b 10082 (match_operator:SI 7 "shiftable_operator"
8a18b90c 10083 [(match_operand:SI 2 "s_register_operand" "r")
10084 (match_operand:SI 3 "arm_rhs_operand" "rI")])
10085 (not:SI (match_operand:SI 1 "s_register_operand" "r"))))
bd5b4116 10086 (clobber (reg:CC CC_REGNUM))]
cffb2a26 10087 "TARGET_ARM"
8a18b90c 10088 "#"
8fa3ba89 10089 [(set_attr "conds" "clob")
1b7da4ac 10090 (set_attr "length" "12")
10091 (set_attr "type" "multiple")]
8fa3ba89 10092)
9c08d1fa 10093
8a18b90c 10094(define_insn "*if_arith_not"
10095 [(set (match_operand:SI 0 "s_register_operand" "=r")
10096 (if_then_else:SI
8fa3ba89 10097 (match_operator 5 "arm_comparison_operator"
8a18b90c 10098 [(match_operand 4 "cc_register" "") (const_int 0)])
10099 (match_operator:SI 6 "shiftable_operator"
10100 [(match_operand:SI 2 "s_register_operand" "r")
10101 (match_operand:SI 3 "arm_rhs_operand" "rI")])
10102 (not:SI (match_operand:SI 1 "s_register_operand" "r"))))]
cffb2a26 10103 "TARGET_ARM"
8a18b90c 10104 "mvn%D5\\t%0, %1\;%I6%d5\\t%0, %2, %3"
8fa3ba89 10105 [(set_attr "conds" "use")
1b7da4ac 10106 (set_attr "type" "multiple")
8fa3ba89 10107 (set_attr "length" "8")]
10108)
8a18b90c 10109
f7fbdd4a 10110(define_insn "*ifcompare_neg_move"
8a18b90c 10111 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5565501b 10112 (if_then_else:SI
8fa3ba89 10113 (match_operator 5 "arm_comparison_operator"
8a18b90c 10114 [(match_operand:SI 3 "s_register_operand" "r,r")
10115 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
10116 (neg:SI (match_operand:SI 2 "s_register_operand" "r,r"))
10117 (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
bd5b4116 10118 (clobber (reg:CC CC_REGNUM))]
cffb2a26 10119 "TARGET_ARM"
8a18b90c 10120 "#"
8fa3ba89 10121 [(set_attr "conds" "clob")
1b7da4ac 10122 (set_attr "length" "8,12")
10123 (set_attr "type" "multiple")]
8fa3ba89 10124)
8a18b90c 10125
530bb693 10126(define_insn_and_split "*if_neg_move"
10127 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
8a18b90c 10128 (if_then_else:SI
8fa3ba89 10129 (match_operator 4 "arm_comparison_operator"
8a18b90c 10130 [(match_operand 3 "cc_register" "") (const_int 0)])
530bb693 10131 (neg:SI (match_operand:SI 2 "s_register_operand" "l,r"))
10132 (match_operand:SI 1 "s_register_operand" "0,0")))]
10133 "TARGET_32BIT"
10134 "#"
10135 "&& reload_completed"
10136 [(cond_exec (match_op_dup 4 [(match_dup 3) (const_int 0)])
10137 (set (match_dup 0) (neg:SI (match_dup 2))))]
10138 ""
8fa3ba89 10139 [(set_attr "conds" "use")
530bb693 10140 (set_attr "length" "4")
10141 (set_attr "arch" "t2,32")
10142 (set_attr "enabled_for_depr_it" "yes,no")
10143 (set_attr "type" "logic_shift_imm")]
8fa3ba89 10144)
9c08d1fa 10145
f7fbdd4a 10146(define_insn "*ifcompare_move_neg"
8a18b90c 10147 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5565501b 10148 (if_then_else:SI
8fa3ba89 10149 (match_operator 5 "arm_comparison_operator"
8a18b90c 10150 [(match_operand:SI 3 "s_register_operand" "r,r")
10151 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
10152 (match_operand:SI 1 "arm_not_operand" "0,?rIK")
10153 (neg:SI (match_operand:SI 2 "s_register_operand" "r,r"))))
bd5b4116 10154 (clobber (reg:CC CC_REGNUM))]
cffb2a26 10155 "TARGET_ARM"
8a18b90c 10156 "#"
8fa3ba89 10157 [(set_attr "conds" "clob")
1b7da4ac 10158 (set_attr "length" "8,12")
10159 (set_attr "type" "multiple")]
8fa3ba89 10160)
8a18b90c 10161
530bb693 10162(define_insn_and_split "*if_move_neg"
10163 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
8a18b90c 10164 (if_then_else:SI
8fa3ba89 10165 (match_operator 4 "arm_comparison_operator"
8a18b90c 10166 [(match_operand 3 "cc_register" "") (const_int 0)])
530bb693 10167 (match_operand:SI 1 "s_register_operand" "0,0")
10168 (neg:SI (match_operand:SI 2 "s_register_operand" "l,r"))))]
10169 "TARGET_32BIT"
10170 "#"
10171 "&& reload_completed"
10172 [(cond_exec (match_dup 5)
10173 (set (match_dup 0) (neg:SI (match_dup 2))))]
10174 {
10175 machine_mode mode = GET_MODE (operands[3]);
10176 rtx_code rc = GET_CODE (operands[4]);
10177
10178 if (mode == CCFPmode || mode == CCFPEmode)
10179 rc = reverse_condition_maybe_unordered (rc);
10180 else
10181 rc = reverse_condition (rc);
10182
10183 operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, operands[3], const0_rtx);
10184 }
0d66636f 10185 [(set_attr "conds" "use")
530bb693 10186 (set_attr "length" "4")
10187 (set_attr "arch" "t2,32")
10188 (set_attr "enabled_for_depr_it" "yes,no")
10189 (set_attr "type" "logic_shift_imm")]
0d66636f 10190)
9c08d1fa 10191
f7fbdd4a 10192(define_insn "*arith_adjacentmem"
9c08d1fa 10193 [(set (match_operand:SI 0 "s_register_operand" "=r")
10194 (match_operator:SI 1 "shiftable_operator"
10195 [(match_operand:SI 2 "memory_operand" "m")
10196 (match_operand:SI 3 "memory_operand" "m")]))
10197 (clobber (match_scratch:SI 4 "=r"))]
cffb2a26 10198 "TARGET_ARM && adjacent_mem_locations (operands[2], operands[3])"
9c08d1fa 10199 "*
215b30b3 10200 {
10201 rtx ldm[3];
10202 rtx arith[4];
94dee231 10203 rtx base_reg;
10204 HOST_WIDE_INT val1 = 0, val2 = 0;
9c08d1fa 10205
215b30b3 10206 if (REGNO (operands[0]) > REGNO (operands[4]))
10207 {
10208 ldm[1] = operands[4];
10209 ldm[2] = operands[0];
10210 }
10211 else
10212 {
10213 ldm[1] = operands[0];
10214 ldm[2] = operands[4];
10215 }
94dee231 10216
10217 base_reg = XEXP (operands[2], 0);
10218
10219 if (!REG_P (base_reg))
10220 {
10221 val1 = INTVAL (XEXP (base_reg, 1));
10222 base_reg = XEXP (base_reg, 0);
10223 }
10224
10225 if (!REG_P (XEXP (operands[3], 0)))
215b30b3 10226 val2 = INTVAL (XEXP (XEXP (operands[3], 0), 1));
94dee231 10227
215b30b3 10228 arith[0] = operands[0];
10229 arith[3] = operands[1];
94dee231 10230
215b30b3 10231 if (val1 < val2)
10232 {
10233 arith[1] = ldm[1];
10234 arith[2] = ldm[2];
10235 }
10236 else
10237 {
10238 arith[1] = ldm[2];
10239 arith[2] = ldm[1];
10240 }
94dee231 10241
10242 ldm[0] = base_reg;
10243 if (val1 !=0 && val2 != 0)
215b30b3 10244 {
cdb1295a 10245 rtx ops[3];
10246
94dee231 10247 if (val1 == 4 || val2 == 4)
10248 /* Other val must be 8, since we know they are adjacent and neither
10249 is zero. */
25f905c2 10250 output_asm_insn (\"ldm%(ib%)\\t%0, {%1, %2}\", ldm);
cdb1295a 10251 else if (const_ok_for_arm (val1) || const_ok_for_arm (-val1))
94dee231 10252 {
94dee231 10253 ldm[0] = ops[0] = operands[4];
10254 ops[1] = base_reg;
10255 ops[2] = GEN_INT (val1);
10256 output_add_immediate (ops);
10257 if (val1 < val2)
25f905c2 10258 output_asm_insn (\"ldm%(ia%)\\t%0, {%1, %2}\", ldm);
94dee231 10259 else
25f905c2 10260 output_asm_insn (\"ldm%(da%)\\t%0, {%1, %2}\", ldm);
94dee231 10261 }
cdb1295a 10262 else
10263 {
10264 /* Offset is out of range for a single add, so use two ldr. */
10265 ops[0] = ldm[1];
10266 ops[1] = base_reg;
10267 ops[2] = GEN_INT (val1);
10268 output_asm_insn (\"ldr%?\\t%0, [%1, %2]\", ops);
10269 ops[0] = ldm[2];
10270 ops[2] = GEN_INT (val2);
10271 output_asm_insn (\"ldr%?\\t%0, [%1, %2]\", ops);
10272 }
215b30b3 10273 }
94dee231 10274 else if (val1 != 0)
215b30b3 10275 {
215b30b3 10276 if (val1 < val2)
25f905c2 10277 output_asm_insn (\"ldm%(da%)\\t%0, {%1, %2}\", ldm);
215b30b3 10278 else
25f905c2 10279 output_asm_insn (\"ldm%(ia%)\\t%0, {%1, %2}\", ldm);
215b30b3 10280 }
10281 else
10282 {
215b30b3 10283 if (val1 < val2)
25f905c2 10284 output_asm_insn (\"ldm%(ia%)\\t%0, {%1, %2}\", ldm);
215b30b3 10285 else
25f905c2 10286 output_asm_insn (\"ldm%(da%)\\t%0, {%1, %2}\", ldm);
215b30b3 10287 }
10288 output_asm_insn (\"%I3%?\\t%0, %1, %2\", arith);
10289 return \"\";
10290 }"
10291 [(set_attr "length" "12")
10292 (set_attr "predicable" "yes")
a2cd141b 10293 (set_attr "type" "load1")]
215b30b3 10294)
9c08d1fa 10295
9c08d1fa 10296; This pattern is never tried by combine, so do it as a peephole
10297
a0f94409 10298(define_peephole2
372575c7 10299 [(set (match_operand:SI 0 "arm_general_register_operand" "")
10300 (match_operand:SI 1 "arm_general_register_operand" ""))
bd5b4116 10301 (set (reg:CC CC_REGNUM)
aea4c774 10302 (compare:CC (match_dup 1) (const_int 0)))]
372575c7 10303 "TARGET_ARM"
a0f94409 10304 [(parallel [(set (reg:CC CC_REGNUM) (compare:CC (match_dup 1) (const_int 0)))
10305 (set (match_dup 0) (match_dup 1))])]
10306 ""
0d66636f 10307)
9c08d1fa 10308
9c08d1fa 10309(define_split
10310 [(set (match_operand:SI 0 "s_register_operand" "")
10311 (and:SI (ge:SI (match_operand:SI 1 "s_register_operand" "")
10312 (const_int 0))
8fa3ba89 10313 (neg:SI (match_operator:SI 2 "arm_comparison_operator"
9c08d1fa 10314 [(match_operand:SI 3 "s_register_operand" "")
10315 (match_operand:SI 4 "arm_rhs_operand" "")]))))
10316 (clobber (match_operand:SI 5 "s_register_operand" ""))]
cffb2a26 10317 "TARGET_ARM"
9c08d1fa 10318 [(set (match_dup 5) (not:SI (ashiftrt:SI (match_dup 1) (const_int 31))))
10319 (set (match_dup 0) (and:SI (match_op_dup 2 [(match_dup 3) (match_dup 4)])
10320 (match_dup 5)))]
215b30b3 10321 ""
10322)
9c08d1fa 10323
aea4c774 10324;; This split can be used because CC_Z mode implies that the following
10325;; branch will be an equality, or an unsigned inequality, so the sign
10326;; extension is not needed.
9c08d1fa 10327
aea4c774 10328(define_split
bd5b4116 10329 [(set (reg:CC_Z CC_REGNUM)
aea4c774 10330 (compare:CC_Z
10331 (ashift:SI (subreg:SI (match_operand:QI 0 "memory_operand" "") 0)
9c08d1fa 10332 (const_int 24))
aea4c774 10333 (match_operand 1 "const_int_operand" "")))
10334 (clobber (match_scratch:SI 2 ""))]
cffb2a26 10335 "TARGET_ARM
10336 && (((unsigned HOST_WIDE_INT) INTVAL (operands[1]))
10337 == (((unsigned HOST_WIDE_INT) INTVAL (operands[1])) >> 24) << 24)"
aea4c774 10338 [(set (match_dup 2) (zero_extend:SI (match_dup 0)))
bd5b4116 10339 (set (reg:CC CC_REGNUM) (compare:CC (match_dup 2) (match_dup 1)))]
aea4c774 10340 "
9c08d1fa 10341 operands[1] = GEN_INT (((unsigned long) INTVAL (operands[1])) >> 24);
215b30b3 10342 "
10343)
25f905c2 10344;; ??? Check the patterns above for Thumb-2 usefulness
9c08d1fa 10345
87b22bf7 10346(define_expand "prologue"
10347 [(clobber (const_int 0))]
cffb2a26 10348 "TARGET_EITHER"
25f905c2 10349 "if (TARGET_32BIT)
cffb2a26 10350 arm_expand_prologue ();
10351 else
25f905c2 10352 thumb1_expand_prologue ();
87b22bf7 10353 DONE;
cffb2a26 10354 "
10355)
87b22bf7 10356
56d27660 10357(define_expand "epilogue"
4c44712e 10358 [(clobber (const_int 0))]
cffb2a26 10359 "TARGET_EITHER"
56d27660 10360 "
18d50ae6 10361 if (crtl->calls_eh_return)
fb94f18b 10362 emit_insn (gen_force_register_use (gen_rtx_REG (Pmode, 2)));
25f905c2 10363 if (TARGET_THUMB1)
c3635784 10364 {
10365 thumb1_expand_epilogue ();
10366 emit_jump_insn (gen_rtx_UNSPEC_VOLATILE (VOIDmode,
10367 gen_rtvec (1, ret_rtx), VUNSPEC_EPILOGUE));
10368 }
10369 else if (HAVE_return)
10370 {
10371 /* HAVE_return is testing for USE_RETURN_INSN (FALSE). Hence,
10372 no need for explicit testing again. */
10373 emit_jump_insn (gen_return ());
10374 }
10375 else if (TARGET_32BIT)
10376 {
10377 arm_expand_epilogue (true);
10378 }
cffb2a26 10379 DONE;
10380 "
10381)
56d27660 10382
ef5651d0 10383;; Note - although unspec_volatile's USE all hard registers,
10384;; USEs are ignored after relaod has completed. Thus we need
10385;; to add an unspec of the link register to ensure that flow
10386;; does not think that it is unused by the sibcall branch that
10387;; will replace the standard function epilogue.
c3635784 10388(define_expand "sibcall_epilogue"
fb94f18b 10389 [(parallel [(unspec:SI [(reg:SI LR_REGNUM)] UNSPEC_REGISTER_USE)
c3635784 10390 (unspec_volatile [(return)] VUNSPEC_EPILOGUE)])]
10391 "TARGET_32BIT"
10392 "
10393 arm_expand_epilogue (false);
10394 DONE;
10395 "
1c494086 10396)
10397
cffb2a26 10398(define_expand "eh_epilogue"
7db9af5d 10399 [(use (match_operand:SI 0 "register_operand" ""))
10400 (use (match_operand:SI 1 "register_operand" ""))
10401 (use (match_operand:SI 2 "register_operand" ""))]
cffb2a26 10402 "TARGET_EITHER"
10403 "
215b30b3 10404 {
10405 cfun->machine->eh_epilogue_sp_ofs = operands[1];
0438d37f 10406 if (!REG_P (operands[2]) || REGNO (operands[2]) != 2)
215b30b3 10407 {
10408 rtx ra = gen_rtx_REG (Pmode, 2);
10409
10410 emit_move_insn (ra, operands[2]);
10411 operands[2] = ra;
10412 }
5cf3595a 10413 /* This is a hack -- we may have crystalized the function type too
10414 early. */
10415 cfun->machine->func_type = 0;
215b30b3 10416 }"
10417)
56d27660 10418
9c08d1fa 10419;; This split is only used during output to reduce the number of patterns
10420;; that need assembler instructions adding to them. We allowed the setting
10421;; of the conditions to be implicit during rtl generation so that
10422;; the conditional compare patterns would work. However this conflicts to
8a18b90c 10423;; some extent with the conditional data operations, so we have to split them
9c08d1fa 10424;; up again here.
10425
25f905c2 10426;; ??? Need to audit these splitters for Thumb-2. Why isn't normal
10427;; conditional execution sufficient?
10428
9c08d1fa 10429(define_split
10430 [(set (match_operand:SI 0 "s_register_operand" "")
8fa3ba89 10431 (if_then_else:SI (match_operator 1 "arm_comparison_operator"
10432 [(match_operand 2 "" "") (match_operand 3 "" "")])
10433 (match_dup 0)
10434 (match_operand 4 "" "")))
bd5b4116 10435 (clobber (reg:CC CC_REGNUM))]
ac8b093b 10436 "TARGET_ARM && reload_completed"
8fa3ba89 10437 [(set (match_dup 5) (match_dup 6))
10438 (cond_exec (match_dup 7)
10439 (set (match_dup 0) (match_dup 4)))]
10440 "
10441 {
3754d046 10442 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
8fa3ba89 10443 operands[2], operands[3]);
10444 enum rtx_code rc = GET_CODE (operands[1]);
10445
bd5b4116 10446 operands[5] = gen_rtx_REG (mode, CC_REGNUM);
8fa3ba89 10447 operands[6] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
10448 if (mode == CCFPmode || mode == CCFPEmode)
10449 rc = reverse_condition_maybe_unordered (rc);
10450 else
10451 rc = reverse_condition (rc);
10452
10453 operands[7] = gen_rtx_fmt_ee (rc, VOIDmode, operands[5], const0_rtx);
10454 }"
10455)
10456
10457(define_split
10458 [(set (match_operand:SI 0 "s_register_operand" "")
10459 (if_then_else:SI (match_operator 1 "arm_comparison_operator"
10460 [(match_operand 2 "" "") (match_operand 3 "" "")])
10461 (match_operand 4 "" "")
10462 (match_dup 0)))
bd5b4116 10463 (clobber (reg:CC CC_REGNUM))]
ac8b093b 10464 "TARGET_ARM && reload_completed"
8fa3ba89 10465 [(set (match_dup 5) (match_dup 6))
10466 (cond_exec (match_op_dup 1 [(match_dup 5) (const_int 0)])
10467 (set (match_dup 0) (match_dup 4)))]
10468 "
10469 {
3754d046 10470 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
8fa3ba89 10471 operands[2], operands[3]);
10472
bd5b4116 10473 operands[5] = gen_rtx_REG (mode, CC_REGNUM);
8fa3ba89 10474 operands[6] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
10475 }"
10476)
10477
10478(define_split
10479 [(set (match_operand:SI 0 "s_register_operand" "")
10480 (if_then_else:SI (match_operator 1 "arm_comparison_operator"
9c08d1fa 10481 [(match_operand 2 "" "") (match_operand 3 "" "")])
10482 (match_operand 4 "" "")
10483 (match_operand 5 "" "")))
bd5b4116 10484 (clobber (reg:CC CC_REGNUM))]
ac8b093b 10485 "TARGET_ARM && reload_completed"
8fa3ba89 10486 [(set (match_dup 6) (match_dup 7))
10487 (cond_exec (match_op_dup 1 [(match_dup 6) (const_int 0)])
10488 (set (match_dup 0) (match_dup 4)))
10489 (cond_exec (match_dup 8)
10490 (set (match_dup 0) (match_dup 5)))]
10491 "
10492 {
3754d046 10493 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
8fa3ba89 10494 operands[2], operands[3]);
10495 enum rtx_code rc = GET_CODE (operands[1]);
10496
bd5b4116 10497 operands[6] = gen_rtx_REG (mode, CC_REGNUM);
8fa3ba89 10498 operands[7] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
10499 if (mode == CCFPmode || mode == CCFPEmode)
10500 rc = reverse_condition_maybe_unordered (rc);
10501 else
10502 rc = reverse_condition (rc);
10503
10504 operands[8] = gen_rtx_fmt_ee (rc, VOIDmode, operands[6], const0_rtx);
10505 }"
10506)
10507
cffb2a26 10508(define_split
10509 [(set (match_operand:SI 0 "s_register_operand" "")
8fa3ba89 10510 (if_then_else:SI (match_operator 1 "arm_comparison_operator"
cffb2a26 10511 [(match_operand:SI 2 "s_register_operand" "")
10512 (match_operand:SI 3 "arm_add_operand" "")])
10513 (match_operand:SI 4 "arm_rhs_operand" "")
10514 (not:SI
10515 (match_operand:SI 5 "s_register_operand" ""))))
bd5b4116 10516 (clobber (reg:CC CC_REGNUM))]
ac8b093b 10517 "TARGET_ARM && reload_completed"
cffb2a26 10518 [(set (match_dup 6) (match_dup 7))
f6c53574 10519 (cond_exec (match_op_dup 1 [(match_dup 6) (const_int 0)])
10520 (set (match_dup 0) (match_dup 4)))
10521 (cond_exec (match_dup 8)
10522 (set (match_dup 0) (not:SI (match_dup 5))))]
cffb2a26 10523 "
215b30b3 10524 {
3754d046 10525 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
215b30b3 10526 operands[2], operands[3]);
f6c53574 10527 enum rtx_code rc = GET_CODE (operands[1]);
cffb2a26 10528
bd5b4116 10529 operands[6] = gen_rtx_REG (mode, CC_REGNUM);
1a83b3ff 10530 operands[7] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
f6c53574 10531 if (mode == CCFPmode || mode == CCFPEmode)
10532 rc = reverse_condition_maybe_unordered (rc);
10533 else
10534 rc = reverse_condition (rc);
10535
10536 operands[8] = gen_rtx_fmt_ee (rc, VOIDmode, operands[6], const0_rtx);
215b30b3 10537 }"
10538)
cffb2a26 10539
10540(define_insn "*cond_move_not"
10541 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8fa3ba89 10542 (if_then_else:SI (match_operator 4 "arm_comparison_operator"
cffb2a26 10543 [(match_operand 3 "cc_register" "") (const_int 0)])
10544 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
10545 (not:SI
10546 (match_operand:SI 2 "s_register_operand" "r,r"))))]
10547 "TARGET_ARM"
10548 "@
10549 mvn%D4\\t%0, %2
10550 mov%d4\\t%0, %1\;mvn%D4\\t%0, %2"
0d66636f 10551 [(set_attr "conds" "use")
1b7da4ac 10552 (set_attr "type" "mvn_reg,multiple")
0d66636f 10553 (set_attr "length" "4,8")]
10554)
cffb2a26 10555
9c08d1fa 10556;; The next two patterns occur when an AND operation is followed by a
10557;; scc insn sequence
10558
f7fbdd4a 10559(define_insn "*sign_extract_onebit"
9c08d1fa 10560 [(set (match_operand:SI 0 "s_register_operand" "=r")
10561 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
10562 (const_int 1)
ed750274 10563 (match_operand:SI 2 "const_int_operand" "n")))
10564 (clobber (reg:CC CC_REGNUM))]
cffb2a26 10565 "TARGET_ARM"
9c08d1fa 10566 "*
0d66636f 10567 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
10568 output_asm_insn (\"ands\\t%0, %1, %2\", operands);
10569 return \"mvnne\\t%0, #0\";
10570 "
10571 [(set_attr "conds" "clob")
1b7da4ac 10572 (set_attr "length" "8")
10573 (set_attr "type" "multiple")]
0d66636f 10574)
9c08d1fa 10575
f7fbdd4a 10576(define_insn "*not_signextract_onebit"
9c08d1fa 10577 [(set (match_operand:SI 0 "s_register_operand" "=r")
10578 (not:SI
10579 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
10580 (const_int 1)
ed750274 10581 (match_operand:SI 2 "const_int_operand" "n"))))
10582 (clobber (reg:CC CC_REGNUM))]
cffb2a26 10583 "TARGET_ARM"
9c08d1fa 10584 "*
0d66636f 10585 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
10586 output_asm_insn (\"tst\\t%1, %2\", operands);
10587 output_asm_insn (\"mvneq\\t%0, #0\", operands);
10588 return \"movne\\t%0, #0\";
10589 "
10590 [(set_attr "conds" "clob")
1b7da4ac 10591 (set_attr "length" "12")
10592 (set_attr "type" "multiple")]
0d66636f 10593)
25f905c2 10594;; ??? The above patterns need auditing for Thumb-2
87b22bf7 10595
0d66636f 10596;; Push multiple registers to the stack. Registers are in parallel (use ...)
10597;; expressions. For simplicity, the first register is also in the unspec
10598;; part.
08508cbf 10599;; To avoid the usage of GNU extension, the length attribute is computed
10600;; in a C function arm_attr_length_push_multi.
f7fbdd4a 10601(define_insn "*push_multi"
87b22bf7 10602 [(match_parallel 2 "multi_register_push"
7571d3f7 10603 [(set (match_operand:BLK 0 "push_mult_memory_operand" "")
3cc80a30 10604 (unspec:BLK [(match_operand:SI 1 "s_register_operand" "")]
e1159bbe 10605 UNSPEC_PUSH_MULT))])]
7571d3f7 10606 ""
87b22bf7 10607 "*
215b30b3 10608 {
10609 int num_saves = XVECLEN (operands[2], 0);
ed593f11 10610
215b30b3 10611 /* For the StrongARM at least it is faster to
25f905c2 10612 use STR to store only a single register.
542d5028 10613 In Thumb mode always use push, and the assembler will pick
10614 something appropriate. */
25f905c2 10615 if (num_saves == 1 && TARGET_ARM)
61309563 10616 output_asm_insn (\"str%?\\t%1, [%m0, #-4]!\", operands);
215b30b3 10617 else
10618 {
10619 int i;
10620 char pattern[100];
ed593f11 10621
25f905c2 10622 if (TARGET_ARM)
61309563 10623 strcpy (pattern, \"stm%(fd%)\\t%m0!, {%1\");
10624 else if (TARGET_THUMB2)
10625 strcpy (pattern, \"push%?\\t{%1\");
25f905c2 10626 else
10627 strcpy (pattern, \"push\\t{%1\");
215b30b3 10628
6079f055 10629 for (i = 1; i < num_saves; i++)
215b30b3 10630 {
10631 strcat (pattern, \", %|\");
10632 strcat (pattern,
10633 reg_names[REGNO (XEXP (XVECEXP (operands[2], 0, i), 0))]);
10634 }
10635
10636 strcat (pattern, \"}\");
10637 output_asm_insn (pattern, operands);
10638 }
10639
10640 return \"\";
10641 }"
a6864a24 10642 [(set_attr "type" "store4")
10643 (set (attr "length")
08508cbf 10644 (symbol_ref "arm_attr_length_push_multi (operands[2], operands[1])"))]
215b30b3 10645)
f7fbdd4a 10646
4c58c898 10647(define_insn "stack_tie"
10648 [(set (mem:BLK (scratch))
aaa37ad6 10649 (unspec:BLK [(match_operand:SI 0 "s_register_operand" "rk")
10650 (match_operand:SI 1 "s_register_operand" "rk")]
4c58c898 10651 UNSPEC_PRLG_STK))]
10652 ""
10653 ""
1b7da4ac 10654 [(set_attr "length" "0")
10655 (set_attr "type" "block")]
4c58c898 10656)
10657
426be8c5 10658;; Pop (as used in epilogue RTL)
10659;;
10660(define_insn "*load_multiple_with_writeback"
10661 [(match_parallel 0 "load_multiple_operation"
10662 [(set (match_operand:SI 1 "s_register_operand" "+rk")
10663 (plus:SI (match_dup 1)
809003b3 10664 (match_operand:SI 2 "const_int_I_operand" "I")))
426be8c5 10665 (set (match_operand:SI 3 "s_register_operand" "=rk")
10666 (mem:SI (match_dup 1)))
10667 ])]
10668 "TARGET_32BIT && (reload_in_progress || reload_completed)"
10669 "*
10670 {
10671 arm_output_multireg_pop (operands, /*return_pc=*/false,
10672 /*cond=*/const_true_rtx,
10673 /*reverse=*/false,
10674 /*update=*/true);
10675 return \"\";
10676 }
10677 "
10678 [(set_attr "type" "load4")
10679 (set_attr "predicable" "yes")]
10680)
10681
10682;; Pop with return (as used in epilogue RTL)
10683;;
10684;; This instruction is generated when the registers are popped at the end of
10685;; epilogue. Here, instead of popping the value into LR and then generating
10686;; jump to LR, value is popped into PC directly. Hence, the pattern is combined
10687;; with (return).
10688(define_insn "*pop_multiple_with_writeback_and_return"
10689 [(match_parallel 0 "pop_multiple_return"
10690 [(return)
10691 (set (match_operand:SI 1 "s_register_operand" "+rk")
10692 (plus:SI (match_dup 1)
809003b3 10693 (match_operand:SI 2 "const_int_I_operand" "I")))
426be8c5 10694 (set (match_operand:SI 3 "s_register_operand" "=rk")
10695 (mem:SI (match_dup 1)))
10696 ])]
10697 "TARGET_32BIT && (reload_in_progress || reload_completed)"
10698 "*
10699 {
10700 arm_output_multireg_pop (operands, /*return_pc=*/true,
10701 /*cond=*/const_true_rtx,
10702 /*reverse=*/false,
10703 /*update=*/true);
10704 return \"\";
10705 }
10706 "
10707 [(set_attr "type" "load4")
10708 (set_attr "predicable" "yes")]
10709)
10710
10711(define_insn "*pop_multiple_with_return"
10712 [(match_parallel 0 "pop_multiple_return"
10713 [(return)
10714 (set (match_operand:SI 2 "s_register_operand" "=rk")
10715 (mem:SI (match_operand:SI 1 "s_register_operand" "rk")))
10716 ])]
10717 "TARGET_32BIT && (reload_in_progress || reload_completed)"
10718 "*
10719 {
10720 arm_output_multireg_pop (operands, /*return_pc=*/true,
10721 /*cond=*/const_true_rtx,
10722 /*reverse=*/false,
10723 /*update=*/false);
10724 return \"\";
10725 }
10726 "
10727 [(set_attr "type" "load4")
10728 (set_attr "predicable" "yes")]
10729)
10730
10731;; Load into PC and return
10732(define_insn "*ldr_with_return"
10733 [(return)
10734 (set (reg:SI PC_REGNUM)
10735 (mem:SI (post_inc:SI (match_operand:SI 0 "s_register_operand" "+rk"))))]
10736 "TARGET_32BIT && (reload_in_progress || reload_completed)"
10737 "ldr%?\t%|pc, [%0], #4"
10738 [(set_attr "type" "load1")
10739 (set_attr "predicable" "yes")]
10740)
1a0b0f12 10741;; Pop for floating point registers (as used in epilogue RTL)
10742(define_insn "*vfp_pop_multiple_with_writeback"
10743 [(match_parallel 0 "pop_multiple_fp"
10744 [(set (match_operand:SI 1 "s_register_operand" "+rk")
10745 (plus:SI (match_dup 1)
809003b3 10746 (match_operand:SI 2 "const_int_I_operand" "I")))
2f2163a4 10747 (set (match_operand:DF 3 "vfp_hard_register_operand" "")
1a0b0f12 10748 (mem:DF (match_dup 1)))])]
10749 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
10750 "*
10751 {
10752 int num_regs = XVECLEN (operands[0], 0);
10753 char pattern[100];
10754 rtx op_list[2];
b34d8dac 10755 strcpy (pattern, \"vldm\\t\");
1a0b0f12 10756 strcat (pattern, reg_names[REGNO (SET_DEST (XVECEXP (operands[0], 0, 0)))]);
10757 strcat (pattern, \"!, {\");
10758 op_list[0] = XEXP (XVECEXP (operands[0], 0, 1), 0);
10759 strcat (pattern, \"%P0\");
10760 if ((num_regs - 1) > 1)
10761 {
10762 strcat (pattern, \"-%P1\");
10763 op_list [1] = XEXP (XVECEXP (operands[0], 0, num_regs - 1), 0);
10764 }
10765
10766 strcat (pattern, \"}\");
10767 output_asm_insn (pattern, op_list);
10768 return \"\";
10769 }
10770 "
10771 [(set_attr "type" "load4")
10772 (set_attr "conds" "unconditional")
10773 (set_attr "predicable" "no")]
10774)
10775
f7fbdd4a 10776;; Special patterns for dealing with the constant pool
10777
cffb2a26 10778(define_insn "align_4"
e1159bbe 10779 [(unspec_volatile [(const_int 0)] VUNSPEC_ALIGN)]
cffb2a26 10780 "TARGET_EITHER"
f7fbdd4a 10781 "*
cffb2a26 10782 assemble_align (32);
f7fbdd4a 10783 return \"\";
cffb2a26 10784 "
1b7da4ac 10785 [(set_attr "type" "no_insn")]
cffb2a26 10786)
f7fbdd4a 10787
755eb2b4 10788(define_insn "align_8"
10789 [(unspec_volatile [(const_int 0)] VUNSPEC_ALIGN8)]
f9273c43 10790 "TARGET_EITHER"
755eb2b4 10791 "*
10792 assemble_align (64);
10793 return \"\";
10794 "
1b7da4ac 10795 [(set_attr "type" "no_insn")]
755eb2b4 10796)
10797
cffb2a26 10798(define_insn "consttable_end"
e1159bbe 10799 [(unspec_volatile [(const_int 0)] VUNSPEC_POOL_END)]
cffb2a26 10800 "TARGET_EITHER"
f7fbdd4a 10801 "*
cffb2a26 10802 making_const_table = FALSE;
f7fbdd4a 10803 return \"\";
cffb2a26 10804 "
1b7da4ac 10805 [(set_attr "type" "no_insn")]
cffb2a26 10806)
f7fbdd4a 10807
0e207eb8 10808(define_insn "consttable_1"
10809 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_1)]
10810 "TARGET_EITHER"
10811 "*
10812 making_const_table = TRUE;
10813 assemble_integer (operands[0], 1, BITS_PER_WORD, 1);
10814 assemble_zeros (3);
10815 return \"\";
10816 "
10817 [(set_attr "length" "4")
10818 (set_attr "type" "no_insn")]
10819)
10820
10821(define_insn "consttable_2"
10822 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_2)]
10823 "TARGET_EITHER"
10824 "*
10825 {
10826 rtx x = operands[0];
10827 making_const_table = TRUE;
10828 switch (GET_MODE_CLASS (GET_MODE (x)))
10829 {
10830 case MODE_FLOAT:
10831 arm_emit_fp16_const (x);
10832 break;
10833 default:
10834 assemble_integer (operands[0], 2, BITS_PER_WORD, 1);
10835 assemble_zeros (2);
10836 break;
10837 }
10838 return \"\";
10839 }"
10840 [(set_attr "length" "4")
10841 (set_attr "type" "no_insn")]
10842)
10843
cffb2a26 10844(define_insn "consttable_4"
e1159bbe 10845 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_4)]
cffb2a26 10846 "TARGET_EITHER"
10847 "*
10848 {
9b8516be 10849 rtx x = operands[0];
cffb2a26 10850 making_const_table = TRUE;
9b8516be 10851 switch (GET_MODE_CLASS (GET_MODE (x)))
cffb2a26 10852 {
10853 case MODE_FLOAT:
945f7b03 10854 assemble_real (*CONST_DOUBLE_REAL_VALUE (x), GET_MODE (x),
10855 BITS_PER_WORD);
10856 break;
cffb2a26 10857 default:
7b04c5d5 10858 /* XXX: Sometimes gcc does something really dumb and ends up with
10859 a HIGH in a constant pool entry, usually because it's trying to
10860 load into a VFP register. We know this will always be used in
10861 combination with a LO_SUM which ignores the high bits, so just
10862 strip off the HIGH. */
10863 if (GET_CODE (x) == HIGH)
10864 x = XEXP (x, 0);
9b8516be 10865 assemble_integer (x, 4, BITS_PER_WORD, 1);
10866 mark_symbol_refs_as_used (x);
cffb2a26 10867 break;
10868 }
10869 return \"\";
10870 }"
1b7da4ac 10871 [(set_attr "length" "4")
10872 (set_attr "type" "no_insn")]
cffb2a26 10873)
10874
10875(define_insn "consttable_8"
e1159bbe 10876 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_8)]
cffb2a26 10877 "TARGET_EITHER"
10878 "*
10879 {
10880 making_const_table = TRUE;
10881 switch (GET_MODE_CLASS (GET_MODE (operands[0])))
10882 {
945f7b03 10883 case MODE_FLOAT:
10884 assemble_real (*CONST_DOUBLE_REAL_VALUE (operands[0]),
10885 GET_MODE (operands[0]), BITS_PER_WORD);
10886 break;
cffb2a26 10887 default:
09d688ff 10888 assemble_integer (operands[0], 8, BITS_PER_WORD, 1);
cffb2a26 10889 break;
10890 }
10891 return \"\";
10892 }"
1b7da4ac 10893 [(set_attr "length" "8")
10894 (set_attr "type" "no_insn")]
cffb2a26 10895)
10896
d98a3884 10897(define_insn "consttable_16"
10898 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_16)]
10899 "TARGET_EITHER"
10900 "*
10901 {
10902 making_const_table = TRUE;
10903 switch (GET_MODE_CLASS (GET_MODE (operands[0])))
10904 {
945f7b03 10905 case MODE_FLOAT:
10906 assemble_real (*CONST_DOUBLE_REAL_VALUE (operands[0]),
10907 GET_MODE (operands[0]), BITS_PER_WORD);
10908 break;
d98a3884 10909 default:
10910 assemble_integer (operands[0], 16, BITS_PER_WORD, 1);
10911 break;
10912 }
10913 return \"\";
10914 }"
1b7da4ac 10915 [(set_attr "length" "16")
10916 (set_attr "type" "no_insn")]
d98a3884 10917)
10918
331beb1a 10919;; V5 Instructions,
10920
8f4be2be 10921(define_insn "clzsi2"
10922 [(set (match_operand:SI 0 "s_register_operand" "=r")
10923 (clz:SI (match_operand:SI 1 "s_register_operand" "r")))]
25f905c2 10924 "TARGET_32BIT && arm_arch5"
ee7cbe0e 10925 "clz%?\\t%0, %1"
bcaec148 10926 [(set_attr "predicable" "yes")
4a510717 10927 (set_attr "predicable_short_it" "no")
bebe9bbb 10928 (set_attr "type" "clz")])
331beb1a 10929
099ad98b 10930(define_insn "rbitsi2"
10931 [(set (match_operand:SI 0 "s_register_operand" "=r")
10932 (unspec:SI [(match_operand:SI 1 "s_register_operand" "r")] UNSPEC_RBIT))]
10933 "TARGET_32BIT && arm_arch_thumb2"
10934 "rbit%?\\t%0, %1"
10935 [(set_attr "predicable" "yes")
4a510717 10936 (set_attr "predicable_short_it" "no")
bebe9bbb 10937 (set_attr "type" "clz")])
099ad98b 10938
10939(define_expand "ctzsi2"
10940 [(set (match_operand:SI 0 "s_register_operand" "")
10941 (ctz:SI (match_operand:SI 1 "s_register_operand" "")))]
10942 "TARGET_32BIT && arm_arch_thumb2"
10943 "
30191172 10944 {
10945 rtx tmp = gen_reg_rtx (SImode);
10946 emit_insn (gen_rbitsi2 (tmp, operands[1]));
10947 emit_insn (gen_clzsi2 (operands[0], tmp));
10948 }
099ad98b 10949 DONE;
10950 "
10951)
10952
e1159bbe 10953;; V5E instructions.
331beb1a 10954
10955(define_insn "prefetch"
f4e79814 10956 [(prefetch (match_operand:SI 0 "address_operand" "p")
10957 (match_operand:SI 1 "" "")
10958 (match_operand:SI 2 "" ""))]
25f905c2 10959 "TARGET_32BIT && arm_arch5e"
1b7da4ac 10960 "pld\\t%a0"
10961 [(set_attr "type" "load1")]
10962)
331beb1a 10963
0d66636f 10964;; General predication pattern
10965
10966(define_cond_exec
10967 [(match_operator 0 "arm_comparison_operator"
10968 [(match_operand 1 "cc_register" "")
10969 (const_int 0)])]
580f4c48 10970 "TARGET_32BIT
10971 && (!TARGET_NO_VOLATILE_CE || !volatile_refs_p (PATTERN (insn)))"
0d66636f 10972 ""
c7a58118 10973[(set_attr "predicated" "yes")]
0d66636f 10974)
10975
fb94f18b 10976(define_insn "force_register_use"
10977 [(unspec:SI [(match_operand:SI 0 "register_operand" "")] UNSPEC_REGISTER_USE)]
063a05c7 10978 ""
fb94f18b 10979 "%@ %0 needed"
1b7da4ac 10980 [(set_attr "length" "0")
10981 (set_attr "type" "no_insn")]
063a05c7 10982)
7db9af5d 10983
4c44712e 10984
10985;; Patterns for exception handling
10986
10987(define_expand "eh_return"
10988 [(use (match_operand 0 "general_operand" ""))]
10989 "TARGET_EITHER"
10990 "
10991 {
25f905c2 10992 if (TARGET_32BIT)
4c44712e 10993 emit_insn (gen_arm_eh_return (operands[0]));
10994 else
10995 emit_insn (gen_thumb_eh_return (operands[0]));
10996 DONE;
10997 }"
10998)
10999
11000;; We can't expand this before we know where the link register is stored.
11001(define_insn_and_split "arm_eh_return"
11002 [(unspec_volatile [(match_operand:SI 0 "s_register_operand" "r")]
11003 VUNSPEC_EH_RETURN)
11004 (clobber (match_scratch:SI 1 "=&r"))]
11005 "TARGET_ARM"
11006 "#"
11007 "&& reload_completed"
11008 [(const_int 0)]
11009 "
11010 {
11011 arm_set_return_address (operands[0], operands[1]);
11012 DONE;
11013 }"
11014)
11015
f655717d 11016\f
11017;; TLS support
11018
11019(define_insn "load_tp_hard"
11020 [(set (match_operand:SI 0 "register_operand" "=r")
11021 (unspec:SI [(const_int 0)] UNSPEC_TLS))]
11022 "TARGET_HARD_TP"
11023 "mrc%?\\tp15, 0, %0, c13, c0, 3\\t@ load_tp_hard"
1b7da4ac 11024 [(set_attr "predicable" "yes")
4b5d7374 11025 (set_attr "type" "mrs")]
f655717d 11026)
11027
11028;; Doesn't clobber R1-R3. Must use r0 for the first operand.
11029(define_insn "load_tp_soft"
11030 [(set (reg:SI 0) (unspec:SI [(const_int 0)] UNSPEC_TLS))
11031 (clobber (reg:SI LR_REGNUM))
11032 (clobber (reg:SI IP_REGNUM))
11033 (clobber (reg:CC CC_REGNUM))]
11034 "TARGET_SOFT_TP"
11035 "bl\\t__aeabi_read_tp\\t@ load_tp_soft"
1b7da4ac 11036 [(set_attr "conds" "clob")
11037 (set_attr "type" "branch")]
f655717d 11038)
11039
f41e4452 11040;; tls descriptor call
11041(define_insn "tlscall"
11042 [(set (reg:SI R0_REGNUM)
11043 (unspec:SI [(reg:SI R0_REGNUM)
11044 (match_operand:SI 0 "" "X")
11045 (match_operand 1 "" "")] UNSPEC_TLS))
11046 (clobber (reg:SI R1_REGNUM))
11047 (clobber (reg:SI LR_REGNUM))
11048 (clobber (reg:SI CC_REGNUM))]
11049 "TARGET_GNU2_TLS"
11050 {
11051 targetm.asm_out.internal_label (asm_out_file, "LPIC",
11052 INTVAL (operands[1]));
11053 return "bl\\t%c0(tlscall)";
11054 }
11055 [(set_attr "conds" "clob")
1b7da4ac 11056 (set_attr "length" "4")
11057 (set_attr "type" "branch")]
f41e4452 11058)
11059
1fe0edab 11060;; For thread pointer builtin
11061(define_expand "get_thread_pointersi"
11062 [(match_operand:SI 0 "s_register_operand" "=r")]
11063 ""
11064 "
11065 {
11066 arm_load_tp (operands[0]);
11067 DONE;
11068 }")
11069
f41e4452 11070;;
11071
aabe09ac 11072;; We only care about the lower 16 bits of the constant
11073;; being inserted into the upper 16 bits of the register.
eca5c984 11074(define_insn "*arm_movtas_ze"
11075 [(set (zero_extract:SI (match_operand:SI 0 "s_register_operand" "+r")
11076 (const_int 16)
11077 (const_int 16))
11078 (match_operand:SI 1 "const_int_operand" ""))]
181ab277 11079 "arm_arch_thumb2"
aabe09ac 11080 "movt%?\t%0, %L1"
eca5c984 11081 [(set_attr "predicable" "yes")
7c36fe71 11082 (set_attr "predicable_short_it" "no")
1b7da4ac 11083 (set_attr "length" "4")
282b4c75 11084 (set_attr "type" "alu_sreg")]
eca5c984 11085)
11086
c0fc3696 11087(define_insn "*arm_rev"
a486b499 11088 [(set (match_operand:SI 0 "s_register_operand" "=l,l,r")
11089 (bswap:SI (match_operand:SI 1 "s_register_operand" "l,l,r")))]
11090 "arm_arch6"
11091 "@
11092 rev\t%0, %1
11093 rev%?\t%0, %1
11094 rev%?\t%0, %1"
11095 [(set_attr "arch" "t1,t2,32")
1b7da4ac 11096 (set_attr "length" "2,2,4")
4a510717 11097 (set_attr "predicable" "no,yes,yes")
11098 (set_attr "predicable_short_it" "no")
1b7da4ac 11099 (set_attr "type" "rev")]
ff82f757 11100)
11101
11102(define_expand "arm_legacy_rev"
11103 [(set (match_operand:SI 2 "s_register_operand" "")
11104 (xor:SI (rotatert:SI (match_operand:SI 1 "s_register_operand" "")
11105 (const_int 16))
11106 (match_dup 1)))
11107 (set (match_dup 2)
11108 (lshiftrt:SI (match_dup 2)
11109 (const_int 8)))
11110 (set (match_operand:SI 3 "s_register_operand" "")
11111 (rotatert:SI (match_dup 1)
11112 (const_int 8)))
11113 (set (match_dup 2)
11114 (and:SI (match_dup 2)
11115 (const_int -65281)))
11116 (set (match_operand:SI 0 "s_register_operand" "")
11117 (xor:SI (match_dup 3)
11118 (match_dup 2)))]
11119 "TARGET_32BIT"
11120 ""
11121)
11122
11123;; Reuse temporaries to keep register pressure down.
11124(define_expand "thumb_legacy_rev"
11125 [(set (match_operand:SI 2 "s_register_operand" "")
11126 (ashift:SI (match_operand:SI 1 "s_register_operand" "")
11127 (const_int 24)))
11128 (set (match_operand:SI 3 "s_register_operand" "")
11129 (lshiftrt:SI (match_dup 1)
11130 (const_int 24)))
11131 (set (match_dup 3)
11132 (ior:SI (match_dup 3)
11133 (match_dup 2)))
11134 (set (match_operand:SI 4 "s_register_operand" "")
11135 (const_int 16))
11136 (set (match_operand:SI 5 "s_register_operand" "")
11137 (rotatert:SI (match_dup 1)
11138 (match_dup 4)))
11139 (set (match_dup 2)
11140 (ashift:SI (match_dup 5)
11141 (const_int 24)))
11142 (set (match_dup 5)
11143 (lshiftrt:SI (match_dup 5)
11144 (const_int 24)))
11145 (set (match_dup 5)
11146 (ior:SI (match_dup 5)
11147 (match_dup 2)))
11148 (set (match_dup 5)
11149 (rotatert:SI (match_dup 5)
11150 (match_dup 4)))
11151 (set (match_operand:SI 0 "s_register_operand" "")
11152 (ior:SI (match_dup 5)
11153 (match_dup 3)))]
11154 "TARGET_THUMB"
11155 ""
11156)
11157
62e39b06 11158;; ARM-specific expansion of signed mod by power of 2
11159;; using conditional negate.
11160;; For r0 % n where n is a power of 2 produce:
11161;; rsbs r1, r0, #0
11162;; and r0, r0, #(n - 1)
11163;; and r1, r1, #(n - 1)
11164;; rsbpl r0, r1, #0
11165
11166(define_expand "modsi3"
11167 [(match_operand:SI 0 "register_operand" "")
11168 (match_operand:SI 1 "register_operand" "")
11169 (match_operand:SI 2 "const_int_operand" "")]
11170 "TARGET_32BIT"
11171 {
11172 HOST_WIDE_INT val = INTVAL (operands[2]);
11173
11174 if (val <= 0
11175 || exact_log2 (val) <= 0)
11176 FAIL;
11177
11178 rtx mask = GEN_INT (val - 1);
11179
11180 /* In the special case of x0 % 2 we can do the even shorter:
11181 cmp r0, #0
11182 and r0, r0, #1
11183 rsblt r0, r0, #0. */
11184
11185 if (val == 2)
11186 {
11187 rtx cc_reg = arm_gen_compare_reg (LT,
11188 operands[1], const0_rtx, NULL_RTX);
11189 rtx cond = gen_rtx_LT (SImode, cc_reg, const0_rtx);
11190 rtx masked = gen_reg_rtx (SImode);
11191
11192 emit_insn (gen_andsi3 (masked, operands[1], mask));
11193 emit_move_insn (operands[0],
11194 gen_rtx_IF_THEN_ELSE (SImode, cond,
11195 gen_rtx_NEG (SImode,
11196 masked),
11197 masked));
11198 DONE;
11199 }
11200
11201 rtx neg_op = gen_reg_rtx (SImode);
11202 rtx_insn *insn = emit_insn (gen_subsi3_compare0 (neg_op, const0_rtx,
11203 operands[1]));
11204
11205 /* Extract the condition register and mode. */
11206 rtx cmp = XVECEXP (PATTERN (insn), 0, 0);
11207 rtx cc_reg = SET_DEST (cmp);
11208 rtx cond = gen_rtx_GE (SImode, cc_reg, const0_rtx);
11209
11210 emit_insn (gen_andsi3 (operands[0], operands[1], mask));
11211
11212 rtx masked_neg = gen_reg_rtx (SImode);
11213 emit_insn (gen_andsi3 (masked_neg, neg_op, mask));
11214
11215 /* We want a conditional negate here, but emitting COND_EXEC rtxes
11216 during expand does not always work. Do an IF_THEN_ELSE instead. */
11217 emit_move_insn (operands[0],
11218 gen_rtx_IF_THEN_ELSE (SImode, cond,
11219 gen_rtx_NEG (SImode, masked_neg),
11220 operands[0]));
11221
11222
11223 DONE;
11224 }
11225)
11226
ff82f757 11227(define_expand "bswapsi2"
11228 [(set (match_operand:SI 0 "s_register_operand" "=r")
11229 (bswap:SI (match_operand:SI 1 "s_register_operand" "r")))]
8d1af482 11230"TARGET_EITHER && (arm_arch6 || !optimize_size)"
ff82f757 11231"
8d1af482 11232 if (!arm_arch6)
11233 {
11234 rtx op2 = gen_reg_rtx (SImode);
11235 rtx op3 = gen_reg_rtx (SImode);
ff82f757 11236
8d1af482 11237 if (TARGET_THUMB)
11238 {
11239 rtx op4 = gen_reg_rtx (SImode);
11240 rtx op5 = gen_reg_rtx (SImode);
ff82f757 11241
8d1af482 11242 emit_insn (gen_thumb_legacy_rev (operands[0], operands[1],
11243 op2, op3, op4, op5));
11244 }
11245 else
11246 {
11247 emit_insn (gen_arm_legacy_rev (operands[0], operands[1],
11248 op2, op3));
11249 }
ff82f757 11250
8d1af482 11251 DONE;
11252 }
ff82f757 11253 "
11254)
11255
a486b499 11256;; bswap16 patterns: use revsh and rev16 instructions for the signed
11257;; and unsigned variants, respectively. For rev16, expose
11258;; byte-swapping in the lower 16 bits only.
11259(define_insn "*arm_revsh"
11260 [(set (match_operand:SI 0 "s_register_operand" "=l,l,r")
11261 (sign_extend:SI (bswap:HI (match_operand:HI 1 "s_register_operand" "l,l,r"))))]
11262 "arm_arch6"
11263 "@
11264 revsh\t%0, %1
11265 revsh%?\t%0, %1
11266 revsh%?\t%0, %1"
11267 [(set_attr "arch" "t1,t2,32")
1b7da4ac 11268 (set_attr "length" "2,2,4")
11269 (set_attr "type" "rev")]
a486b499 11270)
11271
11272(define_insn "*arm_rev16"
11273 [(set (match_operand:HI 0 "s_register_operand" "=l,l,r")
11274 (bswap:HI (match_operand:HI 1 "s_register_operand" "l,l,r")))]
11275 "arm_arch6"
11276 "@
11277 rev16\t%0, %1
11278 rev16%?\t%0, %1
11279 rev16%?\t%0, %1"
11280 [(set_attr "arch" "t1,t2,32")
1b7da4ac 11281 (set_attr "length" "2,2,4")
11282 (set_attr "type" "rev")]
09f69e55 11283)
11284
11285;; There are no canonicalisation rules for the position of the lshiftrt, ashift
11286;; operations within an IOR/AND RTX, therefore we have two patterns matching
11287;; each valid permutation.
11288
11289(define_insn "arm_rev16si2"
11290 [(set (match_operand:SI 0 "register_operand" "=l,l,r")
11291 (ior:SI (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "l,l,r")
11292 (const_int 8))
11293 (match_operand:SI 3 "const_int_operand" "n,n,n"))
11294 (and:SI (lshiftrt:SI (match_dup 1)
11295 (const_int 8))
11296 (match_operand:SI 2 "const_int_operand" "n,n,n"))))]
11297 "arm_arch6
11298 && aarch_rev16_shleft_mask_imm_p (operands[3], SImode)
11299 && aarch_rev16_shright_mask_imm_p (operands[2], SImode)"
11300 "rev16\\t%0, %1"
11301 [(set_attr "arch" "t1,t2,32")
11302 (set_attr "length" "2,2,4")
11303 (set_attr "type" "rev")]
11304)
11305
11306(define_insn "arm_rev16si2_alt"
11307 [(set (match_operand:SI 0 "register_operand" "=l,l,r")
11308 (ior:SI (and:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" "l,l,r")
11309 (const_int 8))
11310 (match_operand:SI 2 "const_int_operand" "n,n,n"))
11311 (and:SI (ashift:SI (match_dup 1)
11312 (const_int 8))
11313 (match_operand:SI 3 "const_int_operand" "n,n,n"))))]
11314 "arm_arch6
11315 && aarch_rev16_shleft_mask_imm_p (operands[3], SImode)
11316 && aarch_rev16_shright_mask_imm_p (operands[2], SImode)"
11317 "rev16\\t%0, %1"
11318 [(set_attr "arch" "t1,t2,32")
11319 (set_attr "length" "2,2,4")
11320 (set_attr "type" "rev")]
a486b499 11321)
11322
11323(define_expand "bswaphi2"
11324 [(set (match_operand:HI 0 "s_register_operand" "=r")
11325 (bswap:HI (match_operand:HI 1 "s_register_operand" "r")))]
11326"arm_arch6"
11327""
11328)
11329
1653cf17 11330;; Patterns for LDRD/STRD in Thumb2 mode
11331
11332(define_insn "*thumb2_ldrd"
11333 [(set (match_operand:SI 0 "s_register_operand" "=r")
11334 (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "rk")
11335 (match_operand:SI 2 "ldrd_strd_offset_operand" "Do"))))
11336 (set (match_operand:SI 3 "s_register_operand" "=r")
11337 (mem:SI (plus:SI (match_dup 1)
11338 (match_operand:SI 4 "const_int_operand" ""))))]
11339 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11340 && current_tune->prefer_ldrd_strd
11341 && ((INTVAL (operands[2]) + 4) == INTVAL (operands[4]))
11342 && (operands_ok_ldrd_strd (operands[0], operands[3],
11343 operands[1], INTVAL (operands[2]),
11344 false, true))"
11345 "ldrd%?\t%0, %3, [%1, %2]"
11346 [(set_attr "type" "load2")
d952d547 11347 (set_attr "predicable" "yes")
11348 (set_attr "predicable_short_it" "no")])
1653cf17 11349
11350(define_insn "*thumb2_ldrd_base"
11351 [(set (match_operand:SI 0 "s_register_operand" "=r")
11352 (mem:SI (match_operand:SI 1 "s_register_operand" "rk")))
11353 (set (match_operand:SI 2 "s_register_operand" "=r")
11354 (mem:SI (plus:SI (match_dup 1)
11355 (const_int 4))))]
11356 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11357 && current_tune->prefer_ldrd_strd
11358 && (operands_ok_ldrd_strd (operands[0], operands[2],
11359 operands[1], 0, false, true))"
11360 "ldrd%?\t%0, %2, [%1]"
11361 [(set_attr "type" "load2")
d952d547 11362 (set_attr "predicable" "yes")
11363 (set_attr "predicable_short_it" "no")])
1653cf17 11364
11365(define_insn "*thumb2_ldrd_base_neg"
11366 [(set (match_operand:SI 0 "s_register_operand" "=r")
11367 (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "rk")
11368 (const_int -4))))
11369 (set (match_operand:SI 2 "s_register_operand" "=r")
11370 (mem:SI (match_dup 1)))]
11371 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11372 && current_tune->prefer_ldrd_strd
11373 && (operands_ok_ldrd_strd (operands[0], operands[2],
11374 operands[1], -4, false, true))"
11375 "ldrd%?\t%0, %2, [%1, #-4]"
11376 [(set_attr "type" "load2")
d952d547 11377 (set_attr "predicable" "yes")
11378 (set_attr "predicable_short_it" "no")])
1653cf17 11379
11380(define_insn "*thumb2_strd"
11381 [(set (mem:SI (plus:SI (match_operand:SI 0 "s_register_operand" "rk")
11382 (match_operand:SI 1 "ldrd_strd_offset_operand" "Do")))
11383 (match_operand:SI 2 "s_register_operand" "r"))
11384 (set (mem:SI (plus:SI (match_dup 0)
11385 (match_operand:SI 3 "const_int_operand" "")))
11386 (match_operand:SI 4 "s_register_operand" "r"))]
11387 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11388 && current_tune->prefer_ldrd_strd
11389 && ((INTVAL (operands[1]) + 4) == INTVAL (operands[3]))
11390 && (operands_ok_ldrd_strd (operands[2], operands[4],
11391 operands[0], INTVAL (operands[1]),
11392 false, false))"
11393 "strd%?\t%2, %4, [%0, %1]"
11394 [(set_attr "type" "store2")
d952d547 11395 (set_attr "predicable" "yes")
11396 (set_attr "predicable_short_it" "no")])
1653cf17 11397
11398(define_insn "*thumb2_strd_base"
11399 [(set (mem:SI (match_operand:SI 0 "s_register_operand" "rk"))
11400 (match_operand:SI 1 "s_register_operand" "r"))
11401 (set (mem:SI (plus:SI (match_dup 0)
11402 (const_int 4)))
11403 (match_operand:SI 2 "s_register_operand" "r"))]
11404 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11405 && current_tune->prefer_ldrd_strd
11406 && (operands_ok_ldrd_strd (operands[1], operands[2],
11407 operands[0], 0, false, false))"
11408 "strd%?\t%1, %2, [%0]"
11409 [(set_attr "type" "store2")
d952d547 11410 (set_attr "predicable" "yes")
11411 (set_attr "predicable_short_it" "no")])
1653cf17 11412
11413(define_insn "*thumb2_strd_base_neg"
11414 [(set (mem:SI (plus:SI (match_operand:SI 0 "s_register_operand" "rk")
11415 (const_int -4)))
11416 (match_operand:SI 1 "s_register_operand" "r"))
11417 (set (mem:SI (match_dup 0))
11418 (match_operand:SI 2 "s_register_operand" "r"))]
11419 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11420 && current_tune->prefer_ldrd_strd
11421 && (operands_ok_ldrd_strd (operands[1], operands[2],
11422 operands[0], -4, false, false))"
11423 "strd%?\t%1, %2, [%0, #-4]"
11424 [(set_attr "type" "store2")
d952d547 11425 (set_attr "predicable" "yes")
11426 (set_attr "predicable_short_it" "no")])
1653cf17 11427
2a0c73f2 11428;; ARMv8 CRC32 instructions.
11429(define_insn "<crc_variant>"
11430 [(set (match_operand:SI 0 "s_register_operand" "=r")
11431 (unspec:SI [(match_operand:SI 1 "s_register_operand" "r")
11432 (match_operand:<crc_mode> 2 "s_register_operand" "r")]
11433 CRC))]
11434 "TARGET_CRC32"
11435 "<crc_variant>\\t%0, %1, %2"
11436 [(set_attr "type" "crc")
11437 (set_attr "conds" "unconditional")]
11438)
1653cf17 11439
353cf59a 11440;; Load the load/store double peephole optimizations.
11441(include "ldrdstrd.md")
11442
320ea44d 11443;; Load the load/store multiple patterns
11444(include "ldmstm.md")
426be8c5 11445
11446;; Patterns in ldmstm.md don't cover more than 4 registers. This pattern covers
11447;; large lists without explicit writeback generated for APCS_FRAME epilogue.
11448(define_insn "*load_multiple"
11449 [(match_parallel 0 "load_multiple_operation"
11450 [(set (match_operand:SI 2 "s_register_operand" "=rk")
11451 (mem:SI (match_operand:SI 1 "s_register_operand" "rk")))
11452 ])]
11453 "TARGET_32BIT"
11454 "*
11455 {
11456 arm_output_multireg_pop (operands, /*return_pc=*/false,
11457 /*cond=*/const_true_rtx,
11458 /*reverse=*/false,
11459 /*update=*/false);
11460 return \"\";
11461 }
11462 "
11463 [(set_attr "predicable" "yes")]
11464)
11465
84450ddc 11466(define_expand "copysignsf3"
11467 [(match_operand:SF 0 "register_operand")
11468 (match_operand:SF 1 "register_operand")
11469 (match_operand:SF 2 "register_operand")]
11470 "TARGET_SOFT_FLOAT && arm_arch_thumb2"
11471 "{
11472 emit_move_insn (operands[0], operands[2]);
11473 emit_insn (gen_insv_t2 (simplify_gen_subreg (SImode, operands[0], SFmode, 0),
11474 GEN_INT (31), GEN_INT (0),
11475 simplify_gen_subreg (SImode, operands[1], SFmode, 0)));
11476 DONE;
11477 }"
11478)
11479
11480(define_expand "copysigndf3"
11481 [(match_operand:DF 0 "register_operand")
11482 (match_operand:DF 1 "register_operand")
11483 (match_operand:DF 2 "register_operand")]
11484 "TARGET_SOFT_FLOAT && arm_arch_thumb2"
11485 "{
11486 rtx op0_low = gen_lowpart (SImode, operands[0]);
11487 rtx op0_high = gen_highpart (SImode, operands[0]);
11488 rtx op1_low = gen_lowpart (SImode, operands[1]);
11489 rtx op1_high = gen_highpart (SImode, operands[1]);
11490 rtx op2_high = gen_highpart (SImode, operands[2]);
11491
11492 rtx scratch1 = gen_reg_rtx (SImode);
11493 rtx scratch2 = gen_reg_rtx (SImode);
11494 emit_move_insn (scratch1, op2_high);
11495 emit_move_insn (scratch2, op1_high);
11496
d1f9b275 11497 emit_insn(gen_rtx_SET(scratch1,
84450ddc 11498 gen_rtx_LSHIFTRT (SImode, op2_high, GEN_INT(31))));
11499 emit_insn(gen_insv_t2(scratch2, GEN_INT(1), GEN_INT(31), scratch1));
11500 emit_move_insn (op0_low, op1_low);
11501 emit_move_insn (op0_high, scratch2);
11502
11503 DONE;
11504 }"
11505)
11506
d98a3884 11507;; Vector bits common to IWMMXT and Neon
11508(include "vec-common.md")
755eb2b4 11509;; Load the Intel Wireless Multimedia Extension patterns
11510(include "iwmmxt.md")
a2cd141b 11511;; Load the VFP co-processor patterns
11512(include "vfp.md")
bc360af8 11513;; Thumb-1 patterns
11514(include "thumb1.md")
25f905c2 11515;; Thumb-2 patterns
11516(include "thumb2.md")
d98a3884 11517;; Neon patterns
11518(include "neon.md")
e84fdf6e 11519;; Crypto patterns
11520(include "crypto.md")
06df6b17 11521;; Synchronization Primitives
11522(include "sync.md")
bbbe4599 11523;; Fixed-point patterns
11524(include "arm-fixed.md")