]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/config/arm/arm.md
* gcc-interface/trans.c (emit_check): Do not touch TREE_SIDE_EFFECTS.
[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 {
6637 REAL_VALUE_TYPE r;
6638 long bits;
6639 rtx ops[4];
6640
6641 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
6642 bits = real_to_target (NULL, &r, HFmode);
6643 ops[0] = operands[0];
6644 ops[1] = GEN_INT (bits);
6645 ops[2] = GEN_INT (bits & 0xff00);
6646 ops[3] = GEN_INT (bits & 0x00ff);
6647
6648 if (arm_arch_thumb2)
6649 output_asm_insn (\"movw%?\\t%0, %1\", ops);
6650 else
6651 output_asm_insn (\"mov%?\\t%0, %2\;orr%?\\t%0, %0, %3\", ops);
6652 return \"\";
6653 }
6654 default:
6655 gcc_unreachable ();
6656 }
6657 "
6658 [(set_attr "conds" "unconditional")
ad4fc3c0 6659 (set_attr "type" "load1,store1,mov_reg,multiple")
9b8516be 6660 (set_attr "length" "4,4,4,8")
ea501323 6661 (set_attr "predicable" "yes")
6662 (set_attr "predicable_short_it" "no")]
9b8516be 6663)
6664
87b22bf7 6665(define_expand "movsf"
6666 [(set (match_operand:SF 0 "general_operand" "")
6667 (match_operand:SF 1 "general_operand" ""))]
cffb2a26 6668 "TARGET_EITHER"
87b22bf7 6669 "
25f905c2 6670 if (TARGET_32BIT)
cffb2a26 6671 {
0438d37f 6672 if (MEM_P (operands[0]))
cffb2a26 6673 operands[1] = force_reg (SFmode, operands[1]);
6674 }
25f905c2 6675 else /* TARGET_THUMB1 */
cffb2a26 6676 {
e1ba4a27 6677 if (can_create_pseudo_p ())
cffb2a26 6678 {
0438d37f 6679 if (!REG_P (operands[0]))
cffb2a26 6680 operands[1] = force_reg (SFmode, operands[1]);
6681 }
6682 }
6683 "
6684)
6685
03d440a6 6686;; Transform a floating-point move of a constant into a core register into
6687;; an SImode operation.
cffb2a26 6688(define_split
03d440a6 6689 [(set (match_operand:SF 0 "arm_general_register_operand" "")
cffb2a26 6690 (match_operand:SF 1 "immediate_operand" ""))]
339034d0 6691 "TARGET_EITHER
cffb2a26 6692 && reload_completed
0438d37f 6693 && CONST_DOUBLE_P (operands[1])"
cffb2a26 6694 [(set (match_dup 2) (match_dup 3))]
6695 "
6696 operands[2] = gen_lowpart (SImode, operands[0]);
6697 operands[3] = gen_lowpart (SImode, operands[1]);
6698 if (operands[2] == 0 || operands[3] == 0)
6699 FAIL;
215b30b3 6700 "
6701)
87b22bf7 6702
cffb2a26 6703(define_insn "*arm_movsf_soft_insn"
6704 [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,m")
6705 (match_operand:SF 1 "general_operand" "r,mE,r"))]
cde1623a 6706 "TARGET_32BIT
cffb2a26 6707 && TARGET_SOFT_FLOAT
0438d37f 6708 && (!MEM_P (operands[0])
215b30b3 6709 || register_operand (operands[1], SFmode))"
9a1112d7 6710 "@
6711 mov%?\\t%0, %1
6712 ldr%?\\t%0, %1\\t%@ float
6713 str%?\\t%1, %0\\t%@ float"
cde1623a 6714 [(set_attr "predicable" "yes")
7c36fe71 6715 (set_attr "predicable_short_it" "no")
1aed5204 6716 (set_attr "type" "mov_reg,load1,store1")
42e1de19 6717 (set_attr "arm_pool_range" "*,4096,*")
6718 (set_attr "thumb2_pool_range" "*,4094,*")
cde1623a 6719 (set_attr "arm_neg_pool_range" "*,4084,*")
6720 (set_attr "thumb2_neg_pool_range" "*,0,*")]
cffb2a26 6721)
6722
9c08d1fa 6723(define_expand "movdf"
87b22bf7 6724 [(set (match_operand:DF 0 "general_operand" "")
6725 (match_operand:DF 1 "general_operand" ""))]
cffb2a26 6726 "TARGET_EITHER"
9c08d1fa 6727 "
25f905c2 6728 if (TARGET_32BIT)
cffb2a26 6729 {
0438d37f 6730 if (MEM_P (operands[0]))
cffb2a26 6731 operands[1] = force_reg (DFmode, operands[1]);
6732 }
6733 else /* TARGET_THUMB */
6734 {
e1ba4a27 6735 if (can_create_pseudo_p ())
cffb2a26 6736 {
0438d37f 6737 if (!REG_P (operands[0]))
cffb2a26 6738 operands[1] = force_reg (DFmode, operands[1]);
6739 }
6740 }
6741 "
6742)
b11cae9e 6743
9c08d1fa 6744;; Reloading a df mode value stored in integer regs to memory can require a
6745;; scratch reg.
6746(define_expand "reload_outdf"
cffb2a26 6747 [(match_operand:DF 0 "arm_reload_memory_operand" "=o")
87b22bf7 6748 (match_operand:DF 1 "s_register_operand" "r")
6749 (match_operand:SI 2 "s_register_operand" "=&r")]
06adefdc 6750 "TARGET_THUMB2"
87b22bf7 6751 "
215b30b3 6752 {
6753 enum rtx_code code = GET_CODE (XEXP (operands[0], 0));
f7fbdd4a 6754
215b30b3 6755 if (code == REG)
6756 operands[2] = XEXP (operands[0], 0);
6757 else if (code == POST_INC || code == PRE_DEC)
6758 {
6759 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
6760 operands[1] = gen_rtx_SUBREG (DImode, operands[1], 0);
6761 emit_insn (gen_movdi (operands[0], operands[1]));
6762 DONE;
6763 }
6764 else if (code == PRE_INC)
6765 {
6766 rtx reg = XEXP (XEXP (operands[0], 0), 0);
f7fbdd4a 6767
215b30b3 6768 emit_insn (gen_addsi3 (reg, reg, GEN_INT (8)));
6769 operands[2] = reg;
6770 }
6771 else if (code == POST_DEC)
6772 operands[2] = XEXP (XEXP (operands[0], 0), 0);
6773 else
6774 emit_insn (gen_addsi3 (operands[2], XEXP (XEXP (operands[0], 0), 0),
6775 XEXP (XEXP (operands[0], 0), 1)));
f7fbdd4a 6776
d1f9b275 6777 emit_insn (gen_rtx_SET (replace_equiv_address (operands[0], operands[2]),
215b30b3 6778 operands[1]));
f7fbdd4a 6779
215b30b3 6780 if (code == POST_DEC)
6781 emit_insn (gen_addsi3 (operands[2], operands[2], GEN_INT (-8)));
6782
6783 DONE;
6784 }"
6785)
9c08d1fa 6786
9a1112d7 6787(define_insn "*movdf_soft_insn"
353cf59a 6788 [(set (match_operand:DF 0 "nonimmediate_soft_df_operand" "=r,r,r,q,m")
6789 (match_operand:DF 1 "soft_df_operand" "rDa,Db,Dc,mF,q"))]
cde1623a 6790 "TARGET_32BIT && TARGET_SOFT_FLOAT
b2778788 6791 && ( register_operand (operands[0], DFmode)
6792 || register_operand (operands[1], DFmode))"
d51f92df 6793 "*
6794 switch (which_alternative)
6795 {
6796 case 0:
6797 case 1:
6798 case 2:
6799 return \"#\";
6800 default:
26ff80c0 6801 return output_move_double (operands, true, NULL);
d51f92df 6802 }
6803 "
359a6e9f 6804 [(set_attr "length" "8,12,16,8,8")
1b7da4ac 6805 (set_attr "type" "multiple,multiple,multiple,load2,store2")
42e1de19 6806 (set_attr "arm_pool_range" "*,*,*,1020,*")
6807 (set_attr "thumb2_pool_range" "*,*,*,1018,*")
8848d797 6808 (set_attr "arm_neg_pool_range" "*,*,*,1004,*")
cde1623a 6809 (set_attr "thumb2_neg_pool_range" "*,*,*,0,*")]
cffb2a26 6810)
b11cae9e 6811\f
b11cae9e 6812
9c08d1fa 6813;; load- and store-multiple insns
6814;; The arm can load/store any set of registers, provided that they are in
320ea44d 6815;; ascending order, but these expanders assume a contiguous set.
b11cae9e 6816
9c08d1fa 6817(define_expand "load_multiple"
6818 [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
6819 (match_operand:SI 1 "" ""))
6820 (use (match_operand:SI 2 "" ""))])]
25f905c2 6821 "TARGET_32BIT"
9580c25f 6822{
6823 HOST_WIDE_INT offset = 0;
6824
bd5b4116 6825 /* Support only fixed point registers. */
0438d37f 6826 if (!CONST_INT_P (operands[2])
6e628811 6827 || INTVAL (operands[2]) > MAX_LDM_STM_OPS
9c08d1fa 6828 || INTVAL (operands[2]) < 2
0438d37f 6829 || !MEM_P (operands[1])
6830 || !REG_P (operands[0])
bd5b4116 6831 || REGNO (operands[0]) > (LAST_ARM_REGNUM - 1)
6832 || REGNO (operands[0]) + INTVAL (operands[2]) > LAST_ARM_REGNUM)
9c08d1fa 6833 FAIL;
6834
6835 operands[3]
320ea44d 6836 = arm_gen_load_multiple (arm_regs_in_sequence + REGNO (operands[0]),
6837 INTVAL (operands[2]),
f082f1c4 6838 force_reg (SImode, XEXP (operands[1], 0)),
320ea44d 6839 FALSE, operands[1], &offset);
9580c25f 6840})
b11cae9e 6841
9c08d1fa 6842(define_expand "store_multiple"
6843 [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
6844 (match_operand:SI 1 "" ""))
6845 (use (match_operand:SI 2 "" ""))])]
25f905c2 6846 "TARGET_32BIT"
9580c25f 6847{
6848 HOST_WIDE_INT offset = 0;
6849
674a8f0b 6850 /* Support only fixed point registers. */
0438d37f 6851 if (!CONST_INT_P (operands[2])
6e628811 6852 || INTVAL (operands[2]) > MAX_LDM_STM_OPS
9c08d1fa 6853 || INTVAL (operands[2]) < 2
0438d37f 6854 || !REG_P (operands[1])
6855 || !MEM_P (operands[0])
bd5b4116 6856 || REGNO (operands[1]) > (LAST_ARM_REGNUM - 1)
6857 || REGNO (operands[1]) + INTVAL (operands[2]) > LAST_ARM_REGNUM)
9c08d1fa 6858 FAIL;
6859
6860 operands[3]
320ea44d 6861 = arm_gen_store_multiple (arm_regs_in_sequence + REGNO (operands[1]),
6862 INTVAL (operands[2]),
f082f1c4 6863 force_reg (SImode, XEXP (operands[0], 0)),
320ea44d 6864 FALSE, operands[0], &offset);
9580c25f 6865})
b11cae9e 6866
9c08d1fa 6867
e34ebfca 6868(define_expand "setmemsi"
6869 [(match_operand:BLK 0 "general_operand" "")
6870 (match_operand:SI 1 "const_int_operand" "")
6871 (match_operand:SI 2 "const_int_operand" "")
6872 (match_operand:SI 3 "const_int_operand" "")]
6873 "TARGET_32BIT"
6874{
6875 if (arm_gen_setmem (operands))
6876 DONE;
6877
6878 FAIL;
6879})
6880
6881
9c08d1fa 6882;; Move a block of memory if it is word aligned and MORE than 2 words long.
6883;; We could let this apply for blocks of less than this, but it clobbers so
6884;; many registers that there is then probably a better way.
6885
008c057d 6886(define_expand "movmemqi"
34191dd1 6887 [(match_operand:BLK 0 "general_operand" "")
6888 (match_operand:BLK 1 "general_operand" "")
6889 (match_operand:SI 2 "const_int_operand" "")
6890 (match_operand:SI 3 "const_int_operand" "")]
ae51a965 6891 ""
9c08d1fa 6892 "
25f905c2 6893 if (TARGET_32BIT)
cffb2a26 6894 {
ae51a965 6895 if (TARGET_LDRD && current_tune->prefer_ldrd_strd
6896 && !optimize_function_for_size_p (cfun))
6897 {
6898 if (gen_movmem_ldrd_strd (operands))
6899 DONE;
6900 FAIL;
6901 }
6902
008c057d 6903 if (arm_gen_movmemqi (operands))
cffb2a26 6904 DONE;
6905 FAIL;
6906 }
25f905c2 6907 else /* TARGET_THUMB1 */
cffb2a26 6908 {
6909 if ( INTVAL (operands[3]) != 4
6910 || INTVAL (operands[2]) > 48)
6911 FAIL;
6912
008c057d 6913 thumb_expand_movmemqi (operands);
cffb2a26 6914 DONE;
6915 }
6916 "
6917)
9c08d1fa 6918\f
b11cae9e 6919
341940e8 6920;; Compare & branch insns
8d232dc7 6921;; The range calculations are based as follows:
341940e8 6922;; For forward branches, the address calculation returns the address of
6923;; the next instruction. This is 2 beyond the branch instruction.
6924;; For backward branches, the address calculation returns the address of
6925;; the first instruction in this pattern (cmp). This is 2 before the branch
6926;; instruction for the shortest sequence, and 4 before the branch instruction
6927;; if we have to jump around an unconditional branch.
6928;; To the basic branch range the PC offset must be added (this is +4).
6929;; So for forward branches we have
6930;; (pos_range - pos_base_offs + pc_offs) = (pos_range - 2 + 4).
6931;; And for backward branches we have
6932;; (neg_range - neg_base_offs + pc_offs) = (neg_range - (-2 or -4) + 4).
6933;;
6934;; For a 'b' pos_range = 2046, neg_range = -2048 giving (-2040->2048).
6935;; For a 'b<cond>' pos_range = 254, neg_range = -256 giving (-250 ->256).
cffb2a26 6936
aeac46d4 6937(define_expand "cbranchsi4"
6938 [(set (pc) (if_then_else
aa06947a 6939 (match_operator 0 "expandable_comparison_operator"
aeac46d4 6940 [(match_operand:SI 1 "s_register_operand" "")
6941 (match_operand:SI 2 "nonmemory_operand" "")])
6942 (label_ref (match_operand 3 "" ""))
6943 (pc)))]
f9aa4160 6944 "TARGET_EITHER"
aeac46d4 6945 "
74f4459c 6946 if (!TARGET_THUMB1)
6947 {
f9aa4160 6948 if (!arm_validize_comparison (&operands[0], &operands[1], &operands[2]))
6949 FAIL;
74f4459c 6950 emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
6951 operands[3]));
6952 DONE;
6953 }
25f905c2 6954 if (thumb1_cmpneg_operand (operands[2], SImode))
aeac46d4 6955 {
6956 emit_jump_insn (gen_cbranchsi4_scratch (NULL, operands[1], operands[2],
6957 operands[3], operands[0]));
6958 DONE;
6959 }
25f905c2 6960 if (!thumb1_cmp_operand (operands[2], SImode))
aeac46d4 6961 operands[2] = force_reg (SImode, operands[2]);
6962 ")
6963
74f4459c 6964(define_expand "cbranchsf4"
6965 [(set (pc) (if_then_else
aa06947a 6966 (match_operator 0 "expandable_comparison_operator"
74f4459c 6967 [(match_operand:SF 1 "s_register_operand" "")
6968 (match_operand:SF 2 "arm_float_compare_operand" "")])
6969 (label_ref (match_operand 3 "" ""))
6970 (pc)))]
6971 "TARGET_32BIT && TARGET_HARD_FLOAT"
6972 "emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
6973 operands[3])); DONE;"
6974)
6975
6976(define_expand "cbranchdf4"
6977 [(set (pc) (if_then_else
aa06947a 6978 (match_operator 0 "expandable_comparison_operator"
74f4459c 6979 [(match_operand:DF 1 "s_register_operand" "")
6980 (match_operand:DF 2 "arm_float_compare_operand" "")])
6981 (label_ref (match_operand 3 "" ""))
6982 (pc)))]
a50d7267 6983 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
74f4459c 6984 "emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
6985 operands[3])); DONE;"
6986)
6987
74f4459c 6988(define_expand "cbranchdi4"
6989 [(set (pc) (if_then_else
aa06947a 6990 (match_operator 0 "expandable_comparison_operator"
b8eae306 6991 [(match_operand:DI 1 "s_register_operand" "")
a8045a4f 6992 (match_operand:DI 2 "cmpdi_operand" "")])
74f4459c 6993 (label_ref (match_operand 3 "" ""))
6994 (pc)))]
a8045a4f 6995 "TARGET_32BIT"
6996 "{
0438d37f 6997 if (!arm_validize_comparison (&operands[0], &operands[1], &operands[2]))
f9aa4160 6998 FAIL;
6999 emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
a8045a4f 7000 operands[3]));
7001 DONE;
7002 }"
74f4459c 7003)
7004
9c08d1fa 7005;; Comparison and test insns
7006
cffb2a26 7007(define_insn "*arm_cmpsi_insn"
bd5b4116 7008 [(set (reg:CC CC_REGNUM)
f9f234ec 7009 (compare:CC (match_operand:SI 0 "s_register_operand" "l,r,r,r,r")
7010 (match_operand:SI 1 "arm_add_operand" "Py,r,r,I,L")))]
25f905c2 7011 "TARGET_32BIT"
5565501b 7012 "@
a6864a24 7013 cmp%?\\t%0, %1
7014 cmp%?\\t%0, %1
aea4c774 7015 cmp%?\\t%0, %1
f9f234ec 7016 cmp%?\\t%0, %1
aea4c774 7017 cmn%?\\t%0, #%n1"
a6864a24 7018 [(set_attr "conds" "set")
f9f234ec 7019 (set_attr "arch" "t2,t2,any,any,any")
7020 (set_attr "length" "2,2,4,4,4")
65f68e55 7021 (set_attr "predicable" "yes")
f9f234ec 7022 (set_attr "predicable_short_it" "yes,yes,yes,no,no")
112eda6f 7023 (set_attr "type" "alus_imm,alus_sreg,alus_sreg,alus_imm,alus_imm")]
cffb2a26 7024)
b11cae9e 7025
d5d4dc8d 7026(define_insn "*cmpsi_shiftsi"
bd5b4116 7027 [(set (reg:CC CC_REGNUM)
d82e788e 7028 (compare:CC (match_operand:SI 0 "s_register_operand" "r,r,r")
cffb2a26 7029 (match_operator:SI 3 "shift_operator"
d82e788e 7030 [(match_operand:SI 1 "s_register_operand" "r,r,r")
7031 (match_operand:SI 2 "shift_amount_operand" "M,r,M")])))]
d5d4dc8d 7032 "TARGET_32BIT"
f9f234ec 7033 "cmp\\t%0, %1%S3"
344495ea 7034 [(set_attr "conds" "set")
331beb1a 7035 (set_attr "shift" "1")
d82e788e 7036 (set_attr "arch" "32,a,a")
282b4c75 7037 (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")])
b11cae9e 7038
d5d4dc8d 7039(define_insn "*cmpsi_shiftsi_swp"
bd5b4116 7040 [(set (reg:CC_SWP CC_REGNUM)
aea4c774 7041 (compare:CC_SWP (match_operator:SI 3 "shift_operator"
d82e788e 7042 [(match_operand:SI 1 "s_register_operand" "r,r,r")
7043 (match_operand:SI 2 "shift_amount_operand" "M,r,M")])
7044 (match_operand:SI 0 "s_register_operand" "r,r,r")))]
d5d4dc8d 7045 "TARGET_32BIT"
aea4c774 7046 "cmp%?\\t%0, %1%S3"
344495ea 7047 [(set_attr "conds" "set")
331beb1a 7048 (set_attr "shift" "1")
d82e788e 7049 (set_attr "arch" "32,a,a")
282b4c75 7050 (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")])
b11cae9e 7051
25f905c2 7052(define_insn "*arm_cmpsi_negshiftsi_si"
aed179ae 7053 [(set (reg:CC_Z CC_REGNUM)
7054 (compare:CC_Z
7055 (neg:SI (match_operator:SI 1 "shift_operator"
7056 [(match_operand:SI 2 "s_register_operand" "r")
7057 (match_operand:SI 3 "reg_or_int_operand" "rM")]))
7058 (match_operand:SI 0 "s_register_operand" "r")))]
cffb2a26 7059 "TARGET_ARM"
aed179ae 7060 "cmn%?\\t%0, %2%S1"
344495ea 7061 [(set_attr "conds" "set")
aed179ae 7062 (set (attr "type") (if_then_else (match_operand 3 "const_int_operand" "")
d82e788e 7063 (const_string "alus_shift_imm")
7064 (const_string "alus_shift_reg")))
596e5e8f 7065 (set_attr "predicable" "yes")]
0d66636f 7066)
b11cae9e 7067
a8045a4f 7068;; DImode comparisons. The generic code generates branches that
7069;; if-conversion can not reduce to a conditional compare, so we do
7070;; that directly.
7071
ba6a3b2f 7072(define_insn_and_split "*arm_cmpdi_insn"
a8045a4f 7073 [(set (reg:CC_NCV CC_REGNUM)
7074 (compare:CC_NCV (match_operand:DI 0 "s_register_operand" "r")
7075 (match_operand:DI 1 "arm_di_operand" "rDi")))
7076 (clobber (match_scratch:SI 2 "=r"))]
b805622c 7077 "TARGET_32BIT"
ba6a3b2f 7078 "#" ; "cmp\\t%Q0, %Q1\;sbcs\\t%2, %R0, %R1"
7079 "&& reload_completed"
7080 [(set (reg:CC CC_REGNUM)
7081 (compare:CC (match_dup 0) (match_dup 1)))
7082 (parallel [(set (reg:CC CC_REGNUM)
7083 (compare:CC (match_dup 3) (match_dup 4)))
7084 (set (match_dup 2)
7085 (minus:SI (match_dup 5)
7086 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))])]
7087 {
7088 operands[3] = gen_highpart (SImode, operands[0]);
7089 operands[0] = gen_lowpart (SImode, operands[0]);
7090 if (CONST_INT_P (operands[1]))
7091 {
7092 operands[4] = GEN_INT (~INTVAL (gen_highpart_mode (SImode,
7093 DImode,
7094 operands[1])));
7095 operands[5] = gen_rtx_PLUS (SImode, operands[3], operands[4]);
7096 }
7097 else
7098 {
7099 operands[4] = gen_highpart (SImode, operands[1]);
7100 operands[5] = gen_rtx_MINUS (SImode, operands[3], operands[4]);
7101 }
7102 operands[1] = gen_lowpart (SImode, operands[1]);
7103 operands[2] = gen_lowpart (SImode, operands[2]);
7104 }
a8045a4f 7105 [(set_attr "conds" "set")
1b7da4ac 7106 (set_attr "length" "8")
7107 (set_attr "type" "multiple")]
a8045a4f 7108)
7109
ba6a3b2f 7110(define_insn_and_split "*arm_cmpdi_unsigned"
a8045a4f 7111 [(set (reg:CC_CZ CC_REGNUM)
1a86364b 7112 (compare:CC_CZ (match_operand:DI 0 "s_register_operand" "l,r,r,r")
7113 (match_operand:DI 1 "arm_di_operand" "Py,r,Di,rDi")))]
7c36fe71 7114
48a98053 7115 "TARGET_32BIT"
ba6a3b2f 7116 "#" ; "cmp\\t%R0, %R1\;it eq\;cmpeq\\t%Q0, %Q1"
7117 "&& reload_completed"
7118 [(set (reg:CC CC_REGNUM)
7119 (compare:CC (match_dup 2) (match_dup 3)))
7120 (cond_exec (eq:SI (reg:CC CC_REGNUM) (const_int 0))
7121 (set (reg:CC CC_REGNUM)
7122 (compare:CC (match_dup 0) (match_dup 1))))]
7123 {
7124 operands[2] = gen_highpart (SImode, operands[0]);
7125 operands[0] = gen_lowpart (SImode, operands[0]);
7126 if (CONST_INT_P (operands[1]))
7127 operands[3] = gen_highpart_mode (SImode, DImode, operands[1]);
7128 else
7129 operands[3] = gen_highpart (SImode, operands[1]);
7130 operands[1] = gen_lowpart (SImode, operands[1]);
7131 }
a8045a4f 7132 [(set_attr "conds" "set")
1a86364b 7133 (set_attr "enabled_for_depr_it" "yes,yes,no,*")
7134 (set_attr "arch" "t2,t2,t2,a")
7135 (set_attr "length" "6,6,10,8")
1b7da4ac 7136 (set_attr "type" "multiple")]
a8045a4f 7137)
7138
7139(define_insn "*arm_cmpdi_zero"
7140 [(set (reg:CC_Z CC_REGNUM)
7141 (compare:CC_Z (match_operand:DI 0 "s_register_operand" "r")
7142 (const_int 0)))
7143 (clobber (match_scratch:SI 1 "=r"))]
7144 "TARGET_32BIT"
7145 "orr%.\\t%1, %Q0, %R0"
1b7da4ac 7146 [(set_attr "conds" "set")
7147 (set_attr "type" "logics_reg")]
a8045a4f 7148)
7149
9c08d1fa 7150; This insn allows redundant compares to be removed by cse, nothing should
7151; ever appear in the output file since (set (reg x) (reg x)) is a no-op that
7152; is deleted later on. The match_dup will match the mode here, so that
7153; mode changes of the condition codes aren't lost by this even though we don't
7154; specify what they are.
7155
8a18b90c 7156(define_insn "*deleted_compare"
9c08d1fa 7157 [(set (match_operand 0 "cc_register" "") (match_dup 0))]
25f905c2 7158 "TARGET_32BIT"
40dbec34 7159 "\\t%@ deleted compare"
cffb2a26 7160 [(set_attr "conds" "set")
1b7da4ac 7161 (set_attr "length" "0")
7162 (set_attr "type" "no_insn")]
cffb2a26 7163)
9c08d1fa 7164
7165\f
7166;; Conditional branch insns
7167
74f4459c 7168(define_expand "cbranch_cc"
9c08d1fa 7169 [(set (pc)
74f4459c 7170 (if_then_else (match_operator 0 "" [(match_operand 1 "" "")
7171 (match_operand 2 "" "")])
7172 (label_ref (match_operand 3 "" ""))
9c08d1fa 7173 (pc)))]
25f905c2 7174 "TARGET_32BIT"
74f4459c 7175 "operands[1] = arm_gen_compare_reg (GET_CODE (operands[0]),
e1b93706 7176 operands[1], operands[2], NULL_RTX);
74f4459c 7177 operands[2] = const0_rtx;"
8fa3ba89 7178)
7179
7180;;
7181;; Patterns to match conditional branch insns.
7182;;
7183
ffcc986d 7184(define_insn "arm_cond_branch"
9c08d1fa 7185 [(set (pc)
8fa3ba89 7186 (if_then_else (match_operator 1 "arm_comparison_operator"
8a18b90c 7187 [(match_operand 2 "cc_register" "") (const_int 0)])
9c08d1fa 7188 (label_ref (match_operand 0 "" ""))
7189 (pc)))]
25f905c2 7190 "TARGET_32BIT"
d75350ce 7191 "*
9c08d1fa 7192 if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
cffb2a26 7193 {
7194 arm_ccfsm_state += 2;
7195 return \"\";
7196 }
e2348bcb 7197 return \"b%d1\\t%l0\";
cffb2a26 7198 "
a2cd141b 7199 [(set_attr "conds" "use")
a6864a24 7200 (set_attr "type" "branch")
7201 (set (attr "length")
7202 (if_then_else
0bf497f5 7203 (and (match_test "TARGET_THUMB2")
a6864a24 7204 (and (ge (minus (match_dup 0) (pc)) (const_int -250))
7205 (le (minus (match_dup 0) (pc)) (const_int 256))))
7206 (const_int 2)
7207 (const_int 4)))]
cffb2a26 7208)
d75350ce 7209
cffb2a26 7210(define_insn "*arm_cond_branch_reversed"
9c08d1fa 7211 [(set (pc)
8fa3ba89 7212 (if_then_else (match_operator 1 "arm_comparison_operator"
8a18b90c 7213 [(match_operand 2 "cc_register" "") (const_int 0)])
9c08d1fa 7214 (pc)
7215 (label_ref (match_operand 0 "" ""))))]
25f905c2 7216 "TARGET_32BIT"
d75350ce 7217 "*
9c08d1fa 7218 if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
cffb2a26 7219 {
7220 arm_ccfsm_state += 2;
7221 return \"\";
7222 }
e2348bcb 7223 return \"b%D1\\t%l0\";
cffb2a26 7224 "
a2cd141b 7225 [(set_attr "conds" "use")
a6864a24 7226 (set_attr "type" "branch")
7227 (set (attr "length")
7228 (if_then_else
0bf497f5 7229 (and (match_test "TARGET_THUMB2")
a6864a24 7230 (and (ge (minus (match_dup 0) (pc)) (const_int -250))
7231 (le (minus (match_dup 0) (pc)) (const_int 256))))
7232 (const_int 2)
7233 (const_int 4)))]
cffb2a26 7234)
7235
b11cae9e 7236\f
9c08d1fa 7237
7238; scc insns
7239
74f4459c 7240(define_expand "cstore_cc"
7db9af5d 7241 [(set (match_operand:SI 0 "s_register_operand" "")
74f4459c 7242 (match_operator:SI 1 "" [(match_operand 2 "" "")
7243 (match_operand 3 "" "")]))]
25f905c2 7244 "TARGET_32BIT"
74f4459c 7245 "operands[2] = arm_gen_compare_reg (GET_CODE (operands[1]),
e1b93706 7246 operands[2], operands[3], NULL_RTX);
74f4459c 7247 operands[3] = const0_rtx;"
8fa3ba89 7248)
7249
a3b84066 7250(define_insn_and_split "*mov_scc"
9c08d1fa 7251 [(set (match_operand:SI 0 "s_register_operand" "=r")
8fa3ba89 7252 (match_operator:SI 1 "arm_comparison_operator"
8a18b90c 7253 [(match_operand 2 "cc_register" "") (const_int 0)]))]
cffb2a26 7254 "TARGET_ARM"
a3b84066 7255 "#" ; "mov%D1\\t%0, #0\;mov%d1\\t%0, #1"
7256 "TARGET_ARM"
7257 [(set (match_dup 0)
7258 (if_then_else:SI (match_dup 1)
7259 (const_int 1)
7260 (const_int 0)))]
7261 ""
cffb2a26 7262 [(set_attr "conds" "use")
1b7da4ac 7263 (set_attr "length" "8")
7264 (set_attr "type" "multiple")]
cffb2a26 7265)
9c08d1fa 7266
a3b84066 7267(define_insn_and_split "*mov_negscc"
9c08d1fa 7268 [(set (match_operand:SI 0 "s_register_operand" "=r")
8fa3ba89 7269 (neg:SI (match_operator:SI 1 "arm_comparison_operator"
8a18b90c 7270 [(match_operand 2 "cc_register" "") (const_int 0)])))]
cffb2a26 7271 "TARGET_ARM"
a3b84066 7272 "#" ; "mov%D1\\t%0, #0\;mvn%d1\\t%0, #0"
7273 "TARGET_ARM"
7274 [(set (match_dup 0)
7275 (if_then_else:SI (match_dup 1)
7276 (match_dup 3)
7277 (const_int 0)))]
7278 {
7279 operands[3] = GEN_INT (~0);
7280 }
cffb2a26 7281 [(set_attr "conds" "use")
1b7da4ac 7282 (set_attr "length" "8")
7283 (set_attr "type" "multiple")]
cffb2a26 7284)
9c08d1fa 7285
a3b84066 7286(define_insn_and_split "*mov_notscc"
9c08d1fa 7287 [(set (match_operand:SI 0 "s_register_operand" "=r")
8fa3ba89 7288 (not:SI (match_operator:SI 1 "arm_comparison_operator"
8a18b90c 7289 [(match_operand 2 "cc_register" "") (const_int 0)])))]
cffb2a26 7290 "TARGET_ARM"
a3b84066 7291 "#" ; "mvn%D1\\t%0, #0\;mvn%d1\\t%0, #1"
7292 "TARGET_ARM"
7293 [(set (match_dup 0)
7294 (if_then_else:SI (match_dup 1)
7295 (match_dup 3)
7296 (match_dup 4)))]
7297 {
7298 operands[3] = GEN_INT (~1);
7299 operands[4] = GEN_INT (~0);
7300 }
cffb2a26 7301 [(set_attr "conds" "use")
1b7da4ac 7302 (set_attr "length" "8")
7303 (set_attr "type" "multiple")]
cffb2a26 7304)
9c08d1fa 7305
595d88b5 7306(define_expand "cstoresi4"
7307 [(set (match_operand:SI 0 "s_register_operand" "")
aa06947a 7308 (match_operator:SI 1 "expandable_comparison_operator"
595d88b5 7309 [(match_operand:SI 2 "s_register_operand" "")
7310 (match_operand:SI 3 "reg_or_int_operand" "")]))]
74f4459c 7311 "TARGET_32BIT || TARGET_THUMB1"
595d88b5 7312 "{
7313 rtx op3, scratch, scratch2;
7314
74f4459c 7315 if (!TARGET_THUMB1)
7316 {
7317 if (!arm_add_operand (operands[3], SImode))
7318 operands[3] = force_reg (SImode, operands[3]);
7319 emit_insn (gen_cstore_cc (operands[0], operands[1],
7320 operands[2], operands[3]));
7321 DONE;
7322 }
7323
595d88b5 7324 if (operands[3] == const0_rtx)
7325 {
7326 switch (GET_CODE (operands[1]))
7327 {
7328 case EQ:
25f905c2 7329 emit_insn (gen_cstoresi_eq0_thumb1 (operands[0], operands[2]));
595d88b5 7330 break;
7331
7332 case NE:
25f905c2 7333 emit_insn (gen_cstoresi_ne0_thumb1 (operands[0], operands[2]));
595d88b5 7334 break;
7335
7336 case LE:
7337 scratch = expand_binop (SImode, add_optab, operands[2], constm1_rtx,
7338 NULL_RTX, 0, OPTAB_WIDEN);
7339 scratch = expand_binop (SImode, ior_optab, operands[2], scratch,
7340 NULL_RTX, 0, OPTAB_WIDEN);
7341 expand_binop (SImode, lshr_optab, scratch, GEN_INT (31),
7342 operands[0], 1, OPTAB_WIDEN);
7343 break;
7344
7345 case GE:
7346 scratch = expand_unop (SImode, one_cmpl_optab, operands[2],
7347 NULL_RTX, 1);
7348 expand_binop (SImode, lshr_optab, scratch, GEN_INT (31),
7349 NULL_RTX, 1, OPTAB_WIDEN);
7350 break;
7351
7352 case GT:
7353 scratch = expand_binop (SImode, ashr_optab, operands[2],
7354 GEN_INT (31), NULL_RTX, 0, OPTAB_WIDEN);
7355 scratch = expand_binop (SImode, sub_optab, scratch, operands[2],
7356 NULL_RTX, 0, OPTAB_WIDEN);
7357 expand_binop (SImode, lshr_optab, scratch, GEN_INT (31), operands[0],
7358 0, OPTAB_WIDEN);
7359 break;
7360
7361 /* LT is handled by generic code. No need for unsigned with 0. */
7362 default:
7363 FAIL;
7364 }
7365 DONE;
7366 }
7367
7368 switch (GET_CODE (operands[1]))
7369 {
7370 case EQ:
7371 scratch = expand_binop (SImode, sub_optab, operands[2], operands[3],
7372 NULL_RTX, 0, OPTAB_WIDEN);
25f905c2 7373 emit_insn (gen_cstoresi_eq0_thumb1 (operands[0], scratch));
595d88b5 7374 break;
7375
7376 case NE:
7377 scratch = expand_binop (SImode, sub_optab, operands[2], operands[3],
7378 NULL_RTX, 0, OPTAB_WIDEN);
25f905c2 7379 emit_insn (gen_cstoresi_ne0_thumb1 (operands[0], scratch));
595d88b5 7380 break;
7381
7382 case LE:
7383 op3 = force_reg (SImode, operands[3]);
7384
7385 scratch = expand_binop (SImode, lshr_optab, operands[2], GEN_INT (31),
7386 NULL_RTX, 1, OPTAB_WIDEN);
7387 scratch2 = expand_binop (SImode, ashr_optab, op3, GEN_INT (31),
7388 NULL_RTX, 0, OPTAB_WIDEN);
25f905c2 7389 emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch2,
595d88b5 7390 op3, operands[2]));
7391 break;
7392
7393 case GE:
7394 op3 = operands[3];
25f905c2 7395 if (!thumb1_cmp_operand (op3, SImode))
595d88b5 7396 op3 = force_reg (SImode, op3);
7397 scratch = expand_binop (SImode, ashr_optab, operands[2], GEN_INT (31),
7398 NULL_RTX, 0, OPTAB_WIDEN);
7399 scratch2 = expand_binop (SImode, lshr_optab, op3, GEN_INT (31),
7400 NULL_RTX, 1, OPTAB_WIDEN);
25f905c2 7401 emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch2,
595d88b5 7402 operands[2], op3));
7403 break;
7404
7405 case LEU:
7406 op3 = force_reg (SImode, operands[3]);
7407 scratch = force_reg (SImode, const0_rtx);
25f905c2 7408 emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch,
595d88b5 7409 op3, operands[2]));
7410 break;
7411
7412 case GEU:
7413 op3 = operands[3];
25f905c2 7414 if (!thumb1_cmp_operand (op3, SImode))
595d88b5 7415 op3 = force_reg (SImode, op3);
7416 scratch = force_reg (SImode, const0_rtx);
25f905c2 7417 emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch,
595d88b5 7418 operands[2], op3));
7419 break;
7420
7421 case LTU:
7422 op3 = operands[3];
25f905c2 7423 if (!thumb1_cmp_operand (op3, SImode))
595d88b5 7424 op3 = force_reg (SImode, op3);
7425 scratch = gen_reg_rtx (SImode);
408b7ae5 7426 emit_insn (gen_cstoresi_ltu_thumb1 (operands[0], operands[2], op3));
595d88b5 7427 break;
7428
7429 case GTU:
7430 op3 = force_reg (SImode, operands[3]);
7431 scratch = gen_reg_rtx (SImode);
408b7ae5 7432 emit_insn (gen_cstoresi_ltu_thumb1 (operands[0], op3, operands[2]));
595d88b5 7433 break;
7434
7435 /* No good sequences for GT, LT. */
7436 default:
7437 FAIL;
7438 }
7439 DONE;
7440}")
7441
74f4459c 7442(define_expand "cstoresf4"
7443 [(set (match_operand:SI 0 "s_register_operand" "")
aa06947a 7444 (match_operator:SI 1 "expandable_comparison_operator"
74f4459c 7445 [(match_operand:SF 2 "s_register_operand" "")
7446 (match_operand:SF 3 "arm_float_compare_operand" "")]))]
7447 "TARGET_32BIT && TARGET_HARD_FLOAT"
7448 "emit_insn (gen_cstore_cc (operands[0], operands[1],
7449 operands[2], operands[3])); DONE;"
7450)
7451
7452(define_expand "cstoredf4"
7453 [(set (match_operand:SI 0 "s_register_operand" "")
aa06947a 7454 (match_operator:SI 1 "expandable_comparison_operator"
74f4459c 7455 [(match_operand:DF 2 "s_register_operand" "")
7456 (match_operand:DF 3 "arm_float_compare_operand" "")]))]
d63ed457 7457 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
74f4459c 7458 "emit_insn (gen_cstore_cc (operands[0], operands[1],
7459 operands[2], operands[3])); DONE;"
7460)
7461
74f4459c 7462(define_expand "cstoredi4"
7463 [(set (match_operand:SI 0 "s_register_operand" "")
aa06947a 7464 (match_operator:SI 1 "expandable_comparison_operator"
b8eae306 7465 [(match_operand:DI 2 "s_register_operand" "")
a8045a4f 7466 (match_operand:DI 3 "cmpdi_operand" "")]))]
7467 "TARGET_32BIT"
7468 "{
f9aa4160 7469 if (!arm_validize_comparison (&operands[1],
7470 &operands[2],
7471 &operands[3]))
7472 FAIL;
7473 emit_insn (gen_cstore_cc (operands[0], operands[1], operands[2],
a8045a4f 7474 operands[3]));
7475 DONE;
7476 }"
74f4459c 7477)
7478
9c08d1fa 7479\f
39b5e676 7480;; Conditional move insns
7481
7482(define_expand "movsicc"
8a18b90c 7483 [(set (match_operand:SI 0 "s_register_operand" "")
aa06947a 7484 (if_then_else:SI (match_operand 1 "expandable_comparison_operator" "")
aea4c774 7485 (match_operand:SI 2 "arm_not_operand" "")
8a18b90c 7486 (match_operand:SI 3 "arm_not_operand" "")))]
25f905c2 7487 "TARGET_32BIT"
39b5e676 7488 "
215b30b3 7489 {
f9aa4160 7490 enum rtx_code code;
278b301d 7491 rtx ccreg;
7492
f9aa4160 7493 if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0),
7494 &XEXP (operands[1], 1)))
278b301d 7495 FAIL;
f9aa4160 7496
7497 code = GET_CODE (operands[1]);
74f4459c 7498 ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
e1b93706 7499 XEXP (operands[1], 1), NULL_RTX);
29bb088d 7500 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
215b30b3 7501 }"
7502)
39b5e676 7503
7504(define_expand "movsfcc"
8a18b90c 7505 [(set (match_operand:SF 0 "s_register_operand" "")
4df97ffc 7506 (if_then_else:SF (match_operand 1 "arm_cond_move_operator" "")
8a18b90c 7507 (match_operand:SF 2 "s_register_operand" "")
d86c91f6 7508 (match_operand:SF 3 "s_register_operand" "")))]
19f6bf8d 7509 "TARGET_32BIT && TARGET_HARD_FLOAT"
39b5e676 7510 "
215b30b3 7511 {
7512 enum rtx_code code = GET_CODE (operands[1]);
7513 rtx ccreg;
f082f1c4 7514
f9aa4160 7515 if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0),
7516 &XEXP (operands[1], 1)))
7517 FAIL;
39b5e676 7518
f9aa4160 7519 code = GET_CODE (operands[1]);
74f4459c 7520 ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
e1b93706 7521 XEXP (operands[1], 1), NULL_RTX);
29bb088d 7522 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
215b30b3 7523 }"
7524)
39b5e676 7525
7526(define_expand "movdfcc"
8a18b90c 7527 [(set (match_operand:DF 0 "s_register_operand" "")
4df97ffc 7528 (if_then_else:DF (match_operand 1 "arm_cond_move_operator" "")
8a18b90c 7529 (match_operand:DF 2 "s_register_operand" "")
d86c91f6 7530 (match_operand:DF 3 "s_register_operand" "")))]
994606f8 7531 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
39b5e676 7532 "
215b30b3 7533 {
7534 enum rtx_code code = GET_CODE (operands[1]);
278b301d 7535 rtx ccreg;
39b5e676 7536
f9aa4160 7537 if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0),
7538 &XEXP (operands[1], 1)))
7539 FAIL;
7540 code = GET_CODE (operands[1]);
74f4459c 7541 ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
e1b93706 7542 XEXP (operands[1], 1), NULL_RTX);
29bb088d 7543 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
215b30b3 7544 }"
7545)
39b5e676 7546
91cb50d2 7547(define_insn "*cmov<mode>"
7548 [(set (match_operand:SDF 0 "s_register_operand" "=<F_constraint>")
7549 (if_then_else:SDF (match_operator 1 "arm_vsel_comparison_operator"
7550 [(match_operand 2 "cc_register" "") (const_int 0)])
7551 (match_operand:SDF 3 "s_register_operand"
7552 "<F_constraint>")
7553 (match_operand:SDF 4 "s_register_operand"
7554 "<F_constraint>")))]
7555 "TARGET_HARD_FLOAT && TARGET_FPU_ARMV8 <vfp_double_cond>"
7556 "*
7557 {
7558 enum arm_cond_code code = maybe_get_arm_condition_code (operands[1]);
7559 switch (code)
7560 {
7561 case ARM_GE:
7562 case ARM_GT:
7563 case ARM_EQ:
7564 case ARM_VS:
7565 return \"vsel%d1.<V_if_elem>\\t%<V_reg>0, %<V_reg>3, %<V_reg>4\";
7566 case ARM_LT:
7567 case ARM_LE:
7568 case ARM_NE:
7569 case ARM_VC:
7570 return \"vsel%D1.<V_if_elem>\\t%<V_reg>0, %<V_reg>4, %<V_reg>3\";
7571 default:
7572 gcc_unreachable ();
7573 }
7574 return \"\";
7575 }"
7576 [(set_attr "conds" "use")
6664d308 7577 (set_attr "type" "fcsel")]
91cb50d2 7578)
7579
190efb17 7580(define_insn_and_split "*movsicc_insn"
f082f1c4 7581 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r,r,r,r,r")
8a18b90c 7582 (if_then_else:SI
8fa3ba89 7583 (match_operator 3 "arm_comparison_operator"
8a18b90c 7584 [(match_operand 4 "cc_register" "") (const_int 0)])
f082f1c4 7585 (match_operand:SI 1 "arm_not_operand" "0,0,rI,K,rI,rI,K,K")
7586 (match_operand:SI 2 "arm_not_operand" "rI,K,0,0,rI,K,rI,K")))]
cffb2a26 7587 "TARGET_ARM"
39b5e676 7588 "@
8a18b90c 7589 mov%D3\\t%0, %2
7590 mvn%D3\\t%0, #%B2
f082f1c4 7591 mov%d3\\t%0, %1
7592 mvn%d3\\t%0, #%B1
190efb17 7593 #
7594 #
7595 #
7596 #"
7597 ; alt4: mov%d3\\t%0, %1\;mov%D3\\t%0, %2
7598 ; alt5: mov%d3\\t%0, %1\;mvn%D3\\t%0, #%B2
7599 ; alt6: mvn%d3\\t%0, #%B1\;mov%D3\\t%0, %2
7600 ; alt7: mvn%d3\\t%0, #%B1\;mvn%D3\\t%0, #%B2"
7601 "&& reload_completed"
7602 [(const_int 0)]
7603 {
7604 enum rtx_code rev_code;
3754d046 7605 machine_mode mode;
190efb17 7606 rtx rev_cond;
7607
7608 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
7609 operands[3],
d1f9b275 7610 gen_rtx_SET (operands[0], operands[1])));
190efb17 7611
7612 rev_code = GET_CODE (operands[3]);
7613 mode = GET_MODE (operands[4]);
7614 if (mode == CCFPmode || mode == CCFPEmode)
7615 rev_code = reverse_condition_maybe_unordered (rev_code);
7616 else
7617 rev_code = reverse_condition (rev_code);
7618
7619 rev_cond = gen_rtx_fmt_ee (rev_code,
7620 VOIDmode,
7621 operands[4],
7622 const0_rtx);
7623 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
7624 rev_cond,
d1f9b275 7625 gen_rtx_SET (operands[0], operands[2])));
190efb17 7626 DONE;
7627 }
f082f1c4 7628 [(set_attr "length" "4,4,4,4,8,8,8,8")
d2a518d1 7629 (set_attr "conds" "use")
65f68e55 7630 (set_attr_alternative "type"
7631 [(if_then_else (match_operand 2 "const_int_operand" "")
1aed5204 7632 (const_string "mov_imm")
7633 (const_string "mov_reg"))
7634 (const_string "mvn_imm")
65f68e55 7635 (if_then_else (match_operand 1 "const_int_operand" "")
1aed5204 7636 (const_string "mov_imm")
7637 (const_string "mov_reg"))
7638 (const_string "mvn_imm")
282b4c75 7639 (const_string "multiple")
7640 (const_string "multiple")
7641 (const_string "multiple")
7642 (const_string "multiple")])]
215b30b3 7643)
39b5e676 7644
39b5e676 7645(define_insn "*movsfcc_soft_insn"
f082f1c4 7646 [(set (match_operand:SF 0 "s_register_operand" "=r,r")
8fa3ba89 7647 (if_then_else:SF (match_operator 3 "arm_comparison_operator"
8a18b90c 7648 [(match_operand 4 "cc_register" "") (const_int 0)])
f082f1c4 7649 (match_operand:SF 1 "s_register_operand" "0,r")
7650 (match_operand:SF 2 "s_register_operand" "r,0")))]
cffb2a26 7651 "TARGET_ARM && TARGET_SOFT_FLOAT"
f082f1c4 7652 "@
7653 mov%D3\\t%0, %2
7654 mov%d3\\t%0, %1"
d2a518d1 7655 [(set_attr "conds" "use")
1aed5204 7656 (set_attr "type" "mov_reg")]
8fa3ba89 7657)
39b5e676 7658
39b5e676 7659\f
9c08d1fa 7660;; Jump and linkage insns
7661
cffb2a26 7662(define_expand "jump"
9c08d1fa 7663 [(set (pc)
7664 (label_ref (match_operand 0 "" "")))]
cffb2a26 7665 "TARGET_EITHER"
9c08d1fa 7666 ""
cffb2a26 7667)
7668
7669(define_insn "*arm_jump"
7670 [(set (pc)
7671 (label_ref (match_operand 0 "" "")))]
25f905c2 7672 "TARGET_32BIT"
9c08d1fa 7673 "*
0d66636f 7674 {
7675 if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
7676 {
7677 arm_ccfsm_state += 2;
7678 return \"\";
7679 }
7680 return \"b%?\\t%l0\";
7681 }
7682 "
a6864a24 7683 [(set_attr "predicable" "yes")
7684 (set (attr "length")
7685 (if_then_else
0bf497f5 7686 (and (match_test "TARGET_THUMB2")
a6864a24 7687 (and (ge (minus (match_dup 0) (pc)) (const_int -2044))
7688 (le (minus (match_dup 0) (pc)) (const_int 2048))))
7689 (const_int 2)
1b7da4ac 7690 (const_int 4)))
7691 (set_attr "type" "branch")]
0d66636f 7692)
9c08d1fa 7693
d3373b54 7694(define_expand "call"
7695 [(parallel [(call (match_operand 0 "memory_operand" "")
7696 (match_operand 1 "general_operand" ""))
cffb2a26 7697 (use (match_operand 2 "" ""))
bd5b4116 7698 (clobber (reg:SI LR_REGNUM))])]
cffb2a26 7699 "TARGET_EITHER"
6c4c2133 7700 "
7701 {
bac7fc85 7702 rtx callee, pat;
bbe777ea 7703
bbe777ea 7704 /* In an untyped call, we can get NULL for operand 2. */
7705 if (operands[2] == NULL_RTX)
7706 operands[2] = const0_rtx;
7707
de55252a 7708 /* Decide if we should generate indirect calls by loading the
85c36fd1 7709 32-bit address of the callee into a register before performing the
de55252a 7710 branch and link. */
7711 callee = XEXP (operands[0], 0);
7712 if (GET_CODE (callee) == SYMBOL_REF
7713 ? arm_is_long_call_p (SYMBOL_REF_DECL (callee))
7714 : !REG_P (callee))
bbe777ea 7715 XEXP (operands[0], 0) = force_reg (Pmode, callee);
bac7fc85 7716
7717 pat = gen_call_internal (operands[0], operands[1], operands[2]);
ca373797 7718 arm_emit_call_insn (pat, XEXP (operands[0], 0), false);
bac7fc85 7719 DONE;
6c4c2133 7720 }"
7721)
d3373b54 7722
bac7fc85 7723(define_expand "call_internal"
7724 [(parallel [(call (match_operand 0 "memory_operand" "")
7725 (match_operand 1 "general_operand" ""))
7726 (use (match_operand 2 "" ""))
7727 (clobber (reg:SI LR_REGNUM))])])
7728
f1039640 7729(define_insn "*call_reg_armv5"
d3373b54 7730 [(call (mem:SI (match_operand:SI 0 "s_register_operand" "r"))
cffb2a26 7731 (match_operand 1 "" ""))
7732 (use (match_operand 2 "" ""))
bd5b4116 7733 (clobber (reg:SI LR_REGNUM))]
33ae7c4b 7734 "TARGET_ARM && arm_arch5 && !SIBLING_CALL_P (insn)"
f1039640 7735 "blx%?\\t%0"
7736 [(set_attr "type" "call")]
7737)
7738
7739(define_insn "*call_reg_arm"
7740 [(call (mem:SI (match_operand:SI 0 "s_register_operand" "r"))
7741 (match_operand 1 "" ""))
7742 (use (match_operand 2 "" ""))
7743 (clobber (reg:SI LR_REGNUM))]
33ae7c4b 7744 "TARGET_ARM && !arm_arch5 && !SIBLING_CALL_P (insn)"
9c08d1fa 7745 "*
5565501b 7746 return output_call (operands);
cffb2a26 7747 "
7748 ;; length is worst case, normally it is only two
7749 [(set_attr "length" "12")
7750 (set_attr "type" "call")]
7751)
9c08d1fa 7752
89504fc1 7753
7754;; Note: not used for armv5+ because the sequence used (ldr pc, ...) is not
7755;; considered a function call by the branch predictor of some cores (PR40887).
7756;; Falls back to blx rN (*call_reg_armv5).
7757
f7fbdd4a 7758(define_insn "*call_mem"
a3c63a9d 7759 [(call (mem:SI (match_operand:SI 0 "call_memory_operand" "m"))
cffb2a26 7760 (match_operand 1 "" ""))
7761 (use (match_operand 2 "" ""))
bd5b4116 7762 (clobber (reg:SI LR_REGNUM))]
33ae7c4b 7763 "TARGET_ARM && !arm_arch5 && !SIBLING_CALL_P (insn)"
9c08d1fa 7764 "*
5565501b 7765 return output_call_mem (operands);
cffb2a26 7766 "
7767 [(set_attr "length" "12")
7768 (set_attr "type" "call")]
7769)
7770
d3373b54 7771(define_expand "call_value"
e0698af7 7772 [(parallel [(set (match_operand 0 "" "")
7773 (call (match_operand 1 "memory_operand" "")
7774 (match_operand 2 "general_operand" "")))
cffb2a26 7775 (use (match_operand 3 "" ""))
bd5b4116 7776 (clobber (reg:SI LR_REGNUM))])]
cffb2a26 7777 "TARGET_EITHER"
6c4c2133 7778 "
7779 {
bac7fc85 7780 rtx pat, callee;
bbe777ea 7781
7782 /* In an untyped call, we can get NULL for operand 2. */
7783 if (operands[3] == 0)
7784 operands[3] = const0_rtx;
7785
de55252a 7786 /* Decide if we should generate indirect calls by loading the
7787 32-bit address of the callee into a register before performing the
7788 branch and link. */
7789 callee = XEXP (operands[1], 0);
7790 if (GET_CODE (callee) == SYMBOL_REF
7791 ? arm_is_long_call_p (SYMBOL_REF_DECL (callee))
7792 : !REG_P (callee))
78fe751b 7793 XEXP (operands[1], 0) = force_reg (Pmode, callee);
bac7fc85 7794
7795 pat = gen_call_value_internal (operands[0], operands[1],
7796 operands[2], operands[3]);
ca373797 7797 arm_emit_call_insn (pat, XEXP (operands[1], 0), false);
bac7fc85 7798 DONE;
6c4c2133 7799 }"
7800)
d3373b54 7801
bac7fc85 7802(define_expand "call_value_internal"
7803 [(parallel [(set (match_operand 0 "" "")
7804 (call (match_operand 1 "memory_operand" "")
7805 (match_operand 2 "general_operand" "")))
7806 (use (match_operand 3 "" ""))
7807 (clobber (reg:SI LR_REGNUM))])])
7808
f1039640 7809(define_insn "*call_value_reg_armv5"
27ed6835 7810 [(set (match_operand 0 "" "")
755eb2b4 7811 (call (mem:SI (match_operand:SI 1 "s_register_operand" "r"))
cffb2a26 7812 (match_operand 2 "" "")))
bbe777ea 7813 (use (match_operand 3 "" ""))
bd5b4116 7814 (clobber (reg:SI LR_REGNUM))]
33ae7c4b 7815 "TARGET_ARM && arm_arch5 && !SIBLING_CALL_P (insn)"
f1039640 7816 "blx%?\\t%1"
7817 [(set_attr "type" "call")]
7818)
7819
7820(define_insn "*call_value_reg_arm"
7821 [(set (match_operand 0 "" "")
7822 (call (mem:SI (match_operand:SI 1 "s_register_operand" "r"))
7823 (match_operand 2 "" "")))
7824 (use (match_operand 3 "" ""))
7825 (clobber (reg:SI LR_REGNUM))]
33ae7c4b 7826 "TARGET_ARM && !arm_arch5 && !SIBLING_CALL_P (insn)"
9c08d1fa 7827 "*
215b30b3 7828 return output_call (&operands[1]);
cffb2a26 7829 "
7830 [(set_attr "length" "12")
7831 (set_attr "type" "call")]
7832)
9c08d1fa 7833
89504fc1 7834;; Note: see *call_mem
7835
f7fbdd4a 7836(define_insn "*call_value_mem"
27ed6835 7837 [(set (match_operand 0 "" "")
a3c63a9d 7838 (call (mem:SI (match_operand:SI 1 "call_memory_operand" "m"))
cffb2a26 7839 (match_operand 2 "" "")))
bbe777ea 7840 (use (match_operand 3 "" ""))
bd5b4116 7841 (clobber (reg:SI LR_REGNUM))]
33ae7c4b 7842 "TARGET_ARM && !arm_arch5 && (!CONSTANT_ADDRESS_P (XEXP (operands[1], 0)))
7843 && !SIBLING_CALL_P (insn)"
9c08d1fa 7844 "*
215b30b3 7845 return output_call_mem (&operands[1]);
cffb2a26 7846 "
7847 [(set_attr "length" "12")
7848 (set_attr "type" "call")]
7849)
9c08d1fa 7850
7851;; Allow calls to SYMBOL_REFs specially as they are not valid general addresses
7852;; The 'a' causes the operand to be treated as an address, i.e. no '#' output.
7853
f7fbdd4a 7854(define_insn "*call_symbol"
27ed6835 7855 [(call (mem:SI (match_operand:SI 0 "" ""))
cffb2a26 7856 (match_operand 1 "" ""))
bbe777ea 7857 (use (match_operand 2 "" ""))
bd5b4116 7858 (clobber (reg:SI LR_REGNUM))]
d68c2c10 7859 "TARGET_32BIT
33ae7c4b 7860 && !SIBLING_CALL_P (insn)
cffb2a26 7861 && (GET_CODE (operands[0]) == SYMBOL_REF)
de55252a 7862 && !arm_is_long_call_p (SYMBOL_REF_DECL (operands[0]))"
6ebaa29d 7863 "*
7864 {
95f1e0d1 7865 rtx op = operands[0];
7866
7867 /* Switch mode now when possible. */
7868 if (SYMBOL_REF_DECL (op) && !TREE_PUBLIC (SYMBOL_REF_DECL (op))
7869 && arm_arch5 && arm_change_mode_p (SYMBOL_REF_DECL (op)))
7870 return NEED_PLT_RELOC ? \"blx%?\\t%a0(PLT)\" : \"blx%?\\t(%a0)\";
7871
55c1e470 7872 return NEED_PLT_RELOC ? \"bl%?\\t%a0(PLT)\" : \"bl%?\\t%a0\";
6ebaa29d 7873 }"
cffb2a26 7874 [(set_attr "type" "call")]
7875)
9c08d1fa 7876
f7fbdd4a 7877(define_insn "*call_value_symbol"
ccd90aaa 7878 [(set (match_operand 0 "" "")
27ed6835 7879 (call (mem:SI (match_operand:SI 1 "" ""))
dd6d7504 7880 (match_operand:SI 2 "" "")))
bbe777ea 7881 (use (match_operand 3 "" ""))
bd5b4116 7882 (clobber (reg:SI LR_REGNUM))]
d68c2c10 7883 "TARGET_32BIT
33ae7c4b 7884 && !SIBLING_CALL_P (insn)
cffb2a26 7885 && (GET_CODE (operands[1]) == SYMBOL_REF)
de55252a 7886 && !arm_is_long_call_p (SYMBOL_REF_DECL (operands[1]))"
6ebaa29d 7887 "*
7888 {
95f1e0d1 7889 rtx op = operands[1];
7890
7891 /* Switch mode now when possible. */
7892 if (SYMBOL_REF_DECL (op) && !TREE_PUBLIC (SYMBOL_REF_DECL (op))
7893 && arm_arch5 && arm_change_mode_p (SYMBOL_REF_DECL (op)))
7894 return NEED_PLT_RELOC ? \"blx%?\\t%a0(PLT)\" : \"blx%?\\t(%a0)\";
7895
55c1e470 7896 return NEED_PLT_RELOC ? \"bl%?\\t%a1(PLT)\" : \"bl%?\\t%a1\";
6ebaa29d 7897 }"
cffb2a26 7898 [(set_attr "type" "call")]
7899)
7900
ca373797 7901(define_expand "sibcall_internal"
7902 [(parallel [(call (match_operand 0 "memory_operand" "")
7903 (match_operand 1 "general_operand" ""))
7904 (return)
7905 (use (match_operand 2 "" ""))])])
7906
1c494086 7907;; We may also be able to do sibcalls for Thumb, but it's much harder...
7908(define_expand "sibcall"
7909 [(parallel [(call (match_operand 0 "memory_operand" "")
7910 (match_operand 1 "general_operand" ""))
2ba80634 7911 (return)
7912 (use (match_operand 2 "" ""))])]
d68c2c10 7913 "TARGET_32BIT"
1c494086 7914 "
7915 {
ca373797 7916 rtx pat;
7917
3112c3f7 7918 if ((!REG_P (XEXP (operands[0], 0))
7919 && GET_CODE (XEXP (operands[0], 0)) != SYMBOL_REF)
7920 || (GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
7921 && arm_is_long_call_p (SYMBOL_REF_DECL (XEXP (operands[0], 0)))))
33ae7c4b 7922 XEXP (operands[0], 0) = force_reg (SImode, XEXP (operands[0], 0));
7923
1c494086 7924 if (operands[2] == NULL_RTX)
7925 operands[2] = const0_rtx;
ca373797 7926
7927 pat = gen_sibcall_internal (operands[0], operands[1], operands[2]);
7928 arm_emit_call_insn (pat, operands[0], true);
7929 DONE;
1c494086 7930 }"
7931)
7932
ca373797 7933(define_expand "sibcall_value_internal"
7934 [(parallel [(set (match_operand 0 "" "")
7935 (call (match_operand 1 "memory_operand" "")
7936 (match_operand 2 "general_operand" "")))
7937 (return)
7938 (use (match_operand 3 "" ""))])])
7939
1c494086 7940(define_expand "sibcall_value"
ccd90aaa 7941 [(parallel [(set (match_operand 0 "" "")
1c494086 7942 (call (match_operand 1 "memory_operand" "")
7943 (match_operand 2 "general_operand" "")))
2ba80634 7944 (return)
7945 (use (match_operand 3 "" ""))])]
d68c2c10 7946 "TARGET_32BIT"
1c494086 7947 "
7948 {
ca373797 7949 rtx pat;
7950
3112c3f7 7951 if ((!REG_P (XEXP (operands[1], 0))
7952 && GET_CODE (XEXP (operands[1], 0)) != SYMBOL_REF)
7953 || (GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
7954 && arm_is_long_call_p (SYMBOL_REF_DECL (XEXP (operands[1], 0)))))
33ae7c4b 7955 XEXP (operands[1], 0) = force_reg (SImode, XEXP (operands[1], 0));
7956
1c494086 7957 if (operands[3] == NULL_RTX)
7958 operands[3] = const0_rtx;
ca373797 7959
7960 pat = gen_sibcall_value_internal (operands[0], operands[1],
7961 operands[2], operands[3]);
7962 arm_emit_call_insn (pat, operands[1], true);
7963 DONE;
1c494086 7964 }"
7965)
7966
7967(define_insn "*sibcall_insn"
84ce8e5c 7968 [(call (mem:SI (match_operand:SI 0 "call_insn_operand" "Cs, US"))
1c494086 7969 (match_operand 1 "" ""))
2ba80634 7970 (return)
7971 (use (match_operand 2 "" ""))]
33ae7c4b 7972 "TARGET_32BIT && SIBLING_CALL_P (insn)"
1c494086 7973 "*
33ae7c4b 7974 if (which_alternative == 1)
7975 return NEED_PLT_RELOC ? \"b%?\\t%a0(PLT)\" : \"b%?\\t%a0\";
7976 else
7977 {
7978 if (arm_arch5 || arm_arch4t)
947d113e 7979 return \"bx%?\\t%0\\t%@ indirect register sibling call\";
33ae7c4b 7980 else
7981 return \"mov%?\\t%|pc, %0\\t%@ indirect register sibling call\";
7982 }
1c494086 7983 "
7984 [(set_attr "type" "call")]
7985)
7986
7987(define_insn "*sibcall_value_insn"
84ce8e5c 7988 [(set (match_operand 0 "" "")
7989 (call (mem:SI (match_operand:SI 1 "call_insn_operand" "Cs,US"))
1c494086 7990 (match_operand 2 "" "")))
2ba80634 7991 (return)
7992 (use (match_operand 3 "" ""))]
33ae7c4b 7993 "TARGET_32BIT && SIBLING_CALL_P (insn)"
1c494086 7994 "*
33ae7c4b 7995 if (which_alternative == 1)
7996 return NEED_PLT_RELOC ? \"b%?\\t%a1(PLT)\" : \"b%?\\t%a1\";
7997 else
7998 {
7999 if (arm_arch5 || arm_arch4t)
84ce8e5c 8000 return \"bx%?\\t%1\";
33ae7c4b 8001 else
8002 return \"mov%?\\t%|pc, %1\\t@ indirect sibling call \";
8003 }
1c494086 8004 "
8005 [(set_attr "type" "call")]
8006)
8007
0686440e 8008(define_expand "<return_str>return"
9b23f0a7 8009 [(RETURNS)]
8cba51a5 8010 "(TARGET_ARM || (TARGET_THUMB2
8011 && ARM_FUNC_TYPE (arm_current_func_type ()) == ARM_FT_NORMAL
8012 && !IS_STACKALIGN (arm_current_func_type ())))
0686440e 8013 <return_cond_false>"
8cba51a5 8014 "
8015 {
8016 if (TARGET_THUMB2)
8017 {
0686440e 8018 thumb2_expand_return (<return_simple_p>);
8cba51a5 8019 DONE;
8020 }
8021 }
8022 "
8023)
d68c2c10 8024
9c08d1fa 8025;; Often the return insn will be the same as loading from memory, so set attr
d68c2c10 8026(define_insn "*arm_return"
9c08d1fa 8027 [(return)]
cffb2a26 8028 "TARGET_ARM && USE_RETURN_INSN (FALSE)"
9c08d1fa 8029 "*
9c08d1fa 8030 {
cffb2a26 8031 if (arm_ccfsm_state == 2)
8032 {
8033 arm_ccfsm_state += 2;
8034 return \"\";
8035 }
e2549f81 8036 return output_return_instruction (const_true_rtx, true, false, false);
cffb2a26 8037 }"
a2cd141b 8038 [(set_attr "type" "load1")
755eb2b4 8039 (set_attr "length" "12")
0d66636f 8040 (set_attr "predicable" "yes")]
cffb2a26 8041)
9c08d1fa 8042
0686440e 8043(define_insn "*cond_<return_str>return"
9c08d1fa 8044 [(set (pc)
8fa3ba89 8045 (if_then_else (match_operator 0 "arm_comparison_operator"
8a18b90c 8046 [(match_operand 1 "cc_register" "") (const_int 0)])
9b23f0a7 8047 (RETURNS)
9c08d1fa 8048 (pc)))]
0686440e 8049 "TARGET_ARM <return_cond_true>"
9c08d1fa 8050 "*
8fa3ba89 8051 {
8052 if (arm_ccfsm_state == 2)
8053 {
8054 arm_ccfsm_state += 2;
8055 return \"\";
8056 }
0686440e 8057 return output_return_instruction (operands[0], true, false,
8058 <return_simple_p>);
8fa3ba89 8059 }"
8060 [(set_attr "conds" "use")
755eb2b4 8061 (set_attr "length" "12")
a2cd141b 8062 (set_attr "type" "load1")]
8fa3ba89 8063)
9c08d1fa 8064
0686440e 8065(define_insn "*cond_<return_str>return_inverted"
9c08d1fa 8066 [(set (pc)
8fa3ba89 8067 (if_then_else (match_operator 0 "arm_comparison_operator"
8a18b90c 8068 [(match_operand 1 "cc_register" "") (const_int 0)])
9c08d1fa 8069 (pc)
9b23f0a7 8070 (RETURNS)))]
0686440e 8071 "TARGET_ARM <return_cond_true>"
9c08d1fa 8072 "*
8fa3ba89 8073 {
8074 if (arm_ccfsm_state == 2)
8075 {
8076 arm_ccfsm_state += 2;
8077 return \"\";
8078 }
0686440e 8079 return output_return_instruction (operands[0], true, true,
8080 <return_simple_p>);
8fa3ba89 8081 }"
8082 [(set_attr "conds" "use")
37a1317b 8083 (set_attr "length" "12")
a2cd141b 8084 (set_attr "type" "load1")]
8fa3ba89 8085)
9c08d1fa 8086
e2549f81 8087(define_insn "*arm_simple_return"
8088 [(simple_return)]
8089 "TARGET_ARM"
8090 "*
8091 {
8092 if (arm_ccfsm_state == 2)
8093 {
8094 arm_ccfsm_state += 2;
8095 return \"\";
8096 }
8097 return output_return_instruction (const_true_rtx, true, false, true);
8098 }"
8099 [(set_attr "type" "branch")
8100 (set_attr "length" "4")
8101 (set_attr "predicable" "yes")]
8102)
8103
68121397 8104;; Generate a sequence of instructions to determine if the processor is
8105;; in 26-bit or 32-bit mode, and return the appropriate return address
8106;; mask.
8107
8108(define_expand "return_addr_mask"
8109 [(set (match_dup 1)
8110 (compare:CC_NOOV (unspec [(const_int 0)] UNSPEC_CHECK_ARCH)
8111 (const_int 0)))
8112 (set (match_operand:SI 0 "s_register_operand" "")
8113 (if_then_else:SI (eq (match_dup 1) (const_int 0))
8114 (const_int -1)
8115 (const_int 67108860)))] ; 0x03fffffc
8116 "TARGET_ARM"
8117 "
62eddbd4 8118 operands[1] = gen_rtx_REG (CC_NOOVmode, CC_REGNUM);
68121397 8119 ")
8120
8121(define_insn "*check_arch2"
8122 [(set (match_operand:CC_NOOV 0 "cc_register" "")
8123 (compare:CC_NOOV (unspec [(const_int 0)] UNSPEC_CHECK_ARCH)
8124 (const_int 0)))]
8125 "TARGET_ARM"
8126 "teq\\t%|r0, %|r0\;teq\\t%|pc, %|pc"
8127 [(set_attr "length" "8")
1b7da4ac 8128 (set_attr "conds" "set")
8129 (set_attr "type" "multiple")]
68121397 8130)
8131
9c08d1fa 8132;; Call subroutine returning any type.
8133
8134(define_expand "untyped_call"
8135 [(parallel [(call (match_operand 0 "" "")
8136 (const_int 0))
8137 (match_operand 1 "" "")
8138 (match_operand 2 "" "")])]
ccd90aaa 8139 "TARGET_EITHER"
9c08d1fa 8140 "
215b30b3 8141 {
8142 int i;
ccd90aaa 8143 rtx par = gen_rtx_PARALLEL (VOIDmode,
8144 rtvec_alloc (XVECLEN (operands[2], 0)));
8145 rtx addr = gen_reg_rtx (Pmode);
8146 rtx mem;
8147 int size = 0;
9c08d1fa 8148
ccd90aaa 8149 emit_move_insn (addr, XEXP (operands[1], 0));
8150 mem = change_address (operands[1], BLKmode, addr);
9c08d1fa 8151
215b30b3 8152 for (i = 0; i < XVECLEN (operands[2], 0); i++)
8153 {
ccd90aaa 8154 rtx src = SET_SRC (XVECEXP (operands[2], 0, i));
9c08d1fa 8155
ccd90aaa 8156 /* Default code only uses r0 as a return value, but we could
8157 be using anything up to 4 registers. */
8158 if (REGNO (src) == R0_REGNUM)
8159 src = gen_rtx_REG (TImode, R0_REGNUM);
8160
8161 XVECEXP (par, 0, i) = gen_rtx_EXPR_LIST (VOIDmode, src,
8162 GEN_INT (size));
8163 size += GET_MODE_SIZE (GET_MODE (src));
8164 }
8165
7f265a08 8166 emit_call_insn (gen_call_value (par, operands[0], const0_rtx, NULL));
ccd90aaa 8167
8168 size = 0;
8169
8170 for (i = 0; i < XVECLEN (par, 0); i++)
8171 {
8172 HOST_WIDE_INT offset = 0;
8173 rtx reg = XEXP (XVECEXP (par, 0, i), 0);
8174
8175 if (size != 0)
29c05e22 8176 emit_move_insn (addr, plus_constant (Pmode, addr, size));
ccd90aaa 8177
8178 mem = change_address (mem, GET_MODE (reg), NULL);
8179 if (REGNO (reg) == R0_REGNUM)
8180 {
8181 /* On thumb we have to use a write-back instruction. */
320ea44d 8182 emit_insn (arm_gen_store_multiple (arm_regs_in_sequence, 4, addr,
8183 TARGET_THUMB ? TRUE : FALSE, mem, &offset));
ccd90aaa 8184 size = TARGET_ARM ? 16 : 0;
8185 }
8186 else
8187 {
8188 emit_move_insn (mem, reg);
8189 size = GET_MODE_SIZE (GET_MODE (reg));
8190 }
215b30b3 8191 }
9c08d1fa 8192
215b30b3 8193 /* The optimizer does not know that the call sets the function value
8194 registers we stored in the result block. We avoid problems by
8195 claiming that all hard registers are used and clobbered at this
8196 point. */
8197 emit_insn (gen_blockage ());
8198
8199 DONE;
8200 }"
8201)
9c08d1fa 8202
ccd90aaa 8203(define_expand "untyped_return"
8204 [(match_operand:BLK 0 "memory_operand" "")
8205 (match_operand 1 "" "")]
8206 "TARGET_EITHER"
8207 "
8208 {
8209 int i;
8210 rtx addr = gen_reg_rtx (Pmode);
8211 rtx mem;
8212 int size = 0;
8213
8214 emit_move_insn (addr, XEXP (operands[0], 0));
8215 mem = change_address (operands[0], BLKmode, addr);
8216
8217 for (i = 0; i < XVECLEN (operands[1], 0); i++)
8218 {
8219 HOST_WIDE_INT offset = 0;
8220 rtx reg = SET_DEST (XVECEXP (operands[1], 0, i));
8221
8222 if (size != 0)
29c05e22 8223 emit_move_insn (addr, plus_constant (Pmode, addr, size));
ccd90aaa 8224
8225 mem = change_address (mem, GET_MODE (reg), NULL);
8226 if (REGNO (reg) == R0_REGNUM)
8227 {
8228 /* On thumb we have to use a write-back instruction. */
320ea44d 8229 emit_insn (arm_gen_load_multiple (arm_regs_in_sequence, 4, addr,
8230 TARGET_THUMB ? TRUE : FALSE, mem, &offset));
ccd90aaa 8231 size = TARGET_ARM ? 16 : 0;
8232 }
8233 else
8234 {
8235 emit_move_insn (reg, mem);
8236 size = GET_MODE_SIZE (GET_MODE (reg));
8237 }
8238 }
8239
8240 /* Emit USE insns before the return. */
8241 for (i = 0; i < XVECLEN (operands[1], 0); i++)
18b42941 8242 emit_use (SET_DEST (XVECEXP (operands[1], 0, i)));
ccd90aaa 8243
8244 /* Construct the return. */
8245 expand_naked_return ();
8246
8247 DONE;
8248 }"
8249)
8250
9c08d1fa 8251;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
8252;; all of memory. This blocks insns from being moved across this point.
8253
8254(define_insn "blockage"
e1159bbe 8255 [(unspec_volatile [(const_int 0)] VUNSPEC_BLOCKAGE)]
cffb2a26 8256 "TARGET_EITHER"
9c08d1fa 8257 ""
cffb2a26 8258 [(set_attr "length" "0")
8259 (set_attr "type" "block")]
8260)
9c08d1fa 8261
706dca65 8262(define_insn "probe_stack"
8263 [(set (match_operand 0 "memory_operand" "=m")
8264 (unspec [(const_int 0)] UNSPEC_PROBE_STACK))]
8265 "TARGET_32BIT"
8266{
8267 return "str%?\\tr0, %0";
8268}
8269 [(set_attr "type" "store1")
8270 (set_attr "predicable" "yes")]
8271)
8272
8273(define_insn "probe_stack_range"
8274 [(set (match_operand:SI 0 "register_operand" "=r")
8275 (unspec_volatile:SI [(match_operand:SI 1 "register_operand" "0")
8276 (match_operand:SI 2 "register_operand" "r")]
8277 UNSPEC_PROBE_STACK_RANGE))]
8278 "TARGET_32BIT"
8279{
8280 return output_probe_stack_range (operands[0], operands[2]);
8281}
8282 [(set_attr "type" "multiple")
8283 (set_attr "conds" "clob")]
8284)
8285
f7fbdd4a 8286(define_expand "casesi"
8287 [(match_operand:SI 0 "s_register_operand" "") ; index to jump on
aea4c774 8288 (match_operand:SI 1 "const_int_operand" "") ; lower bound
8289 (match_operand:SI 2 "const_int_operand" "") ; total range
f7fbdd4a 8290 (match_operand:SI 3 "" "") ; table label
8291 (match_operand:SI 4 "" "")] ; Out of range label
e6ac8414 8292 "TARGET_32BIT || optimize_size || flag_pic"
f7fbdd4a 8293 "
215b30b3 8294 {
e6ac8414 8295 enum insn_code code;
215b30b3 8296 if (operands[1] != const0_rtx)
8297 {
e6ac8414 8298 rtx reg = gen_reg_rtx (SImode);
f7fbdd4a 8299
215b30b3 8300 emit_insn (gen_addsi3 (reg, operands[0],
d022fa24 8301 gen_int_mode (-INTVAL (operands[1]),
8302 SImode)));
215b30b3 8303 operands[0] = reg;
8304 }
9c08d1fa 8305
25f905c2 8306 if (TARGET_ARM)
e6ac8414 8307 code = CODE_FOR_arm_casesi_internal;
3db2019b 8308 else if (TARGET_THUMB1)
e6ac8414 8309 code = CODE_FOR_thumb1_casesi_internal_pic;
25f905c2 8310 else if (flag_pic)
e6ac8414 8311 code = CODE_FOR_thumb2_casesi_internal_pic;
25f905c2 8312 else
e6ac8414 8313 code = CODE_FOR_thumb2_casesi_internal;
8314
8315 if (!insn_data[(int) code].operand[1].predicate(operands[2], SImode))
8316 operands[2] = force_reg (SImode, operands[2]);
8317
8318 emit_jump_insn (GEN_FCN ((int) code) (operands[0], operands[2],
8319 operands[3], operands[4]));
215b30b3 8320 DONE;
8321 }"
8322)
f7fbdd4a 8323
f082f1c4 8324;; The USE in this pattern is needed to tell flow analysis that this is
8325;; a CASESI insn. It has no other purpose.
25f905c2 8326(define_insn "arm_casesi_internal"
f082f1c4 8327 [(parallel [(set (pc)
8328 (if_then_else
8329 (leu (match_operand:SI 0 "s_register_operand" "r")
8330 (match_operand:SI 1 "arm_rhs_operand" "rI"))
8331 (mem:SI (plus:SI (mult:SI (match_dup 0) (const_int 4))
8332 (label_ref (match_operand 2 "" ""))))
8333 (label_ref (match_operand 3 "" ""))))
bd5b4116 8334 (clobber (reg:CC CC_REGNUM))
f082f1c4 8335 (use (label_ref (match_dup 2)))])]
cffb2a26 8336 "TARGET_ARM"
f7fbdd4a 8337 "*
0d66636f 8338 if (flag_pic)
8339 return \"cmp\\t%0, %1\;addls\\t%|pc, %|pc, %0, asl #2\;b\\t%l3\";
8340 return \"cmp\\t%0, %1\;ldrls\\t%|pc, [%|pc, %0, asl #2]\;b\\t%l3\";
8341 "
8342 [(set_attr "conds" "clob")
1b7da4ac 8343 (set_attr "length" "12")
8344 (set_attr "type" "multiple")]
0d66636f 8345)
9c08d1fa 8346
cffb2a26 8347(define_expand "indirect_jump"
9c08d1fa 8348 [(set (pc)
cffb2a26 8349 (match_operand:SI 0 "s_register_operand" ""))]
8350 "TARGET_EITHER"
25f905c2 8351 "
8352 /* Thumb-2 doesn't have mov pc, reg. Explicitly set the low bit of the
8353 address and use bx. */
8354 if (TARGET_THUMB2)
8355 {
8356 rtx tmp;
8357 tmp = gen_reg_rtx (SImode);
8358 emit_insn (gen_iorsi3 (tmp, operands[0], GEN_INT(1)));
8359 operands[0] = tmp;
8360 }
8361 "
cffb2a26 8362)
8363
f1039640 8364;; NB Never uses BX.
cffb2a26 8365(define_insn "*arm_indirect_jump"
8366 [(set (pc)
8367 (match_operand:SI 0 "s_register_operand" "r"))]
8368 "TARGET_ARM"
8369 "mov%?\\t%|pc, %0\\t%@ indirect register jump"
1b7da4ac 8370 [(set_attr "predicable" "yes")
8371 (set_attr "type" "branch")]
cffb2a26 8372)
9c08d1fa 8373
f7fbdd4a 8374(define_insn "*load_indirect_jump"
9c08d1fa 8375 [(set (pc)
8376 (match_operand:SI 0 "memory_operand" "m"))]
cffb2a26 8377 "TARGET_ARM"
8378 "ldr%?\\t%|pc, %0\\t%@ indirect memory jump"
a2cd141b 8379 [(set_attr "type" "load1")
61a2d04c 8380 (set_attr "pool_range" "4096")
8381 (set_attr "neg_pool_range" "4084")
0d66636f 8382 (set_attr "predicable" "yes")]
cffb2a26 8383)
8384
9c08d1fa 8385\f
8386;; Misc insns
8387
8388(define_insn "nop"
8389 [(const_int 0)]
cffb2a26 8390 "TARGET_EITHER"
8391 "*
25f905c2 8392 if (TARGET_UNIFIED_ASM)
8393 return \"nop\";
cffb2a26 8394 if (TARGET_ARM)
8395 return \"mov%?\\t%|r0, %|r0\\t%@ nop\";
8396 return \"mov\\tr8, r8\";
8397 "
8398 [(set (attr "length")
8399 (if_then_else (eq_attr "is_thumb" "yes")
8400 (const_int 2)
1b7da4ac 8401 (const_int 4)))
8402 (set_attr "type" "mov_reg")]
cffb2a26 8403)
8404
ad9d4399 8405(define_insn "trap"
8406 [(trap_if (const_int 1) (const_int 0))]
8407 ""
8408 "*
8409 if (TARGET_ARM)
8410 return \".inst\\t0xe7f000f0\";
8411 else
8412 return \".inst\\t0xdeff\";
8413 "
8414 [(set (attr "length")
8415 (if_then_else (eq_attr "is_thumb" "yes")
8416 (const_int 2)
8417 (const_int 4)))
8418 (set_attr "type" "trap")
8419 (set_attr "conds" "unconditional")]
8420)
8421
9c08d1fa 8422\f
8423;; Patterns to allow combination of arithmetic, cond code and shifts
8424
0abea32c 8425(define_insn "*<arith_shift_insn>_multsi"
8426 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9b23f0a7 8427 (SHIFTABLE_OPS:SI
0abea32c 8428 (mult:SI (match_operand:SI 2 "s_register_operand" "r,r")
8429 (match_operand:SI 3 "power_of_two_operand" ""))
8430 (match_operand:SI 1 "s_register_operand" "rk,<t2_binop0>")))]
d5d4dc8d 8431 "TARGET_32BIT"
0abea32c 8432 "<arith_shift_insn>%?\\t%0, %1, %2, lsl %b3"
8433 [(set_attr "predicable" "yes")
8434 (set_attr "predicable_short_it" "no")
753d9835 8435 (set_attr "shift" "2")
0abea32c 8436 (set_attr "arch" "a,t2")
8437 (set_attr "type" "alu_shift_imm")])
8438
8439(define_insn "*<arith_shift_insn>_shiftsi"
8440 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9b23f0a7 8441 (SHIFTABLE_OPS:SI
0abea32c 8442 (match_operator:SI 2 "shift_nomul_operator"
8443 [(match_operand:SI 3 "s_register_operand" "r,r,r")
8444 (match_operand:SI 4 "shift_amount_operand" "M,M,r")])
8445 (match_operand:SI 1 "s_register_operand" "rk,<t2_binop0>,rk")))]
a021b821 8446 "TARGET_32BIT && GET_CODE (operands[2]) != MULT"
0abea32c 8447 "<arith_shift_insn>%?\\t%0, %1, %3%S2"
344495ea 8448 [(set_attr "predicable" "yes")
74ef923b 8449 (set_attr "predicable_short_it" "no")
753d9835 8450 (set_attr "shift" "3")
0abea32c 8451 (set_attr "arch" "a,t2,a")
8452 (set_attr "type" "alu_shift_imm,alu_shift_imm,alu_shift_reg")])
9c08d1fa 8453
d7863cfe 8454(define_split
8455 [(set (match_operand:SI 0 "s_register_operand" "")
8456 (match_operator:SI 1 "shiftable_operator"
8457 [(match_operator:SI 2 "shiftable_operator"
8458 [(match_operator:SI 3 "shift_operator"
8459 [(match_operand:SI 4 "s_register_operand" "")
8460 (match_operand:SI 5 "reg_or_int_operand" "")])
8461 (match_operand:SI 6 "s_register_operand" "")])
8462 (match_operand:SI 7 "arm_rhs_operand" "")]))
8463 (clobber (match_operand:SI 8 "s_register_operand" ""))]
d5d4dc8d 8464 "TARGET_32BIT"
d7863cfe 8465 [(set (match_dup 8)
8466 (match_op_dup 2 [(match_op_dup 3 [(match_dup 4) (match_dup 5)])
8467 (match_dup 6)]))
8468 (set (match_dup 0)
8469 (match_op_dup 1 [(match_dup 8) (match_dup 7)]))]
8470 "")
8471
f7fbdd4a 8472(define_insn "*arith_shiftsi_compare0"
bd5b4116 8473 [(set (reg:CC_NOOV CC_REGNUM)
d5d4dc8d 8474 (compare:CC_NOOV
8475 (match_operator:SI 1 "shiftable_operator"
8476 [(match_operator:SI 3 "shift_operator"
8477 [(match_operand:SI 4 "s_register_operand" "r,r")
8478 (match_operand:SI 5 "shift_amount_operand" "M,r")])
8479 (match_operand:SI 2 "s_register_operand" "r,r")])
8480 (const_int 0)))
8481 (set (match_operand:SI 0 "s_register_operand" "=r,r")
9c08d1fa 8482 (match_op_dup 1 [(match_op_dup 3 [(match_dup 4) (match_dup 5)])
8483 (match_dup 2)]))]
d5d4dc8d 8484 "TARGET_32BIT"
25f905c2 8485 "%i1%.\\t%0, %2, %4%S3"
344495ea 8486 [(set_attr "conds" "set")
331beb1a 8487 (set_attr "shift" "4")
d5d4dc8d 8488 (set_attr "arch" "32,a")
d82e788e 8489 (set_attr "type" "alus_shift_imm,alus_shift_reg")])
9c08d1fa 8490
f7fbdd4a 8491(define_insn "*arith_shiftsi_compare0_scratch"
bd5b4116 8492 [(set (reg:CC_NOOV CC_REGNUM)
d5d4dc8d 8493 (compare:CC_NOOV
8494 (match_operator:SI 1 "shiftable_operator"
8495 [(match_operator:SI 3 "shift_operator"
8496 [(match_operand:SI 4 "s_register_operand" "r,r")
8497 (match_operand:SI 5 "shift_amount_operand" "M,r")])
8498 (match_operand:SI 2 "s_register_operand" "r,r")])
8499 (const_int 0)))
8500 (clobber (match_scratch:SI 0 "=r,r"))]
8501 "TARGET_32BIT"
25f905c2 8502 "%i1%.\\t%0, %2, %4%S3"
344495ea 8503 [(set_attr "conds" "set")
331beb1a 8504 (set_attr "shift" "4")
d5d4dc8d 8505 (set_attr "arch" "32,a")
d82e788e 8506 (set_attr "type" "alus_shift_imm,alus_shift_reg")])
9c08d1fa 8507
f7fbdd4a 8508(define_insn "*sub_shiftsi"
d5d4dc8d 8509 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8510 (minus:SI (match_operand:SI 1 "s_register_operand" "r,r")
9c08d1fa 8511 (match_operator:SI 2 "shift_operator"
d5d4dc8d 8512 [(match_operand:SI 3 "s_register_operand" "r,r")
8513 (match_operand:SI 4 "shift_amount_operand" "M,r")])))]
8514 "TARGET_32BIT"
6c4c2133 8515 "sub%?\\t%0, %1, %3%S2"
344495ea 8516 [(set_attr "predicable" "yes")
331beb1a 8517 (set_attr "shift" "3")
d5d4dc8d 8518 (set_attr "arch" "32,a")
d82e788e 8519 (set_attr "type" "alus_shift_imm,alus_shift_reg")])
9c08d1fa 8520
f7fbdd4a 8521(define_insn "*sub_shiftsi_compare0"
bd5b4116 8522 [(set (reg:CC_NOOV CC_REGNUM)
40dbec34 8523 (compare:CC_NOOV
d82e788e 8524 (minus:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
40dbec34 8525 (match_operator:SI 2 "shift_operator"
d82e788e 8526 [(match_operand:SI 3 "s_register_operand" "r,r,r")
8527 (match_operand:SI 4 "shift_amount_operand" "M,r,M")]))
40dbec34 8528 (const_int 0)))
d82e788e 8529 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
d5d4dc8d 8530 (minus:SI (match_dup 1)
8531 (match_op_dup 2 [(match_dup 3) (match_dup 4)])))]
8532 "TARGET_32BIT"
25f905c2 8533 "sub%.\\t%0, %1, %3%S2"
344495ea 8534 [(set_attr "conds" "set")
a2cd141b 8535 (set_attr "shift" "3")
d82e788e 8536 (set_attr "arch" "32,a,a")
8537 (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")])
9c08d1fa 8538
f7fbdd4a 8539(define_insn "*sub_shiftsi_compare0_scratch"
bd5b4116 8540 [(set (reg:CC_NOOV CC_REGNUM)
40dbec34 8541 (compare:CC_NOOV
d82e788e 8542 (minus:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
40dbec34 8543 (match_operator:SI 2 "shift_operator"
d82e788e 8544 [(match_operand:SI 3 "s_register_operand" "r,r,r")
8545 (match_operand:SI 4 "shift_amount_operand" "M,r,M")]))
40dbec34 8546 (const_int 0)))
d82e788e 8547 (clobber (match_scratch:SI 0 "=r,r,r"))]
d5d4dc8d 8548 "TARGET_32BIT"
25f905c2 8549 "sub%.\\t%0, %1, %3%S2"
344495ea 8550 [(set_attr "conds" "set")
a2cd141b 8551 (set_attr "shift" "3")
d82e788e 8552 (set_attr "arch" "32,a,a")
8553 (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")])
9c08d1fa 8554\f
8555
190efb17 8556(define_insn_and_split "*and_scc"
9c08d1fa 8557 [(set (match_operand:SI 0 "s_register_operand" "=r")
8fa3ba89 8558 (and:SI (match_operator:SI 1 "arm_comparison_operator"
190efb17 8559 [(match_operand 2 "cc_register" "") (const_int 0)])
8560 (match_operand:SI 3 "s_register_operand" "r")))]
cffb2a26 8561 "TARGET_ARM"
190efb17 8562 "#" ; "mov%D1\\t%0, #0\;and%d1\\t%0, %3, #1"
8563 "&& reload_completed"
8564 [(cond_exec (match_dup 5) (set (match_dup 0) (const_int 0)))
8565 (cond_exec (match_dup 4) (set (match_dup 0)
8566 (and:SI (match_dup 3) (const_int 1))))]
8567 {
3754d046 8568 machine_mode mode = GET_MODE (operands[2]);
190efb17 8569 enum rtx_code rc = GET_CODE (operands[1]);
8570
8571 /* Note that operands[4] is the same as operands[1],
8572 but with VOIDmode as the result. */
8573 operands[4] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
8574 if (mode == CCFPmode || mode == CCFPEmode)
8575 rc = reverse_condition_maybe_unordered (rc);
8576 else
8577 rc = reverse_condition (rc);
8578 operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
8579 }
8fa3ba89 8580 [(set_attr "conds" "use")
1b7da4ac 8581 (set_attr "type" "multiple")
8fa3ba89 8582 (set_attr "length" "8")]
8583)
9c08d1fa 8584
190efb17 8585(define_insn_and_split "*ior_scc"
9c08d1fa 8586 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
190efb17 8587 (ior:SI (match_operator:SI 1 "arm_comparison_operator"
8588 [(match_operand 2 "cc_register" "") (const_int 0)])
8589 (match_operand:SI 3 "s_register_operand" "0,?r")))]
cffb2a26 8590 "TARGET_ARM"
e2348bcb 8591 "@
190efb17 8592 orr%d1\\t%0, %3, #1
8593 #"
8594 "&& reload_completed
8595 && REGNO (operands [0]) != REGNO (operands[3])"
8596 ;; && which_alternative == 1
8597 ; mov%D1\\t%0, %3\;orr%d1\\t%0, %3, #1
8598 [(cond_exec (match_dup 5) (set (match_dup 0) (match_dup 3)))
8599 (cond_exec (match_dup 4) (set (match_dup 0)
8600 (ior:SI (match_dup 3) (const_int 1))))]
8601 {
3754d046 8602 machine_mode mode = GET_MODE (operands[2]);
190efb17 8603 enum rtx_code rc = GET_CODE (operands[1]);
8604
8605 /* Note that operands[4] is the same as operands[1],
8606 but with VOIDmode as the result. */
8607 operands[4] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
8608 if (mode == CCFPmode || mode == CCFPEmode)
8609 rc = reverse_condition_maybe_unordered (rc);
8610 else
8611 rc = reverse_condition (rc);
8612 operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
8613 }
8fa3ba89 8614 [(set_attr "conds" "use")
1b7da4ac 8615 (set_attr "length" "4,8")
8616 (set_attr "type" "logic_imm,multiple")]
8fa3ba89 8617)
9c08d1fa 8618
2df9477b 8619; A series of splitters for the compare_scc pattern below. Note that
8620; order is important.
8621(define_split
8622 [(set (match_operand:SI 0 "s_register_operand" "")
8623 (lt:SI (match_operand:SI 1 "s_register_operand" "")
8624 (const_int 0)))
8625 (clobber (reg:CC CC_REGNUM))]
8626 "TARGET_32BIT && reload_completed"
8627 [(set (match_dup 0) (lshiftrt:SI (match_dup 1) (const_int 31)))])
8628
8629(define_split
8630 [(set (match_operand:SI 0 "s_register_operand" "")
8631 (ge:SI (match_operand:SI 1 "s_register_operand" "")
8632 (const_int 0)))
8633 (clobber (reg:CC CC_REGNUM))]
8634 "TARGET_32BIT && reload_completed"
8635 [(set (match_dup 0) (not:SI (match_dup 1)))
8636 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 31)))])
8637
98562479 8638(define_split
8639 [(set (match_operand:SI 0 "s_register_operand" "")
8640 (eq:SI (match_operand:SI 1 "s_register_operand" "")
8641 (const_int 0)))
8642 (clobber (reg:CC CC_REGNUM))]
8643 "arm_arch5 && TARGET_32BIT"
8644 [(set (match_dup 0) (clz:SI (match_dup 1)))
8645 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 5)))]
8646)
8647
2df9477b 8648(define_split
8649 [(set (match_operand:SI 0 "s_register_operand" "")
8650 (eq:SI (match_operand:SI 1 "s_register_operand" "")
8651 (const_int 0)))
8652 (clobber (reg:CC CC_REGNUM))]
8653 "TARGET_32BIT && reload_completed"
8654 [(parallel
080c0b9a 8655 [(set (reg:CC CC_REGNUM)
8656 (compare:CC (const_int 1) (match_dup 1)))
2df9477b 8657 (set (match_dup 0)
8658 (minus:SI (const_int 1) (match_dup 1)))])
080c0b9a 8659 (cond_exec (ltu:CC (reg:CC CC_REGNUM) (const_int 0))
2df9477b 8660 (set (match_dup 0) (const_int 0)))])
8661
8662(define_split
8663 [(set (match_operand:SI 0 "s_register_operand" "")
8664 (ne:SI (match_operand:SI 1 "s_register_operand" "")
8665 (match_operand:SI 2 "const_int_operand" "")))
8666 (clobber (reg:CC CC_REGNUM))]
8667 "TARGET_32BIT && reload_completed"
8668 [(parallel
8669 [(set (reg:CC CC_REGNUM)
8670 (compare:CC (match_dup 1) (match_dup 2)))
8671 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 3)))])
8672 (cond_exec (ne:CC (reg:CC CC_REGNUM) (const_int 0))
8673 (set (match_dup 0) (const_int 1)))]
8674{
8675 operands[3] = GEN_INT (-INTVAL (operands[2]));
8676})
8677
8678(define_split
8679 [(set (match_operand:SI 0 "s_register_operand" "")
8680 (ne:SI (match_operand:SI 1 "s_register_operand" "")
8681 (match_operand:SI 2 "arm_add_operand" "")))
8682 (clobber (reg:CC CC_REGNUM))]
8683 "TARGET_32BIT && reload_completed"
8684 [(parallel
8685 [(set (reg:CC_NOOV CC_REGNUM)
8686 (compare:CC_NOOV (minus:SI (match_dup 1) (match_dup 2))
8687 (const_int 0)))
8688 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
8689 (cond_exec (ne:CC_NOOV (reg:CC_NOOV CC_REGNUM) (const_int 0))
8690 (set (match_dup 0) (const_int 1)))])
8691
8692(define_insn_and_split "*compare_scc"
fd711051 8693 [(set (match_operand:SI 0 "s_register_operand" "=Ts,Ts")
8fa3ba89 8694 (match_operator:SI 1 "arm_comparison_operator"
5565501b 8695 [(match_operand:SI 2 "s_register_operand" "r,r")
8696 (match_operand:SI 3 "arm_add_operand" "rI,L")]))
bd5b4116 8697 (clobber (reg:CC CC_REGNUM))]
2df9477b 8698 "TARGET_32BIT"
8699 "#"
8700 "&& reload_completed"
8701 [(set (reg:CC CC_REGNUM) (compare:CC (match_dup 2) (match_dup 3)))
8702 (cond_exec (match_dup 4) (set (match_dup 0) (const_int 0)))
8703 (cond_exec (match_dup 5) (set (match_dup 0) (const_int 1)))]
8704{
8705 rtx tmp1;
3754d046 8706 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
2df9477b 8707 operands[2], operands[3]);
8708 enum rtx_code rc = GET_CODE (operands[1]);
e2348bcb 8709
2df9477b 8710 tmp1 = gen_rtx_REG (mode, CC_REGNUM);
080c0b9a 8711
2df9477b 8712 operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, tmp1, const0_rtx);
8713 if (mode == CCFPmode || mode == CCFPEmode)
8714 rc = reverse_condition_maybe_unordered (rc);
8715 else
8716 rc = reverse_condition (rc);
8717 operands[4] = gen_rtx_fmt_ee (rc, VOIDmode, tmp1, const0_rtx);
1b7da4ac 8718}
8719 [(set_attr "type" "multiple")]
8720)
9c08d1fa 8721
080c0b9a 8722;; Attempt to improve the sequence generated by the compare_scc splitters
8723;; not to use conditional execution.
98562479 8724
8725;; Rd = (eq (reg1) (const_int0)) // ARMv5
8726;; clz Rd, reg1
8727;; lsr Rd, Rd, #5
080c0b9a 8728(define_peephole2
8729 [(set (reg:CC CC_REGNUM)
8730 (compare:CC (match_operand:SI 1 "register_operand" "")
98562479 8731 (const_int 0)))
8732 (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
8733 (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
8734 (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
8735 (set (match_dup 0) (const_int 1)))]
8736 "arm_arch5 && TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)"
8737 [(set (match_dup 0) (clz:SI (match_dup 1)))
8738 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 5)))]
8739)
8740
8741;; Rd = (eq (reg1) (const_int0)) // !ARMv5
8742;; negs Rd, reg1
8743;; adc Rd, Rd, reg1
8744(define_peephole2
8745 [(set (reg:CC CC_REGNUM)
8746 (compare:CC (match_operand:SI 1 "register_operand" "")
8747 (const_int 0)))
080c0b9a 8748 (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
8749 (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
8750 (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
8751 (set (match_dup 0) (const_int 1)))
98562479 8752 (match_scratch:SI 2 "r")]
8753 "TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)"
922b6913 8754 [(parallel
8755 [(set (reg:CC CC_REGNUM)
98562479 8756 (compare:CC (const_int 0) (match_dup 1)))
8757 (set (match_dup 2) (minus:SI (const_int 0) (match_dup 1)))])
8758 (set (match_dup 0)
8759 (plus:SI (plus:SI (match_dup 1) (match_dup 2))
8760 (geu:SI (reg:CC CC_REGNUM) (const_int 0))))]
8761)
8762
31991287 8763;; Rd = (eq (reg1) (reg2/imm)) // ARMv5 and optimising for speed.
98562479 8764;; sub Rd, Reg1, reg2
8765;; clz Rd, Rd
8766;; lsr Rd, Rd, #5
8767(define_peephole2
8768 [(set (reg:CC CC_REGNUM)
8769 (compare:CC (match_operand:SI 1 "register_operand" "")
8770 (match_operand:SI 2 "arm_rhs_operand" "")))
8771 (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
8772 (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
8773 (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
8774 (set (match_dup 0) (const_int 1)))]
31991287 8775 "arm_arch5 && TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)
8776 && !(TARGET_THUMB2 && optimize_insn_for_size_p ())"
98562479 8777 [(set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))
8778 (set (match_dup 0) (clz:SI (match_dup 0)))
8779 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 5)))]
8780)
8781
8782
31991287 8783;; Rd = (eq (reg1) (reg2)) // ! ARMv5 or optimising for size.
98562479 8784;; sub T1, Reg1, reg2
8785;; negs Rd, T1
8786;; adc Rd, Rd, T1
8787(define_peephole2
8788 [(set (reg:CC CC_REGNUM)
8789 (compare:CC (match_operand:SI 1 "register_operand" "")
8790 (match_operand:SI 2 "arm_rhs_operand" "")))
8791 (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
8792 (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
8793 (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
8794 (set (match_dup 0) (const_int 1)))
8795 (match_scratch:SI 3 "r")]
8796 "TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)"
31991287 8797 [(set (match_dup 3) (match_dup 4))
080c0b9a 8798 (parallel
8799 [(set (reg:CC CC_REGNUM)
8800 (compare:CC (const_int 0) (match_dup 3)))
8801 (set (match_dup 0) (minus:SI (const_int 0) (match_dup 3)))])
98562479 8802 (set (match_dup 0)
8803 (plus:SI (plus:SI (match_dup 0) (match_dup 3))
8804 (geu:SI (reg:CC CC_REGNUM) (const_int 0))))]
31991287 8805 "
8806 if (CONST_INT_P (operands[2]))
8807 operands[4] = plus_constant (SImode, operands[1], -INTVAL (operands[2]));
8808 else
8809 operands[4] = gen_rtx_MINUS (SImode, operands[1], operands[2]);
8810 ")
080c0b9a 8811
f7fbdd4a 8812(define_insn "*cond_move"
9c08d1fa 8813 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
aea4c774 8814 (if_then_else:SI (match_operator 3 "equality_operator"
8fa3ba89 8815 [(match_operator 4 "arm_comparison_operator"
8a18b90c 8816 [(match_operand 5 "cc_register" "") (const_int 0)])
aea4c774 8817 (const_int 0)])
8818 (match_operand:SI 1 "arm_rhs_operand" "0,rI,?rI")
8819 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))]
cffb2a26 8820 "TARGET_ARM"
9c08d1fa 8821 "*
8fa3ba89 8822 if (GET_CODE (operands[3]) == NE)
8823 {
8824 if (which_alternative != 1)
8825 output_asm_insn (\"mov%D4\\t%0, %2\", operands);
8826 if (which_alternative != 0)
8827 output_asm_insn (\"mov%d4\\t%0, %1\", operands);
8828 return \"\";
8829 }
8830 if (which_alternative != 0)
8831 output_asm_insn (\"mov%D4\\t%0, %1\", operands);
8832 if (which_alternative != 1)
8833 output_asm_insn (\"mov%d4\\t%0, %2\", operands);
8834 return \"\";
8835 "
8836 [(set_attr "conds" "use")
282b4c75 8837 (set_attr_alternative "type"
8838 [(if_then_else (match_operand 2 "const_int_operand" "")
8839 (const_string "mov_imm")
8840 (const_string "mov_reg"))
8841 (if_then_else (match_operand 1 "const_int_operand" "")
8842 (const_string "mov_imm")
8843 (const_string "mov_reg"))
8844 (const_string "multiple")])
8fa3ba89 8845 (set_attr "length" "4,4,8")]
8846)
9c08d1fa 8847
f7fbdd4a 8848(define_insn "*cond_arith"
9c08d1fa 8849 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8850 (match_operator:SI 5 "shiftable_operator"
8fa3ba89 8851 [(match_operator:SI 4 "arm_comparison_operator"
9c08d1fa 8852 [(match_operand:SI 2 "s_register_operand" "r,r")
8853 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
8854 (match_operand:SI 1 "s_register_operand" "0,?r")]))
bd5b4116 8855 (clobber (reg:CC CC_REGNUM))]
cffb2a26 8856 "TARGET_ARM"
9c08d1fa 8857 "*
8fa3ba89 8858 if (GET_CODE (operands[4]) == LT && operands[3] == const0_rtx)
8859 return \"%i5\\t%0, %1, %2, lsr #31\";
40dbec34 8860
8fa3ba89 8861 output_asm_insn (\"cmp\\t%2, %3\", operands);
8862 if (GET_CODE (operands[5]) == AND)
8863 output_asm_insn (\"mov%D4\\t%0, #0\", operands);
8864 else if (GET_CODE (operands[5]) == MINUS)
8865 output_asm_insn (\"rsb%D4\\t%0, %1, #0\", operands);
8866 else if (which_alternative != 0)
8867 output_asm_insn (\"mov%D4\\t%0, %1\", operands);
8868 return \"%i5%d4\\t%0, %1, #1\";
8869 "
8870 [(set_attr "conds" "clob")
1b7da4ac 8871 (set_attr "length" "12")
8872 (set_attr "type" "multiple")]
8fa3ba89 8873)
9c08d1fa 8874
f7fbdd4a 8875(define_insn "*cond_sub"
9c08d1fa 8876 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8877 (minus:SI (match_operand:SI 1 "s_register_operand" "0,?r")
8fa3ba89 8878 (match_operator:SI 4 "arm_comparison_operator"
9c08d1fa 8879 [(match_operand:SI 2 "s_register_operand" "r,r")
8880 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))
bd5b4116 8881 (clobber (reg:CC CC_REGNUM))]
cffb2a26 8882 "TARGET_ARM"
9c08d1fa 8883 "*
8fa3ba89 8884 output_asm_insn (\"cmp\\t%2, %3\", operands);
8885 if (which_alternative != 0)
8886 output_asm_insn (\"mov%D4\\t%0, %1\", operands);
8887 return \"sub%d4\\t%0, %1, #1\";
8888 "
8889 [(set_attr "conds" "clob")
1b7da4ac 8890 (set_attr "length" "8,12")
8891 (set_attr "type" "multiple")]
8fa3ba89 8892)
9c08d1fa 8893
aea4c774 8894(define_insn "*cmp_ite0"
cffb2a26 8895 [(set (match_operand 6 "dominant_cc_register" "")
aea4c774 8896 (compare
8897 (if_then_else:SI
8fa3ba89 8898 (match_operator 4 "arm_comparison_operator"
2ff91fec 8899 [(match_operand:SI 0 "s_register_operand"
8900 "l,l,l,r,r,r,r,r,r")
8901 (match_operand:SI 1 "arm_add_operand"
8902 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
8fa3ba89 8903 (match_operator:SI 5 "arm_comparison_operator"
2ff91fec 8904 [(match_operand:SI 2 "s_register_operand"
8905 "l,r,r,l,l,r,r,r,r")
8906 (match_operand:SI 3 "arm_add_operand"
8907 "lPy,rI,L,lPy,lPy,rI,rI,L,L")])
aea4c774 8908 (const_int 0))
8909 (const_int 0)))]
2ff91fec 8910 "TARGET_32BIT"
9c08d1fa 8911 "*
aea4c774 8912 {
2ff91fec 8913 static const char * const cmp1[NUM_OF_COND_CMP][2] =
8914 {
8915 {\"cmp%d5\\t%0, %1\",
8916 \"cmp%d4\\t%2, %3\"},
8917 {\"cmn%d5\\t%0, #%n1\",
8918 \"cmp%d4\\t%2, %3\"},
8919 {\"cmp%d5\\t%0, %1\",
8920 \"cmn%d4\\t%2, #%n3\"},
8921 {\"cmn%d5\\t%0, #%n1\",
8922 \"cmn%d4\\t%2, #%n3\"}
8923 };
8924 static const char * const cmp2[NUM_OF_COND_CMP][2] =
8925 {
8926 {\"cmp\\t%2, %3\",
8927 \"cmp\\t%0, %1\"},
8928 {\"cmp\\t%2, %3\",
8929 \"cmn\\t%0, #%n1\"},
8930 {\"cmn\\t%2, #%n3\",
8931 \"cmp\\t%0, %1\"},
8932 {\"cmn\\t%2, #%n3\",
8933 \"cmn\\t%0, #%n1\"}
8934 };
8935 static const char * const ite[2] =
8fa3ba89 8936 {
2ff91fec 8937 \"it\\t%d5\",
8938 \"it\\t%d4\"
8fa3ba89 8939 };
2ff91fec 8940 static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
8941 CMP_CMP, CMN_CMP, CMP_CMP,
8942 CMN_CMP, CMP_CMN, CMN_CMN};
8fa3ba89 8943 int swap =
8944 comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4]));
8945
2ff91fec 8946 output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
8947 if (TARGET_THUMB2) {
8948 output_asm_insn (ite[swap], operands);
8949 }
8950 output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
8951 return \"\";
8fa3ba89 8952 }"
8953 [(set_attr "conds" "set")
2ff91fec 8954 (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
1b7da4ac 8955 (set_attr "type" "multiple")
2ff91fec 8956 (set_attr_alternative "length"
8957 [(const_int 6)
8958 (const_int 8)
8959 (const_int 8)
8960 (const_int 8)
8961 (const_int 8)
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))
8971 (if_then_else (eq_attr "is_thumb" "no")
8972 (const_int 8)
8973 (const_int 10))])]
8fa3ba89 8974)
9c08d1fa 8975
aea4c774 8976(define_insn "*cmp_ite1"
cffb2a26 8977 [(set (match_operand 6 "dominant_cc_register" "")
aea4c774 8978 (compare
8979 (if_then_else:SI
8fa3ba89 8980 (match_operator 4 "arm_comparison_operator"
2ff91fec 8981 [(match_operand:SI 0 "s_register_operand"
8982 "l,l,l,r,r,r,r,r,r")
8983 (match_operand:SI 1 "arm_add_operand"
8984 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
8fa3ba89 8985 (match_operator:SI 5 "arm_comparison_operator"
2ff91fec 8986 [(match_operand:SI 2 "s_register_operand"
8987 "l,r,r,l,l,r,r,r,r")
8988 (match_operand:SI 3 "arm_add_operand"
8989 "lPy,rI,L,lPy,lPy,rI,rI,L,L")])
aea4c774 8990 (const_int 1))
8991 (const_int 0)))]
2ff91fec 8992 "TARGET_32BIT"
9c08d1fa 8993 "*
9c08d1fa 8994 {
2ff91fec 8995 static const char * const cmp1[NUM_OF_COND_CMP][2] =
8996 {
8997 {\"cmp\\t%0, %1\",
8998 \"cmp\\t%2, %3\"},
8999 {\"cmn\\t%0, #%n1\",
9000 \"cmp\\t%2, %3\"},
9001 {\"cmp\\t%0, %1\",
9002 \"cmn\\t%2, #%n3\"},
9003 {\"cmn\\t%0, #%n1\",
9004 \"cmn\\t%2, #%n3\"}
9005 };
9006 static const char * const cmp2[NUM_OF_COND_CMP][2] =
215b30b3 9007 {
2ff91fec 9008 {\"cmp%d4\\t%2, %3\",
9009 \"cmp%D5\\t%0, %1\"},
9010 {\"cmp%d4\\t%2, %3\",
9011 \"cmn%D5\\t%0, #%n1\"},
9012 {\"cmn%d4\\t%2, #%n3\",
9013 \"cmp%D5\\t%0, %1\"},
9014 {\"cmn%d4\\t%2, #%n3\",
9015 \"cmn%D5\\t%0, #%n1\"}
215b30b3 9016 };
2ff91fec 9017 static const char * const ite[2] =
9018 {
9019 \"it\\t%d4\",
9020 \"it\\t%D5\"
9021 };
9022 static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
9023 CMP_CMP, CMN_CMP, CMP_CMP,
9024 CMN_CMP, CMP_CMN, CMN_CMN};
215b30b3 9025 int swap =
9026 comparison_dominates_p (GET_CODE (operands[5]),
9027 reverse_condition (GET_CODE (operands[4])));
9028
2ff91fec 9029 output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
9030 if (TARGET_THUMB2) {
9031 output_asm_insn (ite[swap], operands);
9032 }
9033 output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
9034 return \"\";
215b30b3 9035 }"
8fa3ba89 9036 [(set_attr "conds" "set")
2ff91fec 9037 (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
9038 (set_attr_alternative "length"
9039 [(const_int 6)
9040 (const_int 8)
9041 (const_int 8)
9042 (const_int 8)
9043 (const_int 8)
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)
9052 (const_int 10))
9053 (if_then_else (eq_attr "is_thumb" "no")
9054 (const_int 8)
1b7da4ac 9055 (const_int 10))])
9056 (set_attr "type" "multiple")]
8fa3ba89 9057)
9c08d1fa 9058
f6c53574 9059(define_insn "*cmp_and"
9060 [(set (match_operand 6 "dominant_cc_register" "")
9061 (compare
9062 (and:SI
9063 (match_operator 4 "arm_comparison_operator"
2ff91fec 9064 [(match_operand:SI 0 "s_register_operand"
9065 "l,l,l,r,r,r,r,r,r")
9066 (match_operand:SI 1 "arm_add_operand"
9067 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
f6c53574 9068 (match_operator:SI 5 "arm_comparison_operator"
2ff91fec 9069 [(match_operand:SI 2 "s_register_operand"
9070 "l,r,r,l,l,r,r,r,r")
9071 (match_operand:SI 3 "arm_add_operand"
9072 "lPy,rI,L,lPy,lPy,rI,rI,L,L")]))
f6c53574 9073 (const_int 0)))]
2ff91fec 9074 "TARGET_32BIT"
f6c53574 9075 "*
9076 {
2ff91fec 9077 static const char *const cmp1[NUM_OF_COND_CMP][2] =
f6c53574 9078 {
2ff91fec 9079 {\"cmp%d5\\t%0, %1\",
9080 \"cmp%d4\\t%2, %3\"},
9081 {\"cmn%d5\\t%0, #%n1\",
9082 \"cmp%d4\\t%2, %3\"},
9083 {\"cmp%d5\\t%0, %1\",
9084 \"cmn%d4\\t%2, #%n3\"},
9085 {\"cmn%d5\\t%0, #%n1\",
9086 \"cmn%d4\\t%2, #%n3\"}
f6c53574 9087 };
2ff91fec 9088 static const char *const cmp2[NUM_OF_COND_CMP][2] =
9089 {
9090 {\"cmp\\t%2, %3\",
9091 \"cmp\\t%0, %1\"},
9092 {\"cmp\\t%2, %3\",
9093 \"cmn\\t%0, #%n1\"},
9094 {\"cmn\\t%2, #%n3\",
9095 \"cmp\\t%0, %1\"},
9096 {\"cmn\\t%2, #%n3\",
9097 \"cmn\\t%0, #%n1\"}
9098 };
9099 static const char *const ite[2] =
9100 {
9101 \"it\\t%d5\",
9102 \"it\\t%d4\"
9103 };
9104 static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
9105 CMP_CMP, CMN_CMP, CMP_CMP,
9106 CMN_CMP, CMP_CMN, CMN_CMN};
f6c53574 9107 int swap =
9108 comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4]));
9109
2ff91fec 9110 output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
9111 if (TARGET_THUMB2) {
9112 output_asm_insn (ite[swap], operands);
9113 }
9114 output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
9115 return \"\";
f6c53574 9116 }"
9117 [(set_attr "conds" "set")
9118 (set_attr "predicable" "no")
2ff91fec 9119 (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
9120 (set_attr_alternative "length"
9121 [(const_int 6)
9122 (const_int 8)
9123 (const_int 8)
9124 (const_int 8)
9125 (const_int 8)
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)
9134 (const_int 10))
9135 (if_then_else (eq_attr "is_thumb" "no")
9136 (const_int 8)
1b7da4ac 9137 (const_int 10))])
9138 (set_attr "type" "multiple")]
f6c53574 9139)
9140
9141(define_insn "*cmp_ior"
9142 [(set (match_operand 6 "dominant_cc_register" "")
9143 (compare
9144 (ior:SI
9145 (match_operator 4 "arm_comparison_operator"
2ff91fec 9146 [(match_operand:SI 0 "s_register_operand"
9147 "l,l,l,r,r,r,r,r,r")
9148 (match_operand:SI 1 "arm_add_operand"
9149 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
f6c53574 9150 (match_operator:SI 5 "arm_comparison_operator"
2ff91fec 9151 [(match_operand:SI 2 "s_register_operand"
9152 "l,r,r,l,l,r,r,r,r")
9153 (match_operand:SI 3 "arm_add_operand"
9154 "lPy,rI,L,lPy,lPy,rI,rI,L,L")]))
f6c53574 9155 (const_int 0)))]
2ff91fec 9156 "TARGET_32BIT"
f6c53574 9157 "*
f6c53574 9158 {
2ff91fec 9159 static const char *const cmp1[NUM_OF_COND_CMP][2] =
9160 {
9161 {\"cmp\\t%0, %1\",
9162 \"cmp\\t%2, %3\"},
9163 {\"cmn\\t%0, #%n1\",
9164 \"cmp\\t%2, %3\"},
9165 {\"cmp\\t%0, %1\",
9166 \"cmn\\t%2, #%n3\"},
9167 {\"cmn\\t%0, #%n1\",
9168 \"cmn\\t%2, #%n3\"}
9169 };
9170 static const char *const cmp2[NUM_OF_COND_CMP][2] =
9171 {
9172 {\"cmp%D4\\t%2, %3\",
9173 \"cmp%D5\\t%0, %1\"},
9174 {\"cmp%D4\\t%2, %3\",
9175 \"cmn%D5\\t%0, #%n1\"},
9176 {\"cmn%D4\\t%2, #%n3\",
9177 \"cmp%D5\\t%0, %1\"},
9178 {\"cmn%D4\\t%2, #%n3\",
9179 \"cmn%D5\\t%0, #%n1\"}
9180 };
9181 static const char *const ite[2] =
9182 {
9183 \"it\\t%D4\",
9184 \"it\\t%D5\"
9185 };
9186 static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
9187 CMP_CMP, CMN_CMP, CMP_CMP,
9188 CMN_CMP, CMP_CMN, CMN_CMN};
9189 int swap =
9190 comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4]));
9191
9192 output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
9193 if (TARGET_THUMB2) {
9194 output_asm_insn (ite[swap], operands);
9195 }
9196 output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
9197 return \"\";
9198 }
9199 "
f6c53574 9200 [(set_attr "conds" "set")
2ff91fec 9201 (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
9202 (set_attr_alternative "length"
9203 [(const_int 6)
9204 (const_int 8)
9205 (const_int 8)
9206 (const_int 8)
9207 (const_int 8)
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)
9216 (const_int 10))
9217 (if_then_else (eq_attr "is_thumb" "no")
9218 (const_int 8)
1b7da4ac 9219 (const_int 10))])
9220 (set_attr "type" "multiple")]
f6c53574 9221)
9222
3c5afce6 9223(define_insn_and_split "*ior_scc_scc"
fd711051 9224 [(set (match_operand:SI 0 "s_register_operand" "=Ts")
3c5afce6 9225 (ior:SI (match_operator:SI 3 "arm_comparison_operator"
9226 [(match_operand:SI 1 "s_register_operand" "r")
9227 (match_operand:SI 2 "arm_add_operand" "rIL")])
9228 (match_operator:SI 6 "arm_comparison_operator"
9229 [(match_operand:SI 4 "s_register_operand" "r")
9230 (match_operand:SI 5 "arm_add_operand" "rIL")])))
9231 (clobber (reg:CC CC_REGNUM))]
2ff91fec 9232 "TARGET_32BIT
3c5afce6 9233 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_OR_Y)
9234 != CCmode)"
9235 "#"
2ff91fec 9236 "TARGET_32BIT && reload_completed"
3c5afce6 9237 [(set (match_dup 7)
9238 (compare
9239 (ior:SI
9240 (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9241 (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9242 (const_int 0)))
9243 (set (match_dup 0) (ne:SI (match_dup 7) (const_int 0)))]
9244 "operands[7]
9245 = gen_rtx_REG (arm_select_dominance_cc_mode (operands[3], operands[6],
9246 DOM_CC_X_OR_Y),
601f584c 9247 CC_REGNUM);"
9248 [(set_attr "conds" "clob")
1b7da4ac 9249 (set_attr "length" "16")
9250 (set_attr "type" "multiple")]
9251)
601f584c 9252
9253; If the above pattern is followed by a CMP insn, then the compare is
9254; redundant, since we can rework the conditional instruction that follows.
9255(define_insn_and_split "*ior_scc_scc_cmp"
9256 [(set (match_operand 0 "dominant_cc_register" "")
9257 (compare (ior:SI (match_operator:SI 3 "arm_comparison_operator"
9258 [(match_operand:SI 1 "s_register_operand" "r")
9259 (match_operand:SI 2 "arm_add_operand" "rIL")])
9260 (match_operator:SI 6 "arm_comparison_operator"
9261 [(match_operand:SI 4 "s_register_operand" "r")
9262 (match_operand:SI 5 "arm_add_operand" "rIL")]))
9263 (const_int 0)))
fd711051 9264 (set (match_operand:SI 7 "s_register_operand" "=Ts")
601f584c 9265 (ior:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9266 (match_op_dup 6 [(match_dup 4) (match_dup 5)])))]
2ff91fec 9267 "TARGET_32BIT"
601f584c 9268 "#"
2ff91fec 9269 "TARGET_32BIT && reload_completed"
601f584c 9270 [(set (match_dup 0)
9271 (compare
9272 (ior:SI
9273 (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9274 (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9275 (const_int 0)))
9276 (set (match_dup 7) (ne:SI (match_dup 0) (const_int 0)))]
9277 ""
9278 [(set_attr "conds" "set")
1b7da4ac 9279 (set_attr "length" "16")
9280 (set_attr "type" "multiple")]
9281)
3c5afce6 9282
9283(define_insn_and_split "*and_scc_scc"
fd711051 9284 [(set (match_operand:SI 0 "s_register_operand" "=Ts")
3c5afce6 9285 (and:SI (match_operator:SI 3 "arm_comparison_operator"
9286 [(match_operand:SI 1 "s_register_operand" "r")
9287 (match_operand:SI 2 "arm_add_operand" "rIL")])
9288 (match_operator:SI 6 "arm_comparison_operator"
9289 [(match_operand:SI 4 "s_register_operand" "r")
9290 (match_operand:SI 5 "arm_add_operand" "rIL")])))
9291 (clobber (reg:CC CC_REGNUM))]
2ff91fec 9292 "TARGET_32BIT
3c5afce6 9293 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y)
9294 != CCmode)"
9295 "#"
2ff91fec 9296 "TARGET_32BIT && reload_completed
601f584c 9297 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y)
9298 != CCmode)"
3c5afce6 9299 [(set (match_dup 7)
9300 (compare
9301 (and:SI
9302 (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9303 (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9304 (const_int 0)))
9305 (set (match_dup 0) (ne:SI (match_dup 7) (const_int 0)))]
9306 "operands[7]
9307 = gen_rtx_REG (arm_select_dominance_cc_mode (operands[3], operands[6],
9308 DOM_CC_X_AND_Y),
601f584c 9309 CC_REGNUM);"
9310 [(set_attr "conds" "clob")
1b7da4ac 9311 (set_attr "length" "16")
9312 (set_attr "type" "multiple")]
9313)
601f584c 9314
9315; If the above pattern is followed by a CMP insn, then the compare is
9316; redundant, since we can rework the conditional instruction that follows.
9317(define_insn_and_split "*and_scc_scc_cmp"
9318 [(set (match_operand 0 "dominant_cc_register" "")
9319 (compare (and:SI (match_operator:SI 3 "arm_comparison_operator"
9320 [(match_operand:SI 1 "s_register_operand" "r")
9321 (match_operand:SI 2 "arm_add_operand" "rIL")])
9322 (match_operator:SI 6 "arm_comparison_operator"
9323 [(match_operand:SI 4 "s_register_operand" "r")
9324 (match_operand:SI 5 "arm_add_operand" "rIL")]))
9325 (const_int 0)))
fd711051 9326 (set (match_operand:SI 7 "s_register_operand" "=Ts")
601f584c 9327 (and:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9328 (match_op_dup 6 [(match_dup 4) (match_dup 5)])))]
2ff91fec 9329 "TARGET_32BIT"
601f584c 9330 "#"
2ff91fec 9331 "TARGET_32BIT && reload_completed"
601f584c 9332 [(set (match_dup 0)
9333 (compare
9334 (and:SI
9335 (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9336 (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9337 (const_int 0)))
9338 (set (match_dup 7) (ne:SI (match_dup 0) (const_int 0)))]
9339 ""
9340 [(set_attr "conds" "set")
1b7da4ac 9341 (set_attr "length" "16")
9342 (set_attr "type" "multiple")]
9343)
601f584c 9344
9345;; If there is no dominance in the comparison, then we can still save an
9346;; instruction in the AND case, since we can know that the second compare
9347;; need only zero the value if false (if true, then the value is already
9348;; correct).
9349(define_insn_and_split "*and_scc_scc_nodom"
fd711051 9350 [(set (match_operand:SI 0 "s_register_operand" "=&Ts,&Ts,&Ts")
601f584c 9351 (and:SI (match_operator:SI 3 "arm_comparison_operator"
9352 [(match_operand:SI 1 "s_register_operand" "r,r,0")
9353 (match_operand:SI 2 "arm_add_operand" "rIL,0,rIL")])
9354 (match_operator:SI 6 "arm_comparison_operator"
9355 [(match_operand:SI 4 "s_register_operand" "r,r,r")
9356 (match_operand:SI 5 "arm_add_operand" "rIL,rIL,rIL")])))
9357 (clobber (reg:CC CC_REGNUM))]
2ff91fec 9358 "TARGET_32BIT
601f584c 9359 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y)
9360 == CCmode)"
9361 "#"
2ff91fec 9362 "TARGET_32BIT && reload_completed"
601f584c 9363 [(parallel [(set (match_dup 0)
9364 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
9365 (clobber (reg:CC CC_REGNUM))])
9366 (set (match_dup 7) (match_op_dup 8 [(match_dup 4) (match_dup 5)]))
9367 (set (match_dup 0)
9368 (if_then_else:SI (match_op_dup 6 [(match_dup 7) (const_int 0)])
9369 (match_dup 0)
9370 (const_int 0)))]
9371 "operands[7] = gen_rtx_REG (SELECT_CC_MODE (GET_CODE (operands[6]),
9372 operands[4], operands[5]),
9373 CC_REGNUM);
9374 operands[8] = gen_rtx_COMPARE (GET_MODE (operands[7]), operands[4],
9375 operands[5]);"
9376 [(set_attr "conds" "clob")
1b7da4ac 9377 (set_attr "length" "20")
9378 (set_attr "type" "multiple")]
9379)
3c5afce6 9380
3a0bdee0 9381(define_split
9382 [(set (reg:CC_NOOV CC_REGNUM)
9383 (compare:CC_NOOV (ior:SI
9384 (and:SI (match_operand:SI 0 "s_register_operand" "")
9385 (const_int 1))
b0694be0 9386 (match_operator:SI 1 "arm_comparison_operator"
3a0bdee0 9387 [(match_operand:SI 2 "s_register_operand" "")
9388 (match_operand:SI 3 "arm_add_operand" "")]))
9389 (const_int 0)))
9390 (clobber (match_operand:SI 4 "s_register_operand" ""))]
9391 "TARGET_ARM"
9392 [(set (match_dup 4)
9393 (ior:SI (match_op_dup 1 [(match_dup 2) (match_dup 3)])
9394 (match_dup 0)))
9395 (set (reg:CC_NOOV CC_REGNUM)
9396 (compare:CC_NOOV (and:SI (match_dup 4) (const_int 1))
9397 (const_int 0)))]
9398 "")
9399
9400(define_split
9401 [(set (reg:CC_NOOV CC_REGNUM)
9402 (compare:CC_NOOV (ior:SI
b0694be0 9403 (match_operator:SI 1 "arm_comparison_operator"
3a0bdee0 9404 [(match_operand:SI 2 "s_register_operand" "")
9405 (match_operand:SI 3 "arm_add_operand" "")])
9406 (and:SI (match_operand:SI 0 "s_register_operand" "")
9407 (const_int 1)))
9408 (const_int 0)))
9409 (clobber (match_operand:SI 4 "s_register_operand" ""))]
9410 "TARGET_ARM"
9411 [(set (match_dup 4)
9412 (ior:SI (match_op_dup 1 [(match_dup 2) (match_dup 3)])
9413 (match_dup 0)))
9414 (set (reg:CC_NOOV CC_REGNUM)
9415 (compare:CC_NOOV (and:SI (match_dup 4) (const_int 1))
9416 (const_int 0)))]
9417 "")
25f905c2 9418;; ??? The conditional patterns above need checking for Thumb-2 usefulness
3a0bdee0 9419
190efb17 9420(define_insn_and_split "*negscc"
9c08d1fa 9421 [(set (match_operand:SI 0 "s_register_operand" "=r")
8fa3ba89 9422 (neg:SI (match_operator 3 "arm_comparison_operator"
9c08d1fa 9423 [(match_operand:SI 1 "s_register_operand" "r")
9424 (match_operand:SI 2 "arm_rhs_operand" "rI")])))
bd5b4116 9425 (clobber (reg:CC CC_REGNUM))]
cffb2a26 9426 "TARGET_ARM"
190efb17 9427 "#"
9428 "&& reload_completed"
9429 [(const_int 0)]
9430 {
9431 rtx cc_reg = gen_rtx_REG (CCmode, CC_REGNUM);
e2348bcb 9432
190efb17 9433 if (GET_CODE (operands[3]) == LT && operands[2] == const0_rtx)
9434 {
9435 /* Emit mov\\t%0, %1, asr #31 */
d1f9b275 9436 emit_insn (gen_rtx_SET (operands[0],
190efb17 9437 gen_rtx_ASHIFTRT (SImode,
9438 operands[1],
9439 GEN_INT (31))));
9440 DONE;
9441 }
9442 else if (GET_CODE (operands[3]) == NE)
9443 {
9444 /* Emit subs\\t%0, %1, %2\;mvnne\\t%0, #0 */
9445 if (CONST_INT_P (operands[2]))
9446 emit_insn (gen_cmpsi2_addneg (operands[0], operands[1], operands[2],
9447 GEN_INT (- INTVAL (operands[2]))));
9448 else
9449 emit_insn (gen_subsi3_compare (operands[0], operands[1], operands[2]));
9450
9451 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
9452 gen_rtx_NE (SImode,
9453 cc_reg,
9454 const0_rtx),
d1f9b275 9455 gen_rtx_SET (operands[0],
190efb17 9456 GEN_INT (~0))));
9457 DONE;
9458 }
9459 else
9460 {
9461 /* Emit: cmp\\t%1, %2\;mov%D3\\t%0, #0\;mvn%d3\\t%0, #0 */
d1f9b275 9462 emit_insn (gen_rtx_SET (cc_reg,
190efb17 9463 gen_rtx_COMPARE (CCmode, operands[1], operands[2])));
9464 enum rtx_code rc = GET_CODE (operands[3]);
9465
9466 rc = reverse_condition (rc);
9467 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
9468 gen_rtx_fmt_ee (rc,
9469 VOIDmode,
9470 cc_reg,
9471 const0_rtx),
d1f9b275 9472 gen_rtx_SET (operands[0], const0_rtx)));
190efb17 9473 rc = GET_CODE (operands[3]);
9474 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
9475 gen_rtx_fmt_ee (rc,
9476 VOIDmode,
9477 cc_reg,
9478 const0_rtx),
d1f9b275 9479 gen_rtx_SET (operands[0],
190efb17 9480 GEN_INT (~0))));
9481 DONE;
9482 }
9483 FAIL;
9484 }
8fa3ba89 9485 [(set_attr "conds" "clob")
1b7da4ac 9486 (set_attr "length" "12")
9487 (set_attr "type" "multiple")]
8fa3ba89 9488)
9c08d1fa 9489
90404b57 9490(define_insn_and_split "movcond_addsi"
9491 [(set (match_operand:SI 0 "s_register_operand" "=r,l,r")
9492 (if_then_else:SI
9493 (match_operator 5 "comparison_operator"
9494 [(plus:SI (match_operand:SI 3 "s_register_operand" "r,r,r")
9495 (match_operand:SI 4 "arm_add_operand" "rIL,rIL,rIL"))
9496 (const_int 0)])
9497 (match_operand:SI 1 "arm_rhs_operand" "rI,rPy,r")
9498 (match_operand:SI 2 "arm_rhs_operand" "rI,rPy,r")))
9499 (clobber (reg:CC CC_REGNUM))]
9500 "TARGET_32BIT"
9501 "#"
9502 "&& reload_completed"
9503 [(set (reg:CC_NOOV CC_REGNUM)
9504 (compare:CC_NOOV
9505 (plus:SI (match_dup 3)
9506 (match_dup 4))
9507 (const_int 0)))
9508 (set (match_dup 0) (match_dup 1))
9509 (cond_exec (match_dup 6)
9510 (set (match_dup 0) (match_dup 2)))]
9511 "
9512 {
3754d046 9513 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[5]),
90404b57 9514 operands[3], operands[4]);
9515 enum rtx_code rc = GET_CODE (operands[5]);
90404b57 9516 operands[6] = gen_rtx_REG (mode, CC_REGNUM);
9517 gcc_assert (!(mode == CCFPmode || mode == CCFPEmode));
22440aeb 9518 if (!REG_P (operands[2]) || REGNO (operands[2]) != REGNO (operands[0]))
4d01ce2f 9519 rc = reverse_condition (rc);
f145bcba 9520 else
9521 std::swap (operands[1], operands[2]);
90404b57 9522
9523 operands[6] = gen_rtx_fmt_ee (rc, VOIDmode, operands[6], const0_rtx);
9524 }
9525 "
9526 [(set_attr "conds" "clob")
1b7da4ac 9527 (set_attr "enabled_for_depr_it" "no,yes,yes")
9528 (set_attr "type" "multiple")]
90404b57 9529)
9530
9c08d1fa 9531(define_insn "movcond"
9532 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
5565501b 9533 (if_then_else:SI
8fa3ba89 9534 (match_operator 5 "arm_comparison_operator"
5565501b 9535 [(match_operand:SI 3 "s_register_operand" "r,r,r")
9536 (match_operand:SI 4 "arm_add_operand" "rIL,rIL,rIL")])
9537 (match_operand:SI 1 "arm_rhs_operand" "0,rI,?rI")
9538 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
bd5b4116 9539 (clobber (reg:CC CC_REGNUM))]
cffb2a26 9540 "TARGET_ARM"
9c08d1fa 9541 "*
9542 if (GET_CODE (operands[5]) == LT
9543 && (operands[4] == const0_rtx))
9544 {
0438d37f 9545 if (which_alternative != 1 && REG_P (operands[1]))
9c08d1fa 9546 {
9c08d1fa 9547 if (operands[2] == const0_rtx)
e2348bcb 9548 return \"and\\t%0, %1, %3, asr #31\";
9549 return \"ands\\t%0, %1, %3, asr #32\;movcc\\t%0, %2\";
9c08d1fa 9550 }
0438d37f 9551 else if (which_alternative != 0 && REG_P (operands[2]))
9c08d1fa 9552 {
9c08d1fa 9553 if (operands[1] == const0_rtx)
e2348bcb 9554 return \"bic\\t%0, %2, %3, asr #31\";
9555 return \"bics\\t%0, %2, %3, asr #32\;movcs\\t%0, %1\";
9c08d1fa 9556 }
9557 /* The only case that falls through to here is when both ops 1 & 2
674a8f0b 9558 are constants. */
9c08d1fa 9559 }
e2348bcb 9560
9c08d1fa 9561 if (GET_CODE (operands[5]) == GE
9562 && (operands[4] == const0_rtx))
9563 {
0438d37f 9564 if (which_alternative != 1 && REG_P (operands[1]))
9c08d1fa 9565 {
9c08d1fa 9566 if (operands[2] == const0_rtx)
e2348bcb 9567 return \"bic\\t%0, %1, %3, asr #31\";
9568 return \"bics\\t%0, %1, %3, asr #32\;movcs\\t%0, %2\";
9c08d1fa 9569 }
0438d37f 9570 else if (which_alternative != 0 && REG_P (operands[2]))
9c08d1fa 9571 {
9c08d1fa 9572 if (operands[1] == const0_rtx)
e2348bcb 9573 return \"and\\t%0, %2, %3, asr #31\";
9574 return \"ands\\t%0, %2, %3, asr #32\;movcc\\t%0, %1\";
9c08d1fa 9575 }
9576 /* The only case that falls through to here is when both ops 1 & 2
674a8f0b 9577 are constants. */
9c08d1fa 9578 }
0438d37f 9579 if (CONST_INT_P (operands[4])
9c08d1fa 9580 && !const_ok_for_arm (INTVAL (operands[4])))
e2348bcb 9581 output_asm_insn (\"cmn\\t%3, #%n4\", operands);
9c08d1fa 9582 else
e2348bcb 9583 output_asm_insn (\"cmp\\t%3, %4\", operands);
9c08d1fa 9584 if (which_alternative != 0)
e2348bcb 9585 output_asm_insn (\"mov%d5\\t%0, %1\", operands);
9c08d1fa 9586 if (which_alternative != 1)
e2348bcb 9587 output_asm_insn (\"mov%D5\\t%0, %2\", operands);
9c08d1fa 9588 return \"\";
215b30b3 9589 "
8fa3ba89 9590 [(set_attr "conds" "clob")
1b7da4ac 9591 (set_attr "length" "8,8,12")
9592 (set_attr "type" "multiple")]
8fa3ba89 9593)
9c08d1fa 9594
25f905c2 9595;; ??? The patterns below need checking for Thumb-2 usefulness.
9596
8a18b90c 9597(define_insn "*ifcompare_plus_move"
9598 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8fa3ba89 9599 (if_then_else:SI (match_operator 6 "arm_comparison_operator"
8a18b90c 9600 [(match_operand:SI 4 "s_register_operand" "r,r")
9601 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
9602 (plus:SI
9603 (match_operand:SI 2 "s_register_operand" "r,r")
9604 (match_operand:SI 3 "arm_add_operand" "rIL,rIL"))
129a2fe4 9605 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))
bd5b4116 9606 (clobber (reg:CC CC_REGNUM))]
cffb2a26 9607 "TARGET_ARM"
8a18b90c 9608 "#"
8fa3ba89 9609 [(set_attr "conds" "clob")
1b7da4ac 9610 (set_attr "length" "8,12")
9611 (set_attr "type" "multiple")]
8fa3ba89 9612)
8a18b90c 9613
9614(define_insn "*if_plus_move"
129a2fe4 9615 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r")
8a18b90c 9616 (if_then_else:SI
8fa3ba89 9617 (match_operator 4 "arm_comparison_operator"
8a18b90c 9618 [(match_operand 5 "cc_register" "") (const_int 0)])
9619 (plus:SI
129a2fe4 9620 (match_operand:SI 2 "s_register_operand" "r,r,r,r")
9621 (match_operand:SI 3 "arm_add_operand" "rI,L,rI,L"))
9622 (match_operand:SI 1 "arm_rhs_operand" "0,0,?rI,?rI")))]
cffb2a26 9623 "TARGET_ARM"
8a18b90c 9624 "@
9625 add%d4\\t%0, %2, %3
9626 sub%d4\\t%0, %2, #%n3
9627 add%d4\\t%0, %2, %3\;mov%D4\\t%0, %1
129a2fe4 9628 sub%d4\\t%0, %2, #%n3\;mov%D4\\t%0, %1"
8fa3ba89 9629 [(set_attr "conds" "use")
9630 (set_attr "length" "4,4,8,8")
65f68e55 9631 (set_attr_alternative "type"
9632 [(if_then_else (match_operand 3 "const_int_operand" "")
d82e788e 9633 (const_string "alu_imm" )
112eda6f 9634 (const_string "alu_sreg"))
d82e788e 9635 (const_string "alu_imm")
282b4c75 9636 (const_string "multiple")
9637 (const_string "multiple")])]
8fa3ba89 9638)
8a18b90c 9639
9640(define_insn "*ifcompare_move_plus"
5565501b 9641 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8fa3ba89 9642 (if_then_else:SI (match_operator 6 "arm_comparison_operator"
8a18b90c 9643 [(match_operand:SI 4 "s_register_operand" "r,r")
9644 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
129a2fe4 9645 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
8a18b90c 9646 (plus:SI
9647 (match_operand:SI 2 "s_register_operand" "r,r")
9648 (match_operand:SI 3 "arm_add_operand" "rIL,rIL"))))
bd5b4116 9649 (clobber (reg:CC CC_REGNUM))]
cffb2a26 9650 "TARGET_ARM"
8a18b90c 9651 "#"
8fa3ba89 9652 [(set_attr "conds" "clob")
1b7da4ac 9653 (set_attr "length" "8,12")
9654 (set_attr "type" "multiple")]
8fa3ba89 9655)
8a18b90c 9656
9657(define_insn "*if_move_plus"
129a2fe4 9658 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r")
8a18b90c 9659 (if_then_else:SI
8fa3ba89 9660 (match_operator 4 "arm_comparison_operator"
8a18b90c 9661 [(match_operand 5 "cc_register" "") (const_int 0)])
129a2fe4 9662 (match_operand:SI 1 "arm_rhs_operand" "0,0,?rI,?rI")
8a18b90c 9663 (plus:SI
129a2fe4 9664 (match_operand:SI 2 "s_register_operand" "r,r,r,r")
9665 (match_operand:SI 3 "arm_add_operand" "rI,L,rI,L"))))]
cffb2a26 9666 "TARGET_ARM"
8a18b90c 9667 "@
9668 add%D4\\t%0, %2, %3
9669 sub%D4\\t%0, %2, #%n3
9670 add%D4\\t%0, %2, %3\;mov%d4\\t%0, %1
129a2fe4 9671 sub%D4\\t%0, %2, #%n3\;mov%d4\\t%0, %1"
8fa3ba89 9672 [(set_attr "conds" "use")
9673 (set_attr "length" "4,4,8,8")
282b4c75 9674 (set_attr_alternative "type"
9675 [(if_then_else (match_operand 3 "const_int_operand" "")
9676 (const_string "alu_imm" )
9677 (const_string "alu_sreg"))
9678 (const_string "alu_imm")
9679 (const_string "multiple")
9680 (const_string "multiple")])]
8fa3ba89 9681)
8a18b90c 9682
9683(define_insn "*ifcompare_arith_arith"
9684 [(set (match_operand:SI 0 "s_register_operand" "=r")
8fa3ba89 9685 (if_then_else:SI (match_operator 9 "arm_comparison_operator"
8a18b90c 9686 [(match_operand:SI 5 "s_register_operand" "r")
9687 (match_operand:SI 6 "arm_add_operand" "rIL")])
9c08d1fa 9688 (match_operator:SI 8 "shiftable_operator"
8a18b90c 9689 [(match_operand:SI 1 "s_register_operand" "r")
9690 (match_operand:SI 2 "arm_rhs_operand" "rI")])
9c08d1fa 9691 (match_operator:SI 7 "shiftable_operator"
8a18b90c 9692 [(match_operand:SI 3 "s_register_operand" "r")
9693 (match_operand:SI 4 "arm_rhs_operand" "rI")])))
bd5b4116 9694 (clobber (reg:CC CC_REGNUM))]
cffb2a26 9695 "TARGET_ARM"
8a18b90c 9696 "#"
8fa3ba89 9697 [(set_attr "conds" "clob")
1b7da4ac 9698 (set_attr "length" "12")
9699 (set_attr "type" "multiple")]
8fa3ba89 9700)
9c08d1fa 9701
8a18b90c 9702(define_insn "*if_arith_arith"
9703 [(set (match_operand:SI 0 "s_register_operand" "=r")
8fa3ba89 9704 (if_then_else:SI (match_operator 5 "arm_comparison_operator"
8a18b90c 9705 [(match_operand 8 "cc_register" "") (const_int 0)])
9706 (match_operator:SI 6 "shiftable_operator"
9707 [(match_operand:SI 1 "s_register_operand" "r")
9708 (match_operand:SI 2 "arm_rhs_operand" "rI")])
9709 (match_operator:SI 7 "shiftable_operator"
9710 [(match_operand:SI 3 "s_register_operand" "r")
9711 (match_operand:SI 4 "arm_rhs_operand" "rI")])))]
cffb2a26 9712 "TARGET_ARM"
8a18b90c 9713 "%I6%d5\\t%0, %1, %2\;%I7%D5\\t%0, %3, %4"
8fa3ba89 9714 [(set_attr "conds" "use")
1b7da4ac 9715 (set_attr "length" "8")
9716 (set_attr "type" "multiple")]
8fa3ba89 9717)
8a18b90c 9718
f7fbdd4a 9719(define_insn "*ifcompare_arith_move"
9c08d1fa 9720 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8fa3ba89 9721 (if_then_else:SI (match_operator 6 "arm_comparison_operator"
9c08d1fa 9722 [(match_operand:SI 2 "s_register_operand" "r,r")
5565501b 9723 (match_operand:SI 3 "arm_add_operand" "rIL,rIL")])
9c08d1fa 9724 (match_operator:SI 7 "shiftable_operator"
9725 [(match_operand:SI 4 "s_register_operand" "r,r")
9726 (match_operand:SI 5 "arm_rhs_operand" "rI,rI")])
129a2fe4 9727 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))
bd5b4116 9728 (clobber (reg:CC CC_REGNUM))]
cffb2a26 9729 "TARGET_ARM"
9c08d1fa 9730 "*
9c08d1fa 9731 /* If we have an operation where (op x 0) is the identity operation and
01cc3b75 9732 the conditional operator is LT or GE and we are comparing against zero and
674a8f0b 9733 everything is in registers then we can do this in two instructions. */
9c08d1fa 9734 if (operands[3] == const0_rtx
9735 && GET_CODE (operands[7]) != AND
0438d37f 9736 && REG_P (operands[5])
9737 && REG_P (operands[1])
9c08d1fa 9738 && REGNO (operands[1]) == REGNO (operands[4])
9739 && REGNO (operands[4]) != REGNO (operands[0]))
9740 {
9741 if (GET_CODE (operands[6]) == LT)
40dbec34 9742 return \"and\\t%0, %5, %2, asr #31\;%I7\\t%0, %4, %0\";
9c08d1fa 9743 else if (GET_CODE (operands[6]) == GE)
40dbec34 9744 return \"bic\\t%0, %5, %2, asr #31\;%I7\\t%0, %4, %0\";
9c08d1fa 9745 }
0438d37f 9746 if (CONST_INT_P (operands[3])
9c08d1fa 9747 && !const_ok_for_arm (INTVAL (operands[3])))
e2348bcb 9748 output_asm_insn (\"cmn\\t%2, #%n3\", operands);
9c08d1fa 9749 else
e2348bcb 9750 output_asm_insn (\"cmp\\t%2, %3\", operands);
40dbec34 9751 output_asm_insn (\"%I7%d6\\t%0, %4, %5\", operands);
9c08d1fa 9752 if (which_alternative != 0)
129a2fe4 9753 return \"mov%D6\\t%0, %1\";
9c08d1fa 9754 return \"\";
215b30b3 9755 "
8fa3ba89 9756 [(set_attr "conds" "clob")
1b7da4ac 9757 (set_attr "length" "8,12")
9758 (set_attr "type" "multiple")]
8fa3ba89 9759)
9c08d1fa 9760
8a18b90c 9761(define_insn "*if_arith_move"
129a2fe4 9762 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8fa3ba89 9763 (if_then_else:SI (match_operator 4 "arm_comparison_operator"
8a18b90c 9764 [(match_operand 6 "cc_register" "") (const_int 0)])
9765 (match_operator:SI 5 "shiftable_operator"
129a2fe4 9766 [(match_operand:SI 2 "s_register_operand" "r,r")
9767 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
9768 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))]
cffb2a26 9769 "TARGET_ARM"
8a18b90c 9770 "@
9771 %I5%d4\\t%0, %2, %3
129a2fe4 9772 %I5%d4\\t%0, %2, %3\;mov%D4\\t%0, %1"
8fa3ba89 9773 [(set_attr "conds" "use")
9774 (set_attr "length" "4,8")
282b4c75 9775 (set_attr_alternative "type"
9776 [(if_then_else (match_operand 3 "const_int_operand" "")
9777 (const_string "alu_shift_imm" )
9778 (const_string "alu_shift_reg"))
9779 (const_string "multiple")])]
8fa3ba89 9780)
8a18b90c 9781
f7fbdd4a 9782(define_insn "*ifcompare_move_arith"
9c08d1fa 9783 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8fa3ba89 9784 (if_then_else:SI (match_operator 6 "arm_comparison_operator"
9c08d1fa 9785 [(match_operand:SI 4 "s_register_operand" "r,r")
5565501b 9786 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
129a2fe4 9787 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
9c08d1fa 9788 (match_operator:SI 7 "shiftable_operator"
9789 [(match_operand:SI 2 "s_register_operand" "r,r")
9790 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))
bd5b4116 9791 (clobber (reg:CC CC_REGNUM))]
cffb2a26 9792 "TARGET_ARM"
9c08d1fa 9793 "*
9c08d1fa 9794 /* If we have an operation where (op x 0) is the identity operation and
01cc3b75 9795 the conditional operator is LT or GE and we are comparing against zero and
9c08d1fa 9796 everything is in registers then we can do this in two instructions */
9797 if (operands[5] == const0_rtx
9798 && GET_CODE (operands[7]) != AND
0438d37f 9799 && REG_P (operands[3])
9800 && REG_P (operands[1])
9c08d1fa 9801 && REGNO (operands[1]) == REGNO (operands[2])
9802 && REGNO (operands[2]) != REGNO (operands[0]))
9803 {
9804 if (GET_CODE (operands[6]) == GE)
40dbec34 9805 return \"and\\t%0, %3, %4, asr #31\;%I7\\t%0, %2, %0\";
9c08d1fa 9806 else if (GET_CODE (operands[6]) == LT)
40dbec34 9807 return \"bic\\t%0, %3, %4, asr #31\;%I7\\t%0, %2, %0\";
9c08d1fa 9808 }
40dbec34 9809
0438d37f 9810 if (CONST_INT_P (operands[5])
9c08d1fa 9811 && !const_ok_for_arm (INTVAL (operands[5])))
e2348bcb 9812 output_asm_insn (\"cmn\\t%4, #%n5\", operands);
9c08d1fa 9813 else
e2348bcb 9814 output_asm_insn (\"cmp\\t%4, %5\", operands);
40dbec34 9815
9c08d1fa 9816 if (which_alternative != 0)
129a2fe4 9817 output_asm_insn (\"mov%d6\\t%0, %1\", operands);
40dbec34 9818 return \"%I7%D6\\t%0, %2, %3\";
215b30b3 9819 "
8fa3ba89 9820 [(set_attr "conds" "clob")
1b7da4ac 9821 (set_attr "length" "8,12")
9822 (set_attr "type" "multiple")]
8fa3ba89 9823)
9c08d1fa 9824
8a18b90c 9825(define_insn "*if_move_arith"
129a2fe4 9826 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8a18b90c 9827 (if_then_else:SI
8fa3ba89 9828 (match_operator 4 "arm_comparison_operator"
8a18b90c 9829 [(match_operand 6 "cc_register" "") (const_int 0)])
129a2fe4 9830 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
8a18b90c 9831 (match_operator:SI 5 "shiftable_operator"
129a2fe4 9832 [(match_operand:SI 2 "s_register_operand" "r,r")
9833 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))]
cffb2a26 9834 "TARGET_ARM"
8a18b90c 9835 "@
9836 %I5%D4\\t%0, %2, %3
129a2fe4 9837 %I5%D4\\t%0, %2, %3\;mov%d4\\t%0, %1"
8fa3ba89 9838 [(set_attr "conds" "use")
9839 (set_attr "length" "4,8")
282b4c75 9840 (set_attr_alternative "type"
9841 [(if_then_else (match_operand 3 "const_int_operand" "")
9842 (const_string "alu_shift_imm" )
9843 (const_string "alu_shift_reg"))
9844 (const_string "multiple")])]
8fa3ba89 9845)
8a18b90c 9846
9847(define_insn "*ifcompare_move_not"
9c08d1fa 9848 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8a18b90c 9849 (if_then_else:SI
8fa3ba89 9850 (match_operator 5 "arm_comparison_operator"
8a18b90c 9851 [(match_operand:SI 3 "s_register_operand" "r,r")
9852 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
9853 (match_operand:SI 1 "arm_not_operand" "0,?rIK")
9854 (not:SI
9855 (match_operand:SI 2 "s_register_operand" "r,r"))))
bd5b4116 9856 (clobber (reg:CC CC_REGNUM))]
cffb2a26 9857 "TARGET_ARM"
8a18b90c 9858 "#"
8fa3ba89 9859 [(set_attr "conds" "clob")
1b7da4ac 9860 (set_attr "length" "8,12")
9861 (set_attr "type" "multiple")]
8fa3ba89 9862)
9c08d1fa 9863
8a18b90c 9864(define_insn "*if_move_not"
9865 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9866 (if_then_else:SI
8fa3ba89 9867 (match_operator 4 "arm_comparison_operator"
8a18b90c 9868 [(match_operand 3 "cc_register" "") (const_int 0)])
9869 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")
9870 (not:SI (match_operand:SI 2 "s_register_operand" "r,r,r"))))]
cffb2a26 9871 "TARGET_ARM"
8a18b90c 9872 "@
9873 mvn%D4\\t%0, %2
9874 mov%d4\\t%0, %1\;mvn%D4\\t%0, %2
9875 mvn%d4\\t%0, #%B1\;mvn%D4\\t%0, %2"
8fa3ba89 9876 [(set_attr "conds" "use")
1aed5204 9877 (set_attr "type" "mvn_reg")
1b7da4ac 9878 (set_attr "length" "4,8,8")
9879 (set_attr "type" "mvn_reg,multiple,multiple")]
8fa3ba89 9880)
8a18b90c 9881
9882(define_insn "*ifcompare_not_move"
9c08d1fa 9883 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8a18b90c 9884 (if_then_else:SI
8fa3ba89 9885 (match_operator 5 "arm_comparison_operator"
8a18b90c 9886 [(match_operand:SI 3 "s_register_operand" "r,r")
9887 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
9888 (not:SI
9889 (match_operand:SI 2 "s_register_operand" "r,r"))
9890 (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
bd5b4116 9891 (clobber (reg:CC CC_REGNUM))]
cffb2a26 9892 "TARGET_ARM"
8a18b90c 9893 "#"
8fa3ba89 9894 [(set_attr "conds" "clob")
1b7da4ac 9895 (set_attr "length" "8,12")
9896 (set_attr "type" "multiple")]
8fa3ba89 9897)
9c08d1fa 9898
8a18b90c 9899(define_insn "*if_not_move"
9900 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9901 (if_then_else:SI
8fa3ba89 9902 (match_operator 4 "arm_comparison_operator"
8a18b90c 9903 [(match_operand 3 "cc_register" "") (const_int 0)])
9904 (not:SI (match_operand:SI 2 "s_register_operand" "r,r,r"))
9905 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")))]
cffb2a26 9906 "TARGET_ARM"
8a18b90c 9907 "@
9908 mvn%d4\\t%0, %2
9909 mov%D4\\t%0, %1\;mvn%d4\\t%0, %2
9910 mvn%D4\\t%0, #%B1\;mvn%d4\\t%0, %2"
8fa3ba89 9911 [(set_attr "conds" "use")
1b7da4ac 9912 (set_attr "type" "mvn_reg,multiple,multiple")
8fa3ba89 9913 (set_attr "length" "4,8,8")]
9914)
8a18b90c 9915
9916(define_insn "*ifcompare_shift_move"
9c08d1fa 9917 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8a18b90c 9918 (if_then_else:SI
8fa3ba89 9919 (match_operator 6 "arm_comparison_operator"
8a18b90c 9920 [(match_operand:SI 4 "s_register_operand" "r,r")
9921 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
9922 (match_operator:SI 7 "shift_operator"
9923 [(match_operand:SI 2 "s_register_operand" "r,r")
9924 (match_operand:SI 3 "arm_rhs_operand" "rM,rM")])
9925 (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
bd5b4116 9926 (clobber (reg:CC CC_REGNUM))]
cffb2a26 9927 "TARGET_ARM"
9c08d1fa 9928 "#"
8fa3ba89 9929 [(set_attr "conds" "clob")
1b7da4ac 9930 (set_attr "length" "8,12")
9931 (set_attr "type" "multiple")]
8fa3ba89 9932)
9c08d1fa 9933
8a18b90c 9934(define_insn "*if_shift_move"
9935 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9936 (if_then_else:SI
8fa3ba89 9937 (match_operator 5 "arm_comparison_operator"
8a18b90c 9938 [(match_operand 6 "cc_register" "") (const_int 0)])
9939 (match_operator:SI 4 "shift_operator"
9940 [(match_operand:SI 2 "s_register_operand" "r,r,r")
9941 (match_operand:SI 3 "arm_rhs_operand" "rM,rM,rM")])
9942 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")))]
cffb2a26 9943 "TARGET_ARM"
5565501b 9944 "@
8a18b90c 9945 mov%d5\\t%0, %2%S4
9946 mov%D5\\t%0, %1\;mov%d5\\t%0, %2%S4
9947 mvn%D5\\t%0, #%B1\;mov%d5\\t%0, %2%S4"
8fa3ba89 9948 [(set_attr "conds" "use")
331beb1a 9949 (set_attr "shift" "2")
a2cd141b 9950 (set_attr "length" "4,8,8")
282b4c75 9951 (set_attr_alternative "type"
9952 [(if_then_else (match_operand 3 "const_int_operand" "")
9953 (const_string "mov_shift" )
9954 (const_string "mov_shift_reg"))
9955 (const_string "multiple")
9956 (const_string "multiple")])]
8fa3ba89 9957)
5565501b 9958
8a18b90c 9959(define_insn "*ifcompare_move_shift"
9960 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5565501b 9961 (if_then_else:SI
8fa3ba89 9962 (match_operator 6 "arm_comparison_operator"
8a18b90c 9963 [(match_operand:SI 4 "s_register_operand" "r,r")
9964 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
9965 (match_operand:SI 1 "arm_not_operand" "0,?rIK")
5565501b 9966 (match_operator:SI 7 "shift_operator"
8a18b90c 9967 [(match_operand:SI 2 "s_register_operand" "r,r")
9968 (match_operand:SI 3 "arm_rhs_operand" "rM,rM")])))
bd5b4116 9969 (clobber (reg:CC CC_REGNUM))]
cffb2a26 9970 "TARGET_ARM"
8a18b90c 9971 "#"
8fa3ba89 9972 [(set_attr "conds" "clob")
1b7da4ac 9973 (set_attr "length" "8,12")
9974 (set_attr "type" "multiple")]
8fa3ba89 9975)
5565501b 9976
8a18b90c 9977(define_insn "*if_move_shift"
9978 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
5565501b 9979 (if_then_else:SI
8fa3ba89 9980 (match_operator 5 "arm_comparison_operator"
8a18b90c 9981 [(match_operand 6 "cc_register" "") (const_int 0)])
9982 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")
9983 (match_operator:SI 4 "shift_operator"
9984 [(match_operand:SI 2 "s_register_operand" "r,r,r")
9985 (match_operand:SI 3 "arm_rhs_operand" "rM,rM,rM")])))]
cffb2a26 9986 "TARGET_ARM"
5565501b 9987 "@
8a18b90c 9988 mov%D5\\t%0, %2%S4
9989 mov%d5\\t%0, %1\;mov%D5\\t%0, %2%S4
9990 mvn%d5\\t%0, #%B1\;mov%D5\\t%0, %2%S4"
8fa3ba89 9991 [(set_attr "conds" "use")
331beb1a 9992 (set_attr "shift" "2")
a2cd141b 9993 (set_attr "length" "4,8,8")
282b4c75 9994 (set_attr_alternative "type"
9995 [(if_then_else (match_operand 3 "const_int_operand" "")
9996 (const_string "mov_shift" )
9997 (const_string "mov_shift_reg"))
9998 (const_string "multiple")
9999 (const_string "multiple")])]
8fa3ba89 10000)
9c08d1fa 10001
f7fbdd4a 10002(define_insn "*ifcompare_shift_shift"
8a18b90c 10003 [(set (match_operand:SI 0 "s_register_operand" "=r")
5565501b 10004 (if_then_else:SI
8fa3ba89 10005 (match_operator 7 "arm_comparison_operator"
8a18b90c 10006 [(match_operand:SI 5 "s_register_operand" "r")
10007 (match_operand:SI 6 "arm_add_operand" "rIL")])
5565501b 10008 (match_operator:SI 8 "shift_operator"
8a18b90c 10009 [(match_operand:SI 1 "s_register_operand" "r")
10010 (match_operand:SI 2 "arm_rhs_operand" "rM")])
5565501b 10011 (match_operator:SI 9 "shift_operator"
8a18b90c 10012 [(match_operand:SI 3 "s_register_operand" "r")
10013 (match_operand:SI 4 "arm_rhs_operand" "rM")])))
bd5b4116 10014 (clobber (reg:CC CC_REGNUM))]
cffb2a26 10015 "TARGET_ARM"
8a18b90c 10016 "#"
8fa3ba89 10017 [(set_attr "conds" "clob")
1b7da4ac 10018 (set_attr "length" "12")
10019 (set_attr "type" "multiple")]
8fa3ba89 10020)
9c08d1fa 10021
8a18b90c 10022(define_insn "*if_shift_shift"
10023 [(set (match_operand:SI 0 "s_register_operand" "=r")
10024 (if_then_else:SI
8fa3ba89 10025 (match_operator 5 "arm_comparison_operator"
8a18b90c 10026 [(match_operand 8 "cc_register" "") (const_int 0)])
10027 (match_operator:SI 6 "shift_operator"
10028 [(match_operand:SI 1 "s_register_operand" "r")
10029 (match_operand:SI 2 "arm_rhs_operand" "rM")])
10030 (match_operator:SI 7 "shift_operator"
10031 [(match_operand:SI 3 "s_register_operand" "r")
10032 (match_operand:SI 4 "arm_rhs_operand" "rM")])))]
cffb2a26 10033 "TARGET_ARM"
8a18b90c 10034 "mov%d5\\t%0, %1%S6\;mov%D5\\t%0, %3%S7"
8fa3ba89 10035 [(set_attr "conds" "use")
331beb1a 10036 (set_attr "shift" "1")
a2cd141b 10037 (set_attr "length" "8")
10038 (set (attr "type") (if_then_else
10039 (and (match_operand 2 "const_int_operand" "")
10040 (match_operand 4 "const_int_operand" ""))
1aed5204 10041 (const_string "mov_shift")
10042 (const_string "mov_shift_reg")))]
8fa3ba89 10043)
8a18b90c 10044
f7fbdd4a 10045(define_insn "*ifcompare_not_arith"
8a18b90c 10046 [(set (match_operand:SI 0 "s_register_operand" "=r")
5565501b 10047 (if_then_else:SI
8fa3ba89 10048 (match_operator 6 "arm_comparison_operator"
8a18b90c 10049 [(match_operand:SI 4 "s_register_operand" "r")
10050 (match_operand:SI 5 "arm_add_operand" "rIL")])
10051 (not:SI (match_operand:SI 1 "s_register_operand" "r"))
5565501b 10052 (match_operator:SI 7 "shiftable_operator"
8a18b90c 10053 [(match_operand:SI 2 "s_register_operand" "r")
10054 (match_operand:SI 3 "arm_rhs_operand" "rI")])))
bd5b4116 10055 (clobber (reg:CC CC_REGNUM))]
cffb2a26 10056 "TARGET_ARM"
8a18b90c 10057 "#"
8fa3ba89 10058 [(set_attr "conds" "clob")
1b7da4ac 10059 (set_attr "length" "12")
10060 (set_attr "type" "multiple")]
8fa3ba89 10061)
9c08d1fa 10062
8a18b90c 10063(define_insn "*if_not_arith"
10064 [(set (match_operand:SI 0 "s_register_operand" "=r")
10065 (if_then_else:SI
8fa3ba89 10066 (match_operator 5 "arm_comparison_operator"
8a18b90c 10067 [(match_operand 4 "cc_register" "") (const_int 0)])
10068 (not:SI (match_operand:SI 1 "s_register_operand" "r"))
10069 (match_operator:SI 6 "shiftable_operator"
10070 [(match_operand:SI 2 "s_register_operand" "r")
10071 (match_operand:SI 3 "arm_rhs_operand" "rI")])))]
cffb2a26 10072 "TARGET_ARM"
8a18b90c 10073 "mvn%d5\\t%0, %1\;%I6%D5\\t%0, %2, %3"
8fa3ba89 10074 [(set_attr "conds" "use")
1aed5204 10075 (set_attr "type" "mvn_reg")
8fa3ba89 10076 (set_attr "length" "8")]
10077)
8a18b90c 10078
10079(define_insn "*ifcompare_arith_not"
10080 [(set (match_operand:SI 0 "s_register_operand" "=r")
5565501b 10081 (if_then_else:SI
8fa3ba89 10082 (match_operator 6 "arm_comparison_operator"
8a18b90c 10083 [(match_operand:SI 4 "s_register_operand" "r")
10084 (match_operand:SI 5 "arm_add_operand" "rIL")])
5565501b 10085 (match_operator:SI 7 "shiftable_operator"
8a18b90c 10086 [(match_operand:SI 2 "s_register_operand" "r")
10087 (match_operand:SI 3 "arm_rhs_operand" "rI")])
10088 (not:SI (match_operand:SI 1 "s_register_operand" "r"))))
bd5b4116 10089 (clobber (reg:CC CC_REGNUM))]
cffb2a26 10090 "TARGET_ARM"
8a18b90c 10091 "#"
8fa3ba89 10092 [(set_attr "conds" "clob")
1b7da4ac 10093 (set_attr "length" "12")
10094 (set_attr "type" "multiple")]
8fa3ba89 10095)
9c08d1fa 10096
8a18b90c 10097(define_insn "*if_arith_not"
10098 [(set (match_operand:SI 0 "s_register_operand" "=r")
10099 (if_then_else:SI
8fa3ba89 10100 (match_operator 5 "arm_comparison_operator"
8a18b90c 10101 [(match_operand 4 "cc_register" "") (const_int 0)])
10102 (match_operator:SI 6 "shiftable_operator"
10103 [(match_operand:SI 2 "s_register_operand" "r")
10104 (match_operand:SI 3 "arm_rhs_operand" "rI")])
10105 (not:SI (match_operand:SI 1 "s_register_operand" "r"))))]
cffb2a26 10106 "TARGET_ARM"
8a18b90c 10107 "mvn%D5\\t%0, %1\;%I6%d5\\t%0, %2, %3"
8fa3ba89 10108 [(set_attr "conds" "use")
1b7da4ac 10109 (set_attr "type" "multiple")
8fa3ba89 10110 (set_attr "length" "8")]
10111)
8a18b90c 10112
f7fbdd4a 10113(define_insn "*ifcompare_neg_move"
8a18b90c 10114 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5565501b 10115 (if_then_else:SI
8fa3ba89 10116 (match_operator 5 "arm_comparison_operator"
8a18b90c 10117 [(match_operand:SI 3 "s_register_operand" "r,r")
10118 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
10119 (neg:SI (match_operand:SI 2 "s_register_operand" "r,r"))
10120 (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
bd5b4116 10121 (clobber (reg:CC CC_REGNUM))]
cffb2a26 10122 "TARGET_ARM"
8a18b90c 10123 "#"
8fa3ba89 10124 [(set_attr "conds" "clob")
1b7da4ac 10125 (set_attr "length" "8,12")
10126 (set_attr "type" "multiple")]
8fa3ba89 10127)
8a18b90c 10128
530bb693 10129(define_insn_and_split "*if_neg_move"
10130 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
8a18b90c 10131 (if_then_else:SI
8fa3ba89 10132 (match_operator 4 "arm_comparison_operator"
8a18b90c 10133 [(match_operand 3 "cc_register" "") (const_int 0)])
530bb693 10134 (neg:SI (match_operand:SI 2 "s_register_operand" "l,r"))
10135 (match_operand:SI 1 "s_register_operand" "0,0")))]
10136 "TARGET_32BIT"
10137 "#"
10138 "&& reload_completed"
10139 [(cond_exec (match_op_dup 4 [(match_dup 3) (const_int 0)])
10140 (set (match_dup 0) (neg:SI (match_dup 2))))]
10141 ""
8fa3ba89 10142 [(set_attr "conds" "use")
530bb693 10143 (set_attr "length" "4")
10144 (set_attr "arch" "t2,32")
10145 (set_attr "enabled_for_depr_it" "yes,no")
10146 (set_attr "type" "logic_shift_imm")]
8fa3ba89 10147)
9c08d1fa 10148
f7fbdd4a 10149(define_insn "*ifcompare_move_neg"
8a18b90c 10150 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5565501b 10151 (if_then_else:SI
8fa3ba89 10152 (match_operator 5 "arm_comparison_operator"
8a18b90c 10153 [(match_operand:SI 3 "s_register_operand" "r,r")
10154 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
10155 (match_operand:SI 1 "arm_not_operand" "0,?rIK")
10156 (neg:SI (match_operand:SI 2 "s_register_operand" "r,r"))))
bd5b4116 10157 (clobber (reg:CC CC_REGNUM))]
cffb2a26 10158 "TARGET_ARM"
8a18b90c 10159 "#"
8fa3ba89 10160 [(set_attr "conds" "clob")
1b7da4ac 10161 (set_attr "length" "8,12")
10162 (set_attr "type" "multiple")]
8fa3ba89 10163)
8a18b90c 10164
530bb693 10165(define_insn_and_split "*if_move_neg"
10166 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
8a18b90c 10167 (if_then_else:SI
8fa3ba89 10168 (match_operator 4 "arm_comparison_operator"
8a18b90c 10169 [(match_operand 3 "cc_register" "") (const_int 0)])
530bb693 10170 (match_operand:SI 1 "s_register_operand" "0,0")
10171 (neg:SI (match_operand:SI 2 "s_register_operand" "l,r"))))]
10172 "TARGET_32BIT"
10173 "#"
10174 "&& reload_completed"
10175 [(cond_exec (match_dup 5)
10176 (set (match_dup 0) (neg:SI (match_dup 2))))]
10177 {
10178 machine_mode mode = GET_MODE (operands[3]);
10179 rtx_code rc = GET_CODE (operands[4]);
10180
10181 if (mode == CCFPmode || mode == CCFPEmode)
10182 rc = reverse_condition_maybe_unordered (rc);
10183 else
10184 rc = reverse_condition (rc);
10185
10186 operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, operands[3], const0_rtx);
10187 }
0d66636f 10188 [(set_attr "conds" "use")
530bb693 10189 (set_attr "length" "4")
10190 (set_attr "arch" "t2,32")
10191 (set_attr "enabled_for_depr_it" "yes,no")
10192 (set_attr "type" "logic_shift_imm")]
0d66636f 10193)
9c08d1fa 10194
f7fbdd4a 10195(define_insn "*arith_adjacentmem"
9c08d1fa 10196 [(set (match_operand:SI 0 "s_register_operand" "=r")
10197 (match_operator:SI 1 "shiftable_operator"
10198 [(match_operand:SI 2 "memory_operand" "m")
10199 (match_operand:SI 3 "memory_operand" "m")]))
10200 (clobber (match_scratch:SI 4 "=r"))]
cffb2a26 10201 "TARGET_ARM && adjacent_mem_locations (operands[2], operands[3])"
9c08d1fa 10202 "*
215b30b3 10203 {
10204 rtx ldm[3];
10205 rtx arith[4];
94dee231 10206 rtx base_reg;
10207 HOST_WIDE_INT val1 = 0, val2 = 0;
9c08d1fa 10208
215b30b3 10209 if (REGNO (operands[0]) > REGNO (operands[4]))
10210 {
10211 ldm[1] = operands[4];
10212 ldm[2] = operands[0];
10213 }
10214 else
10215 {
10216 ldm[1] = operands[0];
10217 ldm[2] = operands[4];
10218 }
94dee231 10219
10220 base_reg = XEXP (operands[2], 0);
10221
10222 if (!REG_P (base_reg))
10223 {
10224 val1 = INTVAL (XEXP (base_reg, 1));
10225 base_reg = XEXP (base_reg, 0);
10226 }
10227
10228 if (!REG_P (XEXP (operands[3], 0)))
215b30b3 10229 val2 = INTVAL (XEXP (XEXP (operands[3], 0), 1));
94dee231 10230
215b30b3 10231 arith[0] = operands[0];
10232 arith[3] = operands[1];
94dee231 10233
215b30b3 10234 if (val1 < val2)
10235 {
10236 arith[1] = ldm[1];
10237 arith[2] = ldm[2];
10238 }
10239 else
10240 {
10241 arith[1] = ldm[2];
10242 arith[2] = ldm[1];
10243 }
94dee231 10244
10245 ldm[0] = base_reg;
10246 if (val1 !=0 && val2 != 0)
215b30b3 10247 {
cdb1295a 10248 rtx ops[3];
10249
94dee231 10250 if (val1 == 4 || val2 == 4)
10251 /* Other val must be 8, since we know they are adjacent and neither
10252 is zero. */
25f905c2 10253 output_asm_insn (\"ldm%(ib%)\\t%0, {%1, %2}\", ldm);
cdb1295a 10254 else if (const_ok_for_arm (val1) || const_ok_for_arm (-val1))
94dee231 10255 {
94dee231 10256 ldm[0] = ops[0] = operands[4];
10257 ops[1] = base_reg;
10258 ops[2] = GEN_INT (val1);
10259 output_add_immediate (ops);
10260 if (val1 < val2)
25f905c2 10261 output_asm_insn (\"ldm%(ia%)\\t%0, {%1, %2}\", ldm);
94dee231 10262 else
25f905c2 10263 output_asm_insn (\"ldm%(da%)\\t%0, {%1, %2}\", ldm);
94dee231 10264 }
cdb1295a 10265 else
10266 {
10267 /* Offset is out of range for a single add, so use two ldr. */
10268 ops[0] = ldm[1];
10269 ops[1] = base_reg;
10270 ops[2] = GEN_INT (val1);
10271 output_asm_insn (\"ldr%?\\t%0, [%1, %2]\", ops);
10272 ops[0] = ldm[2];
10273 ops[2] = GEN_INT (val2);
10274 output_asm_insn (\"ldr%?\\t%0, [%1, %2]\", ops);
10275 }
215b30b3 10276 }
94dee231 10277 else if (val1 != 0)
215b30b3 10278 {
215b30b3 10279 if (val1 < val2)
25f905c2 10280 output_asm_insn (\"ldm%(da%)\\t%0, {%1, %2}\", ldm);
215b30b3 10281 else
25f905c2 10282 output_asm_insn (\"ldm%(ia%)\\t%0, {%1, %2}\", ldm);
215b30b3 10283 }
10284 else
10285 {
215b30b3 10286 if (val1 < val2)
25f905c2 10287 output_asm_insn (\"ldm%(ia%)\\t%0, {%1, %2}\", ldm);
215b30b3 10288 else
25f905c2 10289 output_asm_insn (\"ldm%(da%)\\t%0, {%1, %2}\", ldm);
215b30b3 10290 }
10291 output_asm_insn (\"%I3%?\\t%0, %1, %2\", arith);
10292 return \"\";
10293 }"
10294 [(set_attr "length" "12")
10295 (set_attr "predicable" "yes")
a2cd141b 10296 (set_attr "type" "load1")]
215b30b3 10297)
9c08d1fa 10298
9c08d1fa 10299; This pattern is never tried by combine, so do it as a peephole
10300
a0f94409 10301(define_peephole2
372575c7 10302 [(set (match_operand:SI 0 "arm_general_register_operand" "")
10303 (match_operand:SI 1 "arm_general_register_operand" ""))
bd5b4116 10304 (set (reg:CC CC_REGNUM)
aea4c774 10305 (compare:CC (match_dup 1) (const_int 0)))]
372575c7 10306 "TARGET_ARM"
a0f94409 10307 [(parallel [(set (reg:CC CC_REGNUM) (compare:CC (match_dup 1) (const_int 0)))
10308 (set (match_dup 0) (match_dup 1))])]
10309 ""
0d66636f 10310)
9c08d1fa 10311
9c08d1fa 10312(define_split
10313 [(set (match_operand:SI 0 "s_register_operand" "")
10314 (and:SI (ge:SI (match_operand:SI 1 "s_register_operand" "")
10315 (const_int 0))
8fa3ba89 10316 (neg:SI (match_operator:SI 2 "arm_comparison_operator"
9c08d1fa 10317 [(match_operand:SI 3 "s_register_operand" "")
10318 (match_operand:SI 4 "arm_rhs_operand" "")]))))
10319 (clobber (match_operand:SI 5 "s_register_operand" ""))]
cffb2a26 10320 "TARGET_ARM"
9c08d1fa 10321 [(set (match_dup 5) (not:SI (ashiftrt:SI (match_dup 1) (const_int 31))))
10322 (set (match_dup 0) (and:SI (match_op_dup 2 [(match_dup 3) (match_dup 4)])
10323 (match_dup 5)))]
215b30b3 10324 ""
10325)
9c08d1fa 10326
aea4c774 10327;; This split can be used because CC_Z mode implies that the following
10328;; branch will be an equality, or an unsigned inequality, so the sign
10329;; extension is not needed.
9c08d1fa 10330
aea4c774 10331(define_split
bd5b4116 10332 [(set (reg:CC_Z CC_REGNUM)
aea4c774 10333 (compare:CC_Z
10334 (ashift:SI (subreg:SI (match_operand:QI 0 "memory_operand" "") 0)
9c08d1fa 10335 (const_int 24))
aea4c774 10336 (match_operand 1 "const_int_operand" "")))
10337 (clobber (match_scratch:SI 2 ""))]
cffb2a26 10338 "TARGET_ARM
10339 && (((unsigned HOST_WIDE_INT) INTVAL (operands[1]))
10340 == (((unsigned HOST_WIDE_INT) INTVAL (operands[1])) >> 24) << 24)"
aea4c774 10341 [(set (match_dup 2) (zero_extend:SI (match_dup 0)))
bd5b4116 10342 (set (reg:CC CC_REGNUM) (compare:CC (match_dup 2) (match_dup 1)))]
aea4c774 10343 "
9c08d1fa 10344 operands[1] = GEN_INT (((unsigned long) INTVAL (operands[1])) >> 24);
215b30b3 10345 "
10346)
25f905c2 10347;; ??? Check the patterns above for Thumb-2 usefulness
9c08d1fa 10348
87b22bf7 10349(define_expand "prologue"
10350 [(clobber (const_int 0))]
cffb2a26 10351 "TARGET_EITHER"
25f905c2 10352 "if (TARGET_32BIT)
cffb2a26 10353 arm_expand_prologue ();
10354 else
25f905c2 10355 thumb1_expand_prologue ();
87b22bf7 10356 DONE;
cffb2a26 10357 "
10358)
87b22bf7 10359
56d27660 10360(define_expand "epilogue"
4c44712e 10361 [(clobber (const_int 0))]
cffb2a26 10362 "TARGET_EITHER"
56d27660 10363 "
18d50ae6 10364 if (crtl->calls_eh_return)
fb94f18b 10365 emit_insn (gen_force_register_use (gen_rtx_REG (Pmode, 2)));
25f905c2 10366 if (TARGET_THUMB1)
c3635784 10367 {
10368 thumb1_expand_epilogue ();
10369 emit_jump_insn (gen_rtx_UNSPEC_VOLATILE (VOIDmode,
10370 gen_rtvec (1, ret_rtx), VUNSPEC_EPILOGUE));
10371 }
10372 else if (HAVE_return)
10373 {
10374 /* HAVE_return is testing for USE_RETURN_INSN (FALSE). Hence,
10375 no need for explicit testing again. */
10376 emit_jump_insn (gen_return ());
10377 }
10378 else if (TARGET_32BIT)
10379 {
10380 arm_expand_epilogue (true);
10381 }
cffb2a26 10382 DONE;
10383 "
10384)
56d27660 10385
ef5651d0 10386;; Note - although unspec_volatile's USE all hard registers,
10387;; USEs are ignored after relaod has completed. Thus we need
10388;; to add an unspec of the link register to ensure that flow
10389;; does not think that it is unused by the sibcall branch that
10390;; will replace the standard function epilogue.
c3635784 10391(define_expand "sibcall_epilogue"
fb94f18b 10392 [(parallel [(unspec:SI [(reg:SI LR_REGNUM)] UNSPEC_REGISTER_USE)
c3635784 10393 (unspec_volatile [(return)] VUNSPEC_EPILOGUE)])]
10394 "TARGET_32BIT"
10395 "
10396 arm_expand_epilogue (false);
10397 DONE;
10398 "
1c494086 10399)
10400
cffb2a26 10401(define_expand "eh_epilogue"
7db9af5d 10402 [(use (match_operand:SI 0 "register_operand" ""))
10403 (use (match_operand:SI 1 "register_operand" ""))
10404 (use (match_operand:SI 2 "register_operand" ""))]
cffb2a26 10405 "TARGET_EITHER"
10406 "
215b30b3 10407 {
10408 cfun->machine->eh_epilogue_sp_ofs = operands[1];
0438d37f 10409 if (!REG_P (operands[2]) || REGNO (operands[2]) != 2)
215b30b3 10410 {
10411 rtx ra = gen_rtx_REG (Pmode, 2);
10412
10413 emit_move_insn (ra, operands[2]);
10414 operands[2] = ra;
10415 }
5cf3595a 10416 /* This is a hack -- we may have crystalized the function type too
10417 early. */
10418 cfun->machine->func_type = 0;
215b30b3 10419 }"
10420)
56d27660 10421
9c08d1fa 10422;; This split is only used during output to reduce the number of patterns
10423;; that need assembler instructions adding to them. We allowed the setting
10424;; of the conditions to be implicit during rtl generation so that
10425;; the conditional compare patterns would work. However this conflicts to
8a18b90c 10426;; some extent with the conditional data operations, so we have to split them
9c08d1fa 10427;; up again here.
10428
25f905c2 10429;; ??? Need to audit these splitters for Thumb-2. Why isn't normal
10430;; conditional execution sufficient?
10431
9c08d1fa 10432(define_split
10433 [(set (match_operand:SI 0 "s_register_operand" "")
8fa3ba89 10434 (if_then_else:SI (match_operator 1 "arm_comparison_operator"
10435 [(match_operand 2 "" "") (match_operand 3 "" "")])
10436 (match_dup 0)
10437 (match_operand 4 "" "")))
bd5b4116 10438 (clobber (reg:CC CC_REGNUM))]
ac8b093b 10439 "TARGET_ARM && reload_completed"
8fa3ba89 10440 [(set (match_dup 5) (match_dup 6))
10441 (cond_exec (match_dup 7)
10442 (set (match_dup 0) (match_dup 4)))]
10443 "
10444 {
3754d046 10445 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
8fa3ba89 10446 operands[2], operands[3]);
10447 enum rtx_code rc = GET_CODE (operands[1]);
10448
bd5b4116 10449 operands[5] = gen_rtx_REG (mode, CC_REGNUM);
8fa3ba89 10450 operands[6] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
10451 if (mode == CCFPmode || mode == CCFPEmode)
10452 rc = reverse_condition_maybe_unordered (rc);
10453 else
10454 rc = reverse_condition (rc);
10455
10456 operands[7] = gen_rtx_fmt_ee (rc, VOIDmode, operands[5], const0_rtx);
10457 }"
10458)
10459
10460(define_split
10461 [(set (match_operand:SI 0 "s_register_operand" "")
10462 (if_then_else:SI (match_operator 1 "arm_comparison_operator"
10463 [(match_operand 2 "" "") (match_operand 3 "" "")])
10464 (match_operand 4 "" "")
10465 (match_dup 0)))
bd5b4116 10466 (clobber (reg:CC CC_REGNUM))]
ac8b093b 10467 "TARGET_ARM && reload_completed"
8fa3ba89 10468 [(set (match_dup 5) (match_dup 6))
10469 (cond_exec (match_op_dup 1 [(match_dup 5) (const_int 0)])
10470 (set (match_dup 0) (match_dup 4)))]
10471 "
10472 {
3754d046 10473 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
8fa3ba89 10474 operands[2], operands[3]);
10475
bd5b4116 10476 operands[5] = gen_rtx_REG (mode, CC_REGNUM);
8fa3ba89 10477 operands[6] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
10478 }"
10479)
10480
10481(define_split
10482 [(set (match_operand:SI 0 "s_register_operand" "")
10483 (if_then_else:SI (match_operator 1 "arm_comparison_operator"
9c08d1fa 10484 [(match_operand 2 "" "") (match_operand 3 "" "")])
10485 (match_operand 4 "" "")
10486 (match_operand 5 "" "")))
bd5b4116 10487 (clobber (reg:CC CC_REGNUM))]
ac8b093b 10488 "TARGET_ARM && reload_completed"
8fa3ba89 10489 [(set (match_dup 6) (match_dup 7))
10490 (cond_exec (match_op_dup 1 [(match_dup 6) (const_int 0)])
10491 (set (match_dup 0) (match_dup 4)))
10492 (cond_exec (match_dup 8)
10493 (set (match_dup 0) (match_dup 5)))]
10494 "
10495 {
3754d046 10496 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
8fa3ba89 10497 operands[2], operands[3]);
10498 enum rtx_code rc = GET_CODE (operands[1]);
10499
bd5b4116 10500 operands[6] = gen_rtx_REG (mode, CC_REGNUM);
8fa3ba89 10501 operands[7] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
10502 if (mode == CCFPmode || mode == CCFPEmode)
10503 rc = reverse_condition_maybe_unordered (rc);
10504 else
10505 rc = reverse_condition (rc);
10506
10507 operands[8] = gen_rtx_fmt_ee (rc, VOIDmode, operands[6], const0_rtx);
10508 }"
10509)
10510
cffb2a26 10511(define_split
10512 [(set (match_operand:SI 0 "s_register_operand" "")
8fa3ba89 10513 (if_then_else:SI (match_operator 1 "arm_comparison_operator"
cffb2a26 10514 [(match_operand:SI 2 "s_register_operand" "")
10515 (match_operand:SI 3 "arm_add_operand" "")])
10516 (match_operand:SI 4 "arm_rhs_operand" "")
10517 (not:SI
10518 (match_operand:SI 5 "s_register_operand" ""))))
bd5b4116 10519 (clobber (reg:CC CC_REGNUM))]
ac8b093b 10520 "TARGET_ARM && reload_completed"
cffb2a26 10521 [(set (match_dup 6) (match_dup 7))
f6c53574 10522 (cond_exec (match_op_dup 1 [(match_dup 6) (const_int 0)])
10523 (set (match_dup 0) (match_dup 4)))
10524 (cond_exec (match_dup 8)
10525 (set (match_dup 0) (not:SI (match_dup 5))))]
cffb2a26 10526 "
215b30b3 10527 {
3754d046 10528 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
215b30b3 10529 operands[2], operands[3]);
f6c53574 10530 enum rtx_code rc = GET_CODE (operands[1]);
cffb2a26 10531
bd5b4116 10532 operands[6] = gen_rtx_REG (mode, CC_REGNUM);
1a83b3ff 10533 operands[7] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
f6c53574 10534 if (mode == CCFPmode || mode == CCFPEmode)
10535 rc = reverse_condition_maybe_unordered (rc);
10536 else
10537 rc = reverse_condition (rc);
10538
10539 operands[8] = gen_rtx_fmt_ee (rc, VOIDmode, operands[6], const0_rtx);
215b30b3 10540 }"
10541)
cffb2a26 10542
10543(define_insn "*cond_move_not"
10544 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8fa3ba89 10545 (if_then_else:SI (match_operator 4 "arm_comparison_operator"
cffb2a26 10546 [(match_operand 3 "cc_register" "") (const_int 0)])
10547 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
10548 (not:SI
10549 (match_operand:SI 2 "s_register_operand" "r,r"))))]
10550 "TARGET_ARM"
10551 "@
10552 mvn%D4\\t%0, %2
10553 mov%d4\\t%0, %1\;mvn%D4\\t%0, %2"
0d66636f 10554 [(set_attr "conds" "use")
1b7da4ac 10555 (set_attr "type" "mvn_reg,multiple")
0d66636f 10556 (set_attr "length" "4,8")]
10557)
cffb2a26 10558
9c08d1fa 10559;; The next two patterns occur when an AND operation is followed by a
10560;; scc insn sequence
10561
f7fbdd4a 10562(define_insn "*sign_extract_onebit"
9c08d1fa 10563 [(set (match_operand:SI 0 "s_register_operand" "=r")
10564 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
10565 (const_int 1)
ed750274 10566 (match_operand:SI 2 "const_int_operand" "n")))
10567 (clobber (reg:CC CC_REGNUM))]
cffb2a26 10568 "TARGET_ARM"
9c08d1fa 10569 "*
0d66636f 10570 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
10571 output_asm_insn (\"ands\\t%0, %1, %2\", operands);
10572 return \"mvnne\\t%0, #0\";
10573 "
10574 [(set_attr "conds" "clob")
1b7da4ac 10575 (set_attr "length" "8")
10576 (set_attr "type" "multiple")]
0d66636f 10577)
9c08d1fa 10578
f7fbdd4a 10579(define_insn "*not_signextract_onebit"
9c08d1fa 10580 [(set (match_operand:SI 0 "s_register_operand" "=r")
10581 (not:SI
10582 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
10583 (const_int 1)
ed750274 10584 (match_operand:SI 2 "const_int_operand" "n"))))
10585 (clobber (reg:CC CC_REGNUM))]
cffb2a26 10586 "TARGET_ARM"
9c08d1fa 10587 "*
0d66636f 10588 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
10589 output_asm_insn (\"tst\\t%1, %2\", operands);
10590 output_asm_insn (\"mvneq\\t%0, #0\", operands);
10591 return \"movne\\t%0, #0\";
10592 "
10593 [(set_attr "conds" "clob")
1b7da4ac 10594 (set_attr "length" "12")
10595 (set_attr "type" "multiple")]
0d66636f 10596)
25f905c2 10597;; ??? The above patterns need auditing for Thumb-2
87b22bf7 10598
0d66636f 10599;; Push multiple registers to the stack. Registers are in parallel (use ...)
10600;; expressions. For simplicity, the first register is also in the unspec
10601;; part.
08508cbf 10602;; To avoid the usage of GNU extension, the length attribute is computed
10603;; in a C function arm_attr_length_push_multi.
f7fbdd4a 10604(define_insn "*push_multi"
87b22bf7 10605 [(match_parallel 2 "multi_register_push"
7571d3f7 10606 [(set (match_operand:BLK 0 "push_mult_memory_operand" "")
3cc80a30 10607 (unspec:BLK [(match_operand:SI 1 "s_register_operand" "")]
e1159bbe 10608 UNSPEC_PUSH_MULT))])]
7571d3f7 10609 ""
87b22bf7 10610 "*
215b30b3 10611 {
10612 int num_saves = XVECLEN (operands[2], 0);
ed593f11 10613
215b30b3 10614 /* For the StrongARM at least it is faster to
25f905c2 10615 use STR to store only a single register.
542d5028 10616 In Thumb mode always use push, and the assembler will pick
10617 something appropriate. */
25f905c2 10618 if (num_saves == 1 && TARGET_ARM)
61309563 10619 output_asm_insn (\"str%?\\t%1, [%m0, #-4]!\", operands);
215b30b3 10620 else
10621 {
10622 int i;
10623 char pattern[100];
ed593f11 10624
25f905c2 10625 if (TARGET_ARM)
61309563 10626 strcpy (pattern, \"stm%(fd%)\\t%m0!, {%1\");
10627 else if (TARGET_THUMB2)
10628 strcpy (pattern, \"push%?\\t{%1\");
25f905c2 10629 else
10630 strcpy (pattern, \"push\\t{%1\");
215b30b3 10631
6079f055 10632 for (i = 1; i < num_saves; i++)
215b30b3 10633 {
10634 strcat (pattern, \", %|\");
10635 strcat (pattern,
10636 reg_names[REGNO (XEXP (XVECEXP (operands[2], 0, i), 0))]);
10637 }
10638
10639 strcat (pattern, \"}\");
10640 output_asm_insn (pattern, operands);
10641 }
10642
10643 return \"\";
10644 }"
a6864a24 10645 [(set_attr "type" "store4")
10646 (set (attr "length")
08508cbf 10647 (symbol_ref "arm_attr_length_push_multi (operands[2], operands[1])"))]
215b30b3 10648)
f7fbdd4a 10649
4c58c898 10650(define_insn "stack_tie"
10651 [(set (mem:BLK (scratch))
aaa37ad6 10652 (unspec:BLK [(match_operand:SI 0 "s_register_operand" "rk")
10653 (match_operand:SI 1 "s_register_operand" "rk")]
4c58c898 10654 UNSPEC_PRLG_STK))]
10655 ""
10656 ""
1b7da4ac 10657 [(set_attr "length" "0")
10658 (set_attr "type" "block")]
4c58c898 10659)
10660
426be8c5 10661;; Pop (as used in epilogue RTL)
10662;;
10663(define_insn "*load_multiple_with_writeback"
10664 [(match_parallel 0 "load_multiple_operation"
10665 [(set (match_operand:SI 1 "s_register_operand" "+rk")
10666 (plus:SI (match_dup 1)
809003b3 10667 (match_operand:SI 2 "const_int_I_operand" "I")))
426be8c5 10668 (set (match_operand:SI 3 "s_register_operand" "=rk")
10669 (mem:SI (match_dup 1)))
10670 ])]
10671 "TARGET_32BIT && (reload_in_progress || reload_completed)"
10672 "*
10673 {
10674 arm_output_multireg_pop (operands, /*return_pc=*/false,
10675 /*cond=*/const_true_rtx,
10676 /*reverse=*/false,
10677 /*update=*/true);
10678 return \"\";
10679 }
10680 "
10681 [(set_attr "type" "load4")
10682 (set_attr "predicable" "yes")]
10683)
10684
10685;; Pop with return (as used in epilogue RTL)
10686;;
10687;; This instruction is generated when the registers are popped at the end of
10688;; epilogue. Here, instead of popping the value into LR and then generating
10689;; jump to LR, value is popped into PC directly. Hence, the pattern is combined
10690;; with (return).
10691(define_insn "*pop_multiple_with_writeback_and_return"
10692 [(match_parallel 0 "pop_multiple_return"
10693 [(return)
10694 (set (match_operand:SI 1 "s_register_operand" "+rk")
10695 (plus:SI (match_dup 1)
809003b3 10696 (match_operand:SI 2 "const_int_I_operand" "I")))
426be8c5 10697 (set (match_operand:SI 3 "s_register_operand" "=rk")
10698 (mem:SI (match_dup 1)))
10699 ])]
10700 "TARGET_32BIT && (reload_in_progress || reload_completed)"
10701 "*
10702 {
10703 arm_output_multireg_pop (operands, /*return_pc=*/true,
10704 /*cond=*/const_true_rtx,
10705 /*reverse=*/false,
10706 /*update=*/true);
10707 return \"\";
10708 }
10709 "
10710 [(set_attr "type" "load4")
10711 (set_attr "predicable" "yes")]
10712)
10713
10714(define_insn "*pop_multiple_with_return"
10715 [(match_parallel 0 "pop_multiple_return"
10716 [(return)
10717 (set (match_operand:SI 2 "s_register_operand" "=rk")
10718 (mem:SI (match_operand:SI 1 "s_register_operand" "rk")))
10719 ])]
10720 "TARGET_32BIT && (reload_in_progress || reload_completed)"
10721 "*
10722 {
10723 arm_output_multireg_pop (operands, /*return_pc=*/true,
10724 /*cond=*/const_true_rtx,
10725 /*reverse=*/false,
10726 /*update=*/false);
10727 return \"\";
10728 }
10729 "
10730 [(set_attr "type" "load4")
10731 (set_attr "predicable" "yes")]
10732)
10733
10734;; Load into PC and return
10735(define_insn "*ldr_with_return"
10736 [(return)
10737 (set (reg:SI PC_REGNUM)
10738 (mem:SI (post_inc:SI (match_operand:SI 0 "s_register_operand" "+rk"))))]
10739 "TARGET_32BIT && (reload_in_progress || reload_completed)"
10740 "ldr%?\t%|pc, [%0], #4"
10741 [(set_attr "type" "load1")
10742 (set_attr "predicable" "yes")]
10743)
1a0b0f12 10744;; Pop for floating point registers (as used in epilogue RTL)
10745(define_insn "*vfp_pop_multiple_with_writeback"
10746 [(match_parallel 0 "pop_multiple_fp"
10747 [(set (match_operand:SI 1 "s_register_operand" "+rk")
10748 (plus:SI (match_dup 1)
809003b3 10749 (match_operand:SI 2 "const_int_I_operand" "I")))
2f2163a4 10750 (set (match_operand:DF 3 "vfp_hard_register_operand" "")
1a0b0f12 10751 (mem:DF (match_dup 1)))])]
10752 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
10753 "*
10754 {
10755 int num_regs = XVECLEN (operands[0], 0);
10756 char pattern[100];
10757 rtx op_list[2];
b34d8dac 10758 strcpy (pattern, \"vldm\\t\");
1a0b0f12 10759 strcat (pattern, reg_names[REGNO (SET_DEST (XVECEXP (operands[0], 0, 0)))]);
10760 strcat (pattern, \"!, {\");
10761 op_list[0] = XEXP (XVECEXP (operands[0], 0, 1), 0);
10762 strcat (pattern, \"%P0\");
10763 if ((num_regs - 1) > 1)
10764 {
10765 strcat (pattern, \"-%P1\");
10766 op_list [1] = XEXP (XVECEXP (operands[0], 0, num_regs - 1), 0);
10767 }
10768
10769 strcat (pattern, \"}\");
10770 output_asm_insn (pattern, op_list);
10771 return \"\";
10772 }
10773 "
10774 [(set_attr "type" "load4")
10775 (set_attr "conds" "unconditional")
10776 (set_attr "predicable" "no")]
10777)
10778
f7fbdd4a 10779;; Special patterns for dealing with the constant pool
10780
cffb2a26 10781(define_insn "align_4"
e1159bbe 10782 [(unspec_volatile [(const_int 0)] VUNSPEC_ALIGN)]
cffb2a26 10783 "TARGET_EITHER"
f7fbdd4a 10784 "*
cffb2a26 10785 assemble_align (32);
f7fbdd4a 10786 return \"\";
cffb2a26 10787 "
1b7da4ac 10788 [(set_attr "type" "no_insn")]
cffb2a26 10789)
f7fbdd4a 10790
755eb2b4 10791(define_insn "align_8"
10792 [(unspec_volatile [(const_int 0)] VUNSPEC_ALIGN8)]
f9273c43 10793 "TARGET_EITHER"
755eb2b4 10794 "*
10795 assemble_align (64);
10796 return \"\";
10797 "
1b7da4ac 10798 [(set_attr "type" "no_insn")]
755eb2b4 10799)
10800
cffb2a26 10801(define_insn "consttable_end"
e1159bbe 10802 [(unspec_volatile [(const_int 0)] VUNSPEC_POOL_END)]
cffb2a26 10803 "TARGET_EITHER"
f7fbdd4a 10804 "*
cffb2a26 10805 making_const_table = FALSE;
f7fbdd4a 10806 return \"\";
cffb2a26 10807 "
1b7da4ac 10808 [(set_attr "type" "no_insn")]
cffb2a26 10809)
f7fbdd4a 10810
0e207eb8 10811(define_insn "consttable_1"
10812 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_1)]
10813 "TARGET_EITHER"
10814 "*
10815 making_const_table = TRUE;
10816 assemble_integer (operands[0], 1, BITS_PER_WORD, 1);
10817 assemble_zeros (3);
10818 return \"\";
10819 "
10820 [(set_attr "length" "4")
10821 (set_attr "type" "no_insn")]
10822)
10823
10824(define_insn "consttable_2"
10825 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_2)]
10826 "TARGET_EITHER"
10827 "*
10828 {
10829 rtx x = operands[0];
10830 making_const_table = TRUE;
10831 switch (GET_MODE_CLASS (GET_MODE (x)))
10832 {
10833 case MODE_FLOAT:
10834 arm_emit_fp16_const (x);
10835 break;
10836 default:
10837 assemble_integer (operands[0], 2, BITS_PER_WORD, 1);
10838 assemble_zeros (2);
10839 break;
10840 }
10841 return \"\";
10842 }"
10843 [(set_attr "length" "4")
10844 (set_attr "type" "no_insn")]
10845)
10846
cffb2a26 10847(define_insn "consttable_4"
e1159bbe 10848 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_4)]
cffb2a26 10849 "TARGET_EITHER"
10850 "*
10851 {
9b8516be 10852 rtx x = operands[0];
cffb2a26 10853 making_const_table = TRUE;
9b8516be 10854 switch (GET_MODE_CLASS (GET_MODE (x)))
cffb2a26 10855 {
10856 case MODE_FLOAT:
0e207eb8 10857 {
10858 REAL_VALUE_TYPE r;
10859 REAL_VALUE_FROM_CONST_DOUBLE (r, x);
10860 assemble_real (r, GET_MODE (x), BITS_PER_WORD);
10861 break;
10862 }
cffb2a26 10863 default:
7b04c5d5 10864 /* XXX: Sometimes gcc does something really dumb and ends up with
10865 a HIGH in a constant pool entry, usually because it's trying to
10866 load into a VFP register. We know this will always be used in
10867 combination with a LO_SUM which ignores the high bits, so just
10868 strip off the HIGH. */
10869 if (GET_CODE (x) == HIGH)
10870 x = XEXP (x, 0);
9b8516be 10871 assemble_integer (x, 4, BITS_PER_WORD, 1);
10872 mark_symbol_refs_as_used (x);
cffb2a26 10873 break;
10874 }
10875 return \"\";
10876 }"
1b7da4ac 10877 [(set_attr "length" "4")
10878 (set_attr "type" "no_insn")]
cffb2a26 10879)
10880
10881(define_insn "consttable_8"
e1159bbe 10882 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_8)]
cffb2a26 10883 "TARGET_EITHER"
10884 "*
10885 {
10886 making_const_table = TRUE;
10887 switch (GET_MODE_CLASS (GET_MODE (operands[0])))
10888 {
10889 case MODE_FLOAT:
10890 {
badfe841 10891 REAL_VALUE_TYPE r;
10892 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[0]);
10893 assemble_real (r, GET_MODE (operands[0]), BITS_PER_WORD);
cffb2a26 10894 break;
10895 }
10896 default:
09d688ff 10897 assemble_integer (operands[0], 8, BITS_PER_WORD, 1);
cffb2a26 10898 break;
10899 }
10900 return \"\";
10901 }"
1b7da4ac 10902 [(set_attr "length" "8")
10903 (set_attr "type" "no_insn")]
cffb2a26 10904)
10905
d98a3884 10906(define_insn "consttable_16"
10907 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_16)]
10908 "TARGET_EITHER"
10909 "*
10910 {
10911 making_const_table = TRUE;
10912 switch (GET_MODE_CLASS (GET_MODE (operands[0])))
10913 {
10914 case MODE_FLOAT:
10915 {
10916 REAL_VALUE_TYPE r;
10917 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[0]);
10918 assemble_real (r, GET_MODE (operands[0]), BITS_PER_WORD);
10919 break;
10920 }
10921 default:
10922 assemble_integer (operands[0], 16, BITS_PER_WORD, 1);
10923 break;
10924 }
10925 return \"\";
10926 }"
1b7da4ac 10927 [(set_attr "length" "16")
10928 (set_attr "type" "no_insn")]
d98a3884 10929)
10930
331beb1a 10931;; V5 Instructions,
10932
8f4be2be 10933(define_insn "clzsi2"
10934 [(set (match_operand:SI 0 "s_register_operand" "=r")
10935 (clz:SI (match_operand:SI 1 "s_register_operand" "r")))]
25f905c2 10936 "TARGET_32BIT && arm_arch5"
ee7cbe0e 10937 "clz%?\\t%0, %1"
bcaec148 10938 [(set_attr "predicable" "yes")
4a510717 10939 (set_attr "predicable_short_it" "no")
bebe9bbb 10940 (set_attr "type" "clz")])
331beb1a 10941
099ad98b 10942(define_insn "rbitsi2"
10943 [(set (match_operand:SI 0 "s_register_operand" "=r")
10944 (unspec:SI [(match_operand:SI 1 "s_register_operand" "r")] UNSPEC_RBIT))]
10945 "TARGET_32BIT && arm_arch_thumb2"
10946 "rbit%?\\t%0, %1"
10947 [(set_attr "predicable" "yes")
4a510717 10948 (set_attr "predicable_short_it" "no")
bebe9bbb 10949 (set_attr "type" "clz")])
099ad98b 10950
10951(define_expand "ctzsi2"
10952 [(set (match_operand:SI 0 "s_register_operand" "")
10953 (ctz:SI (match_operand:SI 1 "s_register_operand" "")))]
10954 "TARGET_32BIT && arm_arch_thumb2"
10955 "
30191172 10956 {
10957 rtx tmp = gen_reg_rtx (SImode);
10958 emit_insn (gen_rbitsi2 (tmp, operands[1]));
10959 emit_insn (gen_clzsi2 (operands[0], tmp));
10960 }
099ad98b 10961 DONE;
10962 "
10963)
10964
e1159bbe 10965;; V5E instructions.
331beb1a 10966
10967(define_insn "prefetch"
f4e79814 10968 [(prefetch (match_operand:SI 0 "address_operand" "p")
10969 (match_operand:SI 1 "" "")
10970 (match_operand:SI 2 "" ""))]
25f905c2 10971 "TARGET_32BIT && arm_arch5e"
1b7da4ac 10972 "pld\\t%a0"
10973 [(set_attr "type" "load1")]
10974)
331beb1a 10975
0d66636f 10976;; General predication pattern
10977
10978(define_cond_exec
10979 [(match_operator 0 "arm_comparison_operator"
10980 [(match_operand 1 "cc_register" "")
10981 (const_int 0)])]
580f4c48 10982 "TARGET_32BIT
10983 && (!TARGET_NO_VOLATILE_CE || !volatile_refs_p (PATTERN (insn)))"
0d66636f 10984 ""
c7a58118 10985[(set_attr "predicated" "yes")]
0d66636f 10986)
10987
fb94f18b 10988(define_insn "force_register_use"
10989 [(unspec:SI [(match_operand:SI 0 "register_operand" "")] UNSPEC_REGISTER_USE)]
063a05c7 10990 ""
fb94f18b 10991 "%@ %0 needed"
1b7da4ac 10992 [(set_attr "length" "0")
10993 (set_attr "type" "no_insn")]
063a05c7 10994)
7db9af5d 10995
4c44712e 10996
10997;; Patterns for exception handling
10998
10999(define_expand "eh_return"
11000 [(use (match_operand 0 "general_operand" ""))]
11001 "TARGET_EITHER"
11002 "
11003 {
25f905c2 11004 if (TARGET_32BIT)
4c44712e 11005 emit_insn (gen_arm_eh_return (operands[0]));
11006 else
11007 emit_insn (gen_thumb_eh_return (operands[0]));
11008 DONE;
11009 }"
11010)
11011
11012;; We can't expand this before we know where the link register is stored.
11013(define_insn_and_split "arm_eh_return"
11014 [(unspec_volatile [(match_operand:SI 0 "s_register_operand" "r")]
11015 VUNSPEC_EH_RETURN)
11016 (clobber (match_scratch:SI 1 "=&r"))]
11017 "TARGET_ARM"
11018 "#"
11019 "&& reload_completed"
11020 [(const_int 0)]
11021 "
11022 {
11023 arm_set_return_address (operands[0], operands[1]);
11024 DONE;
11025 }"
11026)
11027
f655717d 11028\f
11029;; TLS support
11030
11031(define_insn "load_tp_hard"
11032 [(set (match_operand:SI 0 "register_operand" "=r")
11033 (unspec:SI [(const_int 0)] UNSPEC_TLS))]
11034 "TARGET_HARD_TP"
11035 "mrc%?\\tp15, 0, %0, c13, c0, 3\\t@ load_tp_hard"
1b7da4ac 11036 [(set_attr "predicable" "yes")
4b5d7374 11037 (set_attr "type" "mrs")]
f655717d 11038)
11039
11040;; Doesn't clobber R1-R3. Must use r0 for the first operand.
11041(define_insn "load_tp_soft"
11042 [(set (reg:SI 0) (unspec:SI [(const_int 0)] UNSPEC_TLS))
11043 (clobber (reg:SI LR_REGNUM))
11044 (clobber (reg:SI IP_REGNUM))
11045 (clobber (reg:CC CC_REGNUM))]
11046 "TARGET_SOFT_TP"
11047 "bl\\t__aeabi_read_tp\\t@ load_tp_soft"
1b7da4ac 11048 [(set_attr "conds" "clob")
11049 (set_attr "type" "branch")]
f655717d 11050)
11051
f41e4452 11052;; tls descriptor call
11053(define_insn "tlscall"
11054 [(set (reg:SI R0_REGNUM)
11055 (unspec:SI [(reg:SI R0_REGNUM)
11056 (match_operand:SI 0 "" "X")
11057 (match_operand 1 "" "")] UNSPEC_TLS))
11058 (clobber (reg:SI R1_REGNUM))
11059 (clobber (reg:SI LR_REGNUM))
11060 (clobber (reg:SI CC_REGNUM))]
11061 "TARGET_GNU2_TLS"
11062 {
11063 targetm.asm_out.internal_label (asm_out_file, "LPIC",
11064 INTVAL (operands[1]));
11065 return "bl\\t%c0(tlscall)";
11066 }
11067 [(set_attr "conds" "clob")
1b7da4ac 11068 (set_attr "length" "4")
11069 (set_attr "type" "branch")]
f41e4452 11070)
11071
1fe0edab 11072;; For thread pointer builtin
11073(define_expand "get_thread_pointersi"
11074 [(match_operand:SI 0 "s_register_operand" "=r")]
11075 ""
11076 "
11077 {
11078 arm_load_tp (operands[0]);
11079 DONE;
11080 }")
11081
f41e4452 11082;;
11083
aabe09ac 11084;; We only care about the lower 16 bits of the constant
11085;; being inserted into the upper 16 bits of the register.
eca5c984 11086(define_insn "*arm_movtas_ze"
11087 [(set (zero_extract:SI (match_operand:SI 0 "s_register_operand" "+r")
11088 (const_int 16)
11089 (const_int 16))
11090 (match_operand:SI 1 "const_int_operand" ""))]
181ab277 11091 "arm_arch_thumb2"
aabe09ac 11092 "movt%?\t%0, %L1"
eca5c984 11093 [(set_attr "predicable" "yes")
7c36fe71 11094 (set_attr "predicable_short_it" "no")
1b7da4ac 11095 (set_attr "length" "4")
282b4c75 11096 (set_attr "type" "alu_sreg")]
eca5c984 11097)
11098
c0fc3696 11099(define_insn "*arm_rev"
a486b499 11100 [(set (match_operand:SI 0 "s_register_operand" "=l,l,r")
11101 (bswap:SI (match_operand:SI 1 "s_register_operand" "l,l,r")))]
11102 "arm_arch6"
11103 "@
11104 rev\t%0, %1
11105 rev%?\t%0, %1
11106 rev%?\t%0, %1"
11107 [(set_attr "arch" "t1,t2,32")
1b7da4ac 11108 (set_attr "length" "2,2,4")
4a510717 11109 (set_attr "predicable" "no,yes,yes")
11110 (set_attr "predicable_short_it" "no")
1b7da4ac 11111 (set_attr "type" "rev")]
ff82f757 11112)
11113
11114(define_expand "arm_legacy_rev"
11115 [(set (match_operand:SI 2 "s_register_operand" "")
11116 (xor:SI (rotatert:SI (match_operand:SI 1 "s_register_operand" "")
11117 (const_int 16))
11118 (match_dup 1)))
11119 (set (match_dup 2)
11120 (lshiftrt:SI (match_dup 2)
11121 (const_int 8)))
11122 (set (match_operand:SI 3 "s_register_operand" "")
11123 (rotatert:SI (match_dup 1)
11124 (const_int 8)))
11125 (set (match_dup 2)
11126 (and:SI (match_dup 2)
11127 (const_int -65281)))
11128 (set (match_operand:SI 0 "s_register_operand" "")
11129 (xor:SI (match_dup 3)
11130 (match_dup 2)))]
11131 "TARGET_32BIT"
11132 ""
11133)
11134
11135;; Reuse temporaries to keep register pressure down.
11136(define_expand "thumb_legacy_rev"
11137 [(set (match_operand:SI 2 "s_register_operand" "")
11138 (ashift:SI (match_operand:SI 1 "s_register_operand" "")
11139 (const_int 24)))
11140 (set (match_operand:SI 3 "s_register_operand" "")
11141 (lshiftrt:SI (match_dup 1)
11142 (const_int 24)))
11143 (set (match_dup 3)
11144 (ior:SI (match_dup 3)
11145 (match_dup 2)))
11146 (set (match_operand:SI 4 "s_register_operand" "")
11147 (const_int 16))
11148 (set (match_operand:SI 5 "s_register_operand" "")
11149 (rotatert:SI (match_dup 1)
11150 (match_dup 4)))
11151 (set (match_dup 2)
11152 (ashift:SI (match_dup 5)
11153 (const_int 24)))
11154 (set (match_dup 5)
11155 (lshiftrt:SI (match_dup 5)
11156 (const_int 24)))
11157 (set (match_dup 5)
11158 (ior:SI (match_dup 5)
11159 (match_dup 2)))
11160 (set (match_dup 5)
11161 (rotatert:SI (match_dup 5)
11162 (match_dup 4)))
11163 (set (match_operand:SI 0 "s_register_operand" "")
11164 (ior:SI (match_dup 5)
11165 (match_dup 3)))]
11166 "TARGET_THUMB"
11167 ""
11168)
11169
62e39b06 11170;; ARM-specific expansion of signed mod by power of 2
11171;; using conditional negate.
11172;; For r0 % n where n is a power of 2 produce:
11173;; rsbs r1, r0, #0
11174;; and r0, r0, #(n - 1)
11175;; and r1, r1, #(n - 1)
11176;; rsbpl r0, r1, #0
11177
11178(define_expand "modsi3"
11179 [(match_operand:SI 0 "register_operand" "")
11180 (match_operand:SI 1 "register_operand" "")
11181 (match_operand:SI 2 "const_int_operand" "")]
11182 "TARGET_32BIT"
11183 {
11184 HOST_WIDE_INT val = INTVAL (operands[2]);
11185
11186 if (val <= 0
11187 || exact_log2 (val) <= 0)
11188 FAIL;
11189
11190 rtx mask = GEN_INT (val - 1);
11191
11192 /* In the special case of x0 % 2 we can do the even shorter:
11193 cmp r0, #0
11194 and r0, r0, #1
11195 rsblt r0, r0, #0. */
11196
11197 if (val == 2)
11198 {
11199 rtx cc_reg = arm_gen_compare_reg (LT,
11200 operands[1], const0_rtx, NULL_RTX);
11201 rtx cond = gen_rtx_LT (SImode, cc_reg, const0_rtx);
11202 rtx masked = gen_reg_rtx (SImode);
11203
11204 emit_insn (gen_andsi3 (masked, operands[1], mask));
11205 emit_move_insn (operands[0],
11206 gen_rtx_IF_THEN_ELSE (SImode, cond,
11207 gen_rtx_NEG (SImode,
11208 masked),
11209 masked));
11210 DONE;
11211 }
11212
11213 rtx neg_op = gen_reg_rtx (SImode);
11214 rtx_insn *insn = emit_insn (gen_subsi3_compare0 (neg_op, const0_rtx,
11215 operands[1]));
11216
11217 /* Extract the condition register and mode. */
11218 rtx cmp = XVECEXP (PATTERN (insn), 0, 0);
11219 rtx cc_reg = SET_DEST (cmp);
11220 rtx cond = gen_rtx_GE (SImode, cc_reg, const0_rtx);
11221
11222 emit_insn (gen_andsi3 (operands[0], operands[1], mask));
11223
11224 rtx masked_neg = gen_reg_rtx (SImode);
11225 emit_insn (gen_andsi3 (masked_neg, neg_op, mask));
11226
11227 /* We want a conditional negate here, but emitting COND_EXEC rtxes
11228 during expand does not always work. Do an IF_THEN_ELSE instead. */
11229 emit_move_insn (operands[0],
11230 gen_rtx_IF_THEN_ELSE (SImode, cond,
11231 gen_rtx_NEG (SImode, masked_neg),
11232 operands[0]));
11233
11234
11235 DONE;
11236 }
11237)
11238
ff82f757 11239(define_expand "bswapsi2"
11240 [(set (match_operand:SI 0 "s_register_operand" "=r")
11241 (bswap:SI (match_operand:SI 1 "s_register_operand" "r")))]
8d1af482 11242"TARGET_EITHER && (arm_arch6 || !optimize_size)"
ff82f757 11243"
8d1af482 11244 if (!arm_arch6)
11245 {
11246 rtx op2 = gen_reg_rtx (SImode);
11247 rtx op3 = gen_reg_rtx (SImode);
ff82f757 11248
8d1af482 11249 if (TARGET_THUMB)
11250 {
11251 rtx op4 = gen_reg_rtx (SImode);
11252 rtx op5 = gen_reg_rtx (SImode);
ff82f757 11253
8d1af482 11254 emit_insn (gen_thumb_legacy_rev (operands[0], operands[1],
11255 op2, op3, op4, op5));
11256 }
11257 else
11258 {
11259 emit_insn (gen_arm_legacy_rev (operands[0], operands[1],
11260 op2, op3));
11261 }
ff82f757 11262
8d1af482 11263 DONE;
11264 }
ff82f757 11265 "
11266)
11267
a486b499 11268;; bswap16 patterns: use revsh and rev16 instructions for the signed
11269;; and unsigned variants, respectively. For rev16, expose
11270;; byte-swapping in the lower 16 bits only.
11271(define_insn "*arm_revsh"
11272 [(set (match_operand:SI 0 "s_register_operand" "=l,l,r")
11273 (sign_extend:SI (bswap:HI (match_operand:HI 1 "s_register_operand" "l,l,r"))))]
11274 "arm_arch6"
11275 "@
11276 revsh\t%0, %1
11277 revsh%?\t%0, %1
11278 revsh%?\t%0, %1"
11279 [(set_attr "arch" "t1,t2,32")
1b7da4ac 11280 (set_attr "length" "2,2,4")
11281 (set_attr "type" "rev")]
a486b499 11282)
11283
11284(define_insn "*arm_rev16"
11285 [(set (match_operand:HI 0 "s_register_operand" "=l,l,r")
11286 (bswap:HI (match_operand:HI 1 "s_register_operand" "l,l,r")))]
11287 "arm_arch6"
11288 "@
11289 rev16\t%0, %1
11290 rev16%?\t%0, %1
11291 rev16%?\t%0, %1"
11292 [(set_attr "arch" "t1,t2,32")
1b7da4ac 11293 (set_attr "length" "2,2,4")
11294 (set_attr "type" "rev")]
09f69e55 11295)
11296
11297;; There are no canonicalisation rules for the position of the lshiftrt, ashift
11298;; operations within an IOR/AND RTX, therefore we have two patterns matching
11299;; each valid permutation.
11300
11301(define_insn "arm_rev16si2"
11302 [(set (match_operand:SI 0 "register_operand" "=l,l,r")
11303 (ior:SI (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "l,l,r")
11304 (const_int 8))
11305 (match_operand:SI 3 "const_int_operand" "n,n,n"))
11306 (and:SI (lshiftrt:SI (match_dup 1)
11307 (const_int 8))
11308 (match_operand:SI 2 "const_int_operand" "n,n,n"))))]
11309 "arm_arch6
11310 && aarch_rev16_shleft_mask_imm_p (operands[3], SImode)
11311 && aarch_rev16_shright_mask_imm_p (operands[2], SImode)"
11312 "rev16\\t%0, %1"
11313 [(set_attr "arch" "t1,t2,32")
11314 (set_attr "length" "2,2,4")
11315 (set_attr "type" "rev")]
11316)
11317
11318(define_insn "arm_rev16si2_alt"
11319 [(set (match_operand:SI 0 "register_operand" "=l,l,r")
11320 (ior:SI (and:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" "l,l,r")
11321 (const_int 8))
11322 (match_operand:SI 2 "const_int_operand" "n,n,n"))
11323 (and:SI (ashift:SI (match_dup 1)
11324 (const_int 8))
11325 (match_operand:SI 3 "const_int_operand" "n,n,n"))))]
11326 "arm_arch6
11327 && aarch_rev16_shleft_mask_imm_p (operands[3], SImode)
11328 && aarch_rev16_shright_mask_imm_p (operands[2], SImode)"
11329 "rev16\\t%0, %1"
11330 [(set_attr "arch" "t1,t2,32")
11331 (set_attr "length" "2,2,4")
11332 (set_attr "type" "rev")]
a486b499 11333)
11334
11335(define_expand "bswaphi2"
11336 [(set (match_operand:HI 0 "s_register_operand" "=r")
11337 (bswap:HI (match_operand:HI 1 "s_register_operand" "r")))]
11338"arm_arch6"
11339""
11340)
11341
1653cf17 11342;; Patterns for LDRD/STRD in Thumb2 mode
11343
11344(define_insn "*thumb2_ldrd"
11345 [(set (match_operand:SI 0 "s_register_operand" "=r")
11346 (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "rk")
11347 (match_operand:SI 2 "ldrd_strd_offset_operand" "Do"))))
11348 (set (match_operand:SI 3 "s_register_operand" "=r")
11349 (mem:SI (plus:SI (match_dup 1)
11350 (match_operand:SI 4 "const_int_operand" ""))))]
11351 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11352 && current_tune->prefer_ldrd_strd
11353 && ((INTVAL (operands[2]) + 4) == INTVAL (operands[4]))
11354 && (operands_ok_ldrd_strd (operands[0], operands[3],
11355 operands[1], INTVAL (operands[2]),
11356 false, true))"
11357 "ldrd%?\t%0, %3, [%1, %2]"
11358 [(set_attr "type" "load2")
d952d547 11359 (set_attr "predicable" "yes")
11360 (set_attr "predicable_short_it" "no")])
1653cf17 11361
11362(define_insn "*thumb2_ldrd_base"
11363 [(set (match_operand:SI 0 "s_register_operand" "=r")
11364 (mem:SI (match_operand:SI 1 "s_register_operand" "rk")))
11365 (set (match_operand:SI 2 "s_register_operand" "=r")
11366 (mem:SI (plus:SI (match_dup 1)
11367 (const_int 4))))]
11368 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11369 && current_tune->prefer_ldrd_strd
11370 && (operands_ok_ldrd_strd (operands[0], operands[2],
11371 operands[1], 0, false, true))"
11372 "ldrd%?\t%0, %2, [%1]"
11373 [(set_attr "type" "load2")
d952d547 11374 (set_attr "predicable" "yes")
11375 (set_attr "predicable_short_it" "no")])
1653cf17 11376
11377(define_insn "*thumb2_ldrd_base_neg"
11378 [(set (match_operand:SI 0 "s_register_operand" "=r")
11379 (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "rk")
11380 (const_int -4))))
11381 (set (match_operand:SI 2 "s_register_operand" "=r")
11382 (mem:SI (match_dup 1)))]
11383 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11384 && current_tune->prefer_ldrd_strd
11385 && (operands_ok_ldrd_strd (operands[0], operands[2],
11386 operands[1], -4, false, true))"
11387 "ldrd%?\t%0, %2, [%1, #-4]"
11388 [(set_attr "type" "load2")
d952d547 11389 (set_attr "predicable" "yes")
11390 (set_attr "predicable_short_it" "no")])
1653cf17 11391
11392(define_insn "*thumb2_strd"
11393 [(set (mem:SI (plus:SI (match_operand:SI 0 "s_register_operand" "rk")
11394 (match_operand:SI 1 "ldrd_strd_offset_operand" "Do")))
11395 (match_operand:SI 2 "s_register_operand" "r"))
11396 (set (mem:SI (plus:SI (match_dup 0)
11397 (match_operand:SI 3 "const_int_operand" "")))
11398 (match_operand:SI 4 "s_register_operand" "r"))]
11399 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11400 && current_tune->prefer_ldrd_strd
11401 && ((INTVAL (operands[1]) + 4) == INTVAL (operands[3]))
11402 && (operands_ok_ldrd_strd (operands[2], operands[4],
11403 operands[0], INTVAL (operands[1]),
11404 false, false))"
11405 "strd%?\t%2, %4, [%0, %1]"
11406 [(set_attr "type" "store2")
d952d547 11407 (set_attr "predicable" "yes")
11408 (set_attr "predicable_short_it" "no")])
1653cf17 11409
11410(define_insn "*thumb2_strd_base"
11411 [(set (mem:SI (match_operand:SI 0 "s_register_operand" "rk"))
11412 (match_operand:SI 1 "s_register_operand" "r"))
11413 (set (mem:SI (plus:SI (match_dup 0)
11414 (const_int 4)))
11415 (match_operand:SI 2 "s_register_operand" "r"))]
11416 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11417 && current_tune->prefer_ldrd_strd
11418 && (operands_ok_ldrd_strd (operands[1], operands[2],
11419 operands[0], 0, false, false))"
11420 "strd%?\t%1, %2, [%0]"
11421 [(set_attr "type" "store2")
d952d547 11422 (set_attr "predicable" "yes")
11423 (set_attr "predicable_short_it" "no")])
1653cf17 11424
11425(define_insn "*thumb2_strd_base_neg"
11426 [(set (mem:SI (plus:SI (match_operand:SI 0 "s_register_operand" "rk")
11427 (const_int -4)))
11428 (match_operand:SI 1 "s_register_operand" "r"))
11429 (set (mem:SI (match_dup 0))
11430 (match_operand:SI 2 "s_register_operand" "r"))]
11431 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11432 && current_tune->prefer_ldrd_strd
11433 && (operands_ok_ldrd_strd (operands[1], operands[2],
11434 operands[0], -4, false, false))"
11435 "strd%?\t%1, %2, [%0, #-4]"
11436 [(set_attr "type" "store2")
d952d547 11437 (set_attr "predicable" "yes")
11438 (set_attr "predicable_short_it" "no")])
1653cf17 11439
2a0c73f2 11440;; ARMv8 CRC32 instructions.
11441(define_insn "<crc_variant>"
11442 [(set (match_operand:SI 0 "s_register_operand" "=r")
11443 (unspec:SI [(match_operand:SI 1 "s_register_operand" "r")
11444 (match_operand:<crc_mode> 2 "s_register_operand" "r")]
11445 CRC))]
11446 "TARGET_CRC32"
11447 "<crc_variant>\\t%0, %1, %2"
11448 [(set_attr "type" "crc")
11449 (set_attr "conds" "unconditional")]
11450)
1653cf17 11451
353cf59a 11452;; Load the load/store double peephole optimizations.
11453(include "ldrdstrd.md")
11454
320ea44d 11455;; Load the load/store multiple patterns
11456(include "ldmstm.md")
426be8c5 11457
11458;; Patterns in ldmstm.md don't cover more than 4 registers. This pattern covers
11459;; large lists without explicit writeback generated for APCS_FRAME epilogue.
11460(define_insn "*load_multiple"
11461 [(match_parallel 0 "load_multiple_operation"
11462 [(set (match_operand:SI 2 "s_register_operand" "=rk")
11463 (mem:SI (match_operand:SI 1 "s_register_operand" "rk")))
11464 ])]
11465 "TARGET_32BIT"
11466 "*
11467 {
11468 arm_output_multireg_pop (operands, /*return_pc=*/false,
11469 /*cond=*/const_true_rtx,
11470 /*reverse=*/false,
11471 /*update=*/false);
11472 return \"\";
11473 }
11474 "
11475 [(set_attr "predicable" "yes")]
11476)
11477
84450ddc 11478(define_expand "copysignsf3"
11479 [(match_operand:SF 0 "register_operand")
11480 (match_operand:SF 1 "register_operand")
11481 (match_operand:SF 2 "register_operand")]
11482 "TARGET_SOFT_FLOAT && arm_arch_thumb2"
11483 "{
11484 emit_move_insn (operands[0], operands[2]);
11485 emit_insn (gen_insv_t2 (simplify_gen_subreg (SImode, operands[0], SFmode, 0),
11486 GEN_INT (31), GEN_INT (0),
11487 simplify_gen_subreg (SImode, operands[1], SFmode, 0)));
11488 DONE;
11489 }"
11490)
11491
11492(define_expand "copysigndf3"
11493 [(match_operand:DF 0 "register_operand")
11494 (match_operand:DF 1 "register_operand")
11495 (match_operand:DF 2 "register_operand")]
11496 "TARGET_SOFT_FLOAT && arm_arch_thumb2"
11497 "{
11498 rtx op0_low = gen_lowpart (SImode, operands[0]);
11499 rtx op0_high = gen_highpart (SImode, operands[0]);
11500 rtx op1_low = gen_lowpart (SImode, operands[1]);
11501 rtx op1_high = gen_highpart (SImode, operands[1]);
11502 rtx op2_high = gen_highpart (SImode, operands[2]);
11503
11504 rtx scratch1 = gen_reg_rtx (SImode);
11505 rtx scratch2 = gen_reg_rtx (SImode);
11506 emit_move_insn (scratch1, op2_high);
11507 emit_move_insn (scratch2, op1_high);
11508
d1f9b275 11509 emit_insn(gen_rtx_SET(scratch1,
84450ddc 11510 gen_rtx_LSHIFTRT (SImode, op2_high, GEN_INT(31))));
11511 emit_insn(gen_insv_t2(scratch2, GEN_INT(1), GEN_INT(31), scratch1));
11512 emit_move_insn (op0_low, op1_low);
11513 emit_move_insn (op0_high, scratch2);
11514
11515 DONE;
11516 }"
11517)
11518
d98a3884 11519;; Vector bits common to IWMMXT and Neon
11520(include "vec-common.md")
755eb2b4 11521;; Load the Intel Wireless Multimedia Extension patterns
11522(include "iwmmxt.md")
a2cd141b 11523;; Load the VFP co-processor patterns
11524(include "vfp.md")
bc360af8 11525;; Thumb-1 patterns
11526(include "thumb1.md")
25f905c2 11527;; Thumb-2 patterns
11528(include "thumb2.md")
d98a3884 11529;; Neon patterns
11530(include "neon.md")
e84fdf6e 11531;; Crypto patterns
11532(include "crypto.md")
06df6b17 11533;; Synchronization Primitives
11534(include "sync.md")
bbbe4599 11535;; Fixed-point patterns
11536(include "arm-fixed.md")