]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/config/arm/arm.md
* c-common.c (shorten_compare): But look through macros from
[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 "@
3ef90e77 625 adds%?\\t%0, %1, %2
626 subs%?\\t%0, %1, #%n2
627 adds%?\\t%0, %1, %2"
65f68e55 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 "@
3ef90e77 675 adds%?\\t%0, %1, %3
676 subs%?\\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 "@
3ef90e77 732 adds%?\\t%0, %1, %2
733 subs%?\\t%0, %1, #%n2
734 adds%?\\t%0, %1, %2"
65f68e55 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 "@
3ef90e77 749 adds%?\\t%0, %1, %2
38128b57 750 subs%?\\t%0, %1, #%n2
751 adds%?\\t%0, %1, %2"
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"
3ef90e77 859 "adcs%?\\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 "@
3ef90e77 1242 subs%?\\t%0, %1, %2
1243 subs%?\\t%0, %1, %2
1244 rsbs%?\\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 "@
3ef90e77 1257 subs%?\\t%0, %1, %2
1258 subs%?\\t%0, %1, %2
1259 rsbs%?\\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"
3ef90e77 1338 "muls%?\\t%0, %2, %1"
58d7d654 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"
3ef90e77 1352 "muls%?\\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"
3ef90e77 1365 "muls%?\\t%0, %2, %1"
58d7d654 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"
3ef90e77 1378 "muls%?\\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"
3ef90e77 1422 "mlas%?\\t%0, %2, %1, %3"
58d7d654 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"
3ef90e77 1439 "mlas%?\\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"
3ef90e77 1454 "mlas%?\\t%0, %2, %1, %3"
58d7d654 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"
3ef90e77 1469 "mlas%?\\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 "@
3ef90e77 2198 ands%?\\t%0, %1, %2
2199 bics%?\\t%0, %1, #%B2
2200 ands%?\\t%0, %1, %2"
65f68e55 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
3ef90e77 2215 bics%?\\t%2, %0, #%B1
65f68e55 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]))"
3ef90e77 2799 "bics%?\\t%4, %3, %1%S0"
9ed784d8 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]))"
3ef90e77 2825 "bics%?\\t%4, %3, %1%S0"
9ed784d8 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"
3ef90e77 2844 "bics\\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"
3ef90e77 2857 "bics\\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"
3ef90e77 3026 "orrs%?\\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"
3ef90e77 3038 "orrs%?\\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"
3ef90e77 3185 "eors%?\\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
25f905c2 3458(define_expand "umaxsi3"
3459 [(parallel [
3460 (set (match_operand:SI 0 "s_register_operand" "")
3461 (umax:SI (match_operand:SI 1 "s_register_operand" "")
3462 (match_operand:SI 2 "arm_rhs_operand" "")))
3463 (clobber (reg:CC CC_REGNUM))])]
3464 "TARGET_32BIT"
3465 ""
3466)
3467
3dc953f2 3468(define_insn_and_split "*arm_umaxsi3"
9c08d1fa 3469 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
3470 (umax:SI (match_operand:SI 1 "s_register_operand" "0,r,?r")
3471 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
bd5b4116 3472 (clobber (reg:CC CC_REGNUM))]
cffb2a26 3473 "TARGET_ARM"
3dc953f2 3474 "#"
3475 ; cmp\\t%1, %2\;movcc\\t%0, %2
3476 ; cmp\\t%1, %2\;movcs\\t%0, %1
3477 ; cmp\\t%1, %2\;movcs\\t%0, %1\;movcc\\t%0, %2"
3478 "TARGET_ARM"
3479 [(set (reg:CC CC_REGNUM)
3480 (compare:CC (match_dup 1) (match_dup 2)))
3481 (set (match_dup 0)
3482 (if_then_else:SI (geu:SI (reg:CC CC_REGNUM) (const_int 0))
3483 (match_dup 1)
3484 (match_dup 2)))]
3485 ""
0d66636f 3486 [(set_attr "conds" "clob")
1b7da4ac 3487 (set_attr "length" "8,8,12")
3488 (set_attr "type" "store1")]
0d66636f 3489)
9c08d1fa 3490
25f905c2 3491(define_expand "uminsi3"
3492 [(parallel [
3493 (set (match_operand:SI 0 "s_register_operand" "")
3494 (umin:SI (match_operand:SI 1 "s_register_operand" "")
3495 (match_operand:SI 2 "arm_rhs_operand" "")))
3496 (clobber (reg:CC CC_REGNUM))])]
3497 "TARGET_32BIT"
3498 ""
3499)
3500
3dc953f2 3501(define_insn_and_split "*arm_uminsi3"
9c08d1fa 3502 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
3503 (umin:SI (match_operand:SI 1 "s_register_operand" "0,r,?r")
3504 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
bd5b4116 3505 (clobber (reg:CC CC_REGNUM))]
cffb2a26 3506 "TARGET_ARM"
3dc953f2 3507 "#"
3508 ; cmp\\t%1, %2\;movcs\\t%0, %2
3509 ; cmp\\t%1, %2\;movcc\\t%0, %1
3510 ; cmp\\t%1, %2\;movcc\\t%0, %1\;movcs\\t%0, %2"
3511 "TARGET_ARM"
3512 [(set (reg:CC CC_REGNUM)
3513 (compare:CC (match_dup 1) (match_dup 2)))
3514 (set (match_dup 0)
3515 (if_then_else:SI (ltu:SI (reg:CC CC_REGNUM) (const_int 0))
3516 (match_dup 1)
3517 (match_dup 2)))]
3518 ""
0d66636f 3519 [(set_attr "conds" "clob")
1b7da4ac 3520 (set_attr "length" "8,8,12")
3521 (set_attr "type" "store1")]
0d66636f 3522)
9c08d1fa 3523
8a18b90c 3524(define_insn "*store_minmaxsi"
9c08d1fa 3525 [(set (match_operand:SI 0 "memory_operand" "=m")
3526 (match_operator:SI 3 "minmax_operator"
3527 [(match_operand:SI 1 "s_register_operand" "r")
3528 (match_operand:SI 2 "s_register_operand" "r")]))
bd5b4116 3529 (clobber (reg:CC CC_REGNUM))]
b207d152 3530 "TARGET_32BIT && optimize_function_for_size_p (cfun) && !arm_restrict_it"
9c08d1fa 3531 "*
dc55b8a9 3532 operands[3] = gen_rtx_fmt_ee (minmax_code (operands[3]), SImode,
3533 operands[1], operands[2]);
e2348bcb 3534 output_asm_insn (\"cmp\\t%1, %2\", operands);
25f905c2 3535 if (TARGET_THUMB2)
3536 output_asm_insn (\"ite\t%d3\", operands);
e2348bcb 3537 output_asm_insn (\"str%d3\\t%1, %0\", operands);
3538 output_asm_insn (\"str%D3\\t%2, %0\", operands);
3539 return \"\";
0d66636f 3540 "
3541 [(set_attr "conds" "clob")
25f905c2 3542 (set (attr "length")
3543 (if_then_else (eq_attr "is_thumb" "yes")
3544 (const_int 14)
3545 (const_int 12)))
0d66636f 3546 (set_attr "type" "store1")]
3547)
9c08d1fa 3548
8a18b90c 3549; Reject the frame pointer in operand[1], since reloading this after
3550; it has been eliminated can cause carnage.
f7fbdd4a 3551(define_insn "*minmax_arithsi"
9c08d1fa 3552 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
3553 (match_operator:SI 4 "shiftable_operator"
3554 [(match_operator:SI 5 "minmax_operator"
3555 [(match_operand:SI 2 "s_register_operand" "r,r")
3556 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
3557 (match_operand:SI 1 "s_register_operand" "0,?r")]))
bd5b4116 3558 (clobber (reg:CC CC_REGNUM))]
7c36fe71 3559 "TARGET_32BIT && !arm_eliminable_register (operands[1]) && !arm_restrict_it"
9c08d1fa 3560 "*
0d66636f 3561 {
3562 enum rtx_code code = GET_CODE (operands[4]);
25f905c2 3563 bool need_else;
3564
3565 if (which_alternative != 0 || operands[3] != const0_rtx
ca0fc5a2 3566 || (code != PLUS && code != IOR && code != XOR))
25f905c2 3567 need_else = true;
3568 else
3569 need_else = false;
0d66636f 3570
dc55b8a9 3571 operands[5] = gen_rtx_fmt_ee (minmax_code (operands[5]), SImode,
3572 operands[2], operands[3]);
0d66636f 3573 output_asm_insn (\"cmp\\t%2, %3\", operands);
25f905c2 3574 if (TARGET_THUMB2)
3575 {
3576 if (need_else)
3577 output_asm_insn (\"ite\\t%d5\", operands);
3578 else
3579 output_asm_insn (\"it\\t%d5\", operands);
3580 }
0d66636f 3581 output_asm_insn (\"%i4%d5\\t%0, %1, %2\", operands);
25f905c2 3582 if (need_else)
0d66636f 3583 output_asm_insn (\"%i4%D5\\t%0, %1, %3\", operands);
3584 return \"\";
215b30b3 3585 }"
0d66636f 3586 [(set_attr "conds" "clob")
25f905c2 3587 (set (attr "length")
3588 (if_then_else (eq_attr "is_thumb" "yes")
3589 (const_int 14)
1b7da4ac 3590 (const_int 12)))
3591 (set_attr "type" "multiple")]
0d66636f 3592)
9c08d1fa 3593
4164bca1 3594; Reject the frame pointer in operand[1], since reloading this after
3595; it has been eliminated can cause carnage.
3596(define_insn_and_split "*minmax_arithsi_non_canon"
7c36fe71 3597 [(set (match_operand:SI 0 "s_register_operand" "=Ts,Ts")
4164bca1 3598 (minus:SI
7c36fe71 3599 (match_operand:SI 1 "s_register_operand" "0,?Ts")
4164bca1 3600 (match_operator:SI 4 "minmax_operator"
7c36fe71 3601 [(match_operand:SI 2 "s_register_operand" "Ts,Ts")
3602 (match_operand:SI 3 "arm_rhs_operand" "TsI,TsI")])))
4164bca1 3603 (clobber (reg:CC CC_REGNUM))]
7c36fe71 3604 "TARGET_32BIT && !arm_eliminable_register (operands[1])
3605 && !(arm_restrict_it && CONST_INT_P (operands[3]))"
4164bca1 3606 "#"
3607 "TARGET_32BIT && !arm_eliminable_register (operands[1]) && reload_completed"
3608 [(set (reg:CC CC_REGNUM)
3609 (compare:CC (match_dup 2) (match_dup 3)))
3610
3611 (cond_exec (match_op_dup 4 [(reg:CC CC_REGNUM) (const_int 0)])
3612 (set (match_dup 0)
3613 (minus:SI (match_dup 1)
3614 (match_dup 2))))
3615 (cond_exec (match_op_dup 5 [(reg:CC CC_REGNUM) (const_int 0)])
3616 (set (match_dup 0)
36ee0cde 3617 (match_dup 6)))]
4164bca1 3618 {
3754d046 3619 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
4164bca1 3620 operands[2], operands[3]);
3621 enum rtx_code rc = minmax_code (operands[4]);
3622 operands[4] = gen_rtx_fmt_ee (rc, VOIDmode,
3623 operands[2], operands[3]);
3624
3625 if (mode == CCFPmode || mode == CCFPEmode)
3626 rc = reverse_condition_maybe_unordered (rc);
3627 else
3628 rc = reverse_condition (rc);
3629 operands[5] = gen_rtx_fmt_ee (rc, SImode, operands[2], operands[3]);
36ee0cde 3630 if (CONST_INT_P (operands[3]))
3631 operands[6] = plus_constant (SImode, operands[1], -INTVAL (operands[3]));
3632 else
3633 operands[6] = gen_rtx_MINUS (SImode, operands[1], operands[3]);
4164bca1 3634 }
3635 [(set_attr "conds" "clob")
3636 (set (attr "length")
3637 (if_then_else (eq_attr "is_thumb" "yes")
3638 (const_int 14)
1b7da4ac 3639 (const_int 12)))
3640 (set_attr "type" "multiple")]
4164bca1 3641)
3642
b49e3742 3643(define_code_iterator SAT [smin smax])
3644(define_code_iterator SATrev [smin smax])
3645(define_code_attr SATlo [(smin "1") (smax "2")])
3646(define_code_attr SAThi [(smin "2") (smax "1")])
3647
3648(define_insn "*satsi_<SAT:code>"
3649 [(set (match_operand:SI 0 "s_register_operand" "=r")
3650 (SAT:SI (SATrev:SI (match_operand:SI 3 "s_register_operand" "r")
3651 (match_operand:SI 1 "const_int_operand" "i"))
3652 (match_operand:SI 2 "const_int_operand" "i")))]
3653 "TARGET_32BIT && arm_arch6 && <SAT:CODE> != <SATrev:CODE>
3654 && arm_sat_operator_match (operands[<SAT:SATlo>], operands[<SAT:SAThi>], NULL, NULL)"
3655{
3656 int mask;
3657 bool signed_sat;
3658 if (!arm_sat_operator_match (operands[<SAT:SATlo>], operands[<SAT:SAThi>],
3659 &mask, &signed_sat))
3660 gcc_unreachable ();
3661
3662 operands[1] = GEN_INT (mask);
3663 if (signed_sat)
3664 return "ssat%?\t%0, %1, %3";
3665 else
3666 return "usat%?\t%0, %1, %3";
3667}
7c36fe71 3668 [(set_attr "predicable" "yes")
1b7da4ac 3669 (set_attr "predicable_short_it" "no")
3670 (set_attr "type" "alus_imm")]
bebe9bbb 3671)
b49e3742 3672
3673(define_insn "*satsi_<SAT:code>_shift"
3674 [(set (match_operand:SI 0 "s_register_operand" "=r")
3675 (SAT:SI (SATrev:SI (match_operator:SI 3 "sat_shift_operator"
3676 [(match_operand:SI 4 "s_register_operand" "r")
3677 (match_operand:SI 5 "const_int_operand" "i")])
3678 (match_operand:SI 1 "const_int_operand" "i"))
3679 (match_operand:SI 2 "const_int_operand" "i")))]
3680 "TARGET_32BIT && arm_arch6 && <SAT:CODE> != <SATrev:CODE>
3681 && arm_sat_operator_match (operands[<SAT:SATlo>], operands[<SAT:SAThi>], NULL, NULL)"
3682{
3683 int mask;
3684 bool signed_sat;
3685 if (!arm_sat_operator_match (operands[<SAT:SATlo>], operands[<SAT:SAThi>],
3686 &mask, &signed_sat))
3687 gcc_unreachable ();
3688
3689 operands[1] = GEN_INT (mask);
3690 if (signed_sat)
3691 return "ssat%?\t%0, %1, %4%S3";
3692 else
3693 return "usat%?\t%0, %1, %4%S3";
3694}
3695 [(set_attr "predicable" "yes")
7c36fe71 3696 (set_attr "predicable_short_it" "no")
b49e3742 3697 (set_attr "shift" "3")
d82e788e 3698 (set_attr "type" "logic_shift_reg")])
b11cae9e 3699\f
3700;; Shift and rotation insns
3701
a2cd141b 3702(define_expand "ashldi3"
3703 [(set (match_operand:DI 0 "s_register_operand" "")
3704 (ashift:DI (match_operand:DI 1 "s_register_operand" "")
aa06c51c 3705 (match_operand:SI 2 "general_operand" "")))]
25f905c2 3706 "TARGET_32BIT"
a2cd141b 3707 "
aa06c51c 3708 if (TARGET_NEON)
3709 {
3710 /* Delay the decision whether to use NEON or core-regs until
3711 register allocation. */
3712 emit_insn (gen_ashldi3_neon (operands[0], operands[1], operands[2]));
3713 DONE;
3714 }
3715 else
3716 {
3717 /* Only the NEON case can handle in-memory shift counts. */
3718 if (!reg_or_int_operand (operands[2], SImode))
3719 operands[2] = force_reg (SImode, operands[2]);
3720 }
3721
b805622c 3722 if (!CONST_INT_P (operands[2]) && TARGET_REALLY_IWMMXT)
ffcc986d 3723 ; /* No special preparation statements; expand pattern as above. */
3724 else
a2cd141b 3725 {
ffcc986d 3726 rtx scratch1, scratch2;
3727
3728 if (CONST_INT_P (operands[2])
3729 && (HOST_WIDE_INT) INTVAL (operands[2]) == 1)
a2cd141b 3730 {
3731 emit_insn (gen_arm_ashldi3_1bit (operands[0], operands[1]));
3732 DONE;
3733 }
ffcc986d 3734
3735 /* Ideally we should use iwmmxt here if we could know that operands[1]
3736 ends up already living in an iwmmxt register. Otherwise it's
3737 cheaper to have the alternate code being generated than moving
3738 values to iwmmxt regs and back. */
3739
3740 /* If we're optimizing for size, we prefer the libgcc calls. */
3741 if (optimize_function_for_size_p (cfun))
3742 FAIL;
3743
3744 /* Expand operation using core-registers.
3745 'FAIL' would achieve the same thing, but this is a bit smarter. */
3746 scratch1 = gen_reg_rtx (SImode);
3747 scratch2 = gen_reg_rtx (SImode);
3748 arm_emit_coreregs_64bit_shift (ASHIFT, operands[0], operands[1],
3749 operands[2], scratch1, scratch2);
3750 DONE;
a2cd141b 3751 }
a2cd141b 3752 "
3753)
3754
2837e3fb 3755(define_insn "arm_ashldi3_1bit"
50ad1bf9 3756 [(set (match_operand:DI 0 "s_register_operand" "=r,&r")
e5fea38e 3757 (ashift:DI (match_operand:DI 1 "s_register_operand" "0,r")
a2cd141b 3758 (const_int 1)))
3759 (clobber (reg:CC CC_REGNUM))]
25f905c2 3760 "TARGET_32BIT"
2837e3fb 3761 "movs\\t%Q0, %Q1, asl #1\;adc\\t%R0, %R1, %R1"
a2cd141b 3762 [(set_attr "conds" "clob")
1b7da4ac 3763 (set_attr "length" "8")
3764 (set_attr "type" "multiple")]
a2cd141b 3765)
3766
87b22bf7 3767(define_expand "ashlsi3"
cffb2a26 3768 [(set (match_operand:SI 0 "s_register_operand" "")
87b22bf7 3769 (ashift:SI (match_operand:SI 1 "s_register_operand" "")
3770 (match_operand:SI 2 "arm_rhs_operand" "")))]
cffb2a26 3771 "TARGET_EITHER"
87b22bf7 3772 "
0438d37f 3773 if (CONST_INT_P (operands[2])
87b22bf7 3774 && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) > 31)
3775 {
3776 emit_insn (gen_movsi (operands[0], const0_rtx));
3777 DONE;
3778 }
cffb2a26 3779 "
3780)
3781
a2cd141b 3782(define_expand "ashrdi3"
3783 [(set (match_operand:DI 0 "s_register_operand" "")
3784 (ashiftrt:DI (match_operand:DI 1 "s_register_operand" "")
3785 (match_operand:SI 2 "reg_or_int_operand" "")))]
25f905c2 3786 "TARGET_32BIT"
a2cd141b 3787 "
aa06c51c 3788 if (TARGET_NEON)
3789 {
3790 /* Delay the decision whether to use NEON or core-regs until
3791 register allocation. */
3792 emit_insn (gen_ashrdi3_neon (operands[0], operands[1], operands[2]));
3793 DONE;
3794 }
3795
b805622c 3796 if (!CONST_INT_P (operands[2]) && TARGET_REALLY_IWMMXT)
ffcc986d 3797 ; /* No special preparation statements; expand pattern as above. */
3798 else
a2cd141b 3799 {
ffcc986d 3800 rtx scratch1, scratch2;
3801
3802 if (CONST_INT_P (operands[2])
3803 && (HOST_WIDE_INT) INTVAL (operands[2]) == 1)
a2cd141b 3804 {
3805 emit_insn (gen_arm_ashrdi3_1bit (operands[0], operands[1]));
3806 DONE;
3807 }
ffcc986d 3808
3809 /* Ideally we should use iwmmxt here if we could know that operands[1]
3810 ends up already living in an iwmmxt register. Otherwise it's
3811 cheaper to have the alternate code being generated than moving
3812 values to iwmmxt regs and back. */
3813
3814 /* If we're optimizing for size, we prefer the libgcc calls. */
3815 if (optimize_function_for_size_p (cfun))
3816 FAIL;
3817
3818 /* Expand operation using core-registers.
3819 'FAIL' would achieve the same thing, but this is a bit smarter. */
3820 scratch1 = gen_reg_rtx (SImode);
3821 scratch2 = gen_reg_rtx (SImode);
3822 arm_emit_coreregs_64bit_shift (ASHIFTRT, operands[0], operands[1],
3823 operands[2], scratch1, scratch2);
3824 DONE;
a2cd141b 3825 }
a2cd141b 3826 "
3827)
3828
2837e3fb 3829(define_insn "arm_ashrdi3_1bit"
50ad1bf9 3830 [(set (match_operand:DI 0 "s_register_operand" "=r,&r")
e5fea38e 3831 (ashiftrt:DI (match_operand:DI 1 "s_register_operand" "0,r")
a2cd141b 3832 (const_int 1)))
3833 (clobber (reg:CC CC_REGNUM))]
25f905c2 3834 "TARGET_32BIT"
2837e3fb 3835 "movs\\t%R0, %R1, asr #1\;mov\\t%Q0, %Q1, rrx"
a2cd141b 3836 [(set_attr "conds" "clob")
1b7da4ac 3837 (set_attr "length" "8")
3838 (set_attr "type" "multiple")]
a2cd141b 3839)
3840
87b22bf7 3841(define_expand "ashrsi3"
cffb2a26 3842 [(set (match_operand:SI 0 "s_register_operand" "")
87b22bf7 3843 (ashiftrt:SI (match_operand:SI 1 "s_register_operand" "")
3844 (match_operand:SI 2 "arm_rhs_operand" "")))]
cffb2a26 3845 "TARGET_EITHER"
87b22bf7 3846 "
0438d37f 3847 if (CONST_INT_P (operands[2])
87b22bf7 3848 && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) > 31)
3849 operands[2] = GEN_INT (31);
cffb2a26 3850 "
3851)
3852
a2cd141b 3853(define_expand "lshrdi3"
3854 [(set (match_operand:DI 0 "s_register_operand" "")
3855 (lshiftrt:DI (match_operand:DI 1 "s_register_operand" "")
3856 (match_operand:SI 2 "reg_or_int_operand" "")))]
25f905c2 3857 "TARGET_32BIT"
a2cd141b 3858 "
aa06c51c 3859 if (TARGET_NEON)
3860 {
3861 /* Delay the decision whether to use NEON or core-regs until
3862 register allocation. */
3863 emit_insn (gen_lshrdi3_neon (operands[0], operands[1], operands[2]));
3864 DONE;
3865 }
3866
b805622c 3867 if (!CONST_INT_P (operands[2]) && TARGET_REALLY_IWMMXT)
ffcc986d 3868 ; /* No special preparation statements; expand pattern as above. */
3869 else
a2cd141b 3870 {
ffcc986d 3871 rtx scratch1, scratch2;
3872
3873 if (CONST_INT_P (operands[2])
3874 && (HOST_WIDE_INT) INTVAL (operands[2]) == 1)
a2cd141b 3875 {
3876 emit_insn (gen_arm_lshrdi3_1bit (operands[0], operands[1]));
3877 DONE;
3878 }
ffcc986d 3879
3880 /* Ideally we should use iwmmxt here if we could know that operands[1]
3881 ends up already living in an iwmmxt register. Otherwise it's
3882 cheaper to have the alternate code being generated than moving
3883 values to iwmmxt regs and back. */
3884
3885 /* If we're optimizing for size, we prefer the libgcc calls. */
3886 if (optimize_function_for_size_p (cfun))
3887 FAIL;
3888
3889 /* Expand operation using core-registers.
3890 'FAIL' would achieve the same thing, but this is a bit smarter. */
3891 scratch1 = gen_reg_rtx (SImode);
3892 scratch2 = gen_reg_rtx (SImode);
3893 arm_emit_coreregs_64bit_shift (LSHIFTRT, operands[0], operands[1],
3894 operands[2], scratch1, scratch2);
3895 DONE;
a2cd141b 3896 }
a2cd141b 3897 "
3898)
3899
2837e3fb 3900(define_insn "arm_lshrdi3_1bit"
50ad1bf9 3901 [(set (match_operand:DI 0 "s_register_operand" "=r,&r")
e5fea38e 3902 (lshiftrt:DI (match_operand:DI 1 "s_register_operand" "0,r")
a2cd141b 3903 (const_int 1)))
3904 (clobber (reg:CC CC_REGNUM))]
25f905c2 3905 "TARGET_32BIT"
2837e3fb 3906 "movs\\t%R0, %R1, lsr #1\;mov\\t%Q0, %Q1, rrx"
a2cd141b 3907 [(set_attr "conds" "clob")
1b7da4ac 3908 (set_attr "length" "8")
3909 (set_attr "type" "multiple")]
a2cd141b 3910)
3911
87b22bf7 3912(define_expand "lshrsi3"
cffb2a26 3913 [(set (match_operand:SI 0 "s_register_operand" "")
87b22bf7 3914 (lshiftrt:SI (match_operand:SI 1 "s_register_operand" "")
3915 (match_operand:SI 2 "arm_rhs_operand" "")))]
cffb2a26 3916 "TARGET_EITHER"
87b22bf7 3917 "
0438d37f 3918 if (CONST_INT_P (operands[2])
87b22bf7 3919 && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) > 31)
3920 {
3921 emit_insn (gen_movsi (operands[0], const0_rtx));
3922 DONE;
3923 }
cffb2a26 3924 "
3925)
3926
87b22bf7 3927(define_expand "rotlsi3"
cffb2a26 3928 [(set (match_operand:SI 0 "s_register_operand" "")
87b22bf7 3929 (rotatert:SI (match_operand:SI 1 "s_register_operand" "")
3930 (match_operand:SI 2 "reg_or_int_operand" "")))]
25f905c2 3931 "TARGET_32BIT"
87b22bf7 3932 "
0438d37f 3933 if (CONST_INT_P (operands[2]))
87b22bf7 3934 operands[2] = GEN_INT ((32 - INTVAL (operands[2])) % 32);
3935 else
b11cae9e 3936 {
87b22bf7 3937 rtx reg = gen_reg_rtx (SImode);
3938 emit_insn (gen_subsi3 (reg, GEN_INT (32), operands[2]));
3939 operands[2] = reg;
b11cae9e 3940 }
cffb2a26 3941 "
3942)
9c08d1fa 3943
87b22bf7 3944(define_expand "rotrsi3"
cffb2a26 3945 [(set (match_operand:SI 0 "s_register_operand" "")
87b22bf7 3946 (rotatert:SI (match_operand:SI 1 "s_register_operand" "")
3947 (match_operand:SI 2 "arm_rhs_operand" "")))]
cffb2a26 3948 "TARGET_EITHER"
87b22bf7 3949 "
25f905c2 3950 if (TARGET_32BIT)
cffb2a26 3951 {
0438d37f 3952 if (CONST_INT_P (operands[2])
cffb2a26 3953 && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) > 31)
3954 operands[2] = GEN_INT (INTVAL (operands[2]) % 32);
3955 }
25f905c2 3956 else /* TARGET_THUMB1 */
cffb2a26 3957 {
0438d37f 3958 if (CONST_INT_P (operands [2]))
cffb2a26 3959 operands [2] = force_reg (SImode, operands[2]);
3960 }
3961 "
3962)
87b22bf7 3963
cffb2a26 3964(define_insn "*arm_shiftsi3"
88c29385 3965 [(set (match_operand:SI 0 "s_register_operand" "=l,l,r,r")
cffb2a26 3966 (match_operator:SI 3 "shift_operator"
88c29385 3967 [(match_operand:SI 1 "s_register_operand" "0,l,r,r")
3968 (match_operand:SI 2 "reg_or_int_operand" "l,M,M,r")]))]
25f905c2 3969 "TARGET_32BIT"
3970 "* return arm_output_shift(operands, 0);"
344495ea 3971 [(set_attr "predicable" "yes")
88c29385 3972 (set_attr "arch" "t2,t2,*,*")
3973 (set_attr "predicable_short_it" "yes,yes,no,no")
7c36fe71 3974 (set_attr "length" "4")
331beb1a 3975 (set_attr "shift" "1")
88c29385 3976 (set_attr "type" "alu_shift_reg,alu_shift_imm,alu_shift_imm,alu_shift_reg")]
6c4c2133 3977)
87b22bf7 3978
f7fbdd4a 3979(define_insn "*shiftsi3_compare0"
bd5b4116 3980 [(set (reg:CC_NOOV CC_REGNUM)
87b22bf7 3981 (compare:CC_NOOV (match_operator:SI 3 "shift_operator"
6b6abc9c 3982 [(match_operand:SI 1 "s_register_operand" "r,r")
3983 (match_operand:SI 2 "arm_rhs_operand" "M,r")])
9c08d1fa 3984 (const_int 0)))
6b6abc9c 3985 (set (match_operand:SI 0 "s_register_operand" "=r,r")
87b22bf7 3986 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))]
25f905c2 3987 "TARGET_32BIT"
3988 "* return arm_output_shift(operands, 1);"
344495ea 3989 [(set_attr "conds" "set")
331beb1a 3990 (set_attr "shift" "1")
d82e788e 3991 (set_attr "type" "alus_shift_imm,alus_shift_reg")]
0d66636f 3992)
9c08d1fa 3993
f7fbdd4a 3994(define_insn "*shiftsi3_compare0_scratch"
bd5b4116 3995 [(set (reg:CC_NOOV CC_REGNUM)
87b22bf7 3996 (compare:CC_NOOV (match_operator:SI 3 "shift_operator"
6b6abc9c 3997 [(match_operand:SI 1 "s_register_operand" "r,r")
3998 (match_operand:SI 2 "arm_rhs_operand" "M,r")])
9c08d1fa 3999 (const_int 0)))
6b6abc9c 4000 (clobber (match_scratch:SI 0 "=r,r"))]
25f905c2 4001 "TARGET_32BIT"
4002 "* return arm_output_shift(operands, 1);"
344495ea 4003 [(set_attr "conds" "set")
6b6abc9c 4004 (set_attr "shift" "1")
d82e788e 4005 (set_attr "type" "shift_imm,shift_reg")]
0d66636f 4006)
9c08d1fa 4007
d5d4dc8d 4008(define_insn "*not_shiftsi"
4009 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
87b22bf7 4010 (not:SI (match_operator:SI 3 "shift_operator"
d5d4dc8d 4011 [(match_operand:SI 1 "s_register_operand" "r,r")
4012 (match_operand:SI 2 "shift_amount_operand" "M,rM")])))]
4013 "TARGET_32BIT"
6c4c2133 4014 "mvn%?\\t%0, %1%S3"
344495ea 4015 [(set_attr "predicable" "yes")
d952d547 4016 (set_attr "predicable_short_it" "no")
331beb1a 4017 (set_attr "shift" "1")
d5d4dc8d 4018 (set_attr "arch" "32,a")
1aed5204 4019 (set_attr "type" "mvn_shift,mvn_shift_reg")])
9c08d1fa 4020
d5d4dc8d 4021(define_insn "*not_shiftsi_compare0"
bd5b4116 4022 [(set (reg:CC_NOOV CC_REGNUM)
d5d4dc8d 4023 (compare:CC_NOOV
4024 (not:SI (match_operator:SI 3 "shift_operator"
4025 [(match_operand:SI 1 "s_register_operand" "r,r")
4026 (match_operand:SI 2 "shift_amount_operand" "M,rM")]))
4027 (const_int 0)))
4028 (set (match_operand:SI 0 "s_register_operand" "=r,r")
87b22bf7 4029 (not:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)])))]
d5d4dc8d 4030 "TARGET_32BIT"
3ef90e77 4031 "mvns%?\\t%0, %1%S3"
344495ea 4032 [(set_attr "conds" "set")
331beb1a 4033 (set_attr "shift" "1")
d5d4dc8d 4034 (set_attr "arch" "32,a")
1aed5204 4035 (set_attr "type" "mvn_shift,mvn_shift_reg")])
9c08d1fa 4036
d5d4dc8d 4037(define_insn "*not_shiftsi_compare0_scratch"
bd5b4116 4038 [(set (reg:CC_NOOV CC_REGNUM)
d5d4dc8d 4039 (compare:CC_NOOV
4040 (not:SI (match_operator:SI 3 "shift_operator"
4041 [(match_operand:SI 1 "s_register_operand" "r,r")
4042 (match_operand:SI 2 "shift_amount_operand" "M,rM")]))
4043 (const_int 0)))
4044 (clobber (match_scratch:SI 0 "=r,r"))]
4045 "TARGET_32BIT"
3ef90e77 4046 "mvns%?\\t%0, %1%S3"
344495ea 4047 [(set_attr "conds" "set")
331beb1a 4048 (set_attr "shift" "1")
d5d4dc8d 4049 (set_attr "arch" "32,a")
1aed5204 4050 (set_attr "type" "mvn_shift,mvn_shift_reg")])
9c08d1fa 4051
cffb2a26 4052;; We don't really have extzv, but defining this using shifts helps
4053;; to reduce register pressure later on.
4054
4055(define_expand "extzv"
eb04cafb 4056 [(set (match_operand 0 "s_register_operand" "")
4057 (zero_extract (match_operand 1 "nonimmediate_operand" "")
4058 (match_operand 2 "const_int_operand" "")
4059 (match_operand 3 "const_int_operand" "")))]
8b054d5a 4060 "TARGET_THUMB1 || arm_arch_thumb2"
cffb2a26 4061 "
4062 {
4063 HOST_WIDE_INT lshift = 32 - INTVAL (operands[2]) - INTVAL (operands[3]);
4064 HOST_WIDE_INT rshift = 32 - INTVAL (operands[2]);
4065
8b054d5a 4066 if (arm_arch_thumb2)
4067 {
eb04cafb 4068 HOST_WIDE_INT width = INTVAL (operands[2]);
4069 HOST_WIDE_INT bitpos = INTVAL (operands[3]);
4070
4071 if (unaligned_access && MEM_P (operands[1])
4072 && (width == 16 || width == 32) && (bitpos % BITS_PER_UNIT) == 0)
4073 {
4074 rtx base_addr;
4075
4076 if (BYTES_BIG_ENDIAN)
4077 bitpos = GET_MODE_BITSIZE (GET_MODE (operands[0])) - width
4078 - bitpos;
4079
4080 if (width == 32)
4081 {
4082 base_addr = adjust_address (operands[1], SImode,
4083 bitpos / BITS_PER_UNIT);
4084 emit_insn (gen_unaligned_loadsi (operands[0], base_addr));
4085 }
4086 else
4087 {
4088 rtx dest = operands[0];
4089 rtx tmp = gen_reg_rtx (SImode);
4090
4091 /* We may get a paradoxical subreg here. Strip it off. */
4092 if (GET_CODE (dest) == SUBREG
4093 && GET_MODE (dest) == SImode
4094 && GET_MODE (SUBREG_REG (dest)) == HImode)
4095 dest = SUBREG_REG (dest);
4096
4097 if (GET_MODE_BITSIZE (GET_MODE (dest)) != width)
4098 FAIL;
4099
4100 base_addr = adjust_address (operands[1], HImode,
4101 bitpos / BITS_PER_UNIT);
4102 emit_insn (gen_unaligned_loadhiu (tmp, base_addr));
4103 emit_move_insn (gen_lowpart (SImode, dest), tmp);
4104 }
4105 DONE;
4106 }
4107 else if (s_register_operand (operands[1], GET_MODE (operands[1])))
4108 {
4109 emit_insn (gen_extzv_t2 (operands[0], operands[1], operands[2],
4110 operands[3]));
4111 DONE;
4112 }
4113 else
4114 FAIL;
8b054d5a 4115 }
eb04cafb 4116
4117 if (!s_register_operand (operands[1], GET_MODE (operands[1])))
4118 FAIL;
8b054d5a 4119
cffb2a26 4120 operands[3] = GEN_INT (rshift);
4121
4122 if (lshift == 0)
4123 {
4124 emit_insn (gen_lshrsi3 (operands[0], operands[1], operands[3]));
4125 DONE;
4126 }
4127
eb04cafb 4128 emit_insn (gen_extzv_t1 (operands[0], operands[1], GEN_INT (lshift),
4129 operands[3], gen_reg_rtx (SImode)));
4130 DONE;
215b30b3 4131 }"
cffb2a26 4132)
4133
eb04cafb 4134;; Helper for extzv, for the Thumb-1 register-shifts case.
4135
4136(define_expand "extzv_t1"
4137 [(set (match_operand:SI 4 "s_register_operand" "")
4138 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
4139 (match_operand:SI 2 "const_int_operand" "")))
4140 (set (match_operand:SI 0 "s_register_operand" "")
4141 (lshiftrt:SI (match_dup 4)
4142 (match_operand:SI 3 "const_int_operand" "")))]
4143 "TARGET_THUMB1"
4144 "")
4145
4146(define_expand "extv"
4147 [(set (match_operand 0 "s_register_operand" "")
4148 (sign_extract (match_operand 1 "nonimmediate_operand" "")
4149 (match_operand 2 "const_int_operand" "")
4150 (match_operand 3 "const_int_operand" "")))]
4151 "arm_arch_thumb2"
4152{
4153 HOST_WIDE_INT width = INTVAL (operands[2]);
4154 HOST_WIDE_INT bitpos = INTVAL (operands[3]);
4155
4156 if (unaligned_access && MEM_P (operands[1]) && (width == 16 || width == 32)
4157 && (bitpos % BITS_PER_UNIT) == 0)
4158 {
4159 rtx base_addr;
4160
4161 if (BYTES_BIG_ENDIAN)
4162 bitpos = GET_MODE_BITSIZE (GET_MODE (operands[0])) - width - bitpos;
4163
4164 if (width == 32)
4165 {
4166 base_addr = adjust_address (operands[1], SImode,
4167 bitpos / BITS_PER_UNIT);
4168 emit_insn (gen_unaligned_loadsi (operands[0], base_addr));
4169 }
4170 else
4171 {
4172 rtx dest = operands[0];
4173 rtx tmp = gen_reg_rtx (SImode);
4174
4175 /* We may get a paradoxical subreg here. Strip it off. */
4176 if (GET_CODE (dest) == SUBREG
4177 && GET_MODE (dest) == SImode
4178 && GET_MODE (SUBREG_REG (dest)) == HImode)
4179 dest = SUBREG_REG (dest);
4180
4181 if (GET_MODE_BITSIZE (GET_MODE (dest)) != width)
4182 FAIL;
4183
4184 base_addr = adjust_address (operands[1], HImode,
4185 bitpos / BITS_PER_UNIT);
4186 emit_insn (gen_unaligned_loadhis (tmp, base_addr));
4187 emit_move_insn (gen_lowpart (SImode, dest), tmp);
4188 }
4189
4190 DONE;
4191 }
4192 else if (!s_register_operand (operands[1], GET_MODE (operands[1])))
4193 FAIL;
4194 else if (GET_MODE (operands[0]) == SImode
4195 && GET_MODE (operands[1]) == SImode)
4196 {
4197 emit_insn (gen_extv_regsi (operands[0], operands[1], operands[2],
4198 operands[3]));
4199 DONE;
4200 }
4201
4202 FAIL;
4203})
4204
4205; Helper to expand register forms of extv with the proper modes.
4206
4207(define_expand "extv_regsi"
4208 [(set (match_operand:SI 0 "s_register_operand" "")
4209 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "")
4210 (match_operand 2 "const_int_operand" "")
4211 (match_operand 3 "const_int_operand" "")))]
4212 ""
4213{
4214})
4215
4216; ARMv6+ unaligned load/store instructions (used for packed structure accesses).
4217
4218(define_insn "unaligned_loadsi"
4219 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
4220 (unspec:SI [(match_operand:SI 1 "memory_operand" "Uw,m")]
4221 UNSPEC_UNALIGNED_LOAD))]
8fe38eb2 4222 "unaligned_access"
eb04cafb 4223 "ldr%?\t%0, %1\t@ unaligned"
4224 [(set_attr "arch" "t2,any")
4225 (set_attr "length" "2,4")
4226 (set_attr "predicable" "yes")
d952d547 4227 (set_attr "predicable_short_it" "yes,no")
eb04cafb 4228 (set_attr "type" "load1")])
4229
4230(define_insn "unaligned_loadhis"
4231 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
4232 (sign_extend:SI
e3f4ccee 4233 (unspec:HI [(match_operand:HI 1 "memory_operand" "Uw,Uh")]
eb04cafb 4234 UNSPEC_UNALIGNED_LOAD)))]
8fe38eb2 4235 "unaligned_access"
3ef90e77 4236 "ldrsh%?\t%0, %1\t@ unaligned"
eb04cafb 4237 [(set_attr "arch" "t2,any")
4238 (set_attr "length" "2,4")
4239 (set_attr "predicable" "yes")
d952d547 4240 (set_attr "predicable_short_it" "yes,no")
eb04cafb 4241 (set_attr "type" "load_byte")])
4242
4243(define_insn "unaligned_loadhiu"
4244 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
4245 (zero_extend:SI
4246 (unspec:HI [(match_operand:HI 1 "memory_operand" "Uw,m")]
4247 UNSPEC_UNALIGNED_LOAD)))]
8fe38eb2 4248 "unaligned_access"
3ef90e77 4249 "ldrh%?\t%0, %1\t@ unaligned"
eb04cafb 4250 [(set_attr "arch" "t2,any")
4251 (set_attr "length" "2,4")
4252 (set_attr "predicable" "yes")
d952d547 4253 (set_attr "predicable_short_it" "yes,no")
eb04cafb 4254 (set_attr "type" "load_byte")])
4255
4256(define_insn "unaligned_storesi"
4257 [(set (match_operand:SI 0 "memory_operand" "=Uw,m")
4258 (unspec:SI [(match_operand:SI 1 "s_register_operand" "l,r")]
4259 UNSPEC_UNALIGNED_STORE))]
8fe38eb2 4260 "unaligned_access"
eb04cafb 4261 "str%?\t%1, %0\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" "store1")])
4267
4268(define_insn "unaligned_storehi"
4269 [(set (match_operand:HI 0 "memory_operand" "=Uw,m")
4270 (unspec:HI [(match_operand:HI 1 "s_register_operand" "l,r")]
4271 UNSPEC_UNALIGNED_STORE))]
8fe38eb2 4272 "unaligned_access"
3ef90e77 4273 "strh%?\t%1, %0\t@ unaligned"
eb04cafb 4274 [(set_attr "arch" "t2,any")
4275 (set_attr "length" "2,4")
4276 (set_attr "predicable" "yes")
d952d547 4277 (set_attr "predicable_short_it" "yes,no")
eb04cafb 4278 (set_attr "type" "store1")])
4279
ae51a965 4280
eb04cafb 4281(define_insn "*extv_reg"
8b054d5a 4282 [(set (match_operand:SI 0 "s_register_operand" "=r")
4283 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
809003b3 4284 (match_operand:SI 2 "const_int_M_operand" "M")
4285 (match_operand:SI 3 "const_int_M_operand" "M")))]
8b054d5a 4286 "arm_arch_thumb2"
4287 "sbfx%?\t%0, %1, %3, %2"
4288 [(set_attr "length" "4")
d952d547 4289 (set_attr "predicable" "yes")
d82e788e 4290 (set_attr "predicable_short_it" "no")
4291 (set_attr "type" "bfm")]
8b054d5a 4292)
4293
4294(define_insn "extzv_t2"
4295 [(set (match_operand:SI 0 "s_register_operand" "=r")
4296 (zero_extract:SI (match_operand:SI 1 "s_register_operand" "r")
809003b3 4297 (match_operand:SI 2 "const_int_M_operand" "M")
4298 (match_operand:SI 3 "const_int_M_operand" "M")))]
8b054d5a 4299 "arm_arch_thumb2"
4300 "ubfx%?\t%0, %1, %3, %2"
4301 [(set_attr "length" "4")
d952d547 4302 (set_attr "predicable" "yes")
d82e788e 4303 (set_attr "predicable_short_it" "no")
4304 (set_attr "type" "bfm")]
8b054d5a 4305)
4306
7d3cda8c 4307
4308;; Division instructions
4309(define_insn "divsi3"
4310 [(set (match_operand:SI 0 "s_register_operand" "=r")
4311 (div:SI (match_operand:SI 1 "s_register_operand" "r")
4312 (match_operand:SI 2 "s_register_operand" "r")))]
4313 "TARGET_IDIV"
4314 "sdiv%?\t%0, %1, %2"
4315 [(set_attr "predicable" "yes")
d952d547 4316 (set_attr "predicable_short_it" "no")
9da0ec36 4317 (set_attr "type" "sdiv")]
7d3cda8c 4318)
4319
4320(define_insn "udivsi3"
4321 [(set (match_operand:SI 0 "s_register_operand" "=r")
4322 (udiv:SI (match_operand:SI 1 "s_register_operand" "r")
4323 (match_operand:SI 2 "s_register_operand" "r")))]
4324 "TARGET_IDIV"
4325 "udiv%?\t%0, %1, %2"
4326 [(set_attr "predicable" "yes")
d952d547 4327 (set_attr "predicable_short_it" "no")
9da0ec36 4328 (set_attr "type" "udiv")]
7d3cda8c 4329)
4330
b11cae9e 4331\f
4332;; Unary arithmetic insns
4333
cffb2a26 4334(define_expand "negdi2"
4335 [(parallel
8135a42b 4336 [(set (match_operand:DI 0 "s_register_operand" "")
4337 (neg:DI (match_operand:DI 1 "s_register_operand" "")))
bd5b4116 4338 (clobber (reg:CC CC_REGNUM))])]
cffb2a26 4339 "TARGET_EITHER"
774d2fbb 4340 {
4341 if (TARGET_NEON)
4342 {
4343 emit_insn (gen_negdi2_neon (operands[0], operands[1]));
4344 DONE;
4345 }
4346 }
cffb2a26 4347)
4348
4349;; The constraints here are to prevent a *partial* overlap (where %Q0 == %R1).
e5fea38e 4350;; The first alternative allows the common case of a *full* overlap.
ba6a3b2f 4351(define_insn_and_split "*arm_negdi2"
458a8706 4352 [(set (match_operand:DI 0 "s_register_operand" "=r,&r")
e5fea38e 4353 (neg:DI (match_operand:DI 1 "s_register_operand" "0,r")))
bd5b4116 4354 (clobber (reg:CC CC_REGNUM))]
cffb2a26 4355 "TARGET_ARM"
ba6a3b2f 4356 "#" ; "rsbs\\t%Q0, %Q1, #0\;rsc\\t%R0, %R1, #0"
4357 "&& reload_completed"
4358 [(parallel [(set (reg:CC CC_REGNUM)
4359 (compare:CC (const_int 0) (match_dup 1)))
4360 (set (match_dup 0) (minus:SI (const_int 0) (match_dup 1)))])
4361 (set (match_dup 2) (minus:SI (minus:SI (const_int 0) (match_dup 3))
4362 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
4363 {
4364 operands[2] = gen_highpart (SImode, operands[0]);
4365 operands[0] = gen_lowpart (SImode, operands[0]);
4366 operands[3] = gen_highpart (SImode, operands[1]);
4367 operands[1] = gen_lowpart (SImode, operands[1]);
4368 }
cffb2a26 4369 [(set_attr "conds" "clob")
1b7da4ac 4370 (set_attr "length" "8")
4371 (set_attr "type" "multiple")]
cffb2a26 4372)
b11cae9e 4373
cffb2a26 4374(define_expand "negsi2"
4375 [(set (match_operand:SI 0 "s_register_operand" "")
4376 (neg:SI (match_operand:SI 1 "s_register_operand" "")))]
4377 "TARGET_EITHER"
b11cae9e 4378 ""
cffb2a26 4379)
4380
4381(define_insn "*arm_negsi2"
d952d547 4382 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
4383 (neg:SI (match_operand:SI 1 "s_register_operand" "l,r")))]
25f905c2 4384 "TARGET_32BIT"
cffb2a26 4385 "rsb%?\\t%0, %1, #0"
d952d547 4386 [(set_attr "predicable" "yes")
4387 (set_attr "predicable_short_it" "yes,no")
4388 (set_attr "arch" "t2,*")
1b7da4ac 4389 (set_attr "length" "4")
112eda6f 4390 (set_attr "type" "alu_sreg")]
cffb2a26 4391)
4392
604f3a0a 4393(define_expand "negsf2"
4394 [(set (match_operand:SF 0 "s_register_operand" "")
4395 (neg:SF (match_operand:SF 1 "s_register_operand" "")))]
994606f8 4396 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
604f3a0a 4397 ""
4398)
4399
4400(define_expand "negdf2"
4401 [(set (match_operand:DF 0 "s_register_operand" "")
4402 (neg:DF (match_operand:DF 1 "s_register_operand" "")))]
994606f8 4403 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
604f3a0a 4404 "")
4405
7eaf2be0 4406(define_insn_and_split "*zextendsidi_negsi"
4407 [(set (match_operand:DI 0 "s_register_operand" "=r")
4408 (zero_extend:DI (neg:SI (match_operand:SI 1 "s_register_operand" "r"))))]
4409 "TARGET_32BIT"
4410 "#"
4411 ""
4412 [(set (match_dup 2)
4413 (neg:SI (match_dup 1)))
4414 (set (match_dup 3)
4415 (const_int 0))]
4416 {
4417 operands[2] = gen_lowpart (SImode, operands[0]);
4418 operands[3] = gen_highpart (SImode, operands[0]);
4419 }
4420 [(set_attr "length" "8")
4421 (set_attr "type" "multiple")]
4422)
4423
83e2b922 4424;; Negate an extended 32-bit value.
4425(define_insn_and_split "*negdi_extendsidi"
61fa8ff2 4426 [(set (match_operand:DI 0 "s_register_operand" "=l,r")
4427 (neg:DI (sign_extend:DI
4428 (match_operand:SI 1 "s_register_operand" "l,r"))))
83e2b922 4429 (clobber (reg:CC CC_REGNUM))]
4430 "TARGET_32BIT"
61fa8ff2 4431 "#"
83e2b922 4432 "&& reload_completed"
4433 [(const_int 0)]
4434 {
61fa8ff2 4435 rtx low = gen_lowpart (SImode, operands[0]);
4436 rtx high = gen_highpart (SImode, operands[0]);
4437
4438 if (reg_overlap_mentioned_p (low, operands[1]))
4439 {
4440 /* Input overlaps the low word of the output. Use:
4441 asr Rhi, Rin, #31
4442 rsbs Rlo, Rin, #0
4443 rsc Rhi, Rhi, #0 (thumb2: sbc Rhi, Rhi, Rhi, lsl #1). */
4444 rtx cc_reg = gen_rtx_REG (CC_Cmode, CC_REGNUM);
4445
d1f9b275 4446 emit_insn (gen_rtx_SET (high,
61fa8ff2 4447 gen_rtx_ASHIFTRT (SImode, operands[1],
4448 GEN_INT (31))));
4449
4450 emit_insn (gen_subsi3_compare (low, const0_rtx, operands[1]));
4451 if (TARGET_ARM)
d1f9b275 4452 emit_insn (gen_rtx_SET (high,
61fa8ff2 4453 gen_rtx_MINUS (SImode,
4454 gen_rtx_MINUS (SImode,
4455 const0_rtx,
4456 high),
4457 gen_rtx_LTU (SImode,
4458 cc_reg,
4459 const0_rtx))));
4460 else
4461 {
4462 rtx two_x = gen_rtx_ASHIFT (SImode, high, GEN_INT (1));
d1f9b275 4463 emit_insn (gen_rtx_SET (high,
61fa8ff2 4464 gen_rtx_MINUS (SImode,
4465 gen_rtx_MINUS (SImode,
4466 high,
4467 two_x),
4468 gen_rtx_LTU (SImode,
4469 cc_reg,
4470 const0_rtx))));
4471 }
4472 }
4473 else
4474 {
4475 /* No overlap, or overlap on high word. Use:
4476 rsb Rlo, Rin, #0
4477 bic Rhi, Rlo, Rin
4478 asr Rhi, Rhi, #31
4479 Flags not needed for this sequence. */
d1f9b275 4480 emit_insn (gen_rtx_SET (low, gen_rtx_NEG (SImode, operands[1])));
4481 emit_insn (gen_rtx_SET (high,
61fa8ff2 4482 gen_rtx_AND (SImode,
4483 gen_rtx_NOT (SImode, operands[1]),
4484 low)));
d1f9b275 4485 emit_insn (gen_rtx_SET (high,
61fa8ff2 4486 gen_rtx_ASHIFTRT (SImode, high,
4487 GEN_INT (31))));
4488 }
4489 DONE;
83e2b922 4490 }
61fa8ff2 4491 [(set_attr "length" "12")
4492 (set_attr "arch" "t2,*")
1b7da4ac 4493 (set_attr "type" "multiple")]
83e2b922 4494)
4495
4496(define_insn_and_split "*negdi_zero_extendsidi"
4497 [(set (match_operand:DI 0 "s_register_operand" "=r,&r")
4498 (neg:DI (zero_extend:DI (match_operand:SI 1 "s_register_operand" "0,r"))))
4499 (clobber (reg:CC CC_REGNUM))]
4500 "TARGET_32BIT"
4501 "#" ; "rsbs\\t%Q0, %1, #0\;sbc\\t%R0,%R0,%R0"
4502 ;; Don't care what register is input to sbc,
47ae02b7 4503 ;; since we just need to propagate the carry.
83e2b922 4504 "&& reload_completed"
4505 [(parallel [(set (reg:CC CC_REGNUM)
4506 (compare:CC (const_int 0) (match_dup 1)))
4507 (set (match_dup 0) (minus:SI (const_int 0) (match_dup 1)))])
4508 (set (match_dup 2) (minus:SI (minus:SI (match_dup 2) (match_dup 2))
4509 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
4510 {
4511 operands[2] = gen_highpart (SImode, operands[0]);
4512 operands[0] = gen_lowpart (SImode, operands[0]);
4513 }
4514 [(set_attr "conds" "clob")
1b7da4ac 4515 (set_attr "length" "8")
4516 (set_attr "type" "multiple")] ;; length in thumb is 4
83e2b922 4517)
4518
9c08d1fa 4519;; abssi2 doesn't really clobber the condition codes if a different register
4520;; is being set. To keep things simple, assume during rtl manipulations that
4521;; it does, but tell the final scan operator the truth. Similarly for
4522;; (neg (abs...))
4523
604f3a0a 4524(define_expand "abssi2"
4525 [(parallel
4526 [(set (match_operand:SI 0 "s_register_operand" "")
4527 (abs:SI (match_operand:SI 1 "s_register_operand" "")))
ba156559 4528 (clobber (match_dup 2))])]
4529 "TARGET_EITHER"
4530 "
25f905c2 4531 if (TARGET_THUMB1)
ba156559 4532 operands[2] = gen_rtx_SCRATCH (SImode);
4533 else
4534 operands[2] = gen_rtx_REG (CCmode, CC_REGNUM);
4535")
604f3a0a 4536
ba6a3b2f 4537(define_insn_and_split "*arm_abssi2"
ba156559 4538 [(set (match_operand:SI 0 "s_register_operand" "=r,&r")
9c08d1fa 4539 (abs:SI (match_operand:SI 1 "s_register_operand" "0,r")))
bd5b4116 4540 (clobber (reg:CC CC_REGNUM))]
cffb2a26 4541 "TARGET_ARM"
ba6a3b2f 4542 "#"
4543 "&& reload_completed"
4544 [(const_int 0)]
4545 {
4546 /* if (which_alternative == 0) */
4547 if (REGNO(operands[0]) == REGNO(operands[1]))
4548 {
4549 /* Emit the pattern:
4550 cmp\\t%0, #0\;rsblt\\t%0, %0, #0
4551 [(set (reg:CC CC_REGNUM)
4552 (compare:CC (match_dup 0) (const_int 0)))
4553 (cond_exec (lt:CC (reg:CC CC_REGNUM) (const_int 0))
4554 (set (match_dup 0) (minus:SI (const_int 0) (match_dup 1))))]
4555 */
d1f9b275 4556 emit_insn (gen_rtx_SET (gen_rtx_REG (CCmode, CC_REGNUM),
ba6a3b2f 4557 gen_rtx_COMPARE (CCmode, operands[0], const0_rtx)));
4558 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
4559 (gen_rtx_LT (SImode,
4560 gen_rtx_REG (CCmode, CC_REGNUM),
4561 const0_rtx)),
d1f9b275 4562 (gen_rtx_SET (operands[0],
ba6a3b2f 4563 (gen_rtx_MINUS (SImode,
4564 const0_rtx,
4565 operands[1]))))));
4566 DONE;
4567 }
4568 else
4569 {
4570 /* Emit the pattern:
4571 alt1: eor%?\\t%0, %1, %1, asr #31\;sub%?\\t%0, %0, %1, asr #31
4572 [(set (match_dup 0)
4573 (xor:SI (match_dup 1)
4574 (ashiftrt:SI (match_dup 1) (const_int 31))))
4575 (set (match_dup 0)
4576 (minus:SI (match_dup 0)
4577 (ashiftrt:SI (match_dup 1) (const_int 31))))]
4578 */
d1f9b275 4579 emit_insn (gen_rtx_SET (operands[0],
ba6a3b2f 4580 gen_rtx_XOR (SImode,
4581 gen_rtx_ASHIFTRT (SImode,
4582 operands[1],
4583 GEN_INT (31)),
4584 operands[1])));
d1f9b275 4585 emit_insn (gen_rtx_SET (operands[0],
ba6a3b2f 4586 gen_rtx_MINUS (SImode,
4587 operands[0],
4588 gen_rtx_ASHIFTRT (SImode,
4589 operands[1],
4590 GEN_INT (31)))));
4591 DONE;
4592 }
4593 }
cffb2a26 4594 [(set_attr "conds" "clob,*")
331beb1a 4595 (set_attr "shift" "1")
2ad08b65 4596 (set_attr "predicable" "no, yes")
1b7da4ac 4597 (set_attr "length" "8")
4598 (set_attr "type" "multiple")]
cffb2a26 4599)
9c08d1fa 4600
ba6a3b2f 4601(define_insn_and_split "*arm_neg_abssi2"
9c08d1fa 4602 [(set (match_operand:SI 0 "s_register_operand" "=r,&r")
4603 (neg:SI (abs:SI (match_operand:SI 1 "s_register_operand" "0,r"))))
bd5b4116 4604 (clobber (reg:CC CC_REGNUM))]
cffb2a26 4605 "TARGET_ARM"
ba6a3b2f 4606 "#"
4607 "&& reload_completed"
4608 [(const_int 0)]
4609 {
4610 /* if (which_alternative == 0) */
4611 if (REGNO (operands[0]) == REGNO (operands[1]))
4612 {
4613 /* Emit the pattern:
4614 cmp\\t%0, #0\;rsbgt\\t%0, %0, #0
4615 */
d1f9b275 4616 emit_insn (gen_rtx_SET (gen_rtx_REG (CCmode, CC_REGNUM),
ba6a3b2f 4617 gen_rtx_COMPARE (CCmode, operands[0], const0_rtx)));
4618 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
4619 gen_rtx_GT (SImode,
4620 gen_rtx_REG (CCmode, CC_REGNUM),
4621 const0_rtx),
d1f9b275 4622 gen_rtx_SET (operands[0],
ba6a3b2f 4623 (gen_rtx_MINUS (SImode,
4624 const0_rtx,
4625 operands[1])))));
4626 }
4627 else
4628 {
4629 /* Emit the pattern:
4630 eor%?\\t%0, %1, %1, asr #31\;rsb%?\\t%0, %0, %1, asr #31
4631 */
d1f9b275 4632 emit_insn (gen_rtx_SET (operands[0],
ba6a3b2f 4633 gen_rtx_XOR (SImode,
4634 gen_rtx_ASHIFTRT (SImode,
4635 operands[1],
4636 GEN_INT (31)),
4637 operands[1])));
d1f9b275 4638 emit_insn (gen_rtx_SET (operands[0],
ba6a3b2f 4639 gen_rtx_MINUS (SImode,
4640 gen_rtx_ASHIFTRT (SImode,
4641 operands[1],
4642 GEN_INT (31)),
4643 operands[0])));
4644 }
4645 DONE;
4646 }
cffb2a26 4647 [(set_attr "conds" "clob,*")
331beb1a 4648 (set_attr "shift" "1")
2ad08b65 4649 (set_attr "predicable" "no, yes")
1b7da4ac 4650 (set_attr "length" "8")
4651 (set_attr "type" "multiple")]
cffb2a26 4652)
b11cae9e 4653
604f3a0a 4654(define_expand "abssf2"
4655 [(set (match_operand:SF 0 "s_register_operand" "")
4656 (abs:SF (match_operand:SF 1 "s_register_operand" "")))]
25f905c2 4657 "TARGET_32BIT && TARGET_HARD_FLOAT"
604f3a0a 4658 "")
4659
604f3a0a 4660(define_expand "absdf2"
4661 [(set (match_operand:DF 0 "s_register_operand" "")
4662 (abs:DF (match_operand:DF 1 "s_register_operand" "")))]
a50d7267 4663 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
604f3a0a 4664 "")
4665
7db9af5d 4666(define_expand "sqrtsf2"
4667 [(set (match_operand:SF 0 "s_register_operand" "")
4668 (sqrt:SF (match_operand:SF 1 "s_register_operand" "")))]
994606f8 4669 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
7db9af5d 4670 "")
9c08d1fa 4671
7db9af5d 4672(define_expand "sqrtdf2"
4673 [(set (match_operand:DF 0 "s_register_operand" "")
4674 (sqrt:DF (match_operand:DF 1 "s_register_operand" "")))]
994606f8 4675 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
7db9af5d 4676 "")
9c08d1fa 4677
a0f94409 4678(define_insn_and_split "one_cmpldi2"
10efb95f 4679 [(set (match_operand:DI 0 "s_register_operand" "=w,&r,&r,?w")
4680 (not:DI (match_operand:DI 1 "s_register_operand" " w, 0, r, w")))]
25f905c2 4681 "TARGET_32BIT"
10efb95f 4682 "@
4683 vmvn\t%P0, %P1
4684 #
4685 #
4686 vmvn\t%P0, %P1"
4687 "TARGET_32BIT && reload_completed
4688 && arm_general_register_operand (operands[0], DImode)"
a0f94409 4689 [(set (match_dup 0) (not:SI (match_dup 1)))
4690 (set (match_dup 2) (not:SI (match_dup 3)))]
4691 "
4692 {
4693 operands[2] = gen_highpart (SImode, operands[0]);
4694 operands[0] = gen_lowpart (SImode, operands[0]);
4695 operands[3] = gen_highpart (SImode, operands[1]);
4696 operands[1] = gen_lowpart (SImode, operands[1]);
4697 }"
10efb95f 4698 [(set_attr "length" "*,8,8,*")
4699 (set_attr "predicable" "no,yes,yes,no")
32093010 4700 (set_attr "type" "neon_move,multiple,multiple,neon_move")
b6779ddc 4701 (set_attr "arch" "neon_for_64bits,*,*,avoid_neon_for_64bits")]
cffb2a26 4702)
b11cae9e 4703
cffb2a26 4704(define_expand "one_cmplsi2"
4705 [(set (match_operand:SI 0 "s_register_operand" "")
4706 (not:SI (match_operand:SI 1 "s_register_operand" "")))]
4707 "TARGET_EITHER"
b11cae9e 4708 ""
cffb2a26 4709)
4710
4711(define_insn "*arm_one_cmplsi2"
d952d547 4712 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
4713 (not:SI (match_operand:SI 1 "s_register_operand" "l,r")))]
25f905c2 4714 "TARGET_32BIT"
cffb2a26 4715 "mvn%?\\t%0, %1"
d2a518d1 4716 [(set_attr "predicable" "yes")
d952d547 4717 (set_attr "predicable_short_it" "yes,no")
4718 (set_attr "arch" "t2,*")
4719 (set_attr "length" "4")
1aed5204 4720 (set_attr "type" "mvn_reg")]
cffb2a26 4721)
4722
f7fbdd4a 4723(define_insn "*notsi_compare0"
bd5b4116 4724 [(set (reg:CC_NOOV CC_REGNUM)
9c08d1fa 4725 (compare:CC_NOOV (not:SI (match_operand:SI 1 "s_register_operand" "r"))
4726 (const_int 0)))
4727 (set (match_operand:SI 0 "s_register_operand" "=r")
4728 (not:SI (match_dup 1)))]
25f905c2 4729 "TARGET_32BIT"
3ef90e77 4730 "mvns%?\\t%0, %1"
d2a518d1 4731 [(set_attr "conds" "set")
1aed5204 4732 (set_attr "type" "mvn_reg")]
cffb2a26 4733)
9c08d1fa 4734
f7fbdd4a 4735(define_insn "*notsi_compare0_scratch"
bd5b4116 4736 [(set (reg:CC_NOOV CC_REGNUM)
9c08d1fa 4737 (compare:CC_NOOV (not:SI (match_operand:SI 1 "s_register_operand" "r"))
4738 (const_int 0)))
4739 (clobber (match_scratch:SI 0 "=r"))]
25f905c2 4740 "TARGET_32BIT"
3ef90e77 4741 "mvns%?\\t%0, %1"
d2a518d1 4742 [(set_attr "conds" "set")
1aed5204 4743 (set_attr "type" "mvn_reg")]
cffb2a26 4744)
b11cae9e 4745\f
4746;; Fixed <--> Floating conversion insns
4747
9b8516be 4748(define_expand "floatsihf2"
4749 [(set (match_operand:HF 0 "general_operand" "")
4750 (float:HF (match_operand:SI 1 "general_operand" "")))]
4751 "TARGET_EITHER"
4752 "
4753 {
4754 rtx op1 = gen_reg_rtx (SFmode);
4755 expand_float (op1, operands[1], 0);
4756 op1 = convert_to_mode (HFmode, op1, 0);
4757 emit_move_insn (operands[0], op1);
4758 DONE;
4759 }"
4760)
4761
4762(define_expand "floatdihf2"
4763 [(set (match_operand:HF 0 "general_operand" "")
4764 (float:HF (match_operand:DI 1 "general_operand" "")))]
4765 "TARGET_EITHER"
4766 "
4767 {
4768 rtx op1 = gen_reg_rtx (SFmode);
4769 expand_float (op1, operands[1], 0);
4770 op1 = convert_to_mode (HFmode, op1, 0);
4771 emit_move_insn (operands[0], op1);
4772 DONE;
4773 }"
4774)
4775
604f3a0a 4776(define_expand "floatsisf2"
4777 [(set (match_operand:SF 0 "s_register_operand" "")
4778 (float:SF (match_operand:SI 1 "s_register_operand" "")))]
25f905c2 4779 "TARGET_32BIT && TARGET_HARD_FLOAT"
604f3a0a 4780 "
604f3a0a 4781")
4782
604f3a0a 4783(define_expand "floatsidf2"
4784 [(set (match_operand:DF 0 "s_register_operand" "")
4785 (float:DF (match_operand:SI 1 "s_register_operand" "")))]
a50d7267 4786 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
604f3a0a 4787 "
604f3a0a 4788")
4789
9b8516be 4790(define_expand "fix_trunchfsi2"
4791 [(set (match_operand:SI 0 "general_operand" "")
4792 (fix:SI (fix:HF (match_operand:HF 1 "general_operand" ""))))]
4793 "TARGET_EITHER"
4794 "
4795 {
4796 rtx op1 = convert_to_mode (SFmode, operands[1], 0);
4797 expand_fix (operands[0], op1, 0);
4798 DONE;
4799 }"
4800)
4801
4802(define_expand "fix_trunchfdi2"
4803 [(set (match_operand:DI 0 "general_operand" "")
4804 (fix:DI (fix:HF (match_operand:HF 1 "general_operand" ""))))]
4805 "TARGET_EITHER"
4806 "
4807 {
4808 rtx op1 = convert_to_mode (SFmode, operands[1], 0);
4809 expand_fix (operands[0], op1, 0);
4810 DONE;
4811 }"
4812)
4813
604f3a0a 4814(define_expand "fix_truncsfsi2"
4815 [(set (match_operand:SI 0 "s_register_operand" "")
a33d5c9c 4816 (fix:SI (fix:SF (match_operand:SF 1 "s_register_operand" ""))))]
25f905c2 4817 "TARGET_32BIT && TARGET_HARD_FLOAT"
604f3a0a 4818 "
604f3a0a 4819")
4820
604f3a0a 4821(define_expand "fix_truncdfsi2"
4822 [(set (match_operand:SI 0 "s_register_operand" "")
a33d5c9c 4823 (fix:SI (fix:DF (match_operand:DF 1 "s_register_operand" ""))))]
a50d7267 4824 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
604f3a0a 4825 "
604f3a0a 4826")
4827
f544c6d2 4828;; Truncation insns
b11cae9e 4829
604f3a0a 4830(define_expand "truncdfsf2"
4831 [(set (match_operand:SF 0 "s_register_operand" "")
4832 (float_truncate:SF
4833 (match_operand:DF 1 "s_register_operand" "")))]
a50d7267 4834 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
604f3a0a 4835 ""
4836)
9b8516be 4837
4838/* DFmode -> HFmode conversions have to go through SFmode. */
4839(define_expand "truncdfhf2"
4840 [(set (match_operand:HF 0 "general_operand" "")
4841 (float_truncate:HF
4842 (match_operand:DF 1 "general_operand" "")))]
4843 "TARGET_EITHER"
4844 "
4845 {
4846 rtx op1;
4847 op1 = convert_to_mode (SFmode, operands[1], 0);
4848 op1 = convert_to_mode (HFmode, op1, 0);
4849 emit_move_insn (operands[0], op1);
4850 DONE;
4851 }"
4852)
b11cae9e 4853\f
9c08d1fa 4854;; Zero and sign extension instructions.
b11cae9e 4855
848e66ac 4856(define_insn "zero_extend<mode>di2"
6aa689e8 4857 [(set (match_operand:DI 0 "s_register_operand" "=w,r,?r,w")
6d97728e 4858 (zero_extend:DI (match_operand:QHSI 1 "<qhs_zextenddi_op>"
4859 "<qhs_zextenddi_cstr>")))]
848e66ac 4860 "TARGET_32BIT <qhs_zextenddi_cond>"
4861 "#"
6aa689e8 4862 [(set_attr "length" "8,4,8,8")
b6779ddc 4863 (set_attr "arch" "neon_for_64bits,*,*,avoid_neon_for_64bits")
848e66ac 4864 (set_attr "ce_count" "2")
efbb5e19 4865 (set_attr "predicable" "yes")
4866 (set_attr "type" "multiple,mov_reg,multiple,multiple")]
25f905c2 4867)
4868
848e66ac 4869(define_insn "extend<mode>di2"
6aa689e8 4870 [(set (match_operand:DI 0 "s_register_operand" "=w,r,?r,?r,w")
63d204a8 4871 (sign_extend:DI (match_operand:QHSI 1 "<qhs_extenddi_op>"
4872 "<qhs_extenddi_cstr>")))]
848e66ac 4873 "TARGET_32BIT <qhs_sextenddi_cond>"
4874 "#"
6aa689e8 4875 [(set_attr "length" "8,4,8,8,8")
848e66ac 4876 (set_attr "ce_count" "2")
4877 (set_attr "shift" "1")
8012d2c2 4878 (set_attr "predicable" "yes")
1b7da4ac 4879 (set_attr "arch" "neon_for_64bits,*,a,t,avoid_neon_for_64bits")
4880 (set_attr "type" "multiple,mov_reg,multiple,multiple,multiple")]
0d66636f 4881)
9c08d1fa 4882
848e66ac 4883;; Splits for all extensions to DImode
4884(define_split
4885 [(set (match_operand:DI 0 "s_register_operand" "")
4886 (zero_extend:DI (match_operand 1 "nonimmediate_operand" "")))]
6aa689e8 4887 "TARGET_32BIT && reload_completed && !IS_VFP_REGNUM (REGNO (operands[0]))"
848e66ac 4888 [(set (match_dup 0) (match_dup 1))]
4889{
848e66ac 4890 rtx lo_part = gen_lowpart (SImode, operands[0]);
3754d046 4891 machine_mode src_mode = GET_MODE (operands[1]);
848e66ac 4892
4893 if (REG_P (operands[0])
4894 && !reg_overlap_mentioned_p (operands[0], operands[1]))
4895 emit_clobber (operands[0]);
4896 if (!REG_P (lo_part) || src_mode != SImode
4897 || !rtx_equal_p (lo_part, operands[1]))
4898 {
4899 if (src_mode == SImode)
4900 emit_move_insn (lo_part, operands[1]);
4901 else
d1f9b275 4902 emit_insn (gen_rtx_SET (lo_part,
848e66ac 4903 gen_rtx_ZERO_EXTEND (SImode, operands[1])));
4904 operands[1] = lo_part;
4905 }
4906 operands[0] = gen_highpart (SImode, operands[0]);
4907 operands[1] = const0_rtx;
4908})
9c08d1fa 4909
848e66ac 4910(define_split
25f905c2 4911 [(set (match_operand:DI 0 "s_register_operand" "")
848e66ac 4912 (sign_extend:DI (match_operand 1 "nonimmediate_operand" "")))]
6aa689e8 4913 "TARGET_32BIT && reload_completed && !IS_VFP_REGNUM (REGNO (operands[0]))"
848e66ac 4914 [(set (match_dup 0) (ashiftrt:SI (match_dup 1) (const_int 31)))]
4915{
4916 rtx lo_part = gen_lowpart (SImode, operands[0]);
3754d046 4917 machine_mode src_mode = GET_MODE (operands[1]);
25f905c2 4918
848e66ac 4919 if (REG_P (operands[0])
4920 && !reg_overlap_mentioned_p (operands[0], operands[1]))
4921 emit_clobber (operands[0]);
4922
4923 if (!REG_P (lo_part) || src_mode != SImode
4924 || !rtx_equal_p (lo_part, operands[1]))
4925 {
4926 if (src_mode == SImode)
4927 emit_move_insn (lo_part, operands[1]);
4928 else
d1f9b275 4929 emit_insn (gen_rtx_SET (lo_part,
848e66ac 4930 gen_rtx_SIGN_EXTEND (SImode, operands[1])));
4931 operands[1] = lo_part;
4932 }
4933 operands[0] = gen_highpart (SImode, operands[0]);
4934})
9c08d1fa 4935
4936(define_expand "zero_extendhisi2"
ef51b8e1 4937 [(set (match_operand:SI 0 "s_register_operand" "")
4938 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
cffb2a26 4939 "TARGET_EITHER"
ef51b8e1 4940{
4941 if (TARGET_ARM && !arm_arch4 && MEM_P (operands[1]))
f7fbdd4a 4942 {
ef51b8e1 4943 emit_insn (gen_movhi_bytes (operands[0], operands[1]));
4944 DONE;
25f7a26e 4945 }
ef51b8e1 4946 if (!arm_arch6 && !MEM_P (operands[1]))
4947 {
4948 rtx t = gen_lowpart (SImode, operands[1]);
4949 rtx tmp = gen_reg_rtx (SImode);
4950 emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (16)));
4951 emit_insn (gen_lshrsi3 (operands[0], tmp, GEN_INT (16)));
4952 DONE;
4953 }
4954})
9c08d1fa 4955
ef51b8e1 4956(define_split
b146458f 4957 [(set (match_operand:SI 0 "s_register_operand" "")
4958 (zero_extend:SI (match_operand:HI 1 "s_register_operand" "")))]
ef51b8e1 4959 "!TARGET_THUMB2 && !arm_arch6"
4960 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
4961 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 16)))]
4962{
4963 operands[2] = gen_lowpart (SImode, operands[1]);
4964})
4965
cffb2a26 4966(define_insn "*arm_zero_extendhisi2"
ef51b8e1 4967 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4968 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
a2cd141b 4969 "TARGET_ARM && arm_arch4 && !arm_arch6"
ef51b8e1 4970 "@
4971 #
3ef90e77 4972 ldrh%?\\t%0, %1"
d82e788e 4973 [(set_attr "type" "alu_shift_reg,load_byte")
848e66ac 4974 (set_attr "predicable" "yes")]
cffb2a26 4975)
f7fbdd4a 4976
a2cd141b 4977(define_insn "*arm_zero_extendhisi2_v6"
4978 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
e3f4ccee 4979 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,Uh")))]
a2cd141b 4980 "TARGET_ARM && arm_arch6"
4981 "@
4982 uxth%?\\t%0, %1
3ef90e77 4983 ldrh%?\\t%0, %1"
65f68e55 4984 [(set_attr "predicable" "yes")
6b6abc9c 4985 (set_attr "type" "extend,load_byte")]
a2cd141b 4986)
4987
4988(define_insn "*arm_zero_extendhisi2addsi"
4989 [(set (match_operand:SI 0 "s_register_operand" "=r")
4990 (plus:SI (zero_extend:SI (match_operand:HI 1 "s_register_operand" "r"))
4991 (match_operand:SI 2 "s_register_operand" "r")))]
25f905c2 4992 "TARGET_INT_SIMD"
a2cd141b 4993 "uxtah%?\\t%0, %2, %1"
d82e788e 4994 [(set_attr "type" "alu_shift_reg")
d952d547 4995 (set_attr "predicable" "yes")
4996 (set_attr "predicable_short_it" "no")]
a2cd141b 4997)
4998
87b22bf7 4999(define_expand "zero_extendqisi2"
cffb2a26 5000 [(set (match_operand:SI 0 "s_register_operand" "")
5001 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))]
5002 "TARGET_EITHER"
ef51b8e1 5003{
0438d37f 5004 if (TARGET_ARM && !arm_arch6 && !MEM_P (operands[1]))
87b22bf7 5005 {
ef51b8e1 5006 emit_insn (gen_andsi3 (operands[0],
5007 gen_lowpart (SImode, operands[1]),
5008 GEN_INT (255)));
5009 DONE;
5010 }
5011 if (!arm_arch6 && !MEM_P (operands[1]))
5012 {
5013 rtx t = gen_lowpart (SImode, operands[1]);
5014 rtx tmp = gen_reg_rtx (SImode);
5015 emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (24)));
5016 emit_insn (gen_lshrsi3 (operands[0], tmp, GEN_INT (24)));
5017 DONE;
5018 }
5019})
cffb2a26 5020
ef51b8e1 5021(define_split
b146458f 5022 [(set (match_operand:SI 0 "s_register_operand" "")
5023 (zero_extend:SI (match_operand:QI 1 "s_register_operand" "")))]
ef51b8e1 5024 "!arm_arch6"
5025 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 24)))
5026 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 24)))]
5027{
5028 operands[2] = simplify_gen_subreg (SImode, operands[1], QImode, 0);
5029 if (TARGET_ARM)
5030 {
5031 emit_insn (gen_andsi3 (operands[0], operands[2], GEN_INT (255)));
87b22bf7 5032 DONE;
5033 }
ef51b8e1 5034})
9c08d1fa 5035
cffb2a26 5036(define_insn "*arm_zero_extendqisi2"
ef51b8e1 5037 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5038 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
a2cd141b 5039 "TARGET_ARM && !arm_arch6"
ef51b8e1 5040 "@
5041 #
3ef90e77 5042 ldrb%?\\t%0, %1\\t%@ zero_extendqisi2"
ef51b8e1 5043 [(set_attr "length" "8,4")
d82e788e 5044 (set_attr "type" "alu_shift_reg,load_byte")
848e66ac 5045 (set_attr "predicable" "yes")]
cffb2a26 5046)
87b22bf7 5047
a2cd141b 5048(define_insn "*arm_zero_extendqisi2_v6"
5049 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
e3f4ccee 5050 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "r,Uh")))]
a2cd141b 5051 "TARGET_ARM && arm_arch6"
5052 "@
3ef90e77 5053 uxtb%?\\t%0, %1
5054 ldrb%?\\t%0, %1\\t%@ zero_extendqisi2"
6b6abc9c 5055 [(set_attr "type" "extend,load_byte")
848e66ac 5056 (set_attr "predicable" "yes")]
a2cd141b 5057)
5058
5059(define_insn "*arm_zero_extendqisi2addsi"
5060 [(set (match_operand:SI 0 "s_register_operand" "=r")
5061 (plus:SI (zero_extend:SI (match_operand:QI 1 "s_register_operand" "r"))
5062 (match_operand:SI 2 "s_register_operand" "r")))]
25f905c2 5063 "TARGET_INT_SIMD"
a2cd141b 5064 "uxtab%?\\t%0, %2, %1"
5065 [(set_attr "predicable" "yes")
d952d547 5066 (set_attr "predicable_short_it" "no")
d82e788e 5067 (set_attr "type" "alu_shift_reg")]
a2cd141b 5068)
5069
87b22bf7 5070(define_split
5071 [(set (match_operand:SI 0 "s_register_operand" "")
5072 (zero_extend:SI (subreg:QI (match_operand:SI 1 "" "") 0)))
5073 (clobber (match_operand:SI 2 "s_register_operand" ""))]
0438d37f 5074 "TARGET_32BIT && (!MEM_P (operands[1])) && ! BYTES_BIG_ENDIAN"
87b22bf7 5075 [(set (match_dup 2) (match_dup 1))
5076 (set (match_dup 0) (and:SI (match_dup 2) (const_int 255)))]
cffb2a26 5077 ""
5078)
9c08d1fa 5079
8a4d25d6 5080(define_split
5081 [(set (match_operand:SI 0 "s_register_operand" "")
5082 (zero_extend:SI (subreg:QI (match_operand:SI 1 "" "") 3)))
5083 (clobber (match_operand:SI 2 "s_register_operand" ""))]
0438d37f 5084 "TARGET_32BIT && (!MEM_P (operands[1])) && BYTES_BIG_ENDIAN"
8a4d25d6 5085 [(set (match_dup 2) (match_dup 1))
5086 (set (match_dup 0) (and:SI (match_dup 2) (const_int 255)))]
5087 ""
5088)
5089
1c274529 5090
5091(define_split
5092 [(set (match_operand:SI 0 "s_register_operand" "")
9b23f0a7 5093 (IOR_XOR:SI (and:SI (ashift:SI
1c274529 5094 (match_operand:SI 1 "s_register_operand" "")
5095 (match_operand:SI 2 "const_int_operand" ""))
5096 (match_operand:SI 3 "const_int_operand" ""))
5097 (zero_extend:SI
5098 (match_operator 5 "subreg_lowpart_operator"
5099 [(match_operand:SI 4 "s_register_operand" "")]))))]
5100 "TARGET_32BIT
63787642 5101 && ((unsigned HOST_WIDE_INT) INTVAL (operands[3])
1c274529 5102 == (GET_MODE_MASK (GET_MODE (operands[5]))
5103 & (GET_MODE_MASK (GET_MODE (operands[5]))
5104 << (INTVAL (operands[2])))))"
9b23f0a7 5105 [(set (match_dup 0) (IOR_XOR:SI (ashift:SI (match_dup 1) (match_dup 2))
1c274529 5106 (match_dup 4)))
5107 (set (match_dup 0) (zero_extend:SI (match_dup 5)))]
5108 "operands[5] = gen_lowpart (GET_MODE (operands[5]), operands[0]);"
5109)
5110
f7fbdd4a 5111(define_insn "*compareqi_eq0"
bd5b4116 5112 [(set (reg:CC_Z CC_REGNUM)
206ee9a2 5113 (compare:CC_Z (match_operand:QI 0 "s_register_operand" "r")
87b22bf7 5114 (const_int 0)))]
25f905c2 5115 "TARGET_32BIT"
596e5e8f 5116 "tst%?\\t%0, #255"
5117 [(set_attr "conds" "set")
d952d547 5118 (set_attr "predicable" "yes")
1b7da4ac 5119 (set_attr "predicable_short_it" "no")
5120 (set_attr "type" "logic_imm")]
cffb2a26 5121)
b11cae9e 5122
b11cae9e 5123(define_expand "extendhisi2"
ef51b8e1 5124 [(set (match_operand:SI 0 "s_register_operand" "")
5125 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
cffb2a26 5126 "TARGET_EITHER"
ef51b8e1 5127{
5128 if (TARGET_THUMB1)
5129 {
5130 emit_insn (gen_thumb1_extendhisi2 (operands[0], operands[1]));
5131 DONE;
5132 }
5133 if (MEM_P (operands[1]) && TARGET_ARM && !arm_arch4)
5134 {
5135 emit_insn (gen_extendhisi2_mem (operands[0], operands[1]));
5136 DONE;
5137 }
ed29c566 5138
ef51b8e1 5139 if (!arm_arch6 && !MEM_P (operands[1]))
5140 {
5141 rtx t = gen_lowpart (SImode, operands[1]);
5142 rtx tmp = gen_reg_rtx (SImode);
5143 emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (16)));
5144 emit_insn (gen_ashrsi3 (operands[0], tmp, GEN_INT (16)));
5145 DONE;
5146 }
5147})
cffb2a26 5148
ef51b8e1 5149(define_split
5150 [(parallel
5151 [(set (match_operand:SI 0 "register_operand" "")
5152 (sign_extend:SI (match_operand:HI 1 "register_operand" "")))
5153 (clobber (match_scratch:SI 2 ""))])]
5154 "!arm_arch6"
5155 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
5156 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 16)))]
5157{
5158 operands[2] = simplify_gen_subreg (SImode, operands[1], HImode, 0);
5159})
25f7a26e 5160
25f905c2 5161;; This pattern will only be used when ldsh is not available
25f7a26e 5162(define_expand "extendhisi2_mem"
eab14235 5163 [(set (match_dup 2) (zero_extend:SI (match_operand:HI 1 "" "")))
25f7a26e 5164 (set (match_dup 3)
eab14235 5165 (zero_extend:SI (match_dup 7)))
25f7a26e 5166 (set (match_dup 6) (ashift:SI (match_dup 4) (const_int 24)))
5167 (set (match_operand:SI 0 "" "")
5168 (ior:SI (ashiftrt:SI (match_dup 6) (const_int 16)) (match_dup 5)))]
cffb2a26 5169 "TARGET_ARM"
25f7a26e 5170 "
215b30b3 5171 {
5172 rtx mem1, mem2;
5173 rtx addr = copy_to_mode_reg (SImode, XEXP (operands[1], 0));
5174
788fcce0 5175 mem1 = change_address (operands[1], QImode, addr);
29c05e22 5176 mem2 = change_address (operands[1], QImode,
5177 plus_constant (Pmode, addr, 1));
215b30b3 5178 operands[0] = gen_lowpart (SImode, operands[0]);
5179 operands[1] = mem1;
5180 operands[2] = gen_reg_rtx (SImode);
5181 operands[3] = gen_reg_rtx (SImode);
5182 operands[6] = gen_reg_rtx (SImode);
5183 operands[7] = mem2;
25f7a26e 5184
215b30b3 5185 if (BYTES_BIG_ENDIAN)
5186 {
5187 operands[4] = operands[2];
5188 operands[5] = operands[3];
5189 }
5190 else
5191 {
5192 operands[4] = operands[3];
5193 operands[5] = operands[2];
5194 }
5195 }"
5196)
b11cae9e 5197
ef51b8e1 5198(define_split
5199 [(set (match_operand:SI 0 "register_operand" "")
5200 (sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
5201 "!arm_arch6"
5202 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
5203 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 16)))]
5204{
5205 operands[2] = simplify_gen_subreg (SImode, operands[1], HImode, 0);
5206})
5207
a2cd141b 5208(define_insn "*arm_extendhisi2"
ef51b8e1 5209 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
e3f4ccee 5210 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,Uh")))]
a2cd141b 5211 "TARGET_ARM && arm_arch4 && !arm_arch6"
ef51b8e1 5212 "@
5213 #
3ef90e77 5214 ldrsh%?\\t%0, %1"
ef51b8e1 5215 [(set_attr "length" "8,4")
d82e788e 5216 (set_attr "type" "alu_shift_reg,load_byte")
e3f4ccee 5217 (set_attr "predicable" "yes")]
cffb2a26 5218)
f7fbdd4a 5219
25f905c2 5220;; ??? Check Thumb-2 pool range
a2cd141b 5221(define_insn "*arm_extendhisi2_v6"
5222 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
e3f4ccee 5223 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,Uh")))]
25f905c2 5224 "TARGET_32BIT && arm_arch6"
a2cd141b 5225 "@
5226 sxth%?\\t%0, %1
3ef90e77 5227 ldrsh%?\\t%0, %1"
6b6abc9c 5228 [(set_attr "type" "extend,load_byte")
a2cd141b 5229 (set_attr "predicable" "yes")
e3f4ccee 5230 (set_attr "predicable_short_it" "no")]
a2cd141b 5231)
5232
5233(define_insn "*arm_extendhisi2addsi"
5234 [(set (match_operand:SI 0 "s_register_operand" "=r")
5235 (plus:SI (sign_extend:SI (match_operand:HI 1 "s_register_operand" "r"))
5236 (match_operand:SI 2 "s_register_operand" "r")))]
25f905c2 5237 "TARGET_INT_SIMD"
a2cd141b 5238 "sxtah%?\\t%0, %2, %1"
1b7da4ac 5239 [(set_attr "type" "alu_shift_reg")]
a2cd141b 5240)
5241
c8f69309 5242(define_expand "extendqihi2"
5243 [(set (match_dup 2)
bed7d9a5 5244 (ashift:SI (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "")
c8f69309 5245 (const_int 24)))
9c08d1fa 5246 (set (match_operand:HI 0 "s_register_operand" "")
c8f69309 5247 (ashiftrt:SI (match_dup 2)
5248 (const_int 24)))]
cffb2a26 5249 "TARGET_ARM"
c8f69309 5250 "
215b30b3 5251 {
0438d37f 5252 if (arm_arch4 && MEM_P (operands[1]))
215b30b3 5253 {
d1f9b275 5254 emit_insn (gen_rtx_SET (operands[0],
215b30b3 5255 gen_rtx_SIGN_EXTEND (HImode, operands[1])));
5256 DONE;
5257 }
5258 if (!s_register_operand (operands[1], QImode))
5259 operands[1] = copy_to_mode_reg (QImode, operands[1]);
5260 operands[0] = gen_lowpart (SImode, operands[0]);
5261 operands[1] = gen_lowpart (SImode, operands[1]);
5262 operands[2] = gen_reg_rtx (SImode);
5263 }"
5264)
f7fbdd4a 5265
25f905c2 5266(define_insn "*arm_extendqihi_insn"
b4e8a300 5267 [(set (match_operand:HI 0 "s_register_operand" "=r")
bed7d9a5 5268 (sign_extend:HI (match_operand:QI 1 "arm_extendqisi_mem_op" "Uq")))]
cffb2a26 5269 "TARGET_ARM && arm_arch4"
3ef90e77 5270 "ldrsb%?\\t%0, %1"
a2cd141b 5271 [(set_attr "type" "load_byte")
e3f4ccee 5272 (set_attr "predicable" "yes")]
cffb2a26 5273)
3fc2009e 5274
b11cae9e 5275(define_expand "extendqisi2"
ef51b8e1 5276 [(set (match_operand:SI 0 "s_register_operand" "")
5277 (sign_extend:SI (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "")))]
cffb2a26 5278 "TARGET_EITHER"
ef51b8e1 5279{
5280 if (!arm_arch4 && MEM_P (operands[1]))
5281 operands[1] = copy_to_mode_reg (QImode, operands[1]);
a2cd141b 5282
ef51b8e1 5283 if (!arm_arch6 && !MEM_P (operands[1]))
5284 {
5285 rtx t = gen_lowpart (SImode, operands[1]);
5286 rtx tmp = gen_reg_rtx (SImode);
5287 emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (24)));
5288 emit_insn (gen_ashrsi3 (operands[0], tmp, GEN_INT (24)));
5289 DONE;
5290 }
5291})
a2cd141b 5292
ef51b8e1 5293(define_split
5294 [(set (match_operand:SI 0 "register_operand" "")
5295 (sign_extend:SI (match_operand:QI 1 "register_operand" "")))]
5296 "!arm_arch6"
5297 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 24)))
5298 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 24)))]
5299{
5300 operands[2] = simplify_gen_subreg (SImode, operands[1], QImode, 0);
5301})
f7fbdd4a 5302
a2cd141b 5303(define_insn "*arm_extendqisi"
ef51b8e1 5304 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5305 (sign_extend:SI (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "r,Uq")))]
a2cd141b 5306 "TARGET_ARM && arm_arch4 && !arm_arch6"
ef51b8e1 5307 "@
5308 #
3ef90e77 5309 ldrsb%?\\t%0, %1"
ef51b8e1 5310 [(set_attr "length" "8,4")
d82e788e 5311 (set_attr "type" "alu_shift_reg,load_byte")
e3f4ccee 5312 (set_attr "predicable" "yes")]
cffb2a26 5313)
3fc2009e 5314
a2cd141b 5315(define_insn "*arm_extendqisi_v6"
5316 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
bed7d9a5 5317 (sign_extend:SI
5318 (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "r,Uq")))]
a2cd141b 5319 "TARGET_ARM && arm_arch6"
b4e8a300 5320 "@
5321 sxtb%?\\t%0, %1
3ef90e77 5322 ldrsb%?\\t%0, %1"
6b6abc9c 5323 [(set_attr "type" "extend,load_byte")
e3f4ccee 5324 (set_attr "predicable" "yes")]
a2cd141b 5325)
5326
5327(define_insn "*arm_extendqisi2addsi"
5328 [(set (match_operand:SI 0 "s_register_operand" "=r")
5329 (plus:SI (sign_extend:SI (match_operand:QI 1 "s_register_operand" "r"))
5330 (match_operand:SI 2 "s_register_operand" "r")))]
25f905c2 5331 "TARGET_INT_SIMD"
a2cd141b 5332 "sxtab%?\\t%0, %2, %1"
d82e788e 5333 [(set_attr "type" "alu_shift_reg")
d952d547 5334 (set_attr "predicable" "yes")
5335 (set_attr "predicable_short_it" "no")]
a2cd141b 5336)
5337
caedf871 5338(define_expand "extendsfdf2"
5339 [(set (match_operand:DF 0 "s_register_operand" "")
5340 (float_extend:DF (match_operand:SF 1 "s_register_operand" "")))]
a50d7267 5341 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
caedf871 5342 ""
5343)
9b8516be 5344
5345/* HFmode -> DFmode conversions have to go through SFmode. */
5346(define_expand "extendhfdf2"
5347 [(set (match_operand:DF 0 "general_operand" "")
5348 (float_extend:DF (match_operand:HF 1 "general_operand" "")))]
5349 "TARGET_EITHER"
5350 "
5351 {
5352 rtx op1;
5353 op1 = convert_to_mode (SFmode, operands[1], 0);
5354 op1 = convert_to_mode (DFmode, op1, 0);
5355 emit_insn (gen_movdf (operands[0], op1));
5356 DONE;
5357 }"
5358)
b11cae9e 5359\f
5360;; Move insns (including loads and stores)
5361
5362;; XXX Just some ideas about movti.
9c08d1fa 5363;; I don't think these are a good idea on the arm, there just aren't enough
5364;; registers
b11cae9e 5365;;(define_expand "loadti"
9c08d1fa 5366;; [(set (match_operand:TI 0 "s_register_operand" "")
b11cae9e 5367;; (mem:TI (match_operand:SI 1 "address_operand" "")))]
5368;; "" "")
5369
5370;;(define_expand "storeti"
5371;; [(set (mem:TI (match_operand:TI 0 "address_operand" ""))
9c08d1fa 5372;; (match_operand:TI 1 "s_register_operand" ""))]
b11cae9e 5373;; "" "")
5374
5375;;(define_expand "movti"
5376;; [(set (match_operand:TI 0 "general_operand" "")
5377;; (match_operand:TI 1 "general_operand" ""))]
5378;; ""
5379;; "
5380;;{
5381;; rtx insn;
5382;;
0438d37f 5383;; if (MEM_P (operands[0]) && MEM_P (operands[1]))
b11cae9e 5384;; operands[1] = copy_to_reg (operands[1]);
0438d37f 5385;; if (MEM_P (operands[0]))
b11cae9e 5386;; insn = gen_storeti (XEXP (operands[0], 0), operands[1]);
0438d37f 5387;; else if (MEM_P (operands[1]))
b11cae9e 5388;; insn = gen_loadti (operands[0], XEXP (operands[1], 0));
5389;; else
5390;; FAIL;
5391;;
5392;; emit_insn (insn);
5393;; DONE;
5394;;}")
5395
a2f10574 5396;; Recognize garbage generated above.
b11cae9e 5397
5398;;(define_insn ""
5399;; [(set (match_operand:TI 0 "general_operand" "=r,r,r,<,>,m")
5400;; (match_operand:TI 1 "general_operand" "<,>,m,r,r,r"))]
5401;; ""
5402;; "*
5403;; {
5404;; register mem = (which_alternative < 3);
0d66636f 5405;; register const char *template;
b11cae9e 5406;;
5407;; operands[mem] = XEXP (operands[mem], 0);
5408;; switch (which_alternative)
5409;; {
5410;; case 0: template = \"ldmdb\\t%1!, %M0\"; break;
5411;; case 1: template = \"ldmia\\t%1!, %M0\"; break;
5412;; case 2: template = \"ldmia\\t%1, %M0\"; break;
5413;; case 3: template = \"stmdb\\t%0!, %M1\"; break;
5414;; case 4: template = \"stmia\\t%0!, %M1\"; break;
5415;; case 5: template = \"stmia\\t%0, %M1\"; break;
5416;; }
e2348bcb 5417;; output_asm_insn (template, operands);
5418;; return \"\";
b11cae9e 5419;; }")
5420
cffb2a26 5421(define_expand "movdi"
5422 [(set (match_operand:DI 0 "general_operand" "")
5423 (match_operand:DI 1 "general_operand" ""))]
5424 "TARGET_EITHER"
5425 "
e1ba4a27 5426 if (can_create_pseudo_p ())
cffb2a26 5427 {
0438d37f 5428 if (!REG_P (operands[0]))
b2778788 5429 operands[1] = force_reg (DImode, operands[1]);
cffb2a26 5430 }
6b97fdcc 5431 if (REG_P (operands[0]) && REGNO (operands[0]) <= LAST_ARM_REGNUM
4f0e25ca 5432 && !HARD_REGNO_MODE_OK (REGNO (operands[0]), DImode))
5433 {
5434 /* Avoid LDRD's into an odd-numbered register pair in ARM state
5435 when expanding function calls. */
5436 gcc_assert (can_create_pseudo_p ());
5437 if (MEM_P (operands[1]) && MEM_VOLATILE_P (operands[1]))
5438 {
5439 /* Perform load into legal reg pair first, then move. */
5440 rtx reg = gen_reg_rtx (DImode);
5441 emit_insn (gen_movdi (reg, operands[1]));
5442 operands[1] = reg;
5443 }
5444 emit_move_insn (gen_lowpart (SImode, operands[0]),
5445 gen_lowpart (SImode, operands[1]));
5446 emit_move_insn (gen_highpart (SImode, operands[0]),
5447 gen_highpart (SImode, operands[1]));
5448 DONE;
5449 }
6b97fdcc 5450 else if (REG_P (operands[1]) && REGNO (operands[1]) <= LAST_ARM_REGNUM
4f0e25ca 5451 && !HARD_REGNO_MODE_OK (REGNO (operands[1]), DImode))
5452 {
5453 /* Avoid STRD's from an odd-numbered register pair in ARM state
5454 when expanding function prologue. */
5455 gcc_assert (can_create_pseudo_p ());
5456 rtx split_dest = (MEM_P (operands[0]) && MEM_VOLATILE_P (operands[0]))
5457 ? gen_reg_rtx (DImode)
5458 : operands[0];
5459 emit_move_insn (gen_lowpart (SImode, split_dest),
5460 gen_lowpart (SImode, operands[1]));
5461 emit_move_insn (gen_highpart (SImode, split_dest),
5462 gen_highpart (SImode, operands[1]));
5463 if (split_dest != operands[0])
5464 emit_insn (gen_movdi (operands[0], split_dest));
5465 DONE;
5466 }
cffb2a26 5467 "
5468)
b11cae9e 5469
cffb2a26 5470(define_insn "*arm_movdi"
353cf59a 5471 [(set (match_operand:DI 0 "nonimmediate_di_operand" "=r, r, r, q, m")
5472 (match_operand:DI 1 "di_operand" "rDa,Db,Dc,mi,q"))]
cde1623a 5473 "TARGET_32BIT
b805622c 5474 && !(TARGET_HARD_FLOAT && TARGET_VFP)
b2778788 5475 && !TARGET_IWMMXT
5476 && ( register_operand (operands[0], DImode)
5477 || register_operand (operands[1], DImode))"
b11cae9e 5478 "*
d51f92df 5479 switch (which_alternative)
5480 {
5481 case 0:
5482 case 1:
5483 case 2:
5484 return \"#\";
5485 default:
26ff80c0 5486 return output_move_double (operands, true, NULL);
d51f92df 5487 }
cffb2a26 5488 "
359a6e9f 5489 [(set_attr "length" "8,12,16,8,8")
1b7da4ac 5490 (set_attr "type" "multiple,multiple,multiple,load2,store2")
cde1623a 5491 (set_attr "arm_pool_range" "*,*,*,1020,*")
8848d797 5492 (set_attr "arm_neg_pool_range" "*,*,*,1004,*")
42e1de19 5493 (set_attr "thumb2_pool_range" "*,*,*,4094,*")
cde1623a 5494 (set_attr "thumb2_neg_pool_range" "*,*,*,0,*")]
cffb2a26 5495)
5496
d51f92df 5497(define_split
5498 [(set (match_operand:ANY64 0 "arm_general_register_operand" "")
e6dd3afa 5499 (match_operand:ANY64 1 "immediate_operand" ""))]
25f905c2 5500 "TARGET_32BIT
d51f92df 5501 && reload_completed
5502 && (arm_const_double_inline_cost (operands[1])
861033d5 5503 <= arm_max_const_double_inline_cost ())"
d51f92df 5504 [(const_int 0)]
5505 "
5506 arm_split_constant (SET, SImode, curr_insn,
5507 INTVAL (gen_lowpart (SImode, operands[1])),
5508 gen_lowpart (SImode, operands[0]), NULL_RTX, 0);
5509 arm_split_constant (SET, SImode, curr_insn,
5510 INTVAL (gen_highpart_mode (SImode,
5511 GET_MODE (operands[0]),
5512 operands[1])),
5513 gen_highpart (SImode, operands[0]), NULL_RTX, 0);
5514 DONE;
5515 "
5516)
5517
e5ba9289 5518; If optimizing for size, or if we have load delay slots, then
5519; we want to split the constant into two separate operations.
5520; In both cases this may split a trivial part into a single data op
5521; leaving a single complex constant to load. We can also get longer
5522; offsets in a LDR which means we get better chances of sharing the pool
5523; entries. Finally, we can normally do a better job of scheduling
5524; LDR instructions than we can with LDM.
5525; This pattern will only match if the one above did not.
5526(define_split
5527 [(set (match_operand:ANY64 0 "arm_general_register_operand" "")
5528 (match_operand:ANY64 1 "const_double_operand" ""))]
5529 "TARGET_ARM && reload_completed
5530 && arm_const_double_by_parts (operands[1])"
5531 [(set (match_dup 0) (match_dup 1))
5532 (set (match_dup 2) (match_dup 3))]
5533 "
5534 operands[2] = gen_highpart (SImode, operands[0]);
5535 operands[3] = gen_highpart_mode (SImode, GET_MODE (operands[0]),
5536 operands[1]);
5537 operands[0] = gen_lowpart (SImode, operands[0]);
5538 operands[1] = gen_lowpart (SImode, operands[1]);
5539 "
5540)
5541
d51f92df 5542(define_split
5543 [(set (match_operand:ANY64 0 "arm_general_register_operand" "")
5544 (match_operand:ANY64 1 "arm_general_register_operand" ""))]
5545 "TARGET_EITHER && reload_completed"
5546 [(set (match_dup 0) (match_dup 1))
5547 (set (match_dup 2) (match_dup 3))]
5548 "
5549 operands[2] = gen_highpart (SImode, operands[0]);
5550 operands[3] = gen_highpart (SImode, operands[1]);
5551 operands[0] = gen_lowpart (SImode, operands[0]);
5552 operands[1] = gen_lowpart (SImode, operands[1]);
5553
5554 /* Handle a partial overlap. */
5555 if (rtx_equal_p (operands[0], operands[3]))
5556 {
5557 rtx tmp0 = operands[0];
5558 rtx tmp1 = operands[1];
5559
5560 operands[0] = operands[2];
5561 operands[1] = operands[3];
5562 operands[2] = tmp0;
5563 operands[3] = tmp1;
5564 }
5565 "
5566)
5567
a8a3b539 5568;; We can't actually do base+index doubleword loads if the index and
5569;; destination overlap. Split here so that we at least have chance to
5570;; schedule.
5571(define_split
5572 [(set (match_operand:DI 0 "s_register_operand" "")
5573 (mem:DI (plus:SI (match_operand:SI 1 "s_register_operand" "")
5574 (match_operand:SI 2 "s_register_operand" ""))))]
5575 "TARGET_LDRD
5576 && reg_overlap_mentioned_p (operands[0], operands[1])
5577 && reg_overlap_mentioned_p (operands[0], operands[2])"
5578 [(set (match_dup 4)
5579 (plus:SI (match_dup 1)
5580 (match_dup 2)))
5581 (set (match_dup 0)
5582 (mem:DI (match_dup 4)))]
5583 "
5584 operands[4] = gen_rtx_REG (SImode, REGNO(operands[0]));
5585 "
5586)
5587
9c08d1fa 5588(define_expand "movsi"
5589 [(set (match_operand:SI 0 "general_operand" "")
5590 (match_operand:SI 1 "general_operand" ""))]
cffb2a26 5591 "TARGET_EITHER"
9c08d1fa 5592 "
befb0bac 5593 {
e348ff3e 5594 rtx base, offset, tmp;
5595
25f905c2 5596 if (TARGET_32BIT)
9c08d1fa 5597 {
674a8f0b 5598 /* Everything except mem = const or mem = mem can be done easily. */
0438d37f 5599 if (MEM_P (operands[0]))
cffb2a26 5600 operands[1] = force_reg (SImode, operands[1]);
a2cd141b 5601 if (arm_general_register_operand (operands[0], SImode)
0438d37f 5602 && CONST_INT_P (operands[1])
cffb2a26 5603 && !(const_ok_for_arm (INTVAL (operands[1]))
5604 || const_ok_for_arm (~INTVAL (operands[1]))))
5605 {
17202aa5 5606 if (DONT_EARLY_SPLIT_CONSTANT (INTVAL (operands[1]), SET))
5607 {
5608 emit_insn (gen_rtx_SET (operands[0], operands[1]));
5609 DONE;
5610 }
5611 else
5612 {
5613 arm_split_constant (SET, SImode, NULL_RTX,
5614 INTVAL (operands[1]), operands[0], NULL_RTX,
5615 optimize && can_create_pseudo_p ());
5616 DONE;
5617 }
cffb2a26 5618 }
5619 }
25f905c2 5620 else /* TARGET_THUMB1... */
cffb2a26 5621 {
e1ba4a27 5622 if (can_create_pseudo_p ())
cffb2a26 5623 {
0438d37f 5624 if (!REG_P (operands[0]))
cffb2a26 5625 operands[1] = force_reg (SImode, operands[1]);
5626 }
9c08d1fa 5627 }
f655717d 5628
e348ff3e 5629 if (ARM_OFFSETS_MUST_BE_WITHIN_SECTIONS_P)
5630 {
5631 split_const (operands[1], &base, &offset);
5632 if (GET_CODE (base) == SYMBOL_REF
5633 && !offset_within_block_p (base, INTVAL (offset)))
5634 {
b308ddcf 5635 tmp = can_create_pseudo_p () ? gen_reg_rtx (SImode) : operands[0];
e348ff3e 5636 emit_move_insn (tmp, base);
5637 emit_insn (gen_addsi3 (operands[0], tmp, offset));
5638 DONE;
5639 }
5640 }
5641
f655717d 5642 /* Recognize the case where operand[1] is a reference to thread-local
5643 data and load its address to a register. */
5644 if (arm_tls_referenced_p (operands[1]))
5645 {
5646 rtx tmp = operands[1];
5647 rtx addend = NULL;
5648
5649 if (GET_CODE (tmp) == CONST && GET_CODE (XEXP (tmp, 0)) == PLUS)
5650 {
5651 addend = XEXP (XEXP (tmp, 0), 1);
5652 tmp = XEXP (XEXP (tmp, 0), 0);
5653 }
5654
5655 gcc_assert (GET_CODE (tmp) == SYMBOL_REF);
5656 gcc_assert (SYMBOL_REF_TLS_MODEL (tmp) != 0);
5657
e1ba4a27 5658 tmp = legitimize_tls_address (tmp,
5659 !can_create_pseudo_p () ? operands[0] : 0);
f655717d 5660 if (addend)
5661 {
5662 tmp = gen_rtx_PLUS (SImode, tmp, addend);
5663 tmp = force_operand (tmp, operands[0]);
5664 }
5665 operands[1] = tmp;
5666 }
5667 else if (flag_pic
5668 && (CONSTANT_P (operands[1])
5669 || symbol_mentioned_p (operands[1])
5670 || label_mentioned_p (operands[1])))
5671 operands[1] = legitimize_pic_address (operands[1], SImode,
e1ba4a27 5672 (!can_create_pseudo_p ()
5673 ? operands[0]
5674 : 0));
befb0bac 5675 }
215b30b3 5676 "
5677)
9c08d1fa 5678
d0e6a121 5679;; The ARM LO_SUM and HIGH are backwards - HIGH sets the low bits, and
5680;; LO_SUM adds in the high bits. Fortunately these are opaque operations
5681;; so this does not matter.
5682(define_insn "*arm_movt"
5683 [(set (match_operand:SI 0 "nonimmediate_operand" "=r")
5684 (lo_sum:SI (match_operand:SI 1 "nonimmediate_operand" "0")
5685 (match_operand:SI 2 "general_operand" "i")))]
ac528743 5686 "arm_arch_thumb2 && arm_valid_symbolic_address_p (operands[2])"
d0e6a121 5687 "movt%?\t%0, #:upper16:%c2"
5688 [(set_attr "predicable" "yes")
d952d547 5689 (set_attr "predicable_short_it" "no")
1b7da4ac 5690 (set_attr "length" "4")
282b4c75 5691 (set_attr "type" "alu_sreg")]
d0e6a121 5692)
5693
cffb2a26 5694(define_insn "*arm_movsi_insn"
aaa37ad6 5695 [(set (match_operand:SI 0 "nonimmediate_operand" "=rk,r,r,r,rk,m")
110eae03 5696 (match_operand:SI 1 "general_operand" "rk, I,K,j,mi,rk"))]
755eb2b4 5697 "TARGET_ARM && ! TARGET_IWMMXT
a2cd141b 5698 && !(TARGET_HARD_FLOAT && TARGET_VFP)
cffb2a26 5699 && ( register_operand (operands[0], SImode)
5700 || register_operand (operands[1], SImode))"
f7fbdd4a 5701 "@
aaa37ad6 5702 mov%?\\t%0, %1
f7fbdd4a 5703 mov%?\\t%0, %1
5704 mvn%?\\t%0, #%B1
25f905c2 5705 movw%?\\t%0, %1
f7fbdd4a 5706 ldr%?\\t%0, %1
5707 str%?\\t%1, %0"
1aed5204 5708 [(set_attr "type" "mov_reg,mov_imm,mvn_imm,mov_imm,load1,store1")
0d66636f 5709 (set_attr "predicable" "yes")
aaa37ad6 5710 (set_attr "pool_range" "*,*,*,*,4096,*")
5711 (set_attr "neg_pool_range" "*,*,*,*,4084,*")]
cffb2a26 5712)
87b22bf7 5713
5714(define_split
a2cd141b 5715 [(set (match_operand:SI 0 "arm_general_register_operand" "")
87b22bf7 5716 (match_operand:SI 1 "const_int_operand" ""))]
25f905c2 5717 "TARGET_32BIT
215b30b3 5718 && (!(const_ok_for_arm (INTVAL (operands[1]))
5719 || const_ok_for_arm (~INTVAL (operands[1]))))"
87b22bf7 5720 [(clobber (const_int 0))]
5721 "
96f57e36 5722 arm_split_constant (SET, SImode, NULL_RTX,
5723 INTVAL (operands[1]), operands[0], NULL_RTX, 0);
87b22bf7 5724 DONE;
215b30b3 5725 "
5726)
9c08d1fa 5727
861033d5 5728;; A normal way to do (symbol + offset) requires three instructions at least
5729;; (depends on how big the offset is) as below:
5730;; movw r0, #:lower16:g
5731;; movw r0, #:upper16:g
5732;; adds r0, #4
5733;;
5734;; A better way would be:
5735;; movw r0, #:lower16:g+4
5736;; movw r0, #:upper16:g+4
5737;;
5738;; The limitation of this way is that the length of offset should be a 16-bit
5739;; signed value, because current assembler only supports REL type relocation for
5740;; such case. If the more powerful RELA type is supported in future, we should
5741;; update this pattern to go with better way.
5742(define_split
5743 [(set (match_operand:SI 0 "arm_general_register_operand" "")
5744 (const:SI (plus:SI (match_operand:SI 1 "general_operand" "")
5745 (match_operand:SI 2 "const_int_operand" ""))))]
5746 "TARGET_THUMB2
5747 && arm_disable_literal_pool
5748 && reload_completed
5749 && GET_CODE (operands[1]) == SYMBOL_REF"
5750 [(clobber (const_int 0))]
5751 "
5752 int offset = INTVAL (operands[2]);
5753
5754 if (offset < -0x8000 || offset > 0x7fff)
5755 {
5756 arm_emit_movpair (operands[0], operands[1]);
d1f9b275 5757 emit_insn (gen_rtx_SET (operands[0],
861033d5 5758 gen_rtx_PLUS (SImode, operands[0], operands[2])));
5759 }
5760 else
5761 {
5762 rtx op = gen_rtx_CONST (SImode,
5763 gen_rtx_PLUS (SImode, operands[1], operands[2]));
5764 arm_emit_movpair (operands[0], op);
5765 }
5766 "
5767)
5768
b8d5d078 5769;; Split symbol_refs at the later stage (after cprop), instead of generating
5770;; movt/movw pair directly at expand. Otherwise corresponding high_sum
5771;; and lo_sum would be merged back into memory load at cprop. However,
5772;; if the default is to prefer movt/movw rather than a load from the constant
5773;; pool, the performance is better.
5774(define_split
5775 [(set (match_operand:SI 0 "arm_general_register_operand" "")
5776 (match_operand:SI 1 "general_operand" ""))]
5777 "TARGET_32BIT
5778 && TARGET_USE_MOVT && GET_CODE (operands[1]) == SYMBOL_REF
5779 && !flag_pic && !target_word_relocations
5780 && !arm_tls_referenced_p (operands[1])"
5781 [(clobber (const_int 0))]
5782{
5783 arm_emit_movpair (operands[0], operands[1]);
5784 DONE;
5785})
5786
bc360af8 5787;; When generating pic, we need to load the symbol offset into a register.
5788;; So that the optimizer does not confuse this with a normal symbol load
5789;; we use an unspec. The offset will be loaded from a constant pool entry,
5790;; since that is the only type of relocation we can use.
cffb2a26 5791
bc360af8 5792;; Wrap calculation of the whole PIC address in a single pattern for the
5793;; benefit of optimizers, particularly, PRE and HOIST. Calculation of
5794;; a PIC address involves two loads from memory, so we want to CSE it
5795;; as often as possible.
5796;; This pattern will be split into one of the pic_load_addr_* patterns
5797;; and a move after GCSE optimizations.
5798;;
5799;; Note: Update arm.c: legitimize_pic_address() when changing this pattern.
5800(define_expand "calculate_pic_address"
94f8caca 5801 [(set (match_operand:SI 0 "register_operand" "")
5802 (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "")
5803 (unspec:SI [(match_operand:SI 2 "" "")]
5804 UNSPEC_PIC_SYM))))]
5805 "flag_pic"
5806)
5807
5808;; Split calculate_pic_address into pic_load_addr_* and a move.
5809(define_split
5810 [(set (match_operand:SI 0 "register_operand" "")
5811 (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "")
5812 (unspec:SI [(match_operand:SI 2 "" "")]
5813 UNSPEC_PIC_SYM))))]
5814 "flag_pic"
5815 [(set (match_dup 3) (unspec:SI [(match_dup 2)] UNSPEC_PIC_SYM))
5816 (set (match_dup 0) (mem:SI (plus:SI (match_dup 1) (match_dup 3))))]
5817 "operands[3] = can_create_pseudo_p () ? gen_reg_rtx (SImode) : operands[0];"
5818)
5819
350ccca5 5820;; operand1 is the memory address to go into
5821;; pic_load_addr_32bit.
5822;; operand2 is the PIC label to be emitted
5823;; from pic_add_dot_plus_eight.
5824;; We do this to allow hoisting of the entire insn.
5825(define_insn_and_split "pic_load_addr_unified"
5826 [(set (match_operand:SI 0 "s_register_operand" "=r,r,l")
5827 (unspec:SI [(match_operand:SI 1 "" "mX,mX,mX")
5828 (match_operand:SI 2 "" "")]
5829 UNSPEC_PIC_UNIFIED))]
5830 "flag_pic"
5831 "#"
5832 "&& reload_completed"
5833 [(set (match_dup 0) (unspec:SI [(match_dup 1)] UNSPEC_PIC_SYM))
5834 (set (match_dup 0) (unspec:SI [(match_dup 0) (match_dup 3)
5835 (match_dup 2)] UNSPEC_PIC_BASE))]
5836 "operands[3] = TARGET_THUMB ? GEN_INT (4) : GEN_INT (8);"
5837 [(set_attr "type" "load1,load1,load1")
42e1de19 5838 (set_attr "pool_range" "4096,4094,1022")
350ccca5 5839 (set_attr "neg_pool_range" "4084,0,0")
5840 (set_attr "arch" "a,t2,t1")
5841 (set_attr "length" "8,6,4")]
5842)
5843
67336bcf 5844;; The rather odd constraints on the following are to force reload to leave
5845;; the insn alone, and to force the minipool generation pass to then move
5846;; the GOT symbol to memory.
849170fd 5847
b3cd5f55 5848(define_insn "pic_load_addr_32bit"
849170fd 5849 [(set (match_operand:SI 0 "s_register_operand" "=r")
e1159bbe 5850 (unspec:SI [(match_operand:SI 1 "" "mX")] UNSPEC_PIC_SYM))]
b3cd5f55 5851 "TARGET_32BIT && flag_pic"
67336bcf 5852 "ldr%?\\t%0, %1"
a2cd141b 5853 [(set_attr "type" "load1")
42e1de19 5854 (set (attr "pool_range")
5855 (if_then_else (eq_attr "is_thumb" "no")
5856 (const_int 4096)
5857 (const_int 4094)))
b3cd5f55 5858 (set (attr "neg_pool_range")
5859 (if_then_else (eq_attr "is_thumb" "no")
5860 (const_int 4084)
5861 (const_int 0)))]
8c4d8060 5862)
5863
25f905c2 5864(define_insn "pic_load_addr_thumb1"
8c4d8060 5865 [(set (match_operand:SI 0 "s_register_operand" "=l")
e1159bbe 5866 (unspec:SI [(match_operand:SI 1 "" "mX")] UNSPEC_PIC_SYM))]
25f905c2 5867 "TARGET_THUMB1 && flag_pic"
8c4d8060 5868 "ldr\\t%0, %1"
a2cd141b 5869 [(set_attr "type" "load1")
42e1de19 5870 (set (attr "pool_range") (const_int 1018))]
cffb2a26 5871)
849170fd 5872
cffb2a26 5873(define_insn "pic_add_dot_plus_four"
15d5d060 5874 [(set (match_operand:SI 0 "register_operand" "=r")
c0c1fba5 5875 (unspec:SI [(match_operand:SI 1 "register_operand" "0")
5876 (const_int 4)
beef0fb5 5877 (match_operand 2 "" "")]
5878 UNSPEC_PIC_BASE))]
b3cd5f55 5879 "TARGET_THUMB"
cffb2a26 5880 "*
6cdcb15c 5881 (*targetm.asm_out.internal_label) (asm_out_file, \"LPIC\",
5882 INTVAL (operands[2]));
cffb2a26 5883 return \"add\\t%0, %|pc\";
5884 "
1b7da4ac 5885 [(set_attr "length" "2")
112eda6f 5886 (set_attr "type" "alu_sreg")]
cffb2a26 5887)
849170fd 5888
5889(define_insn "pic_add_dot_plus_eight"
15d5d060 5890 [(set (match_operand:SI 0 "register_operand" "=r")
c0c1fba5 5891 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
5892 (const_int 8)
beef0fb5 5893 (match_operand 2 "" "")]
5894 UNSPEC_PIC_BASE))]
f655717d 5895 "TARGET_ARM"
c4034607 5896 "*
6cdcb15c 5897 (*targetm.asm_out.internal_label) (asm_out_file, \"LPIC\",
5898 INTVAL (operands[2]));
15d5d060 5899 return \"add%?\\t%0, %|pc, %1\";
cffb2a26 5900 "
1b7da4ac 5901 [(set_attr "predicable" "yes")
112eda6f 5902 (set_attr "type" "alu_sreg")]
cffb2a26 5903)
849170fd 5904
f655717d 5905(define_insn "tls_load_dot_plus_eight"
cc071db6 5906 [(set (match_operand:SI 0 "register_operand" "=r")
c0c1fba5 5907 (mem:SI (unspec:SI [(match_operand:SI 1 "register_operand" "r")
5908 (const_int 8)
beef0fb5 5909 (match_operand 2 "" "")]
5910 UNSPEC_PIC_BASE)))]
f655717d 5911 "TARGET_ARM"
5912 "*
6cdcb15c 5913 (*targetm.asm_out.internal_label) (asm_out_file, \"LPIC\",
5914 INTVAL (operands[2]));
f655717d 5915 return \"ldr%?\\t%0, [%|pc, %1]\t\t@ tls_load_dot_plus_eight\";
5916 "
1b7da4ac 5917 [(set_attr "predicable" "yes")
5918 (set_attr "type" "load1")]
f655717d 5919)
5920
5921;; PIC references to local variables can generate pic_add_dot_plus_eight
5922;; followed by a load. These sequences can be crunched down to
5923;; tls_load_dot_plus_eight by a peephole.
5924
5925(define_peephole2
c0c1fba5 5926 [(set (match_operand:SI 0 "register_operand" "")
5927 (unspec:SI [(match_operand:SI 3 "register_operand" "")
5928 (const_int 8)
5929 (match_operand 1 "" "")]
5930 UNSPEC_PIC_BASE))
2d05dfad 5931 (set (match_operand:SI 2 "arm_general_register_operand" "")
5932 (mem:SI (match_dup 0)))]
f655717d 5933 "TARGET_ARM && peep2_reg_dead_p (2, operands[0])"
c0c1fba5 5934 [(set (match_dup 2)
5935 (mem:SI (unspec:SI [(match_dup 3)
5936 (const_int 8)
5937 (match_dup 1)]
5938 UNSPEC_PIC_BASE)))]
f655717d 5939 ""
5940)
5941
bac7fc85 5942(define_insn "pic_offset_arm"
5943 [(set (match_operand:SI 0 "register_operand" "=r")
5944 (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
5945 (unspec:SI [(match_operand:SI 2 "" "X")]
5946 UNSPEC_PIC_OFFSET))))]
5947 "TARGET_VXWORKS_RTP && TARGET_ARM && flag_pic"
5948 "ldr%?\\t%0, [%1,%2]"
5949 [(set_attr "type" "load1")]
5950)
5951
95373f08 5952(define_expand "builtin_setjmp_receiver"
5953 [(label_ref (match_operand 0 "" ""))]
5954 "flag_pic"
5955 "
5956{
b935b306 5957 /* r3 is clobbered by set/longjmp, so we can use it as a scratch
5958 register. */
2cb7d577 5959 if (arm_pic_register != INVALID_REGNUM)
5960 arm_load_pic_register (1UL << 3);
95373f08 5961 DONE;
5962}")
5963
9c08d1fa 5964;; If copying one reg to another we can set the condition codes according to
5965;; its value. Such a move is common after a return from subroutine and the
5966;; result is being tested against zero.
5967
f7fbdd4a 5968(define_insn "*movsi_compare0"
bd5b4116 5969 [(set (reg:CC CC_REGNUM)
cffb2a26 5970 (compare:CC (match_operand:SI 1 "s_register_operand" "0,r")
5971 (const_int 0)))
5972 (set (match_operand:SI 0 "s_register_operand" "=r,r")
5973 (match_dup 1))]
25f905c2 5974 "TARGET_32BIT"
e2348bcb 5975 "@
40dbec34 5976 cmp%?\\t%0, #0
3ef90e77 5977 subs%?\\t%0, %1, #0"
65f68e55 5978 [(set_attr "conds" "set")
d82e788e 5979 (set_attr "type" "alus_imm,alus_imm")]
cffb2a26 5980)
b11cae9e 5981
b11cae9e 5982;; Subroutine to store a half word from a register into memory.
5983;; Operand 0 is the source register (HImode)
c8f69309 5984;; Operand 1 is the destination address in a register (SImode)
b11cae9e 5985
9c08d1fa 5986;; In both this routine and the next, we must be careful not to spill
01cc3b75 5987;; a memory address of reg+large_const into a separate PLUS insn, since this
9c08d1fa 5988;; can generate unrecognizable rtl.
5989
b11cae9e 5990(define_expand "storehi"
c8f69309 5991 [;; store the low byte
f082f1c4 5992 (set (match_operand 1 "" "") (match_dup 3))
b11cae9e 5993 ;; extract the high byte
c8f69309 5994 (set (match_dup 2)
5995 (ashiftrt:SI (match_operand 0 "" "") (const_int 8)))
b11cae9e 5996 ;; store the high byte
787f8210 5997 (set (match_dup 4) (match_dup 5))]
cffb2a26 5998 "TARGET_ARM"
b11cae9e 5999 "
215b30b3 6000 {
537ffcfc 6001 rtx op1 = operands[1];
6002 rtx addr = XEXP (op1, 0);
215b30b3 6003 enum rtx_code code = GET_CODE (addr);
6004
0438d37f 6005 if ((code == PLUS && !CONST_INT_P (XEXP (addr, 1)))
215b30b3 6006 || code == MINUS)
537ffcfc 6007 op1 = replace_equiv_address (operands[1], force_reg (SImode, addr));
215b30b3 6008
537ffcfc 6009 operands[4] = adjust_address (op1, QImode, 1);
e513d163 6010 operands[1] = adjust_address (operands[1], QImode, 0);
215b30b3 6011 operands[3] = gen_lowpart (QImode, operands[0]);
6012 operands[0] = gen_lowpart (SImode, operands[0]);
787f8210 6013 operands[2] = gen_reg_rtx (SImode);
6014 operands[5] = gen_lowpart (QImode, operands[2]);
215b30b3 6015 }"
6016)
b11cae9e 6017
c7597b5d 6018(define_expand "storehi_bigend"
f082f1c4 6019 [(set (match_dup 4) (match_dup 3))
c7597b5d 6020 (set (match_dup 2)
6021 (ashiftrt:SI (match_operand 0 "" "") (const_int 8)))
787f8210 6022 (set (match_operand 1 "" "") (match_dup 5))]
cffb2a26 6023 "TARGET_ARM"
b11cae9e 6024 "
215b30b3 6025 {
537ffcfc 6026 rtx op1 = operands[1];
6027 rtx addr = XEXP (op1, 0);
215b30b3 6028 enum rtx_code code = GET_CODE (addr);
6029
0438d37f 6030 if ((code == PLUS && !CONST_INT_P (XEXP (addr, 1)))
215b30b3 6031 || code == MINUS)
537ffcfc 6032 op1 = replace_equiv_address (op1, force_reg (SImode, addr));
215b30b3 6033
537ffcfc 6034 operands[4] = adjust_address (op1, QImode, 1);
e513d163 6035 operands[1] = adjust_address (operands[1], QImode, 0);
215b30b3 6036 operands[3] = gen_lowpart (QImode, operands[0]);
6037 operands[0] = gen_lowpart (SImode, operands[0]);
6038 operands[2] = gen_reg_rtx (SImode);
787f8210 6039 operands[5] = gen_lowpart (QImode, operands[2]);
215b30b3 6040 }"
6041)
c7597b5d 6042
6043;; Subroutine to store a half word integer constant into memory.
6044(define_expand "storeinthi"
f082f1c4 6045 [(set (match_operand 0 "" "")
787f8210 6046 (match_operand 1 "" ""))
9e8503e6 6047 (set (match_dup 3) (match_dup 2))]
cffb2a26 6048 "TARGET_ARM"
c7597b5d 6049 "
215b30b3 6050 {
6051 HOST_WIDE_INT value = INTVAL (operands[1]);
6052 rtx addr = XEXP (operands[0], 0);
537ffcfc 6053 rtx op0 = operands[0];
215b30b3 6054 enum rtx_code code = GET_CODE (addr);
c7597b5d 6055
0438d37f 6056 if ((code == PLUS && !CONST_INT_P (XEXP (addr, 1)))
215b30b3 6057 || code == MINUS)
537ffcfc 6058 op0 = replace_equiv_address (op0, force_reg (SImode, addr));
c7597b5d 6059
215b30b3 6060 operands[1] = gen_reg_rtx (SImode);
6061 if (BYTES_BIG_ENDIAN)
6062 {
6063 emit_insn (gen_movsi (operands[1], GEN_INT ((value >> 8) & 255)));
6064 if ((value & 255) == ((value >> 8) & 255))
6065 operands[2] = operands[1];
6066 else
6067 {
6068 operands[2] = gen_reg_rtx (SImode);
6069 emit_insn (gen_movsi (operands[2], GEN_INT (value & 255)));
6070 }
6071 }
6072 else
6073 {
6074 emit_insn (gen_movsi (operands[1], GEN_INT (value & 255)));
6075 if ((value & 255) == ((value >> 8) & 255))
6076 operands[2] = operands[1];
6077 else
6078 {
6079 operands[2] = gen_reg_rtx (SImode);
6080 emit_insn (gen_movsi (operands[2], GEN_INT ((value >> 8) & 255)));
6081 }
6082 }
c7597b5d 6083
537ffcfc 6084 operands[3] = adjust_address (op0, QImode, 1);
e513d163 6085 operands[0] = adjust_address (operands[0], QImode, 0);
9e8503e6 6086 operands[2] = gen_lowpart (QImode, operands[2]);
787f8210 6087 operands[1] = gen_lowpart (QImode, operands[1]);
215b30b3 6088 }"
6089)
b11cae9e 6090
f7fbdd4a 6091(define_expand "storehi_single_op"
6092 [(set (match_operand:HI 0 "memory_operand" "")
6093 (match_operand:HI 1 "general_operand" ""))]
25f905c2 6094 "TARGET_32BIT && arm_arch4"
f7fbdd4a 6095 "
215b30b3 6096 if (!s_register_operand (operands[1], HImode))
f7fbdd4a 6097 operands[1] = copy_to_mode_reg (HImode, operands[1]);
215b30b3 6098 "
6099)
f7fbdd4a 6100
b11cae9e 6101(define_expand "movhi"
6102 [(set (match_operand:HI 0 "general_operand" "")
c8f69309 6103 (match_operand:HI 1 "general_operand" ""))]
cffb2a26 6104 "TARGET_EITHER"
b11cae9e 6105 "
cffb2a26 6106 if (TARGET_ARM)
b11cae9e 6107 {
e1ba4a27 6108 if (can_create_pseudo_p ())
cffb2a26 6109 {
0438d37f 6110 if (MEM_P (operands[0]))
b11cae9e 6111 {
cffb2a26 6112 if (arm_arch4)
6113 {
6114 emit_insn (gen_storehi_single_op (operands[0], operands[1]));
6115 DONE;
6116 }
0438d37f 6117 if (CONST_INT_P (operands[1]))
cffb2a26 6118 emit_insn (gen_storeinthi (operands[0], operands[1]));
c7597b5d 6119 else
cffb2a26 6120 {
0438d37f 6121 if (MEM_P (operands[1]))
cffb2a26 6122 operands[1] = force_reg (HImode, operands[1]);
6123 if (BYTES_BIG_ENDIAN)
6124 emit_insn (gen_storehi_bigend (operands[1], operands[0]));
6125 else
6126 emit_insn (gen_storehi (operands[1], operands[0]));
6127 }
6128 DONE;
b11cae9e 6129 }
cffb2a26 6130 /* Sign extend a constant, and keep it in an SImode reg. */
0438d37f 6131 else if (CONST_INT_P (operands[1]))
9c08d1fa 6132 {
cffb2a26 6133 rtx reg = gen_reg_rtx (SImode);
6134 HOST_WIDE_INT val = INTVAL (operands[1]) & 0xffff;
6135
6136 /* If the constant is already valid, leave it alone. */
215b30b3 6137 if (!const_ok_for_arm (val))
cffb2a26 6138 {
6139 /* If setting all the top bits will make the constant
6140 loadable in a single instruction, then set them.
6141 Otherwise, sign extend the number. */
6142
215b30b3 6143 if (const_ok_for_arm (~(val | ~0xffff)))
cffb2a26 6144 val |= ~0xffff;
6145 else if (val & 0x8000)
6146 val |= ~0xffff;
6147 }
6148
6149 emit_insn (gen_movsi (reg, GEN_INT (val)));
9e8503e6 6150 operands[1] = gen_lowpart (HImode, reg);
9c08d1fa 6151 }
e1ba4a27 6152 else if (arm_arch4 && optimize && can_create_pseudo_p ()
0438d37f 6153 && MEM_P (operands[1]))
0045890a 6154 {
6155 rtx reg = gen_reg_rtx (SImode);
6156
6157 emit_insn (gen_zero_extendhisi2 (reg, operands[1]));
6158 operands[1] = gen_lowpart (HImode, reg);
6159 }
215b30b3 6160 else if (!arm_arch4)
f7fbdd4a 6161 {
0438d37f 6162 if (MEM_P (operands[1]))
cffb2a26 6163 {
c1a66faf 6164 rtx base;
6165 rtx offset = const0_rtx;
6166 rtx reg = gen_reg_rtx (SImode);
6167
0438d37f 6168 if ((REG_P (base = XEXP (operands[1], 0))
c1a66faf 6169 || (GET_CODE (base) == PLUS
0438d37f 6170 && (CONST_INT_P (offset = XEXP (base, 1)))
c1a66faf 6171 && ((INTVAL(offset) & 1) != 1)
0438d37f 6172 && REG_P (base = XEXP (base, 0))))
c1a66faf 6173 && REGNO_POINTER_ALIGN (REGNO (base)) >= 32)
206ee9a2 6174 {
8deb3959 6175 rtx new_rtx;
c1a66faf 6176
8deb3959 6177 new_rtx = widen_memory_access (operands[1], SImode,
6178 ((INTVAL (offset) & ~3)
6179 - INTVAL (offset)));
6180 emit_insn (gen_movsi (reg, new_rtx));
c1a66faf 6181 if (((INTVAL (offset) & 2) != 0)
6182 ^ (BYTES_BIG_ENDIAN ? 1 : 0))
6183 {
6184 rtx reg2 = gen_reg_rtx (SImode);
6185
6186 emit_insn (gen_lshrsi3 (reg2, reg, GEN_INT (16)));
6187 reg = reg2;
6188 }
206ee9a2 6189 }
c1a66faf 6190 else
6191 emit_insn (gen_movhi_bytes (reg, operands[1]));
6192
6193 operands[1] = gen_lowpart (HImode, reg);
cffb2a26 6194 }
6195 }
6196 }
674a8f0b 6197 /* Handle loading a large integer during reload. */
0438d37f 6198 else if (CONST_INT_P (operands[1])
215b30b3 6199 && !const_ok_for_arm (INTVAL (operands[1]))
6200 && !const_ok_for_arm (~INTVAL (operands[1])))
cffb2a26 6201 {
6202 /* Writing a constant to memory needs a scratch, which should
6203 be handled with SECONDARY_RELOADs. */
0438d37f 6204 gcc_assert (REG_P (operands[0]));
cffb2a26 6205
6206 operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
6207 emit_insn (gen_movsi (operands[0], operands[1]));
6208 DONE;
6209 }
6210 }
25f905c2 6211 else if (TARGET_THUMB2)
6212 {
6213 /* Thumb-2 can do everything except mem=mem and mem=const easily. */
e1ba4a27 6214 if (can_create_pseudo_p ())
25f905c2 6215 {
0438d37f 6216 if (!REG_P (operands[0]))
25f905c2 6217 operands[1] = force_reg (HImode, operands[1]);
6218 /* Zero extend a constant, and keep it in an SImode reg. */
0438d37f 6219 else if (CONST_INT_P (operands[1]))
25f905c2 6220 {
6221 rtx reg = gen_reg_rtx (SImode);
6222 HOST_WIDE_INT val = INTVAL (operands[1]) & 0xffff;
6223
6224 emit_insn (gen_movsi (reg, GEN_INT (val)));
6225 operands[1] = gen_lowpart (HImode, reg);
6226 }
6227 }
6228 }
6229 else /* TARGET_THUMB1 */
cffb2a26 6230 {
e1ba4a27 6231 if (can_create_pseudo_p ())
cffb2a26 6232 {
0438d37f 6233 if (CONST_INT_P (operands[1]))
6cffc037 6234 {
6235 rtx reg = gen_reg_rtx (SImode);
6236
6237 emit_insn (gen_movsi (reg, operands[1]));
6238 operands[1] = gen_lowpart (HImode, reg);
6239 }
cffb2a26 6240
6241 /* ??? We shouldn't really get invalid addresses here, but this can
215b30b3 6242 happen if we are passed a SP (never OK for HImode/QImode) or
bc409cb4 6243 virtual register (also rejected as illegitimate for HImode/QImode)
6244 relative address. */
cffb2a26 6245 /* ??? This should perhaps be fixed elsewhere, for instance, in
6246 fixup_stack_1, by checking for other kinds of invalid addresses,
6247 e.g. a bare reference to a virtual register. This may confuse the
6248 alpha though, which must handle this case differently. */
0438d37f 6249 if (MEM_P (operands[0])
215b30b3 6250 && !memory_address_p (GET_MODE (operands[0]),
6251 XEXP (operands[0], 0)))
537ffcfc 6252 operands[0]
6253 = replace_equiv_address (operands[0],
6254 copy_to_reg (XEXP (operands[0], 0)));
cffb2a26 6255
0438d37f 6256 if (MEM_P (operands[1])
215b30b3 6257 && !memory_address_p (GET_MODE (operands[1]),
6258 XEXP (operands[1], 0)))
537ffcfc 6259 operands[1]
6260 = replace_equiv_address (operands[1],
6261 copy_to_reg (XEXP (operands[1], 0)));
6cffc037 6262
0438d37f 6263 if (MEM_P (operands[1]) && optimize > 0)
6cffc037 6264 {
6265 rtx reg = gen_reg_rtx (SImode);
6266
6267 emit_insn (gen_zero_extendhisi2 (reg, operands[1]));
6268 operands[1] = gen_lowpart (HImode, reg);
6269 }
6270
0438d37f 6271 if (MEM_P (operands[0]))
6cffc037 6272 operands[1] = force_reg (HImode, operands[1]);
cffb2a26 6273 }
0438d37f 6274 else if (CONST_INT_P (operands[1])
234f6557 6275 && !satisfies_constraint_I (operands[1]))
cffb2a26 6276 {
6cffc037 6277 /* Handle loading a large integer during reload. */
6278
cffb2a26 6279 /* Writing a constant to memory needs a scratch, which should
6280 be handled with SECONDARY_RELOADs. */
0438d37f 6281 gcc_assert (REG_P (operands[0]));
cffb2a26 6282
1a83b3ff 6283 operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
cffb2a26 6284 emit_insn (gen_movsi (operands[0], operands[1]));
6285 DONE;
6286 }
b11cae9e 6287 }
cffb2a26 6288 "
6289)
6290
25f7a26e 6291(define_expand "movhi_bytes"
eab14235 6292 [(set (match_dup 2) (zero_extend:SI (match_operand:HI 1 "" "")))
25f7a26e 6293 (set (match_dup 3)
eab14235 6294 (zero_extend:SI (match_dup 6)))
25f7a26e 6295 (set (match_operand:SI 0 "" "")
6296 (ior:SI (ashift:SI (match_dup 4) (const_int 8)) (match_dup 5)))]
cffb2a26 6297 "TARGET_ARM"
25f7a26e 6298 "
215b30b3 6299 {
6300 rtx mem1, mem2;
6301 rtx addr = copy_to_mode_reg (SImode, XEXP (operands[1], 0));
6302
788fcce0 6303 mem1 = change_address (operands[1], QImode, addr);
29c05e22 6304 mem2 = change_address (operands[1], QImode,
6305 plus_constant (Pmode, addr, 1));
215b30b3 6306 operands[0] = gen_lowpart (SImode, operands[0]);
6307 operands[1] = mem1;
6308 operands[2] = gen_reg_rtx (SImode);
6309 operands[3] = gen_reg_rtx (SImode);
6310 operands[6] = mem2;
25f7a26e 6311
215b30b3 6312 if (BYTES_BIG_ENDIAN)
6313 {
6314 operands[4] = operands[2];
6315 operands[5] = operands[3];
6316 }
6317 else
6318 {
6319 operands[4] = operands[3];
6320 operands[5] = operands[2];
6321 }
6322 }"
6323)
25f7a26e 6324
c7597b5d 6325(define_expand "movhi_bigend"
6326 [(set (match_dup 2)
6327 (rotate:SI (subreg:SI (match_operand:HI 1 "memory_operand" "") 0)
6328 (const_int 16)))
6329 (set (match_dup 3)
6330 (ashiftrt:SI (match_dup 2) (const_int 16)))
6331 (set (match_operand:HI 0 "s_register_operand" "")
787f8210 6332 (match_dup 4))]
cffb2a26 6333 "TARGET_ARM"
c7597b5d 6334 "
6335 operands[2] = gen_reg_rtx (SImode);
6336 operands[3] = gen_reg_rtx (SImode);
787f8210 6337 operands[4] = gen_lowpart (HImode, operands[3]);
215b30b3 6338 "
6339)
b11cae9e 6340
a2f10574 6341;; Pattern to recognize insn generated default case above
f7fbdd4a 6342(define_insn "*movhi_insn_arch4"
e4585731 6343 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m,r")
6344 (match_operand:HI 1 "general_operand" "rIk,K,n,r,mi"))]
cffb2a26 6345 "TARGET_ARM
6346 && arm_arch4
85e02ccb 6347 && (register_operand (operands[0], HImode)
6348 || register_operand (operands[1], HImode))"
f7fbdd4a 6349 "@
6350 mov%?\\t%0, %1\\t%@ movhi
6351 mvn%?\\t%0, #%B1\\t%@ movhi
b1c1a101 6352 movw%?\\t%0, %L1\\t%@ movhi
3ef90e77 6353 strh%?\\t%1, %0\\t%@ movhi
6354 ldrh%?\\t%0, %1\\t%@ movhi"
65f68e55 6355 [(set_attr "predicable" "yes")
e4585731 6356 (set_attr "pool_range" "*,*,*,*,256")
6357 (set_attr "neg_pool_range" "*,*,*,*,244")
6358 (set_attr "arch" "*,*,v6t2,*,*")
65f68e55 6359 (set_attr_alternative "type"
6360 [(if_then_else (match_operand 1 "const_int_operand" "")
1aed5204 6361 (const_string "mov_imm" )
6362 (const_string "mov_reg"))
6363 (const_string "mvn_imm")
e4585731 6364 (const_string "mov_imm")
65f68e55 6365 (const_string "store1")
6366 (const_string "load1")])]
cffb2a26 6367)
f7fbdd4a 6368
f7fbdd4a 6369(define_insn "*movhi_bytes"
65f68e55 6370 [(set (match_operand:HI 0 "s_register_operand" "=r,r,r")
5fd254ed 6371 (match_operand:HI 1 "arm_rhs_operand" "I,rk,K"))]
c1a66faf 6372 "TARGET_ARM"
25f7a26e 6373 "@
65f68e55 6374 mov%?\\t%0, %1\\t%@ movhi
25f7a26e 6375 mov%?\\t%0, %1\\t%@ movhi
0d66636f 6376 mvn%?\\t%0, #%B1\\t%@ movhi"
d2a518d1 6377 [(set_attr "predicable" "yes")
1aed5204 6378 (set_attr "type" "mov_imm,mov_reg,mvn_imm")]
0d66636f 6379)
cffb2a26 6380
bc5c7e08 6381;; We use a DImode scratch because we may occasionally need an additional
6382;; temporary if the address isn't offsettable -- push_reload doesn't seem
6383;; to take any notice of the "o" constraints on reload_memory_operand operand.
d3373b54 6384(define_expand "reload_outhi"
cffb2a26 6385 [(parallel [(match_operand:HI 0 "arm_reload_memory_operand" "=o")
215b30b3 6386 (match_operand:HI 1 "s_register_operand" "r")
6387 (match_operand:DI 2 "s_register_operand" "=&l")])]
cffb2a26 6388 "TARGET_EITHER"
6389 "if (TARGET_ARM)
6390 arm_reload_out_hi (operands);
6391 else
6392 thumb_reload_out_hi (operands);
d3373b54 6393 DONE;
cffb2a26 6394 "
6395)
d3373b54 6396
25f7a26e 6397(define_expand "reload_inhi"
6398 [(parallel [(match_operand:HI 0 "s_register_operand" "=r")
cffb2a26 6399 (match_operand:HI 1 "arm_reload_memory_operand" "o")
bc5c7e08 6400 (match_operand:DI 2 "s_register_operand" "=&r")])]
c1a66faf 6401 "TARGET_EITHER"
25f7a26e 6402 "
cffb2a26 6403 if (TARGET_ARM)
6404 arm_reload_in_hi (operands);
6405 else
6406 thumb_reload_out_hi (operands);
25f7a26e 6407 DONE;
6408")
6409
9c08d1fa 6410(define_expand "movqi"
6411 [(set (match_operand:QI 0 "general_operand" "")
6412 (match_operand:QI 1 "general_operand" ""))]
cffb2a26 6413 "TARGET_EITHER"
9c08d1fa 6414 "
6cffc037 6415 /* Everything except mem = const or mem = mem can be done easily */
0045890a 6416
e1ba4a27 6417 if (can_create_pseudo_p ())
cffb2a26 6418 {
0438d37f 6419 if (CONST_INT_P (operands[1]))
6cffc037 6420 {
6421 rtx reg = gen_reg_rtx (SImode);
6422
03770691 6423 /* For thumb we want an unsigned immediate, then we are more likely
6424 to be able to use a movs insn. */
6425 if (TARGET_THUMB)
6426 operands[1] = GEN_INT (INTVAL (operands[1]) & 255);
6427
6cffc037 6428 emit_insn (gen_movsi (reg, operands[1]));
6429 operands[1] = gen_lowpart (QImode, reg);
6430 }
cffb2a26 6431
6cffc037 6432 if (TARGET_THUMB)
6433 {
cffb2a26 6434 /* ??? We shouldn't really get invalid addresses here, but this can
215b30b3 6435 happen if we are passed a SP (never OK for HImode/QImode) or
bc409cb4 6436 virtual register (also rejected as illegitimate for HImode/QImode)
6437 relative address. */
cffb2a26 6438 /* ??? This should perhaps be fixed elsewhere, for instance, in
6439 fixup_stack_1, by checking for other kinds of invalid addresses,
6440 e.g. a bare reference to a virtual register. This may confuse the
6441 alpha though, which must handle this case differently. */
0438d37f 6442 if (MEM_P (operands[0])
215b30b3 6443 && !memory_address_p (GET_MODE (operands[0]),
cffb2a26 6444 XEXP (operands[0], 0)))
537ffcfc 6445 operands[0]
6446 = replace_equiv_address (operands[0],
6447 copy_to_reg (XEXP (operands[0], 0)));
0438d37f 6448 if (MEM_P (operands[1])
215b30b3 6449 && !memory_address_p (GET_MODE (operands[1]),
cffb2a26 6450 XEXP (operands[1], 0)))
537ffcfc 6451 operands[1]
6452 = replace_equiv_address (operands[1],
6453 copy_to_reg (XEXP (operands[1], 0)));
6cffc037 6454 }
6455
0438d37f 6456 if (MEM_P (operands[1]) && optimize > 0)
6cffc037 6457 {
6458 rtx reg = gen_reg_rtx (SImode);
6459
6460 emit_insn (gen_zero_extendqisi2 (reg, operands[1]));
6461 operands[1] = gen_lowpart (QImode, reg);
6462 }
6463
0438d37f 6464 if (MEM_P (operands[0]))
6cffc037 6465 operands[1] = force_reg (QImode, operands[1]);
6466 }
6467 else if (TARGET_THUMB
0438d37f 6468 && CONST_INT_P (operands[1])
234f6557 6469 && !satisfies_constraint_I (operands[1]))
6cffc037 6470 {
674a8f0b 6471 /* Handle loading a large integer during reload. */
cffb2a26 6472
6cffc037 6473 /* Writing a constant to memory needs a scratch, which should
6474 be handled with SECONDARY_RELOADs. */
0438d37f 6475 gcc_assert (REG_P (operands[0]));
6cffc037 6476
6477 operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
6478 emit_insn (gen_movsi (operands[0], operands[1]));
6479 DONE;
cffb2a26 6480 }
6481 "
6482)
b11cae9e 6483
cffb2a26 6484(define_insn "*arm_movqi_insn"
fd711051 6485 [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,r,l,r,l,Uu,r,m")
490f62ca 6486 (match_operand:QI 1 "general_operand" "rk,rk,I,Py,K,Uu,l,Uh,r"))]
25f905c2 6487 "TARGET_32BIT
cffb2a26 6488 && ( register_operand (operands[0], QImode)
6489 || register_operand (operands[1], QImode))"
5565501b 6490 "@
fd711051 6491 mov%?\\t%0, %1
6492 mov%?\\t%0, %1
65f68e55 6493 mov%?\\t%0, %1
5565501b 6494 mov%?\\t%0, %1
6495 mvn%?\\t%0, #%B1
3ef90e77 6496 ldrb%?\\t%0, %1
6497 strb%?\\t%1, %0
6498 ldrb%?\\t%0, %1
6499 strb%?\\t%1, %0"
1aed5204 6500 [(set_attr "type" "mov_reg,mov_reg,mov_imm,mov_imm,mvn_imm,load1,store1,load1,store1")
a54e3e7b 6501 (set_attr "predicable" "yes")
fd711051 6502 (set_attr "predicable_short_it" "yes,yes,yes,no,no,no,no,no,no")
6503 (set_attr "arch" "t2,any,any,t2,any,t2,t2,any,any")
6504 (set_attr "length" "2,4,4,2,4,2,2,4,4")]
cffb2a26 6505)
6506
9b8516be 6507;; HFmode moves
6508(define_expand "movhf"
6509 [(set (match_operand:HF 0 "general_operand" "")
6510 (match_operand:HF 1 "general_operand" ""))]
6511 "TARGET_EITHER"
6512 "
6513 if (TARGET_32BIT)
6514 {
0438d37f 6515 if (MEM_P (operands[0]))
9b8516be 6516 operands[1] = force_reg (HFmode, operands[1]);
6517 }
6518 else /* TARGET_THUMB1 */
6519 {
6520 if (can_create_pseudo_p ())
6521 {
0438d37f 6522 if (!REG_P (operands[0]))
9b8516be 6523 operands[1] = force_reg (HFmode, operands[1]);
6524 }
6525 }
6526 "
6527)
6528
6529(define_insn "*arm32_movhf"
6530 [(set (match_operand:HF 0 "nonimmediate_operand" "=r,m,r,r")
6531 (match_operand:HF 1 "general_operand" " m,r,r,F"))]
ea501323 6532 "TARGET_32BIT && !(TARGET_HARD_FLOAT && TARGET_FP16)
9b8516be 6533 && ( s_register_operand (operands[0], HFmode)
6534 || s_register_operand (operands[1], HFmode))"
6535 "*
6536 switch (which_alternative)
6537 {
6538 case 0: /* ARM register from memory */
3ef90e77 6539 return \"ldrh%?\\t%0, %1\\t%@ __fp16\";
9b8516be 6540 case 1: /* memory from ARM register */
3ef90e77 6541 return \"strh%?\\t%1, %0\\t%@ __fp16\";
9b8516be 6542 case 2: /* ARM register from ARM register */
6543 return \"mov%?\\t%0, %1\\t%@ __fp16\";
6544 case 3: /* ARM register from constant */
6545 {
9b8516be 6546 long bits;
6547 rtx ops[4];
6548
945f7b03 6549 bits = real_to_target (NULL, CONST_DOUBLE_REAL_VALUE (operands[1]),
6550 HFmode);
9b8516be 6551 ops[0] = operands[0];
6552 ops[1] = GEN_INT (bits);
6553 ops[2] = GEN_INT (bits & 0xff00);
6554 ops[3] = GEN_INT (bits & 0x00ff);
6555
6556 if (arm_arch_thumb2)
6557 output_asm_insn (\"movw%?\\t%0, %1\", ops);
6558 else
6559 output_asm_insn (\"mov%?\\t%0, %2\;orr%?\\t%0, %0, %3\", ops);
6560 return \"\";
6561 }
6562 default:
6563 gcc_unreachable ();
6564 }
6565 "
6566 [(set_attr "conds" "unconditional")
ad4fc3c0 6567 (set_attr "type" "load1,store1,mov_reg,multiple")
9b8516be 6568 (set_attr "length" "4,4,4,8")
ea501323 6569 (set_attr "predicable" "yes")
6570 (set_attr "predicable_short_it" "no")]
9b8516be 6571)
6572
87b22bf7 6573(define_expand "movsf"
6574 [(set (match_operand:SF 0 "general_operand" "")
6575 (match_operand:SF 1 "general_operand" ""))]
cffb2a26 6576 "TARGET_EITHER"
87b22bf7 6577 "
25f905c2 6578 if (TARGET_32BIT)
cffb2a26 6579 {
0438d37f 6580 if (MEM_P (operands[0]))
cffb2a26 6581 operands[1] = force_reg (SFmode, operands[1]);
6582 }
25f905c2 6583 else /* TARGET_THUMB1 */
cffb2a26 6584 {
e1ba4a27 6585 if (can_create_pseudo_p ())
cffb2a26 6586 {
0438d37f 6587 if (!REG_P (operands[0]))
cffb2a26 6588 operands[1] = force_reg (SFmode, operands[1]);
6589 }
6590 }
6591 "
6592)
6593
03d440a6 6594;; Transform a floating-point move of a constant into a core register into
6595;; an SImode operation.
cffb2a26 6596(define_split
03d440a6 6597 [(set (match_operand:SF 0 "arm_general_register_operand" "")
cffb2a26 6598 (match_operand:SF 1 "immediate_operand" ""))]
339034d0 6599 "TARGET_EITHER
cffb2a26 6600 && reload_completed
0438d37f 6601 && CONST_DOUBLE_P (operands[1])"
cffb2a26 6602 [(set (match_dup 2) (match_dup 3))]
6603 "
6604 operands[2] = gen_lowpart (SImode, operands[0]);
6605 operands[3] = gen_lowpart (SImode, operands[1]);
6606 if (operands[2] == 0 || operands[3] == 0)
6607 FAIL;
215b30b3 6608 "
6609)
87b22bf7 6610
cffb2a26 6611(define_insn "*arm_movsf_soft_insn"
6612 [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,m")
6613 (match_operand:SF 1 "general_operand" "r,mE,r"))]
cde1623a 6614 "TARGET_32BIT
cffb2a26 6615 && TARGET_SOFT_FLOAT
0438d37f 6616 && (!MEM_P (operands[0])
215b30b3 6617 || register_operand (operands[1], SFmode))"
9a1112d7 6618 "@
6619 mov%?\\t%0, %1
6620 ldr%?\\t%0, %1\\t%@ float
6621 str%?\\t%1, %0\\t%@ float"
cde1623a 6622 [(set_attr "predicable" "yes")
7c36fe71 6623 (set_attr "predicable_short_it" "no")
1aed5204 6624 (set_attr "type" "mov_reg,load1,store1")
42e1de19 6625 (set_attr "arm_pool_range" "*,4096,*")
6626 (set_attr "thumb2_pool_range" "*,4094,*")
cde1623a 6627 (set_attr "arm_neg_pool_range" "*,4084,*")
6628 (set_attr "thumb2_neg_pool_range" "*,0,*")]
cffb2a26 6629)
6630
9c08d1fa 6631(define_expand "movdf"
87b22bf7 6632 [(set (match_operand:DF 0 "general_operand" "")
6633 (match_operand:DF 1 "general_operand" ""))]
cffb2a26 6634 "TARGET_EITHER"
9c08d1fa 6635 "
25f905c2 6636 if (TARGET_32BIT)
cffb2a26 6637 {
0438d37f 6638 if (MEM_P (operands[0]))
cffb2a26 6639 operands[1] = force_reg (DFmode, operands[1]);
6640 }
6641 else /* TARGET_THUMB */
6642 {
e1ba4a27 6643 if (can_create_pseudo_p ())
cffb2a26 6644 {
0438d37f 6645 if (!REG_P (operands[0]))
cffb2a26 6646 operands[1] = force_reg (DFmode, operands[1]);
6647 }
6648 }
6649 "
6650)
b11cae9e 6651
9c08d1fa 6652;; Reloading a df mode value stored in integer regs to memory can require a
6653;; scratch reg.
6654(define_expand "reload_outdf"
cffb2a26 6655 [(match_operand:DF 0 "arm_reload_memory_operand" "=o")
87b22bf7 6656 (match_operand:DF 1 "s_register_operand" "r")
6657 (match_operand:SI 2 "s_register_operand" "=&r")]
06adefdc 6658 "TARGET_THUMB2"
87b22bf7 6659 "
215b30b3 6660 {
6661 enum rtx_code code = GET_CODE (XEXP (operands[0], 0));
f7fbdd4a 6662
215b30b3 6663 if (code == REG)
6664 operands[2] = XEXP (operands[0], 0);
6665 else if (code == POST_INC || code == PRE_DEC)
6666 {
6667 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
6668 operands[1] = gen_rtx_SUBREG (DImode, operands[1], 0);
6669 emit_insn (gen_movdi (operands[0], operands[1]));
6670 DONE;
6671 }
6672 else if (code == PRE_INC)
6673 {
6674 rtx reg = XEXP (XEXP (operands[0], 0), 0);
f7fbdd4a 6675
215b30b3 6676 emit_insn (gen_addsi3 (reg, reg, GEN_INT (8)));
6677 operands[2] = reg;
6678 }
6679 else if (code == POST_DEC)
6680 operands[2] = XEXP (XEXP (operands[0], 0), 0);
6681 else
6682 emit_insn (gen_addsi3 (operands[2], XEXP (XEXP (operands[0], 0), 0),
6683 XEXP (XEXP (operands[0], 0), 1)));
f7fbdd4a 6684
d1f9b275 6685 emit_insn (gen_rtx_SET (replace_equiv_address (operands[0], operands[2]),
215b30b3 6686 operands[1]));
f7fbdd4a 6687
215b30b3 6688 if (code == POST_DEC)
6689 emit_insn (gen_addsi3 (operands[2], operands[2], GEN_INT (-8)));
6690
6691 DONE;
6692 }"
6693)
9c08d1fa 6694
9a1112d7 6695(define_insn "*movdf_soft_insn"
353cf59a 6696 [(set (match_operand:DF 0 "nonimmediate_soft_df_operand" "=r,r,r,q,m")
6697 (match_operand:DF 1 "soft_df_operand" "rDa,Db,Dc,mF,q"))]
cde1623a 6698 "TARGET_32BIT && TARGET_SOFT_FLOAT
b2778788 6699 && ( register_operand (operands[0], DFmode)
6700 || register_operand (operands[1], DFmode))"
d51f92df 6701 "*
6702 switch (which_alternative)
6703 {
6704 case 0:
6705 case 1:
6706 case 2:
6707 return \"#\";
6708 default:
26ff80c0 6709 return output_move_double (operands, true, NULL);
d51f92df 6710 }
6711 "
359a6e9f 6712 [(set_attr "length" "8,12,16,8,8")
1b7da4ac 6713 (set_attr "type" "multiple,multiple,multiple,load2,store2")
42e1de19 6714 (set_attr "arm_pool_range" "*,*,*,1020,*")
6715 (set_attr "thumb2_pool_range" "*,*,*,1018,*")
8848d797 6716 (set_attr "arm_neg_pool_range" "*,*,*,1004,*")
cde1623a 6717 (set_attr "thumb2_neg_pool_range" "*,*,*,0,*")]
cffb2a26 6718)
b11cae9e 6719\f
b11cae9e 6720
9c08d1fa 6721;; load- and store-multiple insns
6722;; The arm can load/store any set of registers, provided that they are in
320ea44d 6723;; ascending order, but these expanders assume a contiguous set.
b11cae9e 6724
9c08d1fa 6725(define_expand "load_multiple"
6726 [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
6727 (match_operand:SI 1 "" ""))
6728 (use (match_operand:SI 2 "" ""))])]
25f905c2 6729 "TARGET_32BIT"
9580c25f 6730{
6731 HOST_WIDE_INT offset = 0;
6732
bd5b4116 6733 /* Support only fixed point registers. */
0438d37f 6734 if (!CONST_INT_P (operands[2])
6e628811 6735 || INTVAL (operands[2]) > MAX_LDM_STM_OPS
9c08d1fa 6736 || INTVAL (operands[2]) < 2
0438d37f 6737 || !MEM_P (operands[1])
6738 || !REG_P (operands[0])
bd5b4116 6739 || REGNO (operands[0]) > (LAST_ARM_REGNUM - 1)
6740 || REGNO (operands[0]) + INTVAL (operands[2]) > LAST_ARM_REGNUM)
9c08d1fa 6741 FAIL;
6742
6743 operands[3]
320ea44d 6744 = arm_gen_load_multiple (arm_regs_in_sequence + REGNO (operands[0]),
6745 INTVAL (operands[2]),
f082f1c4 6746 force_reg (SImode, XEXP (operands[1], 0)),
320ea44d 6747 FALSE, operands[1], &offset);
9580c25f 6748})
b11cae9e 6749
9c08d1fa 6750(define_expand "store_multiple"
6751 [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
6752 (match_operand:SI 1 "" ""))
6753 (use (match_operand:SI 2 "" ""))])]
25f905c2 6754 "TARGET_32BIT"
9580c25f 6755{
6756 HOST_WIDE_INT offset = 0;
6757
674a8f0b 6758 /* Support only fixed point registers. */
0438d37f 6759 if (!CONST_INT_P (operands[2])
6e628811 6760 || INTVAL (operands[2]) > MAX_LDM_STM_OPS
9c08d1fa 6761 || INTVAL (operands[2]) < 2
0438d37f 6762 || !REG_P (operands[1])
6763 || !MEM_P (operands[0])
bd5b4116 6764 || REGNO (operands[1]) > (LAST_ARM_REGNUM - 1)
6765 || REGNO (operands[1]) + INTVAL (operands[2]) > LAST_ARM_REGNUM)
9c08d1fa 6766 FAIL;
6767
6768 operands[3]
320ea44d 6769 = arm_gen_store_multiple (arm_regs_in_sequence + REGNO (operands[1]),
6770 INTVAL (operands[2]),
f082f1c4 6771 force_reg (SImode, XEXP (operands[0], 0)),
320ea44d 6772 FALSE, operands[0], &offset);
9580c25f 6773})
b11cae9e 6774
9c08d1fa 6775
e34ebfca 6776(define_expand "setmemsi"
6777 [(match_operand:BLK 0 "general_operand" "")
6778 (match_operand:SI 1 "const_int_operand" "")
6779 (match_operand:SI 2 "const_int_operand" "")
6780 (match_operand:SI 3 "const_int_operand" "")]
6781 "TARGET_32BIT"
6782{
6783 if (arm_gen_setmem (operands))
6784 DONE;
6785
6786 FAIL;
6787})
6788
6789
9c08d1fa 6790;; Move a block of memory if it is word aligned and MORE than 2 words long.
6791;; We could let this apply for blocks of less than this, but it clobbers so
6792;; many registers that there is then probably a better way.
6793
008c057d 6794(define_expand "movmemqi"
34191dd1 6795 [(match_operand:BLK 0 "general_operand" "")
6796 (match_operand:BLK 1 "general_operand" "")
6797 (match_operand:SI 2 "const_int_operand" "")
6798 (match_operand:SI 3 "const_int_operand" "")]
ae51a965 6799 ""
9c08d1fa 6800 "
25f905c2 6801 if (TARGET_32BIT)
cffb2a26 6802 {
ae51a965 6803 if (TARGET_LDRD && current_tune->prefer_ldrd_strd
6804 && !optimize_function_for_size_p (cfun))
6805 {
6806 if (gen_movmem_ldrd_strd (operands))
6807 DONE;
6808 FAIL;
6809 }
6810
008c057d 6811 if (arm_gen_movmemqi (operands))
cffb2a26 6812 DONE;
6813 FAIL;
6814 }
25f905c2 6815 else /* TARGET_THUMB1 */
cffb2a26 6816 {
6817 if ( INTVAL (operands[3]) != 4
6818 || INTVAL (operands[2]) > 48)
6819 FAIL;
6820
008c057d 6821 thumb_expand_movmemqi (operands);
cffb2a26 6822 DONE;
6823 }
6824 "
6825)
9c08d1fa 6826\f
b11cae9e 6827
341940e8 6828;; Compare & branch insns
8d232dc7 6829;; The range calculations are based as follows:
341940e8 6830;; For forward branches, the address calculation returns the address of
6831;; the next instruction. This is 2 beyond the branch instruction.
6832;; For backward branches, the address calculation returns the address of
6833;; the first instruction in this pattern (cmp). This is 2 before the branch
6834;; instruction for the shortest sequence, and 4 before the branch instruction
6835;; if we have to jump around an unconditional branch.
6836;; To the basic branch range the PC offset must be added (this is +4).
6837;; So for forward branches we have
6838;; (pos_range - pos_base_offs + pc_offs) = (pos_range - 2 + 4).
6839;; And for backward branches we have
6840;; (neg_range - neg_base_offs + pc_offs) = (neg_range - (-2 or -4) + 4).
6841;;
6842;; For a 'b' pos_range = 2046, neg_range = -2048 giving (-2040->2048).
6843;; For a 'b<cond>' pos_range = 254, neg_range = -256 giving (-250 ->256).
cffb2a26 6844
aeac46d4 6845(define_expand "cbranchsi4"
6846 [(set (pc) (if_then_else
aa06947a 6847 (match_operator 0 "expandable_comparison_operator"
aeac46d4 6848 [(match_operand:SI 1 "s_register_operand" "")
6849 (match_operand:SI 2 "nonmemory_operand" "")])
6850 (label_ref (match_operand 3 "" ""))
6851 (pc)))]
f9aa4160 6852 "TARGET_EITHER"
aeac46d4 6853 "
74f4459c 6854 if (!TARGET_THUMB1)
6855 {
f9aa4160 6856 if (!arm_validize_comparison (&operands[0], &operands[1], &operands[2]))
6857 FAIL;
74f4459c 6858 emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
6859 operands[3]));
6860 DONE;
6861 }
25f905c2 6862 if (thumb1_cmpneg_operand (operands[2], SImode))
aeac46d4 6863 {
6864 emit_jump_insn (gen_cbranchsi4_scratch (NULL, operands[1], operands[2],
6865 operands[3], operands[0]));
6866 DONE;
6867 }
25f905c2 6868 if (!thumb1_cmp_operand (operands[2], SImode))
aeac46d4 6869 operands[2] = force_reg (SImode, operands[2]);
6870 ")
6871
74f4459c 6872(define_expand "cbranchsf4"
6873 [(set (pc) (if_then_else
aa06947a 6874 (match_operator 0 "expandable_comparison_operator"
74f4459c 6875 [(match_operand:SF 1 "s_register_operand" "")
6876 (match_operand:SF 2 "arm_float_compare_operand" "")])
6877 (label_ref (match_operand 3 "" ""))
6878 (pc)))]
6879 "TARGET_32BIT && TARGET_HARD_FLOAT"
6880 "emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
6881 operands[3])); DONE;"
6882)
6883
6884(define_expand "cbranchdf4"
6885 [(set (pc) (if_then_else
aa06947a 6886 (match_operator 0 "expandable_comparison_operator"
74f4459c 6887 [(match_operand:DF 1 "s_register_operand" "")
6888 (match_operand:DF 2 "arm_float_compare_operand" "")])
6889 (label_ref (match_operand 3 "" ""))
6890 (pc)))]
a50d7267 6891 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
74f4459c 6892 "emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
6893 operands[3])); DONE;"
6894)
6895
74f4459c 6896(define_expand "cbranchdi4"
6897 [(set (pc) (if_then_else
aa06947a 6898 (match_operator 0 "expandable_comparison_operator"
b8eae306 6899 [(match_operand:DI 1 "s_register_operand" "")
a8045a4f 6900 (match_operand:DI 2 "cmpdi_operand" "")])
74f4459c 6901 (label_ref (match_operand 3 "" ""))
6902 (pc)))]
a8045a4f 6903 "TARGET_32BIT"
6904 "{
0438d37f 6905 if (!arm_validize_comparison (&operands[0], &operands[1], &operands[2]))
f9aa4160 6906 FAIL;
6907 emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
a8045a4f 6908 operands[3]));
6909 DONE;
6910 }"
74f4459c 6911)
6912
9c08d1fa 6913;; Comparison and test insns
6914
cffb2a26 6915(define_insn "*arm_cmpsi_insn"
bd5b4116 6916 [(set (reg:CC CC_REGNUM)
f9f234ec 6917 (compare:CC (match_operand:SI 0 "s_register_operand" "l,r,r,r,r")
6918 (match_operand:SI 1 "arm_add_operand" "Py,r,r,I,L")))]
25f905c2 6919 "TARGET_32BIT"
5565501b 6920 "@
a6864a24 6921 cmp%?\\t%0, %1
6922 cmp%?\\t%0, %1
aea4c774 6923 cmp%?\\t%0, %1
f9f234ec 6924 cmp%?\\t%0, %1
aea4c774 6925 cmn%?\\t%0, #%n1"
a6864a24 6926 [(set_attr "conds" "set")
f9f234ec 6927 (set_attr "arch" "t2,t2,any,any,any")
6928 (set_attr "length" "2,2,4,4,4")
65f68e55 6929 (set_attr "predicable" "yes")
f9f234ec 6930 (set_attr "predicable_short_it" "yes,yes,yes,no,no")
112eda6f 6931 (set_attr "type" "alus_imm,alus_sreg,alus_sreg,alus_imm,alus_imm")]
cffb2a26 6932)
b11cae9e 6933
d5d4dc8d 6934(define_insn "*cmpsi_shiftsi"
bd5b4116 6935 [(set (reg:CC CC_REGNUM)
d82e788e 6936 (compare:CC (match_operand:SI 0 "s_register_operand" "r,r,r")
cffb2a26 6937 (match_operator:SI 3 "shift_operator"
d82e788e 6938 [(match_operand:SI 1 "s_register_operand" "r,r,r")
6939 (match_operand:SI 2 "shift_amount_operand" "M,r,M")])))]
d5d4dc8d 6940 "TARGET_32BIT"
f9f234ec 6941 "cmp\\t%0, %1%S3"
344495ea 6942 [(set_attr "conds" "set")
331beb1a 6943 (set_attr "shift" "1")
d82e788e 6944 (set_attr "arch" "32,a,a")
282b4c75 6945 (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")])
b11cae9e 6946
d5d4dc8d 6947(define_insn "*cmpsi_shiftsi_swp"
bd5b4116 6948 [(set (reg:CC_SWP CC_REGNUM)
aea4c774 6949 (compare:CC_SWP (match_operator:SI 3 "shift_operator"
d82e788e 6950 [(match_operand:SI 1 "s_register_operand" "r,r,r")
6951 (match_operand:SI 2 "shift_amount_operand" "M,r,M")])
6952 (match_operand:SI 0 "s_register_operand" "r,r,r")))]
d5d4dc8d 6953 "TARGET_32BIT"
aea4c774 6954 "cmp%?\\t%0, %1%S3"
344495ea 6955 [(set_attr "conds" "set")
331beb1a 6956 (set_attr "shift" "1")
d82e788e 6957 (set_attr "arch" "32,a,a")
282b4c75 6958 (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")])
b11cae9e 6959
25f905c2 6960(define_insn "*arm_cmpsi_negshiftsi_si"
aed179ae 6961 [(set (reg:CC_Z CC_REGNUM)
6962 (compare:CC_Z
6963 (neg:SI (match_operator:SI 1 "shift_operator"
6964 [(match_operand:SI 2 "s_register_operand" "r")
6965 (match_operand:SI 3 "reg_or_int_operand" "rM")]))
6966 (match_operand:SI 0 "s_register_operand" "r")))]
cffb2a26 6967 "TARGET_ARM"
aed179ae 6968 "cmn%?\\t%0, %2%S1"
344495ea 6969 [(set_attr "conds" "set")
aed179ae 6970 (set (attr "type") (if_then_else (match_operand 3 "const_int_operand" "")
d82e788e 6971 (const_string "alus_shift_imm")
6972 (const_string "alus_shift_reg")))
596e5e8f 6973 (set_attr "predicable" "yes")]
0d66636f 6974)
b11cae9e 6975
a8045a4f 6976;; DImode comparisons. The generic code generates branches that
6977;; if-conversion can not reduce to a conditional compare, so we do
6978;; that directly.
6979
ba6a3b2f 6980(define_insn_and_split "*arm_cmpdi_insn"
a8045a4f 6981 [(set (reg:CC_NCV CC_REGNUM)
6982 (compare:CC_NCV (match_operand:DI 0 "s_register_operand" "r")
6983 (match_operand:DI 1 "arm_di_operand" "rDi")))
6984 (clobber (match_scratch:SI 2 "=r"))]
b805622c 6985 "TARGET_32BIT"
ba6a3b2f 6986 "#" ; "cmp\\t%Q0, %Q1\;sbcs\\t%2, %R0, %R1"
6987 "&& reload_completed"
6988 [(set (reg:CC CC_REGNUM)
6989 (compare:CC (match_dup 0) (match_dup 1)))
6990 (parallel [(set (reg:CC CC_REGNUM)
6991 (compare:CC (match_dup 3) (match_dup 4)))
6992 (set (match_dup 2)
6993 (minus:SI (match_dup 5)
6994 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))])]
6995 {
6996 operands[3] = gen_highpart (SImode, operands[0]);
6997 operands[0] = gen_lowpart (SImode, operands[0]);
6998 if (CONST_INT_P (operands[1]))
6999 {
7000 operands[4] = GEN_INT (~INTVAL (gen_highpart_mode (SImode,
7001 DImode,
7002 operands[1])));
7003 operands[5] = gen_rtx_PLUS (SImode, operands[3], operands[4]);
7004 }
7005 else
7006 {
7007 operands[4] = gen_highpart (SImode, operands[1]);
7008 operands[5] = gen_rtx_MINUS (SImode, operands[3], operands[4]);
7009 }
7010 operands[1] = gen_lowpart (SImode, operands[1]);
7011 operands[2] = gen_lowpart (SImode, operands[2]);
7012 }
a8045a4f 7013 [(set_attr "conds" "set")
1b7da4ac 7014 (set_attr "length" "8")
7015 (set_attr "type" "multiple")]
a8045a4f 7016)
7017
ba6a3b2f 7018(define_insn_and_split "*arm_cmpdi_unsigned"
a8045a4f 7019 [(set (reg:CC_CZ CC_REGNUM)
1a86364b 7020 (compare:CC_CZ (match_operand:DI 0 "s_register_operand" "l,r,r,r")
7021 (match_operand:DI 1 "arm_di_operand" "Py,r,Di,rDi")))]
7c36fe71 7022
48a98053 7023 "TARGET_32BIT"
ba6a3b2f 7024 "#" ; "cmp\\t%R0, %R1\;it eq\;cmpeq\\t%Q0, %Q1"
7025 "&& reload_completed"
7026 [(set (reg:CC CC_REGNUM)
7027 (compare:CC (match_dup 2) (match_dup 3)))
7028 (cond_exec (eq:SI (reg:CC CC_REGNUM) (const_int 0))
7029 (set (reg:CC CC_REGNUM)
7030 (compare:CC (match_dup 0) (match_dup 1))))]
7031 {
7032 operands[2] = gen_highpart (SImode, operands[0]);
7033 operands[0] = gen_lowpart (SImode, operands[0]);
7034 if (CONST_INT_P (operands[1]))
7035 operands[3] = gen_highpart_mode (SImode, DImode, operands[1]);
7036 else
7037 operands[3] = gen_highpart (SImode, operands[1]);
7038 operands[1] = gen_lowpart (SImode, operands[1]);
7039 }
a8045a4f 7040 [(set_attr "conds" "set")
1a86364b 7041 (set_attr "enabled_for_depr_it" "yes,yes,no,*")
7042 (set_attr "arch" "t2,t2,t2,a")
7043 (set_attr "length" "6,6,10,8")
1b7da4ac 7044 (set_attr "type" "multiple")]
a8045a4f 7045)
7046
7047(define_insn "*arm_cmpdi_zero"
7048 [(set (reg:CC_Z CC_REGNUM)
7049 (compare:CC_Z (match_operand:DI 0 "s_register_operand" "r")
7050 (const_int 0)))
7051 (clobber (match_scratch:SI 1 "=r"))]
7052 "TARGET_32BIT"
3ef90e77 7053 "orrs%?\\t%1, %Q0, %R0"
1b7da4ac 7054 [(set_attr "conds" "set")
7055 (set_attr "type" "logics_reg")]
a8045a4f 7056)
7057
9c08d1fa 7058; This insn allows redundant compares to be removed by cse, nothing should
7059; ever appear in the output file since (set (reg x) (reg x)) is a no-op that
7060; is deleted later on. The match_dup will match the mode here, so that
7061; mode changes of the condition codes aren't lost by this even though we don't
7062; specify what they are.
7063
8a18b90c 7064(define_insn "*deleted_compare"
9c08d1fa 7065 [(set (match_operand 0 "cc_register" "") (match_dup 0))]
25f905c2 7066 "TARGET_32BIT"
40dbec34 7067 "\\t%@ deleted compare"
cffb2a26 7068 [(set_attr "conds" "set")
1b7da4ac 7069 (set_attr "length" "0")
7070 (set_attr "type" "no_insn")]
cffb2a26 7071)
9c08d1fa 7072
7073\f
7074;; Conditional branch insns
7075
74f4459c 7076(define_expand "cbranch_cc"
9c08d1fa 7077 [(set (pc)
74f4459c 7078 (if_then_else (match_operator 0 "" [(match_operand 1 "" "")
7079 (match_operand 2 "" "")])
7080 (label_ref (match_operand 3 "" ""))
9c08d1fa 7081 (pc)))]
25f905c2 7082 "TARGET_32BIT"
74f4459c 7083 "operands[1] = arm_gen_compare_reg (GET_CODE (operands[0]),
e1b93706 7084 operands[1], operands[2], NULL_RTX);
74f4459c 7085 operands[2] = const0_rtx;"
8fa3ba89 7086)
7087
7088;;
7089;; Patterns to match conditional branch insns.
7090;;
7091
ffcc986d 7092(define_insn "arm_cond_branch"
9c08d1fa 7093 [(set (pc)
8fa3ba89 7094 (if_then_else (match_operator 1 "arm_comparison_operator"
8a18b90c 7095 [(match_operand 2 "cc_register" "") (const_int 0)])
9c08d1fa 7096 (label_ref (match_operand 0 "" ""))
7097 (pc)))]
25f905c2 7098 "TARGET_32BIT"
d75350ce 7099 "*
9c08d1fa 7100 if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
cffb2a26 7101 {
7102 arm_ccfsm_state += 2;
7103 return \"\";
7104 }
e2348bcb 7105 return \"b%d1\\t%l0\";
cffb2a26 7106 "
a2cd141b 7107 [(set_attr "conds" "use")
a6864a24 7108 (set_attr "type" "branch")
7109 (set (attr "length")
7110 (if_then_else
0bf497f5 7111 (and (match_test "TARGET_THUMB2")
a6864a24 7112 (and (ge (minus (match_dup 0) (pc)) (const_int -250))
7113 (le (minus (match_dup 0) (pc)) (const_int 256))))
7114 (const_int 2)
7115 (const_int 4)))]
cffb2a26 7116)
d75350ce 7117
cffb2a26 7118(define_insn "*arm_cond_branch_reversed"
9c08d1fa 7119 [(set (pc)
8fa3ba89 7120 (if_then_else (match_operator 1 "arm_comparison_operator"
8a18b90c 7121 [(match_operand 2 "cc_register" "") (const_int 0)])
9c08d1fa 7122 (pc)
7123 (label_ref (match_operand 0 "" ""))))]
25f905c2 7124 "TARGET_32BIT"
d75350ce 7125 "*
9c08d1fa 7126 if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
cffb2a26 7127 {
7128 arm_ccfsm_state += 2;
7129 return \"\";
7130 }
e2348bcb 7131 return \"b%D1\\t%l0\";
cffb2a26 7132 "
a2cd141b 7133 [(set_attr "conds" "use")
a6864a24 7134 (set_attr "type" "branch")
7135 (set (attr "length")
7136 (if_then_else
0bf497f5 7137 (and (match_test "TARGET_THUMB2")
a6864a24 7138 (and (ge (minus (match_dup 0) (pc)) (const_int -250))
7139 (le (minus (match_dup 0) (pc)) (const_int 256))))
7140 (const_int 2)
7141 (const_int 4)))]
cffb2a26 7142)
7143
b11cae9e 7144\f
9c08d1fa 7145
7146; scc insns
7147
74f4459c 7148(define_expand "cstore_cc"
7db9af5d 7149 [(set (match_operand:SI 0 "s_register_operand" "")
74f4459c 7150 (match_operator:SI 1 "" [(match_operand 2 "" "")
7151 (match_operand 3 "" "")]))]
25f905c2 7152 "TARGET_32BIT"
74f4459c 7153 "operands[2] = arm_gen_compare_reg (GET_CODE (operands[1]),
e1b93706 7154 operands[2], operands[3], NULL_RTX);
74f4459c 7155 operands[3] = const0_rtx;"
8fa3ba89 7156)
7157
a3b84066 7158(define_insn_and_split "*mov_scc"
9c08d1fa 7159 [(set (match_operand:SI 0 "s_register_operand" "=r")
8fa3ba89 7160 (match_operator:SI 1 "arm_comparison_operator"
8a18b90c 7161 [(match_operand 2 "cc_register" "") (const_int 0)]))]
cffb2a26 7162 "TARGET_ARM"
a3b84066 7163 "#" ; "mov%D1\\t%0, #0\;mov%d1\\t%0, #1"
7164 "TARGET_ARM"
7165 [(set (match_dup 0)
7166 (if_then_else:SI (match_dup 1)
7167 (const_int 1)
7168 (const_int 0)))]
7169 ""
cffb2a26 7170 [(set_attr "conds" "use")
1b7da4ac 7171 (set_attr "length" "8")
7172 (set_attr "type" "multiple")]
cffb2a26 7173)
9c08d1fa 7174
a3b84066 7175(define_insn_and_split "*mov_negscc"
9c08d1fa 7176 [(set (match_operand:SI 0 "s_register_operand" "=r")
8fa3ba89 7177 (neg:SI (match_operator:SI 1 "arm_comparison_operator"
8a18b90c 7178 [(match_operand 2 "cc_register" "") (const_int 0)])))]
cffb2a26 7179 "TARGET_ARM"
a3b84066 7180 "#" ; "mov%D1\\t%0, #0\;mvn%d1\\t%0, #0"
7181 "TARGET_ARM"
7182 [(set (match_dup 0)
7183 (if_then_else:SI (match_dup 1)
7184 (match_dup 3)
7185 (const_int 0)))]
7186 {
7187 operands[3] = GEN_INT (~0);
7188 }
cffb2a26 7189 [(set_attr "conds" "use")
1b7da4ac 7190 (set_attr "length" "8")
7191 (set_attr "type" "multiple")]
cffb2a26 7192)
9c08d1fa 7193
a3b84066 7194(define_insn_and_split "*mov_notscc"
9c08d1fa 7195 [(set (match_operand:SI 0 "s_register_operand" "=r")
8fa3ba89 7196 (not:SI (match_operator:SI 1 "arm_comparison_operator"
8a18b90c 7197 [(match_operand 2 "cc_register" "") (const_int 0)])))]
cffb2a26 7198 "TARGET_ARM"
a3b84066 7199 "#" ; "mvn%D1\\t%0, #0\;mvn%d1\\t%0, #1"
7200 "TARGET_ARM"
7201 [(set (match_dup 0)
7202 (if_then_else:SI (match_dup 1)
7203 (match_dup 3)
7204 (match_dup 4)))]
7205 {
7206 operands[3] = GEN_INT (~1);
7207 operands[4] = GEN_INT (~0);
7208 }
cffb2a26 7209 [(set_attr "conds" "use")
1b7da4ac 7210 (set_attr "length" "8")
7211 (set_attr "type" "multiple")]
cffb2a26 7212)
9c08d1fa 7213
595d88b5 7214(define_expand "cstoresi4"
7215 [(set (match_operand:SI 0 "s_register_operand" "")
aa06947a 7216 (match_operator:SI 1 "expandable_comparison_operator"
595d88b5 7217 [(match_operand:SI 2 "s_register_operand" "")
7218 (match_operand:SI 3 "reg_or_int_operand" "")]))]
74f4459c 7219 "TARGET_32BIT || TARGET_THUMB1"
595d88b5 7220 "{
7221 rtx op3, scratch, scratch2;
7222
74f4459c 7223 if (!TARGET_THUMB1)
7224 {
7225 if (!arm_add_operand (operands[3], SImode))
7226 operands[3] = force_reg (SImode, operands[3]);
7227 emit_insn (gen_cstore_cc (operands[0], operands[1],
7228 operands[2], operands[3]));
7229 DONE;
7230 }
7231
595d88b5 7232 if (operands[3] == const0_rtx)
7233 {
7234 switch (GET_CODE (operands[1]))
7235 {
7236 case EQ:
25f905c2 7237 emit_insn (gen_cstoresi_eq0_thumb1 (operands[0], operands[2]));
595d88b5 7238 break;
7239
7240 case NE:
25f905c2 7241 emit_insn (gen_cstoresi_ne0_thumb1 (operands[0], operands[2]));
595d88b5 7242 break;
7243
7244 case LE:
7245 scratch = expand_binop (SImode, add_optab, operands[2], constm1_rtx,
7246 NULL_RTX, 0, OPTAB_WIDEN);
7247 scratch = expand_binop (SImode, ior_optab, operands[2], scratch,
7248 NULL_RTX, 0, OPTAB_WIDEN);
7249 expand_binop (SImode, lshr_optab, scratch, GEN_INT (31),
7250 operands[0], 1, OPTAB_WIDEN);
7251 break;
7252
7253 case GE:
7254 scratch = expand_unop (SImode, one_cmpl_optab, operands[2],
7255 NULL_RTX, 1);
7256 expand_binop (SImode, lshr_optab, scratch, GEN_INT (31),
7257 NULL_RTX, 1, OPTAB_WIDEN);
7258 break;
7259
7260 case GT:
7261 scratch = expand_binop (SImode, ashr_optab, operands[2],
7262 GEN_INT (31), NULL_RTX, 0, OPTAB_WIDEN);
7263 scratch = expand_binop (SImode, sub_optab, scratch, operands[2],
7264 NULL_RTX, 0, OPTAB_WIDEN);
7265 expand_binop (SImode, lshr_optab, scratch, GEN_INT (31), operands[0],
7266 0, OPTAB_WIDEN);
7267 break;
7268
7269 /* LT is handled by generic code. No need for unsigned with 0. */
7270 default:
7271 FAIL;
7272 }
7273 DONE;
7274 }
7275
7276 switch (GET_CODE (operands[1]))
7277 {
7278 case EQ:
7279 scratch = expand_binop (SImode, sub_optab, operands[2], operands[3],
7280 NULL_RTX, 0, OPTAB_WIDEN);
25f905c2 7281 emit_insn (gen_cstoresi_eq0_thumb1 (operands[0], scratch));
595d88b5 7282 break;
7283
7284 case NE:
7285 scratch = expand_binop (SImode, sub_optab, operands[2], operands[3],
7286 NULL_RTX, 0, OPTAB_WIDEN);
25f905c2 7287 emit_insn (gen_cstoresi_ne0_thumb1 (operands[0], scratch));
595d88b5 7288 break;
7289
7290 case LE:
7291 op3 = force_reg (SImode, operands[3]);
7292
7293 scratch = expand_binop (SImode, lshr_optab, operands[2], GEN_INT (31),
7294 NULL_RTX, 1, OPTAB_WIDEN);
7295 scratch2 = expand_binop (SImode, ashr_optab, op3, GEN_INT (31),
7296 NULL_RTX, 0, OPTAB_WIDEN);
25f905c2 7297 emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch2,
595d88b5 7298 op3, operands[2]));
7299 break;
7300
7301 case GE:
7302 op3 = operands[3];
25f905c2 7303 if (!thumb1_cmp_operand (op3, SImode))
595d88b5 7304 op3 = force_reg (SImode, op3);
7305 scratch = expand_binop (SImode, ashr_optab, operands[2], GEN_INT (31),
7306 NULL_RTX, 0, OPTAB_WIDEN);
7307 scratch2 = expand_binop (SImode, lshr_optab, op3, GEN_INT (31),
7308 NULL_RTX, 1, OPTAB_WIDEN);
25f905c2 7309 emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch2,
595d88b5 7310 operands[2], op3));
7311 break;
7312
7313 case LEU:
7314 op3 = force_reg (SImode, operands[3]);
7315 scratch = force_reg (SImode, const0_rtx);
25f905c2 7316 emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch,
595d88b5 7317 op3, operands[2]));
7318 break;
7319
7320 case GEU:
7321 op3 = operands[3];
25f905c2 7322 if (!thumb1_cmp_operand (op3, SImode))
595d88b5 7323 op3 = force_reg (SImode, op3);
7324 scratch = force_reg (SImode, const0_rtx);
25f905c2 7325 emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch,
595d88b5 7326 operands[2], op3));
7327 break;
7328
7329 case LTU:
7330 op3 = operands[3];
25f905c2 7331 if (!thumb1_cmp_operand (op3, SImode))
595d88b5 7332 op3 = force_reg (SImode, op3);
7333 scratch = gen_reg_rtx (SImode);
408b7ae5 7334 emit_insn (gen_cstoresi_ltu_thumb1 (operands[0], operands[2], op3));
595d88b5 7335 break;
7336
7337 case GTU:
7338 op3 = force_reg (SImode, operands[3]);
7339 scratch = gen_reg_rtx (SImode);
408b7ae5 7340 emit_insn (gen_cstoresi_ltu_thumb1 (operands[0], op3, operands[2]));
595d88b5 7341 break;
7342
7343 /* No good sequences for GT, LT. */
7344 default:
7345 FAIL;
7346 }
7347 DONE;
7348}")
7349
74f4459c 7350(define_expand "cstoresf4"
7351 [(set (match_operand:SI 0 "s_register_operand" "")
aa06947a 7352 (match_operator:SI 1 "expandable_comparison_operator"
74f4459c 7353 [(match_operand:SF 2 "s_register_operand" "")
7354 (match_operand:SF 3 "arm_float_compare_operand" "")]))]
7355 "TARGET_32BIT && TARGET_HARD_FLOAT"
7356 "emit_insn (gen_cstore_cc (operands[0], operands[1],
7357 operands[2], operands[3])); DONE;"
7358)
7359
7360(define_expand "cstoredf4"
7361 [(set (match_operand:SI 0 "s_register_operand" "")
aa06947a 7362 (match_operator:SI 1 "expandable_comparison_operator"
74f4459c 7363 [(match_operand:DF 2 "s_register_operand" "")
7364 (match_operand:DF 3 "arm_float_compare_operand" "")]))]
d63ed457 7365 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
74f4459c 7366 "emit_insn (gen_cstore_cc (operands[0], operands[1],
7367 operands[2], operands[3])); DONE;"
7368)
7369
74f4459c 7370(define_expand "cstoredi4"
7371 [(set (match_operand:SI 0 "s_register_operand" "")
aa06947a 7372 (match_operator:SI 1 "expandable_comparison_operator"
b8eae306 7373 [(match_operand:DI 2 "s_register_operand" "")
a8045a4f 7374 (match_operand:DI 3 "cmpdi_operand" "")]))]
7375 "TARGET_32BIT"
7376 "{
f9aa4160 7377 if (!arm_validize_comparison (&operands[1],
7378 &operands[2],
7379 &operands[3]))
7380 FAIL;
7381 emit_insn (gen_cstore_cc (operands[0], operands[1], operands[2],
a8045a4f 7382 operands[3]));
7383 DONE;
7384 }"
74f4459c 7385)
7386
9c08d1fa 7387\f
39b5e676 7388;; Conditional move insns
7389
7390(define_expand "movsicc"
8a18b90c 7391 [(set (match_operand:SI 0 "s_register_operand" "")
aa06947a 7392 (if_then_else:SI (match_operand 1 "expandable_comparison_operator" "")
aea4c774 7393 (match_operand:SI 2 "arm_not_operand" "")
8a18b90c 7394 (match_operand:SI 3 "arm_not_operand" "")))]
25f905c2 7395 "TARGET_32BIT"
39b5e676 7396 "
215b30b3 7397 {
f9aa4160 7398 enum rtx_code code;
278b301d 7399 rtx ccreg;
7400
f9aa4160 7401 if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0),
7402 &XEXP (operands[1], 1)))
278b301d 7403 FAIL;
f9aa4160 7404
7405 code = GET_CODE (operands[1]);
74f4459c 7406 ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
e1b93706 7407 XEXP (operands[1], 1), NULL_RTX);
29bb088d 7408 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
215b30b3 7409 }"
7410)
39b5e676 7411
7412(define_expand "movsfcc"
8a18b90c 7413 [(set (match_operand:SF 0 "s_register_operand" "")
4df97ffc 7414 (if_then_else:SF (match_operand 1 "arm_cond_move_operator" "")
8a18b90c 7415 (match_operand:SF 2 "s_register_operand" "")
d86c91f6 7416 (match_operand:SF 3 "s_register_operand" "")))]
19f6bf8d 7417 "TARGET_32BIT && TARGET_HARD_FLOAT"
39b5e676 7418 "
215b30b3 7419 {
7420 enum rtx_code code = GET_CODE (operands[1]);
7421 rtx ccreg;
f082f1c4 7422
f9aa4160 7423 if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0),
7424 &XEXP (operands[1], 1)))
7425 FAIL;
39b5e676 7426
f9aa4160 7427 code = GET_CODE (operands[1]);
74f4459c 7428 ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
e1b93706 7429 XEXP (operands[1], 1), NULL_RTX);
29bb088d 7430 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
215b30b3 7431 }"
7432)
39b5e676 7433
7434(define_expand "movdfcc"
8a18b90c 7435 [(set (match_operand:DF 0 "s_register_operand" "")
4df97ffc 7436 (if_then_else:DF (match_operand 1 "arm_cond_move_operator" "")
8a18b90c 7437 (match_operand:DF 2 "s_register_operand" "")
d86c91f6 7438 (match_operand:DF 3 "s_register_operand" "")))]
994606f8 7439 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
39b5e676 7440 "
215b30b3 7441 {
7442 enum rtx_code code = GET_CODE (operands[1]);
278b301d 7443 rtx ccreg;
39b5e676 7444
f9aa4160 7445 if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0),
7446 &XEXP (operands[1], 1)))
7447 FAIL;
7448 code = GET_CODE (operands[1]);
74f4459c 7449 ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
e1b93706 7450 XEXP (operands[1], 1), NULL_RTX);
29bb088d 7451 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
215b30b3 7452 }"
7453)
39b5e676 7454
91cb50d2 7455(define_insn "*cmov<mode>"
7456 [(set (match_operand:SDF 0 "s_register_operand" "=<F_constraint>")
7457 (if_then_else:SDF (match_operator 1 "arm_vsel_comparison_operator"
7458 [(match_operand 2 "cc_register" "") (const_int 0)])
7459 (match_operand:SDF 3 "s_register_operand"
7460 "<F_constraint>")
7461 (match_operand:SDF 4 "s_register_operand"
7462 "<F_constraint>")))]
7463 "TARGET_HARD_FLOAT && TARGET_FPU_ARMV8 <vfp_double_cond>"
7464 "*
7465 {
7466 enum arm_cond_code code = maybe_get_arm_condition_code (operands[1]);
7467 switch (code)
7468 {
7469 case ARM_GE:
7470 case ARM_GT:
7471 case ARM_EQ:
7472 case ARM_VS:
7473 return \"vsel%d1.<V_if_elem>\\t%<V_reg>0, %<V_reg>3, %<V_reg>4\";
7474 case ARM_LT:
7475 case ARM_LE:
7476 case ARM_NE:
7477 case ARM_VC:
7478 return \"vsel%D1.<V_if_elem>\\t%<V_reg>0, %<V_reg>4, %<V_reg>3\";
7479 default:
7480 gcc_unreachable ();
7481 }
7482 return \"\";
7483 }"
7484 [(set_attr "conds" "use")
6664d308 7485 (set_attr "type" "fcsel")]
91cb50d2 7486)
7487
190efb17 7488(define_insn_and_split "*movsicc_insn"
f082f1c4 7489 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r,r,r,r,r")
8a18b90c 7490 (if_then_else:SI
8fa3ba89 7491 (match_operator 3 "arm_comparison_operator"
8a18b90c 7492 [(match_operand 4 "cc_register" "") (const_int 0)])
f082f1c4 7493 (match_operand:SI 1 "arm_not_operand" "0,0,rI,K,rI,rI,K,K")
7494 (match_operand:SI 2 "arm_not_operand" "rI,K,0,0,rI,K,rI,K")))]
cffb2a26 7495 "TARGET_ARM"
39b5e676 7496 "@
8a18b90c 7497 mov%D3\\t%0, %2
7498 mvn%D3\\t%0, #%B2
f082f1c4 7499 mov%d3\\t%0, %1
7500 mvn%d3\\t%0, #%B1
190efb17 7501 #
7502 #
7503 #
7504 #"
7505 ; alt4: mov%d3\\t%0, %1\;mov%D3\\t%0, %2
7506 ; alt5: mov%d3\\t%0, %1\;mvn%D3\\t%0, #%B2
7507 ; alt6: mvn%d3\\t%0, #%B1\;mov%D3\\t%0, %2
7508 ; alt7: mvn%d3\\t%0, #%B1\;mvn%D3\\t%0, #%B2"
7509 "&& reload_completed"
7510 [(const_int 0)]
7511 {
7512 enum rtx_code rev_code;
3754d046 7513 machine_mode mode;
190efb17 7514 rtx rev_cond;
7515
7516 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
7517 operands[3],
d1f9b275 7518 gen_rtx_SET (operands[0], operands[1])));
190efb17 7519
7520 rev_code = GET_CODE (operands[3]);
7521 mode = GET_MODE (operands[4]);
7522 if (mode == CCFPmode || mode == CCFPEmode)
7523 rev_code = reverse_condition_maybe_unordered (rev_code);
7524 else
7525 rev_code = reverse_condition (rev_code);
7526
7527 rev_cond = gen_rtx_fmt_ee (rev_code,
7528 VOIDmode,
7529 operands[4],
7530 const0_rtx);
7531 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
7532 rev_cond,
d1f9b275 7533 gen_rtx_SET (operands[0], operands[2])));
190efb17 7534 DONE;
7535 }
f082f1c4 7536 [(set_attr "length" "4,4,4,4,8,8,8,8")
d2a518d1 7537 (set_attr "conds" "use")
65f68e55 7538 (set_attr_alternative "type"
7539 [(if_then_else (match_operand 2 "const_int_operand" "")
1aed5204 7540 (const_string "mov_imm")
7541 (const_string "mov_reg"))
7542 (const_string "mvn_imm")
65f68e55 7543 (if_then_else (match_operand 1 "const_int_operand" "")
1aed5204 7544 (const_string "mov_imm")
7545 (const_string "mov_reg"))
7546 (const_string "mvn_imm")
282b4c75 7547 (const_string "multiple")
7548 (const_string "multiple")
7549 (const_string "multiple")
7550 (const_string "multiple")])]
215b30b3 7551)
39b5e676 7552
39b5e676 7553(define_insn "*movsfcc_soft_insn"
f082f1c4 7554 [(set (match_operand:SF 0 "s_register_operand" "=r,r")
8fa3ba89 7555 (if_then_else:SF (match_operator 3 "arm_comparison_operator"
8a18b90c 7556 [(match_operand 4 "cc_register" "") (const_int 0)])
f082f1c4 7557 (match_operand:SF 1 "s_register_operand" "0,r")
7558 (match_operand:SF 2 "s_register_operand" "r,0")))]
cffb2a26 7559 "TARGET_ARM && TARGET_SOFT_FLOAT"
f082f1c4 7560 "@
7561 mov%D3\\t%0, %2
7562 mov%d3\\t%0, %1"
d2a518d1 7563 [(set_attr "conds" "use")
1aed5204 7564 (set_attr "type" "mov_reg")]
8fa3ba89 7565)
39b5e676 7566
39b5e676 7567\f
9c08d1fa 7568;; Jump and linkage insns
7569
cffb2a26 7570(define_expand "jump"
9c08d1fa 7571 [(set (pc)
7572 (label_ref (match_operand 0 "" "")))]
cffb2a26 7573 "TARGET_EITHER"
9c08d1fa 7574 ""
cffb2a26 7575)
7576
7577(define_insn "*arm_jump"
7578 [(set (pc)
7579 (label_ref (match_operand 0 "" "")))]
25f905c2 7580 "TARGET_32BIT"
9c08d1fa 7581 "*
0d66636f 7582 {
7583 if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
7584 {
7585 arm_ccfsm_state += 2;
7586 return \"\";
7587 }
7588 return \"b%?\\t%l0\";
7589 }
7590 "
a6864a24 7591 [(set_attr "predicable" "yes")
7592 (set (attr "length")
7593 (if_then_else
0bf497f5 7594 (and (match_test "TARGET_THUMB2")
a6864a24 7595 (and (ge (minus (match_dup 0) (pc)) (const_int -2044))
7596 (le (minus (match_dup 0) (pc)) (const_int 2048))))
7597 (const_int 2)
1b7da4ac 7598 (const_int 4)))
7599 (set_attr "type" "branch")]
0d66636f 7600)
9c08d1fa 7601
d3373b54 7602(define_expand "call"
7603 [(parallel [(call (match_operand 0 "memory_operand" "")
7604 (match_operand 1 "general_operand" ""))
cffb2a26 7605 (use (match_operand 2 "" ""))
bd5b4116 7606 (clobber (reg:SI LR_REGNUM))])]
cffb2a26 7607 "TARGET_EITHER"
6c4c2133 7608 "
7609 {
bac7fc85 7610 rtx callee, pat;
bbe777ea 7611
bbe777ea 7612 /* In an untyped call, we can get NULL for operand 2. */
7613 if (operands[2] == NULL_RTX)
7614 operands[2] = const0_rtx;
7615
de55252a 7616 /* Decide if we should generate indirect calls by loading the
85c36fd1 7617 32-bit address of the callee into a register before performing the
de55252a 7618 branch and link. */
7619 callee = XEXP (operands[0], 0);
7620 if (GET_CODE (callee) == SYMBOL_REF
7621 ? arm_is_long_call_p (SYMBOL_REF_DECL (callee))
7622 : !REG_P (callee))
bbe777ea 7623 XEXP (operands[0], 0) = force_reg (Pmode, callee);
bac7fc85 7624
7625 pat = gen_call_internal (operands[0], operands[1], operands[2]);
ca373797 7626 arm_emit_call_insn (pat, XEXP (operands[0], 0), false);
bac7fc85 7627 DONE;
6c4c2133 7628 }"
7629)
d3373b54 7630
bac7fc85 7631(define_expand "call_internal"
7632 [(parallel [(call (match_operand 0 "memory_operand" "")
7633 (match_operand 1 "general_operand" ""))
7634 (use (match_operand 2 "" ""))
7635 (clobber (reg:SI LR_REGNUM))])])
7636
f1039640 7637(define_insn "*call_reg_armv5"
d3373b54 7638 [(call (mem:SI (match_operand:SI 0 "s_register_operand" "r"))
cffb2a26 7639 (match_operand 1 "" ""))
7640 (use (match_operand 2 "" ""))
bd5b4116 7641 (clobber (reg:SI LR_REGNUM))]
33ae7c4b 7642 "TARGET_ARM && arm_arch5 && !SIBLING_CALL_P (insn)"
f1039640 7643 "blx%?\\t%0"
7644 [(set_attr "type" "call")]
7645)
7646
7647(define_insn "*call_reg_arm"
7648 [(call (mem:SI (match_operand:SI 0 "s_register_operand" "r"))
7649 (match_operand 1 "" ""))
7650 (use (match_operand 2 "" ""))
7651 (clobber (reg:SI LR_REGNUM))]
33ae7c4b 7652 "TARGET_ARM && !arm_arch5 && !SIBLING_CALL_P (insn)"
9c08d1fa 7653 "*
5565501b 7654 return output_call (operands);
cffb2a26 7655 "
7656 ;; length is worst case, normally it is only two
7657 [(set_attr "length" "12")
7658 (set_attr "type" "call")]
7659)
9c08d1fa 7660
89504fc1 7661
7662;; Note: not used for armv5+ because the sequence used (ldr pc, ...) is not
7663;; considered a function call by the branch predictor of some cores (PR40887).
7664;; Falls back to blx rN (*call_reg_armv5).
7665
f7fbdd4a 7666(define_insn "*call_mem"
a3c63a9d 7667 [(call (mem:SI (match_operand:SI 0 "call_memory_operand" "m"))
cffb2a26 7668 (match_operand 1 "" ""))
7669 (use (match_operand 2 "" ""))
bd5b4116 7670 (clobber (reg:SI LR_REGNUM))]
33ae7c4b 7671 "TARGET_ARM && !arm_arch5 && !SIBLING_CALL_P (insn)"
9c08d1fa 7672 "*
5565501b 7673 return output_call_mem (operands);
cffb2a26 7674 "
7675 [(set_attr "length" "12")
7676 (set_attr "type" "call")]
7677)
7678
d3373b54 7679(define_expand "call_value"
e0698af7 7680 [(parallel [(set (match_operand 0 "" "")
7681 (call (match_operand 1 "memory_operand" "")
7682 (match_operand 2 "general_operand" "")))
cffb2a26 7683 (use (match_operand 3 "" ""))
bd5b4116 7684 (clobber (reg:SI LR_REGNUM))])]
cffb2a26 7685 "TARGET_EITHER"
6c4c2133 7686 "
7687 {
bac7fc85 7688 rtx pat, callee;
bbe777ea 7689
7690 /* In an untyped call, we can get NULL for operand 2. */
7691 if (operands[3] == 0)
7692 operands[3] = const0_rtx;
7693
de55252a 7694 /* Decide if we should generate indirect calls by loading the
7695 32-bit address of the callee into a register before performing the
7696 branch and link. */
7697 callee = XEXP (operands[1], 0);
7698 if (GET_CODE (callee) == SYMBOL_REF
7699 ? arm_is_long_call_p (SYMBOL_REF_DECL (callee))
7700 : !REG_P (callee))
78fe751b 7701 XEXP (operands[1], 0) = force_reg (Pmode, callee);
bac7fc85 7702
7703 pat = gen_call_value_internal (operands[0], operands[1],
7704 operands[2], operands[3]);
ca373797 7705 arm_emit_call_insn (pat, XEXP (operands[1], 0), false);
bac7fc85 7706 DONE;
6c4c2133 7707 }"
7708)
d3373b54 7709
bac7fc85 7710(define_expand "call_value_internal"
7711 [(parallel [(set (match_operand 0 "" "")
7712 (call (match_operand 1 "memory_operand" "")
7713 (match_operand 2 "general_operand" "")))
7714 (use (match_operand 3 "" ""))
7715 (clobber (reg:SI LR_REGNUM))])])
7716
f1039640 7717(define_insn "*call_value_reg_armv5"
27ed6835 7718 [(set (match_operand 0 "" "")
755eb2b4 7719 (call (mem:SI (match_operand:SI 1 "s_register_operand" "r"))
cffb2a26 7720 (match_operand 2 "" "")))
bbe777ea 7721 (use (match_operand 3 "" ""))
bd5b4116 7722 (clobber (reg:SI LR_REGNUM))]
33ae7c4b 7723 "TARGET_ARM && arm_arch5 && !SIBLING_CALL_P (insn)"
f1039640 7724 "blx%?\\t%1"
7725 [(set_attr "type" "call")]
7726)
7727
7728(define_insn "*call_value_reg_arm"
7729 [(set (match_operand 0 "" "")
7730 (call (mem:SI (match_operand:SI 1 "s_register_operand" "r"))
7731 (match_operand 2 "" "")))
7732 (use (match_operand 3 "" ""))
7733 (clobber (reg:SI LR_REGNUM))]
33ae7c4b 7734 "TARGET_ARM && !arm_arch5 && !SIBLING_CALL_P (insn)"
9c08d1fa 7735 "*
215b30b3 7736 return output_call (&operands[1]);
cffb2a26 7737 "
7738 [(set_attr "length" "12")
7739 (set_attr "type" "call")]
7740)
9c08d1fa 7741
89504fc1 7742;; Note: see *call_mem
7743
f7fbdd4a 7744(define_insn "*call_value_mem"
27ed6835 7745 [(set (match_operand 0 "" "")
a3c63a9d 7746 (call (mem:SI (match_operand:SI 1 "call_memory_operand" "m"))
cffb2a26 7747 (match_operand 2 "" "")))
bbe777ea 7748 (use (match_operand 3 "" ""))
bd5b4116 7749 (clobber (reg:SI LR_REGNUM))]
33ae7c4b 7750 "TARGET_ARM && !arm_arch5 && (!CONSTANT_ADDRESS_P (XEXP (operands[1], 0)))
7751 && !SIBLING_CALL_P (insn)"
9c08d1fa 7752 "*
215b30b3 7753 return output_call_mem (&operands[1]);
cffb2a26 7754 "
7755 [(set_attr "length" "12")
7756 (set_attr "type" "call")]
7757)
9c08d1fa 7758
7759;; Allow calls to SYMBOL_REFs specially as they are not valid general addresses
7760;; The 'a' causes the operand to be treated as an address, i.e. no '#' output.
7761
f7fbdd4a 7762(define_insn "*call_symbol"
27ed6835 7763 [(call (mem:SI (match_operand:SI 0 "" ""))
cffb2a26 7764 (match_operand 1 "" ""))
bbe777ea 7765 (use (match_operand 2 "" ""))
bd5b4116 7766 (clobber (reg:SI LR_REGNUM))]
d68c2c10 7767 "TARGET_32BIT
33ae7c4b 7768 && !SIBLING_CALL_P (insn)
cffb2a26 7769 && (GET_CODE (operands[0]) == SYMBOL_REF)
de55252a 7770 && !arm_is_long_call_p (SYMBOL_REF_DECL (operands[0]))"
6ebaa29d 7771 "*
7772 {
95f1e0d1 7773 rtx op = operands[0];
7774
7775 /* Switch mode now when possible. */
7776 if (SYMBOL_REF_DECL (op) && !TREE_PUBLIC (SYMBOL_REF_DECL (op))
7777 && arm_arch5 && arm_change_mode_p (SYMBOL_REF_DECL (op)))
7778 return NEED_PLT_RELOC ? \"blx%?\\t%a0(PLT)\" : \"blx%?\\t(%a0)\";
7779
55c1e470 7780 return NEED_PLT_RELOC ? \"bl%?\\t%a0(PLT)\" : \"bl%?\\t%a0\";
6ebaa29d 7781 }"
cffb2a26 7782 [(set_attr "type" "call")]
7783)
9c08d1fa 7784
f7fbdd4a 7785(define_insn "*call_value_symbol"
ccd90aaa 7786 [(set (match_operand 0 "" "")
27ed6835 7787 (call (mem:SI (match_operand:SI 1 "" ""))
dd6d7504 7788 (match_operand:SI 2 "" "")))
bbe777ea 7789 (use (match_operand 3 "" ""))
bd5b4116 7790 (clobber (reg:SI LR_REGNUM))]
d68c2c10 7791 "TARGET_32BIT
33ae7c4b 7792 && !SIBLING_CALL_P (insn)
cffb2a26 7793 && (GET_CODE (operands[1]) == SYMBOL_REF)
de55252a 7794 && !arm_is_long_call_p (SYMBOL_REF_DECL (operands[1]))"
6ebaa29d 7795 "*
7796 {
95f1e0d1 7797 rtx op = operands[1];
7798
7799 /* Switch mode now when possible. */
7800 if (SYMBOL_REF_DECL (op) && !TREE_PUBLIC (SYMBOL_REF_DECL (op))
7801 && arm_arch5 && arm_change_mode_p (SYMBOL_REF_DECL (op)))
3f6b66fa 7802 return NEED_PLT_RELOC ? \"blx%?\\t%a1(PLT)\" : \"blx%?\\t(%a1)\";
95f1e0d1 7803
55c1e470 7804 return NEED_PLT_RELOC ? \"bl%?\\t%a1(PLT)\" : \"bl%?\\t%a1\";
6ebaa29d 7805 }"
cffb2a26 7806 [(set_attr "type" "call")]
7807)
7808
ca373797 7809(define_expand "sibcall_internal"
7810 [(parallel [(call (match_operand 0 "memory_operand" "")
7811 (match_operand 1 "general_operand" ""))
7812 (return)
7813 (use (match_operand 2 "" ""))])])
7814
1c494086 7815;; We may also be able to do sibcalls for Thumb, but it's much harder...
7816(define_expand "sibcall"
7817 [(parallel [(call (match_operand 0 "memory_operand" "")
7818 (match_operand 1 "general_operand" ""))
2ba80634 7819 (return)
7820 (use (match_operand 2 "" ""))])]
d68c2c10 7821 "TARGET_32BIT"
1c494086 7822 "
7823 {
ca373797 7824 rtx pat;
7825
3112c3f7 7826 if ((!REG_P (XEXP (operands[0], 0))
7827 && GET_CODE (XEXP (operands[0], 0)) != SYMBOL_REF)
7828 || (GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
7829 && arm_is_long_call_p (SYMBOL_REF_DECL (XEXP (operands[0], 0)))))
33ae7c4b 7830 XEXP (operands[0], 0) = force_reg (SImode, XEXP (operands[0], 0));
7831
1c494086 7832 if (operands[2] == NULL_RTX)
7833 operands[2] = const0_rtx;
ca373797 7834
7835 pat = gen_sibcall_internal (operands[0], operands[1], operands[2]);
7836 arm_emit_call_insn (pat, operands[0], true);
7837 DONE;
1c494086 7838 }"
7839)
7840
ca373797 7841(define_expand "sibcall_value_internal"
7842 [(parallel [(set (match_operand 0 "" "")
7843 (call (match_operand 1 "memory_operand" "")
7844 (match_operand 2 "general_operand" "")))
7845 (return)
7846 (use (match_operand 3 "" ""))])])
7847
1c494086 7848(define_expand "sibcall_value"
ccd90aaa 7849 [(parallel [(set (match_operand 0 "" "")
1c494086 7850 (call (match_operand 1 "memory_operand" "")
7851 (match_operand 2 "general_operand" "")))
2ba80634 7852 (return)
7853 (use (match_operand 3 "" ""))])]
d68c2c10 7854 "TARGET_32BIT"
1c494086 7855 "
7856 {
ca373797 7857 rtx pat;
7858
3112c3f7 7859 if ((!REG_P (XEXP (operands[1], 0))
7860 && GET_CODE (XEXP (operands[1], 0)) != SYMBOL_REF)
7861 || (GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
7862 && arm_is_long_call_p (SYMBOL_REF_DECL (XEXP (operands[1], 0)))))
33ae7c4b 7863 XEXP (operands[1], 0) = force_reg (SImode, XEXP (operands[1], 0));
7864
1c494086 7865 if (operands[3] == NULL_RTX)
7866 operands[3] = const0_rtx;
ca373797 7867
7868 pat = gen_sibcall_value_internal (operands[0], operands[1],
7869 operands[2], operands[3]);
7870 arm_emit_call_insn (pat, operands[1], true);
7871 DONE;
1c494086 7872 }"
7873)
7874
7875(define_insn "*sibcall_insn"
84ce8e5c 7876 [(call (mem:SI (match_operand:SI 0 "call_insn_operand" "Cs, US"))
1c494086 7877 (match_operand 1 "" ""))
2ba80634 7878 (return)
7879 (use (match_operand 2 "" ""))]
33ae7c4b 7880 "TARGET_32BIT && SIBLING_CALL_P (insn)"
1c494086 7881 "*
33ae7c4b 7882 if (which_alternative == 1)
7883 return NEED_PLT_RELOC ? \"b%?\\t%a0(PLT)\" : \"b%?\\t%a0\";
7884 else
7885 {
7886 if (arm_arch5 || arm_arch4t)
947d113e 7887 return \"bx%?\\t%0\\t%@ indirect register sibling call\";
33ae7c4b 7888 else
7889 return \"mov%?\\t%|pc, %0\\t%@ indirect register sibling call\";
7890 }
1c494086 7891 "
7892 [(set_attr "type" "call")]
7893)
7894
7895(define_insn "*sibcall_value_insn"
84ce8e5c 7896 [(set (match_operand 0 "" "")
7897 (call (mem:SI (match_operand:SI 1 "call_insn_operand" "Cs,US"))
1c494086 7898 (match_operand 2 "" "")))
2ba80634 7899 (return)
7900 (use (match_operand 3 "" ""))]
33ae7c4b 7901 "TARGET_32BIT && SIBLING_CALL_P (insn)"
1c494086 7902 "*
33ae7c4b 7903 if (which_alternative == 1)
7904 return NEED_PLT_RELOC ? \"b%?\\t%a1(PLT)\" : \"b%?\\t%a1\";
7905 else
7906 {
7907 if (arm_arch5 || arm_arch4t)
84ce8e5c 7908 return \"bx%?\\t%1\";
33ae7c4b 7909 else
7910 return \"mov%?\\t%|pc, %1\\t@ indirect sibling call \";
7911 }
1c494086 7912 "
7913 [(set_attr "type" "call")]
7914)
7915
0686440e 7916(define_expand "<return_str>return"
9b23f0a7 7917 [(RETURNS)]
8cba51a5 7918 "(TARGET_ARM || (TARGET_THUMB2
7919 && ARM_FUNC_TYPE (arm_current_func_type ()) == ARM_FT_NORMAL
7920 && !IS_STACKALIGN (arm_current_func_type ())))
0686440e 7921 <return_cond_false>"
8cba51a5 7922 "
7923 {
7924 if (TARGET_THUMB2)
7925 {
0686440e 7926 thumb2_expand_return (<return_simple_p>);
8cba51a5 7927 DONE;
7928 }
7929 }
7930 "
7931)
d68c2c10 7932
9c08d1fa 7933;; Often the return insn will be the same as loading from memory, so set attr
d68c2c10 7934(define_insn "*arm_return"
9c08d1fa 7935 [(return)]
cffb2a26 7936 "TARGET_ARM && USE_RETURN_INSN (FALSE)"
9c08d1fa 7937 "*
9c08d1fa 7938 {
cffb2a26 7939 if (arm_ccfsm_state == 2)
7940 {
7941 arm_ccfsm_state += 2;
7942 return \"\";
7943 }
e2549f81 7944 return output_return_instruction (const_true_rtx, true, false, false);
cffb2a26 7945 }"
a2cd141b 7946 [(set_attr "type" "load1")
755eb2b4 7947 (set_attr "length" "12")
0d66636f 7948 (set_attr "predicable" "yes")]
cffb2a26 7949)
9c08d1fa 7950
0686440e 7951(define_insn "*cond_<return_str>return"
9c08d1fa 7952 [(set (pc)
8fa3ba89 7953 (if_then_else (match_operator 0 "arm_comparison_operator"
8a18b90c 7954 [(match_operand 1 "cc_register" "") (const_int 0)])
9b23f0a7 7955 (RETURNS)
9c08d1fa 7956 (pc)))]
0686440e 7957 "TARGET_ARM <return_cond_true>"
9c08d1fa 7958 "*
8fa3ba89 7959 {
7960 if (arm_ccfsm_state == 2)
7961 {
7962 arm_ccfsm_state += 2;
7963 return \"\";
7964 }
0686440e 7965 return output_return_instruction (operands[0], true, false,
7966 <return_simple_p>);
8fa3ba89 7967 }"
7968 [(set_attr "conds" "use")
755eb2b4 7969 (set_attr "length" "12")
a2cd141b 7970 (set_attr "type" "load1")]
8fa3ba89 7971)
9c08d1fa 7972
0686440e 7973(define_insn "*cond_<return_str>return_inverted"
9c08d1fa 7974 [(set (pc)
8fa3ba89 7975 (if_then_else (match_operator 0 "arm_comparison_operator"
8a18b90c 7976 [(match_operand 1 "cc_register" "") (const_int 0)])
9c08d1fa 7977 (pc)
9b23f0a7 7978 (RETURNS)))]
0686440e 7979 "TARGET_ARM <return_cond_true>"
9c08d1fa 7980 "*
8fa3ba89 7981 {
7982 if (arm_ccfsm_state == 2)
7983 {
7984 arm_ccfsm_state += 2;
7985 return \"\";
7986 }
0686440e 7987 return output_return_instruction (operands[0], true, true,
7988 <return_simple_p>);
8fa3ba89 7989 }"
7990 [(set_attr "conds" "use")
37a1317b 7991 (set_attr "length" "12")
a2cd141b 7992 (set_attr "type" "load1")]
8fa3ba89 7993)
9c08d1fa 7994
e2549f81 7995(define_insn "*arm_simple_return"
7996 [(simple_return)]
7997 "TARGET_ARM"
7998 "*
7999 {
8000 if (arm_ccfsm_state == 2)
8001 {
8002 arm_ccfsm_state += 2;
8003 return \"\";
8004 }
8005 return output_return_instruction (const_true_rtx, true, false, true);
8006 }"
8007 [(set_attr "type" "branch")
8008 (set_attr "length" "4")
8009 (set_attr "predicable" "yes")]
8010)
8011
68121397 8012;; Generate a sequence of instructions to determine if the processor is
8013;; in 26-bit or 32-bit mode, and return the appropriate return address
8014;; mask.
8015
8016(define_expand "return_addr_mask"
8017 [(set (match_dup 1)
8018 (compare:CC_NOOV (unspec [(const_int 0)] UNSPEC_CHECK_ARCH)
8019 (const_int 0)))
8020 (set (match_operand:SI 0 "s_register_operand" "")
8021 (if_then_else:SI (eq (match_dup 1) (const_int 0))
8022 (const_int -1)
8023 (const_int 67108860)))] ; 0x03fffffc
8024 "TARGET_ARM"
8025 "
62eddbd4 8026 operands[1] = gen_rtx_REG (CC_NOOVmode, CC_REGNUM);
68121397 8027 ")
8028
8029(define_insn "*check_arch2"
8030 [(set (match_operand:CC_NOOV 0 "cc_register" "")
8031 (compare:CC_NOOV (unspec [(const_int 0)] UNSPEC_CHECK_ARCH)
8032 (const_int 0)))]
8033 "TARGET_ARM"
8034 "teq\\t%|r0, %|r0\;teq\\t%|pc, %|pc"
8035 [(set_attr "length" "8")
1b7da4ac 8036 (set_attr "conds" "set")
8037 (set_attr "type" "multiple")]
68121397 8038)
8039
9c08d1fa 8040;; Call subroutine returning any type.
8041
8042(define_expand "untyped_call"
8043 [(parallel [(call (match_operand 0 "" "")
8044 (const_int 0))
8045 (match_operand 1 "" "")
8046 (match_operand 2 "" "")])]
ccd90aaa 8047 "TARGET_EITHER"
9c08d1fa 8048 "
215b30b3 8049 {
8050 int i;
ccd90aaa 8051 rtx par = gen_rtx_PARALLEL (VOIDmode,
8052 rtvec_alloc (XVECLEN (operands[2], 0)));
8053 rtx addr = gen_reg_rtx (Pmode);
8054 rtx mem;
8055 int size = 0;
9c08d1fa 8056
ccd90aaa 8057 emit_move_insn (addr, XEXP (operands[1], 0));
8058 mem = change_address (operands[1], BLKmode, addr);
9c08d1fa 8059
215b30b3 8060 for (i = 0; i < XVECLEN (operands[2], 0); i++)
8061 {
ccd90aaa 8062 rtx src = SET_SRC (XVECEXP (operands[2], 0, i));
9c08d1fa 8063
ccd90aaa 8064 /* Default code only uses r0 as a return value, but we could
8065 be using anything up to 4 registers. */
8066 if (REGNO (src) == R0_REGNUM)
8067 src = gen_rtx_REG (TImode, R0_REGNUM);
8068
8069 XVECEXP (par, 0, i) = gen_rtx_EXPR_LIST (VOIDmode, src,
8070 GEN_INT (size));
8071 size += GET_MODE_SIZE (GET_MODE (src));
8072 }
8073
7f265a08 8074 emit_call_insn (gen_call_value (par, operands[0], const0_rtx, NULL));
ccd90aaa 8075
8076 size = 0;
8077
8078 for (i = 0; i < XVECLEN (par, 0); i++)
8079 {
8080 HOST_WIDE_INT offset = 0;
8081 rtx reg = XEXP (XVECEXP (par, 0, i), 0);
8082
8083 if (size != 0)
29c05e22 8084 emit_move_insn (addr, plus_constant (Pmode, addr, size));
ccd90aaa 8085
8086 mem = change_address (mem, GET_MODE (reg), NULL);
8087 if (REGNO (reg) == R0_REGNUM)
8088 {
8089 /* On thumb we have to use a write-back instruction. */
320ea44d 8090 emit_insn (arm_gen_store_multiple (arm_regs_in_sequence, 4, addr,
8091 TARGET_THUMB ? TRUE : FALSE, mem, &offset));
ccd90aaa 8092 size = TARGET_ARM ? 16 : 0;
8093 }
8094 else
8095 {
8096 emit_move_insn (mem, reg);
8097 size = GET_MODE_SIZE (GET_MODE (reg));
8098 }
215b30b3 8099 }
9c08d1fa 8100
215b30b3 8101 /* The optimizer does not know that the call sets the function value
8102 registers we stored in the result block. We avoid problems by
8103 claiming that all hard registers are used and clobbered at this
8104 point. */
8105 emit_insn (gen_blockage ());
8106
8107 DONE;
8108 }"
8109)
9c08d1fa 8110
ccd90aaa 8111(define_expand "untyped_return"
8112 [(match_operand:BLK 0 "memory_operand" "")
8113 (match_operand 1 "" "")]
8114 "TARGET_EITHER"
8115 "
8116 {
8117 int i;
8118 rtx addr = gen_reg_rtx (Pmode);
8119 rtx mem;
8120 int size = 0;
8121
8122 emit_move_insn (addr, XEXP (operands[0], 0));
8123 mem = change_address (operands[0], BLKmode, addr);
8124
8125 for (i = 0; i < XVECLEN (operands[1], 0); i++)
8126 {
8127 HOST_WIDE_INT offset = 0;
8128 rtx reg = SET_DEST (XVECEXP (operands[1], 0, i));
8129
8130 if (size != 0)
29c05e22 8131 emit_move_insn (addr, plus_constant (Pmode, addr, size));
ccd90aaa 8132
8133 mem = change_address (mem, GET_MODE (reg), NULL);
8134 if (REGNO (reg) == R0_REGNUM)
8135 {
8136 /* On thumb we have to use a write-back instruction. */
320ea44d 8137 emit_insn (arm_gen_load_multiple (arm_regs_in_sequence, 4, addr,
8138 TARGET_THUMB ? TRUE : FALSE, mem, &offset));
ccd90aaa 8139 size = TARGET_ARM ? 16 : 0;
8140 }
8141 else
8142 {
8143 emit_move_insn (reg, mem);
8144 size = GET_MODE_SIZE (GET_MODE (reg));
8145 }
8146 }
8147
8148 /* Emit USE insns before the return. */
8149 for (i = 0; i < XVECLEN (operands[1], 0); i++)
18b42941 8150 emit_use (SET_DEST (XVECEXP (operands[1], 0, i)));
ccd90aaa 8151
8152 /* Construct the return. */
8153 expand_naked_return ();
8154
8155 DONE;
8156 }"
8157)
8158
9c08d1fa 8159;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
8160;; all of memory. This blocks insns from being moved across this point.
8161
8162(define_insn "blockage"
e1159bbe 8163 [(unspec_volatile [(const_int 0)] VUNSPEC_BLOCKAGE)]
cffb2a26 8164 "TARGET_EITHER"
9c08d1fa 8165 ""
cffb2a26 8166 [(set_attr "length" "0")
8167 (set_attr "type" "block")]
8168)
9c08d1fa 8169
706dca65 8170(define_insn "probe_stack"
8171 [(set (match_operand 0 "memory_operand" "=m")
8172 (unspec [(const_int 0)] UNSPEC_PROBE_STACK))]
8173 "TARGET_32BIT"
154ae8e6 8174 "str%?\\tr0, %0"
706dca65 8175 [(set_attr "type" "store1")
8176 (set_attr "predicable" "yes")]
8177)
8178
8179(define_insn "probe_stack_range"
8180 [(set (match_operand:SI 0 "register_operand" "=r")
8181 (unspec_volatile:SI [(match_operand:SI 1 "register_operand" "0")
8182 (match_operand:SI 2 "register_operand" "r")]
8183 UNSPEC_PROBE_STACK_RANGE))]
8184 "TARGET_32BIT"
8185{
8186 return output_probe_stack_range (operands[0], operands[2]);
8187}
8188 [(set_attr "type" "multiple")
8189 (set_attr "conds" "clob")]
8190)
8191
f7fbdd4a 8192(define_expand "casesi"
8193 [(match_operand:SI 0 "s_register_operand" "") ; index to jump on
aea4c774 8194 (match_operand:SI 1 "const_int_operand" "") ; lower bound
8195 (match_operand:SI 2 "const_int_operand" "") ; total range
f7fbdd4a 8196 (match_operand:SI 3 "" "") ; table label
8197 (match_operand:SI 4 "" "")] ; Out of range label
e6ac8414 8198 "TARGET_32BIT || optimize_size || flag_pic"
f7fbdd4a 8199 "
215b30b3 8200 {
e6ac8414 8201 enum insn_code code;
215b30b3 8202 if (operands[1] != const0_rtx)
8203 {
e6ac8414 8204 rtx reg = gen_reg_rtx (SImode);
f7fbdd4a 8205
215b30b3 8206 emit_insn (gen_addsi3 (reg, operands[0],
d022fa24 8207 gen_int_mode (-INTVAL (operands[1]),
8208 SImode)));
215b30b3 8209 operands[0] = reg;
8210 }
9c08d1fa 8211
25f905c2 8212 if (TARGET_ARM)
e6ac8414 8213 code = CODE_FOR_arm_casesi_internal;
3db2019b 8214 else if (TARGET_THUMB1)
e6ac8414 8215 code = CODE_FOR_thumb1_casesi_internal_pic;
25f905c2 8216 else if (flag_pic)
e6ac8414 8217 code = CODE_FOR_thumb2_casesi_internal_pic;
25f905c2 8218 else
e6ac8414 8219 code = CODE_FOR_thumb2_casesi_internal;
8220
8221 if (!insn_data[(int) code].operand[1].predicate(operands[2], SImode))
8222 operands[2] = force_reg (SImode, operands[2]);
8223
8224 emit_jump_insn (GEN_FCN ((int) code) (operands[0], operands[2],
8225 operands[3], operands[4]));
215b30b3 8226 DONE;
8227 }"
8228)
f7fbdd4a 8229
f082f1c4 8230;; The USE in this pattern is needed to tell flow analysis that this is
8231;; a CASESI insn. It has no other purpose.
25f905c2 8232(define_insn "arm_casesi_internal"
f082f1c4 8233 [(parallel [(set (pc)
8234 (if_then_else
8235 (leu (match_operand:SI 0 "s_register_operand" "r")
8236 (match_operand:SI 1 "arm_rhs_operand" "rI"))
8237 (mem:SI (plus:SI (mult:SI (match_dup 0) (const_int 4))
8238 (label_ref (match_operand 2 "" ""))))
8239 (label_ref (match_operand 3 "" ""))))
bd5b4116 8240 (clobber (reg:CC CC_REGNUM))
f082f1c4 8241 (use (label_ref (match_dup 2)))])]
cffb2a26 8242 "TARGET_ARM"
f7fbdd4a 8243 "*
0d66636f 8244 if (flag_pic)
8245 return \"cmp\\t%0, %1\;addls\\t%|pc, %|pc, %0, asl #2\;b\\t%l3\";
8246 return \"cmp\\t%0, %1\;ldrls\\t%|pc, [%|pc, %0, asl #2]\;b\\t%l3\";
8247 "
8248 [(set_attr "conds" "clob")
1b7da4ac 8249 (set_attr "length" "12")
8250 (set_attr "type" "multiple")]
0d66636f 8251)
9c08d1fa 8252
cffb2a26 8253(define_expand "indirect_jump"
9c08d1fa 8254 [(set (pc)
cffb2a26 8255 (match_operand:SI 0 "s_register_operand" ""))]
8256 "TARGET_EITHER"
25f905c2 8257 "
8258 /* Thumb-2 doesn't have mov pc, reg. Explicitly set the low bit of the
8259 address and use bx. */
8260 if (TARGET_THUMB2)
8261 {
8262 rtx tmp;
8263 tmp = gen_reg_rtx (SImode);
8264 emit_insn (gen_iorsi3 (tmp, operands[0], GEN_INT(1)));
8265 operands[0] = tmp;
8266 }
8267 "
cffb2a26 8268)
8269
f1039640 8270;; NB Never uses BX.
cffb2a26 8271(define_insn "*arm_indirect_jump"
8272 [(set (pc)
8273 (match_operand:SI 0 "s_register_operand" "r"))]
8274 "TARGET_ARM"
8275 "mov%?\\t%|pc, %0\\t%@ indirect register jump"
1b7da4ac 8276 [(set_attr "predicable" "yes")
8277 (set_attr "type" "branch")]
cffb2a26 8278)
9c08d1fa 8279
f7fbdd4a 8280(define_insn "*load_indirect_jump"
9c08d1fa 8281 [(set (pc)
8282 (match_operand:SI 0 "memory_operand" "m"))]
cffb2a26 8283 "TARGET_ARM"
8284 "ldr%?\\t%|pc, %0\\t%@ indirect memory jump"
a2cd141b 8285 [(set_attr "type" "load1")
61a2d04c 8286 (set_attr "pool_range" "4096")
8287 (set_attr "neg_pool_range" "4084")
0d66636f 8288 (set_attr "predicable" "yes")]
cffb2a26 8289)
8290
9c08d1fa 8291\f
8292;; Misc insns
8293
8294(define_insn "nop"
8295 [(const_int 0)]
cffb2a26 8296 "TARGET_EITHER"
3ef90e77 8297 "nop"
cffb2a26 8298 [(set (attr "length")
8299 (if_then_else (eq_attr "is_thumb" "yes")
8300 (const_int 2)
1b7da4ac 8301 (const_int 4)))
8302 (set_attr "type" "mov_reg")]
cffb2a26 8303)
8304
ad9d4399 8305(define_insn "trap"
8306 [(trap_if (const_int 1) (const_int 0))]
8307 ""
8308 "*
8309 if (TARGET_ARM)
8310 return \".inst\\t0xe7f000f0\";
8311 else
8312 return \".inst\\t0xdeff\";
8313 "
8314 [(set (attr "length")
8315 (if_then_else (eq_attr "is_thumb" "yes")
8316 (const_int 2)
8317 (const_int 4)))
8318 (set_attr "type" "trap")
8319 (set_attr "conds" "unconditional")]
8320)
8321
9c08d1fa 8322\f
8323;; Patterns to allow combination of arithmetic, cond code and shifts
8324
0abea32c 8325(define_insn "*<arith_shift_insn>_multsi"
8326 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9b23f0a7 8327 (SHIFTABLE_OPS:SI
0abea32c 8328 (mult:SI (match_operand:SI 2 "s_register_operand" "r,r")
8329 (match_operand:SI 3 "power_of_two_operand" ""))
8330 (match_operand:SI 1 "s_register_operand" "rk,<t2_binop0>")))]
d5d4dc8d 8331 "TARGET_32BIT"
0abea32c 8332 "<arith_shift_insn>%?\\t%0, %1, %2, lsl %b3"
8333 [(set_attr "predicable" "yes")
8334 (set_attr "predicable_short_it" "no")
753d9835 8335 (set_attr "shift" "2")
0abea32c 8336 (set_attr "arch" "a,t2")
8337 (set_attr "type" "alu_shift_imm")])
8338
8339(define_insn "*<arith_shift_insn>_shiftsi"
8340 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9b23f0a7 8341 (SHIFTABLE_OPS:SI
0abea32c 8342 (match_operator:SI 2 "shift_nomul_operator"
8343 [(match_operand:SI 3 "s_register_operand" "r,r,r")
8344 (match_operand:SI 4 "shift_amount_operand" "M,M,r")])
8345 (match_operand:SI 1 "s_register_operand" "rk,<t2_binop0>,rk")))]
a021b821 8346 "TARGET_32BIT && GET_CODE (operands[2]) != MULT"
0abea32c 8347 "<arith_shift_insn>%?\\t%0, %1, %3%S2"
344495ea 8348 [(set_attr "predicable" "yes")
74ef923b 8349 (set_attr "predicable_short_it" "no")
753d9835 8350 (set_attr "shift" "3")
0abea32c 8351 (set_attr "arch" "a,t2,a")
8352 (set_attr "type" "alu_shift_imm,alu_shift_imm,alu_shift_reg")])
9c08d1fa 8353
d7863cfe 8354(define_split
8355 [(set (match_operand:SI 0 "s_register_operand" "")
8356 (match_operator:SI 1 "shiftable_operator"
8357 [(match_operator:SI 2 "shiftable_operator"
8358 [(match_operator:SI 3 "shift_operator"
8359 [(match_operand:SI 4 "s_register_operand" "")
8360 (match_operand:SI 5 "reg_or_int_operand" "")])
8361 (match_operand:SI 6 "s_register_operand" "")])
8362 (match_operand:SI 7 "arm_rhs_operand" "")]))
8363 (clobber (match_operand:SI 8 "s_register_operand" ""))]
d5d4dc8d 8364 "TARGET_32BIT"
d7863cfe 8365 [(set (match_dup 8)
8366 (match_op_dup 2 [(match_op_dup 3 [(match_dup 4) (match_dup 5)])
8367 (match_dup 6)]))
8368 (set (match_dup 0)
8369 (match_op_dup 1 [(match_dup 8) (match_dup 7)]))]
8370 "")
8371
f7fbdd4a 8372(define_insn "*arith_shiftsi_compare0"
bd5b4116 8373 [(set (reg:CC_NOOV CC_REGNUM)
d5d4dc8d 8374 (compare:CC_NOOV
8375 (match_operator:SI 1 "shiftable_operator"
8376 [(match_operator:SI 3 "shift_operator"
8377 [(match_operand:SI 4 "s_register_operand" "r,r")
8378 (match_operand:SI 5 "shift_amount_operand" "M,r")])
8379 (match_operand:SI 2 "s_register_operand" "r,r")])
8380 (const_int 0)))
8381 (set (match_operand:SI 0 "s_register_operand" "=r,r")
9c08d1fa 8382 (match_op_dup 1 [(match_op_dup 3 [(match_dup 4) (match_dup 5)])
8383 (match_dup 2)]))]
d5d4dc8d 8384 "TARGET_32BIT"
3ef90e77 8385 "%i1s%?\\t%0, %2, %4%S3"
344495ea 8386 [(set_attr "conds" "set")
331beb1a 8387 (set_attr "shift" "4")
d5d4dc8d 8388 (set_attr "arch" "32,a")
d82e788e 8389 (set_attr "type" "alus_shift_imm,alus_shift_reg")])
9c08d1fa 8390
f7fbdd4a 8391(define_insn "*arith_shiftsi_compare0_scratch"
bd5b4116 8392 [(set (reg:CC_NOOV CC_REGNUM)
d5d4dc8d 8393 (compare:CC_NOOV
8394 (match_operator:SI 1 "shiftable_operator"
8395 [(match_operator:SI 3 "shift_operator"
8396 [(match_operand:SI 4 "s_register_operand" "r,r")
8397 (match_operand:SI 5 "shift_amount_operand" "M,r")])
8398 (match_operand:SI 2 "s_register_operand" "r,r")])
8399 (const_int 0)))
8400 (clobber (match_scratch:SI 0 "=r,r"))]
8401 "TARGET_32BIT"
3ef90e77 8402 "%i1s%?\\t%0, %2, %4%S3"
344495ea 8403 [(set_attr "conds" "set")
331beb1a 8404 (set_attr "shift" "4")
d5d4dc8d 8405 (set_attr "arch" "32,a")
d82e788e 8406 (set_attr "type" "alus_shift_imm,alus_shift_reg")])
9c08d1fa 8407
f7fbdd4a 8408(define_insn "*sub_shiftsi"
d5d4dc8d 8409 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8410 (minus:SI (match_operand:SI 1 "s_register_operand" "r,r")
9c08d1fa 8411 (match_operator:SI 2 "shift_operator"
d5d4dc8d 8412 [(match_operand:SI 3 "s_register_operand" "r,r")
8413 (match_operand:SI 4 "shift_amount_operand" "M,r")])))]
8414 "TARGET_32BIT"
6c4c2133 8415 "sub%?\\t%0, %1, %3%S2"
344495ea 8416 [(set_attr "predicable" "yes")
331beb1a 8417 (set_attr "shift" "3")
d5d4dc8d 8418 (set_attr "arch" "32,a")
d82e788e 8419 (set_attr "type" "alus_shift_imm,alus_shift_reg")])
9c08d1fa 8420
f7fbdd4a 8421(define_insn "*sub_shiftsi_compare0"
bd5b4116 8422 [(set (reg:CC_NOOV CC_REGNUM)
40dbec34 8423 (compare:CC_NOOV
d82e788e 8424 (minus:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
40dbec34 8425 (match_operator:SI 2 "shift_operator"
d82e788e 8426 [(match_operand:SI 3 "s_register_operand" "r,r,r")
8427 (match_operand:SI 4 "shift_amount_operand" "M,r,M")]))
40dbec34 8428 (const_int 0)))
d82e788e 8429 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
d5d4dc8d 8430 (minus:SI (match_dup 1)
8431 (match_op_dup 2 [(match_dup 3) (match_dup 4)])))]
8432 "TARGET_32BIT"
3ef90e77 8433 "subs%?\\t%0, %1, %3%S2"
344495ea 8434 [(set_attr "conds" "set")
a2cd141b 8435 (set_attr "shift" "3")
d82e788e 8436 (set_attr "arch" "32,a,a")
8437 (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")])
9c08d1fa 8438
f7fbdd4a 8439(define_insn "*sub_shiftsi_compare0_scratch"
bd5b4116 8440 [(set (reg:CC_NOOV CC_REGNUM)
40dbec34 8441 (compare:CC_NOOV
d82e788e 8442 (minus:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
40dbec34 8443 (match_operator:SI 2 "shift_operator"
d82e788e 8444 [(match_operand:SI 3 "s_register_operand" "r,r,r")
8445 (match_operand:SI 4 "shift_amount_operand" "M,r,M")]))
40dbec34 8446 (const_int 0)))
d82e788e 8447 (clobber (match_scratch:SI 0 "=r,r,r"))]
d5d4dc8d 8448 "TARGET_32BIT"
3ef90e77 8449 "subs%?\\t%0, %1, %3%S2"
344495ea 8450 [(set_attr "conds" "set")
a2cd141b 8451 (set_attr "shift" "3")
d82e788e 8452 (set_attr "arch" "32,a,a")
8453 (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")])
9c08d1fa 8454\f
8455
190efb17 8456(define_insn_and_split "*and_scc"
9c08d1fa 8457 [(set (match_operand:SI 0 "s_register_operand" "=r")
8fa3ba89 8458 (and:SI (match_operator:SI 1 "arm_comparison_operator"
190efb17 8459 [(match_operand 2 "cc_register" "") (const_int 0)])
8460 (match_operand:SI 3 "s_register_operand" "r")))]
cffb2a26 8461 "TARGET_ARM"
190efb17 8462 "#" ; "mov%D1\\t%0, #0\;and%d1\\t%0, %3, #1"
8463 "&& reload_completed"
8464 [(cond_exec (match_dup 5) (set (match_dup 0) (const_int 0)))
8465 (cond_exec (match_dup 4) (set (match_dup 0)
8466 (and:SI (match_dup 3) (const_int 1))))]
8467 {
3754d046 8468 machine_mode mode = GET_MODE (operands[2]);
190efb17 8469 enum rtx_code rc = GET_CODE (operands[1]);
8470
8471 /* Note that operands[4] is the same as operands[1],
8472 but with VOIDmode as the result. */
8473 operands[4] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
8474 if (mode == CCFPmode || mode == CCFPEmode)
8475 rc = reverse_condition_maybe_unordered (rc);
8476 else
8477 rc = reverse_condition (rc);
8478 operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
8479 }
8fa3ba89 8480 [(set_attr "conds" "use")
1b7da4ac 8481 (set_attr "type" "multiple")
8fa3ba89 8482 (set_attr "length" "8")]
8483)
9c08d1fa 8484
190efb17 8485(define_insn_and_split "*ior_scc"
9c08d1fa 8486 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
190efb17 8487 (ior:SI (match_operator:SI 1 "arm_comparison_operator"
8488 [(match_operand 2 "cc_register" "") (const_int 0)])
8489 (match_operand:SI 3 "s_register_operand" "0,?r")))]
cffb2a26 8490 "TARGET_ARM"
e2348bcb 8491 "@
190efb17 8492 orr%d1\\t%0, %3, #1
8493 #"
8494 "&& reload_completed
8495 && REGNO (operands [0]) != REGNO (operands[3])"
8496 ;; && which_alternative == 1
8497 ; mov%D1\\t%0, %3\;orr%d1\\t%0, %3, #1
8498 [(cond_exec (match_dup 5) (set (match_dup 0) (match_dup 3)))
8499 (cond_exec (match_dup 4) (set (match_dup 0)
8500 (ior:SI (match_dup 3) (const_int 1))))]
8501 {
3754d046 8502 machine_mode mode = GET_MODE (operands[2]);
190efb17 8503 enum rtx_code rc = GET_CODE (operands[1]);
8504
8505 /* Note that operands[4] is the same as operands[1],
8506 but with VOIDmode as the result. */
8507 operands[4] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
8508 if (mode == CCFPmode || mode == CCFPEmode)
8509 rc = reverse_condition_maybe_unordered (rc);
8510 else
8511 rc = reverse_condition (rc);
8512 operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
8513 }
8fa3ba89 8514 [(set_attr "conds" "use")
1b7da4ac 8515 (set_attr "length" "4,8")
8516 (set_attr "type" "logic_imm,multiple")]
8fa3ba89 8517)
9c08d1fa 8518
2df9477b 8519; A series of splitters for the compare_scc pattern below. Note that
8520; order is important.
8521(define_split
8522 [(set (match_operand:SI 0 "s_register_operand" "")
8523 (lt:SI (match_operand:SI 1 "s_register_operand" "")
8524 (const_int 0)))
8525 (clobber (reg:CC CC_REGNUM))]
8526 "TARGET_32BIT && reload_completed"
8527 [(set (match_dup 0) (lshiftrt:SI (match_dup 1) (const_int 31)))])
8528
8529(define_split
8530 [(set (match_operand:SI 0 "s_register_operand" "")
8531 (ge:SI (match_operand:SI 1 "s_register_operand" "")
8532 (const_int 0)))
8533 (clobber (reg:CC CC_REGNUM))]
8534 "TARGET_32BIT && reload_completed"
8535 [(set (match_dup 0) (not:SI (match_dup 1)))
8536 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 31)))])
8537
98562479 8538(define_split
8539 [(set (match_operand:SI 0 "s_register_operand" "")
8540 (eq:SI (match_operand:SI 1 "s_register_operand" "")
8541 (const_int 0)))
8542 (clobber (reg:CC CC_REGNUM))]
8543 "arm_arch5 && TARGET_32BIT"
8544 [(set (match_dup 0) (clz:SI (match_dup 1)))
8545 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 5)))]
8546)
8547
2df9477b 8548(define_split
8549 [(set (match_operand:SI 0 "s_register_operand" "")
8550 (eq:SI (match_operand:SI 1 "s_register_operand" "")
8551 (const_int 0)))
8552 (clobber (reg:CC CC_REGNUM))]
8553 "TARGET_32BIT && reload_completed"
8554 [(parallel
080c0b9a 8555 [(set (reg:CC CC_REGNUM)
8556 (compare:CC (const_int 1) (match_dup 1)))
2df9477b 8557 (set (match_dup 0)
8558 (minus:SI (const_int 1) (match_dup 1)))])
080c0b9a 8559 (cond_exec (ltu:CC (reg:CC CC_REGNUM) (const_int 0))
2df9477b 8560 (set (match_dup 0) (const_int 0)))])
8561
8562(define_split
8563 [(set (match_operand:SI 0 "s_register_operand" "")
8564 (ne:SI (match_operand:SI 1 "s_register_operand" "")
8565 (match_operand:SI 2 "const_int_operand" "")))
8566 (clobber (reg:CC CC_REGNUM))]
8567 "TARGET_32BIT && reload_completed"
8568 [(parallel
8569 [(set (reg:CC CC_REGNUM)
8570 (compare:CC (match_dup 1) (match_dup 2)))
8571 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 3)))])
8572 (cond_exec (ne:CC (reg:CC CC_REGNUM) (const_int 0))
8573 (set (match_dup 0) (const_int 1)))]
8574{
8575 operands[3] = GEN_INT (-INTVAL (operands[2]));
8576})
8577
8578(define_split
8579 [(set (match_operand:SI 0 "s_register_operand" "")
8580 (ne:SI (match_operand:SI 1 "s_register_operand" "")
8581 (match_operand:SI 2 "arm_add_operand" "")))
8582 (clobber (reg:CC CC_REGNUM))]
8583 "TARGET_32BIT && reload_completed"
8584 [(parallel
8585 [(set (reg:CC_NOOV CC_REGNUM)
8586 (compare:CC_NOOV (minus:SI (match_dup 1) (match_dup 2))
8587 (const_int 0)))
8588 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
8589 (cond_exec (ne:CC_NOOV (reg:CC_NOOV CC_REGNUM) (const_int 0))
8590 (set (match_dup 0) (const_int 1)))])
8591
8592(define_insn_and_split "*compare_scc"
fd711051 8593 [(set (match_operand:SI 0 "s_register_operand" "=Ts,Ts")
8fa3ba89 8594 (match_operator:SI 1 "arm_comparison_operator"
5565501b 8595 [(match_operand:SI 2 "s_register_operand" "r,r")
8596 (match_operand:SI 3 "arm_add_operand" "rI,L")]))
bd5b4116 8597 (clobber (reg:CC CC_REGNUM))]
2df9477b 8598 "TARGET_32BIT"
8599 "#"
8600 "&& reload_completed"
8601 [(set (reg:CC CC_REGNUM) (compare:CC (match_dup 2) (match_dup 3)))
8602 (cond_exec (match_dup 4) (set (match_dup 0) (const_int 0)))
8603 (cond_exec (match_dup 5) (set (match_dup 0) (const_int 1)))]
8604{
8605 rtx tmp1;
3754d046 8606 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
2df9477b 8607 operands[2], operands[3]);
8608 enum rtx_code rc = GET_CODE (operands[1]);
e2348bcb 8609
2df9477b 8610 tmp1 = gen_rtx_REG (mode, CC_REGNUM);
080c0b9a 8611
2df9477b 8612 operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, tmp1, const0_rtx);
8613 if (mode == CCFPmode || mode == CCFPEmode)
8614 rc = reverse_condition_maybe_unordered (rc);
8615 else
8616 rc = reverse_condition (rc);
8617 operands[4] = gen_rtx_fmt_ee (rc, VOIDmode, tmp1, const0_rtx);
1b7da4ac 8618}
8619 [(set_attr "type" "multiple")]
8620)
9c08d1fa 8621
080c0b9a 8622;; Attempt to improve the sequence generated by the compare_scc splitters
8623;; not to use conditional execution.
98562479 8624
8625;; Rd = (eq (reg1) (const_int0)) // ARMv5
8626;; clz Rd, reg1
8627;; lsr Rd, Rd, #5
080c0b9a 8628(define_peephole2
8629 [(set (reg:CC CC_REGNUM)
8630 (compare:CC (match_operand:SI 1 "register_operand" "")
98562479 8631 (const_int 0)))
8632 (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
8633 (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
8634 (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
8635 (set (match_dup 0) (const_int 1)))]
8636 "arm_arch5 && TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)"
8637 [(set (match_dup 0) (clz:SI (match_dup 1)))
8638 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 5)))]
8639)
8640
8641;; Rd = (eq (reg1) (const_int0)) // !ARMv5
8642;; negs Rd, reg1
8643;; adc Rd, Rd, reg1
8644(define_peephole2
8645 [(set (reg:CC CC_REGNUM)
8646 (compare:CC (match_operand:SI 1 "register_operand" "")
8647 (const_int 0)))
080c0b9a 8648 (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
8649 (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
8650 (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
8651 (set (match_dup 0) (const_int 1)))
98562479 8652 (match_scratch:SI 2 "r")]
8653 "TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)"
922b6913 8654 [(parallel
8655 [(set (reg:CC CC_REGNUM)
98562479 8656 (compare:CC (const_int 0) (match_dup 1)))
8657 (set (match_dup 2) (minus:SI (const_int 0) (match_dup 1)))])
8658 (set (match_dup 0)
8659 (plus:SI (plus:SI (match_dup 1) (match_dup 2))
8660 (geu:SI (reg:CC CC_REGNUM) (const_int 0))))]
8661)
8662
31991287 8663;; Rd = (eq (reg1) (reg2/imm)) // ARMv5 and optimising for speed.
98562479 8664;; sub Rd, Reg1, reg2
8665;; clz Rd, Rd
8666;; lsr Rd, Rd, #5
8667(define_peephole2
8668 [(set (reg:CC CC_REGNUM)
8669 (compare:CC (match_operand:SI 1 "register_operand" "")
8670 (match_operand:SI 2 "arm_rhs_operand" "")))
8671 (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
8672 (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
8673 (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
8674 (set (match_dup 0) (const_int 1)))]
31991287 8675 "arm_arch5 && TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)
8676 && !(TARGET_THUMB2 && optimize_insn_for_size_p ())"
98562479 8677 [(set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))
8678 (set (match_dup 0) (clz:SI (match_dup 0)))
8679 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 5)))]
8680)
8681
8682
31991287 8683;; Rd = (eq (reg1) (reg2)) // ! ARMv5 or optimising for size.
98562479 8684;; sub T1, Reg1, reg2
8685;; negs Rd, T1
8686;; adc Rd, Rd, T1
8687(define_peephole2
8688 [(set (reg:CC CC_REGNUM)
8689 (compare:CC (match_operand:SI 1 "register_operand" "")
8690 (match_operand:SI 2 "arm_rhs_operand" "")))
8691 (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
8692 (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
8693 (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
8694 (set (match_dup 0) (const_int 1)))
8695 (match_scratch:SI 3 "r")]
8696 "TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)"
31991287 8697 [(set (match_dup 3) (match_dup 4))
080c0b9a 8698 (parallel
8699 [(set (reg:CC CC_REGNUM)
8700 (compare:CC (const_int 0) (match_dup 3)))
8701 (set (match_dup 0) (minus:SI (const_int 0) (match_dup 3)))])
98562479 8702 (set (match_dup 0)
8703 (plus:SI (plus:SI (match_dup 0) (match_dup 3))
8704 (geu:SI (reg:CC CC_REGNUM) (const_int 0))))]
31991287 8705 "
8706 if (CONST_INT_P (operands[2]))
8707 operands[4] = plus_constant (SImode, operands[1], -INTVAL (operands[2]));
8708 else
8709 operands[4] = gen_rtx_MINUS (SImode, operands[1], operands[2]);
8710 ")
080c0b9a 8711
f7fbdd4a 8712(define_insn "*cond_move"
9c08d1fa 8713 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
aea4c774 8714 (if_then_else:SI (match_operator 3 "equality_operator"
8fa3ba89 8715 [(match_operator 4 "arm_comparison_operator"
8a18b90c 8716 [(match_operand 5 "cc_register" "") (const_int 0)])
aea4c774 8717 (const_int 0)])
8718 (match_operand:SI 1 "arm_rhs_operand" "0,rI,?rI")
8719 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))]
cffb2a26 8720 "TARGET_ARM"
9c08d1fa 8721 "*
8fa3ba89 8722 if (GET_CODE (operands[3]) == NE)
8723 {
8724 if (which_alternative != 1)
8725 output_asm_insn (\"mov%D4\\t%0, %2\", operands);
8726 if (which_alternative != 0)
8727 output_asm_insn (\"mov%d4\\t%0, %1\", operands);
8728 return \"\";
8729 }
8730 if (which_alternative != 0)
8731 output_asm_insn (\"mov%D4\\t%0, %1\", operands);
8732 if (which_alternative != 1)
8733 output_asm_insn (\"mov%d4\\t%0, %2\", operands);
8734 return \"\";
8735 "
8736 [(set_attr "conds" "use")
282b4c75 8737 (set_attr_alternative "type"
8738 [(if_then_else (match_operand 2 "const_int_operand" "")
8739 (const_string "mov_imm")
8740 (const_string "mov_reg"))
8741 (if_then_else (match_operand 1 "const_int_operand" "")
8742 (const_string "mov_imm")
8743 (const_string "mov_reg"))
8744 (const_string "multiple")])
8fa3ba89 8745 (set_attr "length" "4,4,8")]
8746)
9c08d1fa 8747
f7fbdd4a 8748(define_insn "*cond_arith"
9c08d1fa 8749 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8750 (match_operator:SI 5 "shiftable_operator"
8fa3ba89 8751 [(match_operator:SI 4 "arm_comparison_operator"
9c08d1fa 8752 [(match_operand:SI 2 "s_register_operand" "r,r")
8753 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
8754 (match_operand:SI 1 "s_register_operand" "0,?r")]))
bd5b4116 8755 (clobber (reg:CC CC_REGNUM))]
cffb2a26 8756 "TARGET_ARM"
9c08d1fa 8757 "*
8fa3ba89 8758 if (GET_CODE (operands[4]) == LT && operands[3] == const0_rtx)
8759 return \"%i5\\t%0, %1, %2, lsr #31\";
40dbec34 8760
8fa3ba89 8761 output_asm_insn (\"cmp\\t%2, %3\", operands);
8762 if (GET_CODE (operands[5]) == AND)
8763 output_asm_insn (\"mov%D4\\t%0, #0\", operands);
8764 else if (GET_CODE (operands[5]) == MINUS)
8765 output_asm_insn (\"rsb%D4\\t%0, %1, #0\", operands);
8766 else if (which_alternative != 0)
8767 output_asm_insn (\"mov%D4\\t%0, %1\", operands);
8768 return \"%i5%d4\\t%0, %1, #1\";
8769 "
8770 [(set_attr "conds" "clob")
1b7da4ac 8771 (set_attr "length" "12")
8772 (set_attr "type" "multiple")]
8fa3ba89 8773)
9c08d1fa 8774
f7fbdd4a 8775(define_insn "*cond_sub"
9c08d1fa 8776 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8777 (minus:SI (match_operand:SI 1 "s_register_operand" "0,?r")
8fa3ba89 8778 (match_operator:SI 4 "arm_comparison_operator"
9c08d1fa 8779 [(match_operand:SI 2 "s_register_operand" "r,r")
8780 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))
bd5b4116 8781 (clobber (reg:CC CC_REGNUM))]
cffb2a26 8782 "TARGET_ARM"
9c08d1fa 8783 "*
8fa3ba89 8784 output_asm_insn (\"cmp\\t%2, %3\", operands);
8785 if (which_alternative != 0)
8786 output_asm_insn (\"mov%D4\\t%0, %1\", operands);
8787 return \"sub%d4\\t%0, %1, #1\";
8788 "
8789 [(set_attr "conds" "clob")
1b7da4ac 8790 (set_attr "length" "8,12")
8791 (set_attr "type" "multiple")]
8fa3ba89 8792)
9c08d1fa 8793
aea4c774 8794(define_insn "*cmp_ite0"
cffb2a26 8795 [(set (match_operand 6 "dominant_cc_register" "")
aea4c774 8796 (compare
8797 (if_then_else:SI
8fa3ba89 8798 (match_operator 4 "arm_comparison_operator"
2ff91fec 8799 [(match_operand:SI 0 "s_register_operand"
8800 "l,l,l,r,r,r,r,r,r")
8801 (match_operand:SI 1 "arm_add_operand"
8802 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
8fa3ba89 8803 (match_operator:SI 5 "arm_comparison_operator"
2ff91fec 8804 [(match_operand:SI 2 "s_register_operand"
8805 "l,r,r,l,l,r,r,r,r")
8806 (match_operand:SI 3 "arm_add_operand"
8807 "lPy,rI,L,lPy,lPy,rI,rI,L,L")])
aea4c774 8808 (const_int 0))
8809 (const_int 0)))]
2ff91fec 8810 "TARGET_32BIT"
9c08d1fa 8811 "*
aea4c774 8812 {
2ff91fec 8813 static const char * const cmp1[NUM_OF_COND_CMP][2] =
8814 {
8815 {\"cmp%d5\\t%0, %1\",
8816 \"cmp%d4\\t%2, %3\"},
8817 {\"cmn%d5\\t%0, #%n1\",
8818 \"cmp%d4\\t%2, %3\"},
8819 {\"cmp%d5\\t%0, %1\",
8820 \"cmn%d4\\t%2, #%n3\"},
8821 {\"cmn%d5\\t%0, #%n1\",
8822 \"cmn%d4\\t%2, #%n3\"}
8823 };
8824 static const char * const cmp2[NUM_OF_COND_CMP][2] =
8825 {
8826 {\"cmp\\t%2, %3\",
8827 \"cmp\\t%0, %1\"},
8828 {\"cmp\\t%2, %3\",
8829 \"cmn\\t%0, #%n1\"},
8830 {\"cmn\\t%2, #%n3\",
8831 \"cmp\\t%0, %1\"},
8832 {\"cmn\\t%2, #%n3\",
8833 \"cmn\\t%0, #%n1\"}
8834 };
8835 static const char * const ite[2] =
8fa3ba89 8836 {
2ff91fec 8837 \"it\\t%d5\",
8838 \"it\\t%d4\"
8fa3ba89 8839 };
2ff91fec 8840 static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
8841 CMP_CMP, CMN_CMP, CMP_CMP,
8842 CMN_CMP, CMP_CMN, CMN_CMN};
8fa3ba89 8843 int swap =
8844 comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4]));
8845
2ff91fec 8846 output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
8847 if (TARGET_THUMB2) {
8848 output_asm_insn (ite[swap], operands);
8849 }
8850 output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
8851 return \"\";
8fa3ba89 8852 }"
8853 [(set_attr "conds" "set")
2ff91fec 8854 (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
1b7da4ac 8855 (set_attr "type" "multiple")
2ff91fec 8856 (set_attr_alternative "length"
8857 [(const_int 6)
8858 (const_int 8)
8859 (const_int 8)
8860 (const_int 8)
8861 (const_int 8)
8862 (if_then_else (eq_attr "is_thumb" "no")
8863 (const_int 8)
8864 (const_int 10))
8865 (if_then_else (eq_attr "is_thumb" "no")
8866 (const_int 8)
8867 (const_int 10))
8868 (if_then_else (eq_attr "is_thumb" "no")
8869 (const_int 8)
8870 (const_int 10))
8871 (if_then_else (eq_attr "is_thumb" "no")
8872 (const_int 8)
8873 (const_int 10))])]
8fa3ba89 8874)
9c08d1fa 8875
aea4c774 8876(define_insn "*cmp_ite1"
cffb2a26 8877 [(set (match_operand 6 "dominant_cc_register" "")
aea4c774 8878 (compare
8879 (if_then_else:SI
8fa3ba89 8880 (match_operator 4 "arm_comparison_operator"
2ff91fec 8881 [(match_operand:SI 0 "s_register_operand"
8882 "l,l,l,r,r,r,r,r,r")
8883 (match_operand:SI 1 "arm_add_operand"
8884 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
8fa3ba89 8885 (match_operator:SI 5 "arm_comparison_operator"
2ff91fec 8886 [(match_operand:SI 2 "s_register_operand"
8887 "l,r,r,l,l,r,r,r,r")
8888 (match_operand:SI 3 "arm_add_operand"
8889 "lPy,rI,L,lPy,lPy,rI,rI,L,L")])
aea4c774 8890 (const_int 1))
8891 (const_int 0)))]
2ff91fec 8892 "TARGET_32BIT"
9c08d1fa 8893 "*
9c08d1fa 8894 {
2ff91fec 8895 static const char * const cmp1[NUM_OF_COND_CMP][2] =
8896 {
8897 {\"cmp\\t%0, %1\",
8898 \"cmp\\t%2, %3\"},
8899 {\"cmn\\t%0, #%n1\",
8900 \"cmp\\t%2, %3\"},
8901 {\"cmp\\t%0, %1\",
8902 \"cmn\\t%2, #%n3\"},
8903 {\"cmn\\t%0, #%n1\",
8904 \"cmn\\t%2, #%n3\"}
8905 };
8906 static const char * const cmp2[NUM_OF_COND_CMP][2] =
215b30b3 8907 {
2ff91fec 8908 {\"cmp%d4\\t%2, %3\",
8909 \"cmp%D5\\t%0, %1\"},
8910 {\"cmp%d4\\t%2, %3\",
8911 \"cmn%D5\\t%0, #%n1\"},
8912 {\"cmn%d4\\t%2, #%n3\",
8913 \"cmp%D5\\t%0, %1\"},
8914 {\"cmn%d4\\t%2, #%n3\",
8915 \"cmn%D5\\t%0, #%n1\"}
215b30b3 8916 };
2ff91fec 8917 static const char * const ite[2] =
8918 {
8919 \"it\\t%d4\",
8920 \"it\\t%D5\"
8921 };
8922 static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
8923 CMP_CMP, CMN_CMP, CMP_CMP,
8924 CMN_CMP, CMP_CMN, CMN_CMN};
215b30b3 8925 int swap =
8926 comparison_dominates_p (GET_CODE (operands[5]),
8927 reverse_condition (GET_CODE (operands[4])));
8928
2ff91fec 8929 output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
8930 if (TARGET_THUMB2) {
8931 output_asm_insn (ite[swap], operands);
8932 }
8933 output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
8934 return \"\";
215b30b3 8935 }"
8fa3ba89 8936 [(set_attr "conds" "set")
2ff91fec 8937 (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
8938 (set_attr_alternative "length"
8939 [(const_int 6)
8940 (const_int 8)
8941 (const_int 8)
8942 (const_int 8)
8943 (const_int 8)
8944 (if_then_else (eq_attr "is_thumb" "no")
8945 (const_int 8)
8946 (const_int 10))
8947 (if_then_else (eq_attr "is_thumb" "no")
8948 (const_int 8)
8949 (const_int 10))
8950 (if_then_else (eq_attr "is_thumb" "no")
8951 (const_int 8)
8952 (const_int 10))
8953 (if_then_else (eq_attr "is_thumb" "no")
8954 (const_int 8)
1b7da4ac 8955 (const_int 10))])
8956 (set_attr "type" "multiple")]
8fa3ba89 8957)
9c08d1fa 8958
f6c53574 8959(define_insn "*cmp_and"
8960 [(set (match_operand 6 "dominant_cc_register" "")
8961 (compare
8962 (and:SI
8963 (match_operator 4 "arm_comparison_operator"
2ff91fec 8964 [(match_operand:SI 0 "s_register_operand"
8965 "l,l,l,r,r,r,r,r,r")
8966 (match_operand:SI 1 "arm_add_operand"
8967 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
f6c53574 8968 (match_operator:SI 5 "arm_comparison_operator"
2ff91fec 8969 [(match_operand:SI 2 "s_register_operand"
8970 "l,r,r,l,l,r,r,r,r")
8971 (match_operand:SI 3 "arm_add_operand"
8972 "lPy,rI,L,lPy,lPy,rI,rI,L,L")]))
f6c53574 8973 (const_int 0)))]
2ff91fec 8974 "TARGET_32BIT"
f6c53574 8975 "*
8976 {
2ff91fec 8977 static const char *const cmp1[NUM_OF_COND_CMP][2] =
f6c53574 8978 {
2ff91fec 8979 {\"cmp%d5\\t%0, %1\",
8980 \"cmp%d4\\t%2, %3\"},
8981 {\"cmn%d5\\t%0, #%n1\",
8982 \"cmp%d4\\t%2, %3\"},
8983 {\"cmp%d5\\t%0, %1\",
8984 \"cmn%d4\\t%2, #%n3\"},
8985 {\"cmn%d5\\t%0, #%n1\",
8986 \"cmn%d4\\t%2, #%n3\"}
f6c53574 8987 };
2ff91fec 8988 static const char *const cmp2[NUM_OF_COND_CMP][2] =
8989 {
8990 {\"cmp\\t%2, %3\",
8991 \"cmp\\t%0, %1\"},
8992 {\"cmp\\t%2, %3\",
8993 \"cmn\\t%0, #%n1\"},
8994 {\"cmn\\t%2, #%n3\",
8995 \"cmp\\t%0, %1\"},
8996 {\"cmn\\t%2, #%n3\",
8997 \"cmn\\t%0, #%n1\"}
8998 };
8999 static const char *const ite[2] =
9000 {
9001 \"it\\t%d5\",
9002 \"it\\t%d4\"
9003 };
9004 static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
9005 CMP_CMP, CMN_CMP, CMP_CMP,
9006 CMN_CMP, CMP_CMN, CMN_CMN};
f6c53574 9007 int swap =
9008 comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4]));
9009
2ff91fec 9010 output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
9011 if (TARGET_THUMB2) {
9012 output_asm_insn (ite[swap], operands);
9013 }
9014 output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
9015 return \"\";
f6c53574 9016 }"
9017 [(set_attr "conds" "set")
9018 (set_attr "predicable" "no")
2ff91fec 9019 (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
9020 (set_attr_alternative "length"
9021 [(const_int 6)
9022 (const_int 8)
9023 (const_int 8)
9024 (const_int 8)
9025 (const_int 8)
9026 (if_then_else (eq_attr "is_thumb" "no")
9027 (const_int 8)
9028 (const_int 10))
9029 (if_then_else (eq_attr "is_thumb" "no")
9030 (const_int 8)
9031 (const_int 10))
9032 (if_then_else (eq_attr "is_thumb" "no")
9033 (const_int 8)
9034 (const_int 10))
9035 (if_then_else (eq_attr "is_thumb" "no")
9036 (const_int 8)
1b7da4ac 9037 (const_int 10))])
9038 (set_attr "type" "multiple")]
f6c53574 9039)
9040
9041(define_insn "*cmp_ior"
9042 [(set (match_operand 6 "dominant_cc_register" "")
9043 (compare
9044 (ior:SI
9045 (match_operator 4 "arm_comparison_operator"
2ff91fec 9046 [(match_operand:SI 0 "s_register_operand"
9047 "l,l,l,r,r,r,r,r,r")
9048 (match_operand:SI 1 "arm_add_operand"
9049 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
f6c53574 9050 (match_operator:SI 5 "arm_comparison_operator"
2ff91fec 9051 [(match_operand:SI 2 "s_register_operand"
9052 "l,r,r,l,l,r,r,r,r")
9053 (match_operand:SI 3 "arm_add_operand"
9054 "lPy,rI,L,lPy,lPy,rI,rI,L,L")]))
f6c53574 9055 (const_int 0)))]
2ff91fec 9056 "TARGET_32BIT"
f6c53574 9057 "*
f6c53574 9058 {
2ff91fec 9059 static const char *const cmp1[NUM_OF_COND_CMP][2] =
9060 {
9061 {\"cmp\\t%0, %1\",
9062 \"cmp\\t%2, %3\"},
9063 {\"cmn\\t%0, #%n1\",
9064 \"cmp\\t%2, %3\"},
9065 {\"cmp\\t%0, %1\",
9066 \"cmn\\t%2, #%n3\"},
9067 {\"cmn\\t%0, #%n1\",
9068 \"cmn\\t%2, #%n3\"}
9069 };
9070 static const char *const cmp2[NUM_OF_COND_CMP][2] =
9071 {
9072 {\"cmp%D4\\t%2, %3\",
9073 \"cmp%D5\\t%0, %1\"},
9074 {\"cmp%D4\\t%2, %3\",
9075 \"cmn%D5\\t%0, #%n1\"},
9076 {\"cmn%D4\\t%2, #%n3\",
9077 \"cmp%D5\\t%0, %1\"},
9078 {\"cmn%D4\\t%2, #%n3\",
9079 \"cmn%D5\\t%0, #%n1\"}
9080 };
9081 static const char *const ite[2] =
9082 {
9083 \"it\\t%D4\",
9084 \"it\\t%D5\"
9085 };
9086 static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
9087 CMP_CMP, CMN_CMP, CMP_CMP,
9088 CMN_CMP, CMP_CMN, CMN_CMN};
9089 int swap =
9090 comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4]));
9091
9092 output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
9093 if (TARGET_THUMB2) {
9094 output_asm_insn (ite[swap], operands);
9095 }
9096 output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
9097 return \"\";
9098 }
9099 "
f6c53574 9100 [(set_attr "conds" "set")
2ff91fec 9101 (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
9102 (set_attr_alternative "length"
9103 [(const_int 6)
9104 (const_int 8)
9105 (const_int 8)
9106 (const_int 8)
9107 (const_int 8)
9108 (if_then_else (eq_attr "is_thumb" "no")
9109 (const_int 8)
9110 (const_int 10))
9111 (if_then_else (eq_attr "is_thumb" "no")
9112 (const_int 8)
9113 (const_int 10))
9114 (if_then_else (eq_attr "is_thumb" "no")
9115 (const_int 8)
9116 (const_int 10))
9117 (if_then_else (eq_attr "is_thumb" "no")
9118 (const_int 8)
1b7da4ac 9119 (const_int 10))])
9120 (set_attr "type" "multiple")]
f6c53574 9121)
9122
3c5afce6 9123(define_insn_and_split "*ior_scc_scc"
fd711051 9124 [(set (match_operand:SI 0 "s_register_operand" "=Ts")
3c5afce6 9125 (ior:SI (match_operator:SI 3 "arm_comparison_operator"
9126 [(match_operand:SI 1 "s_register_operand" "r")
9127 (match_operand:SI 2 "arm_add_operand" "rIL")])
9128 (match_operator:SI 6 "arm_comparison_operator"
9129 [(match_operand:SI 4 "s_register_operand" "r")
9130 (match_operand:SI 5 "arm_add_operand" "rIL")])))
9131 (clobber (reg:CC CC_REGNUM))]
2ff91fec 9132 "TARGET_32BIT
3c5afce6 9133 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_OR_Y)
9134 != CCmode)"
9135 "#"
2ff91fec 9136 "TARGET_32BIT && reload_completed"
3c5afce6 9137 [(set (match_dup 7)
9138 (compare
9139 (ior:SI
9140 (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9141 (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9142 (const_int 0)))
9143 (set (match_dup 0) (ne:SI (match_dup 7) (const_int 0)))]
9144 "operands[7]
9145 = gen_rtx_REG (arm_select_dominance_cc_mode (operands[3], operands[6],
9146 DOM_CC_X_OR_Y),
601f584c 9147 CC_REGNUM);"
9148 [(set_attr "conds" "clob")
1b7da4ac 9149 (set_attr "length" "16")
9150 (set_attr "type" "multiple")]
9151)
601f584c 9152
9153; If the above pattern is followed by a CMP insn, then the compare is
9154; redundant, since we can rework the conditional instruction that follows.
9155(define_insn_and_split "*ior_scc_scc_cmp"
9156 [(set (match_operand 0 "dominant_cc_register" "")
9157 (compare (ior:SI (match_operator:SI 3 "arm_comparison_operator"
9158 [(match_operand:SI 1 "s_register_operand" "r")
9159 (match_operand:SI 2 "arm_add_operand" "rIL")])
9160 (match_operator:SI 6 "arm_comparison_operator"
9161 [(match_operand:SI 4 "s_register_operand" "r")
9162 (match_operand:SI 5 "arm_add_operand" "rIL")]))
9163 (const_int 0)))
fd711051 9164 (set (match_operand:SI 7 "s_register_operand" "=Ts")
601f584c 9165 (ior:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9166 (match_op_dup 6 [(match_dup 4) (match_dup 5)])))]
2ff91fec 9167 "TARGET_32BIT"
601f584c 9168 "#"
2ff91fec 9169 "TARGET_32BIT && reload_completed"
601f584c 9170 [(set (match_dup 0)
9171 (compare
9172 (ior:SI
9173 (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9174 (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9175 (const_int 0)))
9176 (set (match_dup 7) (ne:SI (match_dup 0) (const_int 0)))]
9177 ""
9178 [(set_attr "conds" "set")
1b7da4ac 9179 (set_attr "length" "16")
9180 (set_attr "type" "multiple")]
9181)
3c5afce6 9182
9183(define_insn_and_split "*and_scc_scc"
fd711051 9184 [(set (match_operand:SI 0 "s_register_operand" "=Ts")
3c5afce6 9185 (and:SI (match_operator:SI 3 "arm_comparison_operator"
9186 [(match_operand:SI 1 "s_register_operand" "r")
9187 (match_operand:SI 2 "arm_add_operand" "rIL")])
9188 (match_operator:SI 6 "arm_comparison_operator"
9189 [(match_operand:SI 4 "s_register_operand" "r")
9190 (match_operand:SI 5 "arm_add_operand" "rIL")])))
9191 (clobber (reg:CC CC_REGNUM))]
2ff91fec 9192 "TARGET_32BIT
3c5afce6 9193 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y)
9194 != CCmode)"
9195 "#"
2ff91fec 9196 "TARGET_32BIT && reload_completed
601f584c 9197 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y)
9198 != CCmode)"
3c5afce6 9199 [(set (match_dup 7)
9200 (compare
9201 (and:SI
9202 (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9203 (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9204 (const_int 0)))
9205 (set (match_dup 0) (ne:SI (match_dup 7) (const_int 0)))]
9206 "operands[7]
9207 = gen_rtx_REG (arm_select_dominance_cc_mode (operands[3], operands[6],
9208 DOM_CC_X_AND_Y),
601f584c 9209 CC_REGNUM);"
9210 [(set_attr "conds" "clob")
1b7da4ac 9211 (set_attr "length" "16")
9212 (set_attr "type" "multiple")]
9213)
601f584c 9214
9215; If the above pattern is followed by a CMP insn, then the compare is
9216; redundant, since we can rework the conditional instruction that follows.
9217(define_insn_and_split "*and_scc_scc_cmp"
9218 [(set (match_operand 0 "dominant_cc_register" "")
9219 (compare (and:SI (match_operator:SI 3 "arm_comparison_operator"
9220 [(match_operand:SI 1 "s_register_operand" "r")
9221 (match_operand:SI 2 "arm_add_operand" "rIL")])
9222 (match_operator:SI 6 "arm_comparison_operator"
9223 [(match_operand:SI 4 "s_register_operand" "r")
9224 (match_operand:SI 5 "arm_add_operand" "rIL")]))
9225 (const_int 0)))
fd711051 9226 (set (match_operand:SI 7 "s_register_operand" "=Ts")
601f584c 9227 (and:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9228 (match_op_dup 6 [(match_dup 4) (match_dup 5)])))]
2ff91fec 9229 "TARGET_32BIT"
601f584c 9230 "#"
2ff91fec 9231 "TARGET_32BIT && reload_completed"
601f584c 9232 [(set (match_dup 0)
9233 (compare
9234 (and:SI
9235 (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9236 (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9237 (const_int 0)))
9238 (set (match_dup 7) (ne:SI (match_dup 0) (const_int 0)))]
9239 ""
9240 [(set_attr "conds" "set")
1b7da4ac 9241 (set_attr "length" "16")
9242 (set_attr "type" "multiple")]
9243)
601f584c 9244
9245;; If there is no dominance in the comparison, then we can still save an
9246;; instruction in the AND case, since we can know that the second compare
9247;; need only zero the value if false (if true, then the value is already
9248;; correct).
9249(define_insn_and_split "*and_scc_scc_nodom"
fd711051 9250 [(set (match_operand:SI 0 "s_register_operand" "=&Ts,&Ts,&Ts")
601f584c 9251 (and:SI (match_operator:SI 3 "arm_comparison_operator"
9252 [(match_operand:SI 1 "s_register_operand" "r,r,0")
9253 (match_operand:SI 2 "arm_add_operand" "rIL,0,rIL")])
9254 (match_operator:SI 6 "arm_comparison_operator"
9255 [(match_operand:SI 4 "s_register_operand" "r,r,r")
9256 (match_operand:SI 5 "arm_add_operand" "rIL,rIL,rIL")])))
9257 (clobber (reg:CC CC_REGNUM))]
2ff91fec 9258 "TARGET_32BIT
601f584c 9259 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y)
9260 == CCmode)"
9261 "#"
2ff91fec 9262 "TARGET_32BIT && reload_completed"
601f584c 9263 [(parallel [(set (match_dup 0)
9264 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
9265 (clobber (reg:CC CC_REGNUM))])
9266 (set (match_dup 7) (match_op_dup 8 [(match_dup 4) (match_dup 5)]))
9267 (set (match_dup 0)
9268 (if_then_else:SI (match_op_dup 6 [(match_dup 7) (const_int 0)])
9269 (match_dup 0)
9270 (const_int 0)))]
9271 "operands[7] = gen_rtx_REG (SELECT_CC_MODE (GET_CODE (operands[6]),
9272 operands[4], operands[5]),
9273 CC_REGNUM);
9274 operands[8] = gen_rtx_COMPARE (GET_MODE (operands[7]), operands[4],
9275 operands[5]);"
9276 [(set_attr "conds" "clob")
1b7da4ac 9277 (set_attr "length" "20")
9278 (set_attr "type" "multiple")]
9279)
3c5afce6 9280
3a0bdee0 9281(define_split
9282 [(set (reg:CC_NOOV CC_REGNUM)
9283 (compare:CC_NOOV (ior:SI
9284 (and:SI (match_operand:SI 0 "s_register_operand" "")
9285 (const_int 1))
b0694be0 9286 (match_operator:SI 1 "arm_comparison_operator"
3a0bdee0 9287 [(match_operand:SI 2 "s_register_operand" "")
9288 (match_operand:SI 3 "arm_add_operand" "")]))
9289 (const_int 0)))
9290 (clobber (match_operand:SI 4 "s_register_operand" ""))]
9291 "TARGET_ARM"
9292 [(set (match_dup 4)
9293 (ior:SI (match_op_dup 1 [(match_dup 2) (match_dup 3)])
9294 (match_dup 0)))
9295 (set (reg:CC_NOOV CC_REGNUM)
9296 (compare:CC_NOOV (and:SI (match_dup 4) (const_int 1))
9297 (const_int 0)))]
9298 "")
9299
9300(define_split
9301 [(set (reg:CC_NOOV CC_REGNUM)
9302 (compare:CC_NOOV (ior:SI
b0694be0 9303 (match_operator:SI 1 "arm_comparison_operator"
3a0bdee0 9304 [(match_operand:SI 2 "s_register_operand" "")
9305 (match_operand:SI 3 "arm_add_operand" "")])
9306 (and:SI (match_operand:SI 0 "s_register_operand" "")
9307 (const_int 1)))
9308 (const_int 0)))
9309 (clobber (match_operand:SI 4 "s_register_operand" ""))]
9310 "TARGET_ARM"
9311 [(set (match_dup 4)
9312 (ior:SI (match_op_dup 1 [(match_dup 2) (match_dup 3)])
9313 (match_dup 0)))
9314 (set (reg:CC_NOOV CC_REGNUM)
9315 (compare:CC_NOOV (and:SI (match_dup 4) (const_int 1))
9316 (const_int 0)))]
9317 "")
25f905c2 9318;; ??? The conditional patterns above need checking for Thumb-2 usefulness
3a0bdee0 9319
190efb17 9320(define_insn_and_split "*negscc"
9c08d1fa 9321 [(set (match_operand:SI 0 "s_register_operand" "=r")
8fa3ba89 9322 (neg:SI (match_operator 3 "arm_comparison_operator"
9c08d1fa 9323 [(match_operand:SI 1 "s_register_operand" "r")
9324 (match_operand:SI 2 "arm_rhs_operand" "rI")])))
bd5b4116 9325 (clobber (reg:CC CC_REGNUM))]
cffb2a26 9326 "TARGET_ARM"
190efb17 9327 "#"
9328 "&& reload_completed"
9329 [(const_int 0)]
9330 {
9331 rtx cc_reg = gen_rtx_REG (CCmode, CC_REGNUM);
e2348bcb 9332
190efb17 9333 if (GET_CODE (operands[3]) == LT && operands[2] == const0_rtx)
9334 {
9335 /* Emit mov\\t%0, %1, asr #31 */
d1f9b275 9336 emit_insn (gen_rtx_SET (operands[0],
190efb17 9337 gen_rtx_ASHIFTRT (SImode,
9338 operands[1],
9339 GEN_INT (31))));
9340 DONE;
9341 }
9342 else if (GET_CODE (operands[3]) == NE)
9343 {
9344 /* Emit subs\\t%0, %1, %2\;mvnne\\t%0, #0 */
9345 if (CONST_INT_P (operands[2]))
9346 emit_insn (gen_cmpsi2_addneg (operands[0], operands[1], operands[2],
9347 GEN_INT (- INTVAL (operands[2]))));
9348 else
9349 emit_insn (gen_subsi3_compare (operands[0], operands[1], operands[2]));
9350
9351 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
9352 gen_rtx_NE (SImode,
9353 cc_reg,
9354 const0_rtx),
d1f9b275 9355 gen_rtx_SET (operands[0],
190efb17 9356 GEN_INT (~0))));
9357 DONE;
9358 }
9359 else
9360 {
9361 /* Emit: cmp\\t%1, %2\;mov%D3\\t%0, #0\;mvn%d3\\t%0, #0 */
d1f9b275 9362 emit_insn (gen_rtx_SET (cc_reg,
190efb17 9363 gen_rtx_COMPARE (CCmode, operands[1], operands[2])));
9364 enum rtx_code rc = GET_CODE (operands[3]);
9365
9366 rc = reverse_condition (rc);
9367 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
9368 gen_rtx_fmt_ee (rc,
9369 VOIDmode,
9370 cc_reg,
9371 const0_rtx),
d1f9b275 9372 gen_rtx_SET (operands[0], const0_rtx)));
190efb17 9373 rc = GET_CODE (operands[3]);
9374 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
9375 gen_rtx_fmt_ee (rc,
9376 VOIDmode,
9377 cc_reg,
9378 const0_rtx),
d1f9b275 9379 gen_rtx_SET (operands[0],
190efb17 9380 GEN_INT (~0))));
9381 DONE;
9382 }
9383 FAIL;
9384 }
8fa3ba89 9385 [(set_attr "conds" "clob")
1b7da4ac 9386 (set_attr "length" "12")
9387 (set_attr "type" "multiple")]
8fa3ba89 9388)
9c08d1fa 9389
90404b57 9390(define_insn_and_split "movcond_addsi"
9391 [(set (match_operand:SI 0 "s_register_operand" "=r,l,r")
9392 (if_then_else:SI
9393 (match_operator 5 "comparison_operator"
9394 [(plus:SI (match_operand:SI 3 "s_register_operand" "r,r,r")
9395 (match_operand:SI 4 "arm_add_operand" "rIL,rIL,rIL"))
9396 (const_int 0)])
9397 (match_operand:SI 1 "arm_rhs_operand" "rI,rPy,r")
9398 (match_operand:SI 2 "arm_rhs_operand" "rI,rPy,r")))
9399 (clobber (reg:CC CC_REGNUM))]
9400 "TARGET_32BIT"
9401 "#"
9402 "&& reload_completed"
9403 [(set (reg:CC_NOOV CC_REGNUM)
9404 (compare:CC_NOOV
9405 (plus:SI (match_dup 3)
9406 (match_dup 4))
9407 (const_int 0)))
9408 (set (match_dup 0) (match_dup 1))
9409 (cond_exec (match_dup 6)
9410 (set (match_dup 0) (match_dup 2)))]
9411 "
9412 {
3754d046 9413 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[5]),
90404b57 9414 operands[3], operands[4]);
9415 enum rtx_code rc = GET_CODE (operands[5]);
90404b57 9416 operands[6] = gen_rtx_REG (mode, CC_REGNUM);
9417 gcc_assert (!(mode == CCFPmode || mode == CCFPEmode));
22440aeb 9418 if (!REG_P (operands[2]) || REGNO (operands[2]) != REGNO (operands[0]))
4d01ce2f 9419 rc = reverse_condition (rc);
f145bcba 9420 else
9421 std::swap (operands[1], operands[2]);
90404b57 9422
9423 operands[6] = gen_rtx_fmt_ee (rc, VOIDmode, operands[6], const0_rtx);
9424 }
9425 "
9426 [(set_attr "conds" "clob")
1b7da4ac 9427 (set_attr "enabled_for_depr_it" "no,yes,yes")
9428 (set_attr "type" "multiple")]
90404b57 9429)
9430
9c08d1fa 9431(define_insn "movcond"
9432 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
5565501b 9433 (if_then_else:SI
8fa3ba89 9434 (match_operator 5 "arm_comparison_operator"
5565501b 9435 [(match_operand:SI 3 "s_register_operand" "r,r,r")
9436 (match_operand:SI 4 "arm_add_operand" "rIL,rIL,rIL")])
9437 (match_operand:SI 1 "arm_rhs_operand" "0,rI,?rI")
9438 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
bd5b4116 9439 (clobber (reg:CC CC_REGNUM))]
cffb2a26 9440 "TARGET_ARM"
9c08d1fa 9441 "*
9442 if (GET_CODE (operands[5]) == LT
9443 && (operands[4] == const0_rtx))
9444 {
0438d37f 9445 if (which_alternative != 1 && REG_P (operands[1]))
9c08d1fa 9446 {
9c08d1fa 9447 if (operands[2] == const0_rtx)
e2348bcb 9448 return \"and\\t%0, %1, %3, asr #31\";
9449 return \"ands\\t%0, %1, %3, asr #32\;movcc\\t%0, %2\";
9c08d1fa 9450 }
0438d37f 9451 else if (which_alternative != 0 && REG_P (operands[2]))
9c08d1fa 9452 {
9c08d1fa 9453 if (operands[1] == const0_rtx)
e2348bcb 9454 return \"bic\\t%0, %2, %3, asr #31\";
9455 return \"bics\\t%0, %2, %3, asr #32\;movcs\\t%0, %1\";
9c08d1fa 9456 }
9457 /* The only case that falls through to here is when both ops 1 & 2
674a8f0b 9458 are constants. */
9c08d1fa 9459 }
e2348bcb 9460
9c08d1fa 9461 if (GET_CODE (operands[5]) == GE
9462 && (operands[4] == const0_rtx))
9463 {
0438d37f 9464 if (which_alternative != 1 && REG_P (operands[1]))
9c08d1fa 9465 {
9c08d1fa 9466 if (operands[2] == const0_rtx)
e2348bcb 9467 return \"bic\\t%0, %1, %3, asr #31\";
9468 return \"bics\\t%0, %1, %3, asr #32\;movcs\\t%0, %2\";
9c08d1fa 9469 }
0438d37f 9470 else if (which_alternative != 0 && REG_P (operands[2]))
9c08d1fa 9471 {
9c08d1fa 9472 if (operands[1] == const0_rtx)
e2348bcb 9473 return \"and\\t%0, %2, %3, asr #31\";
9474 return \"ands\\t%0, %2, %3, asr #32\;movcc\\t%0, %1\";
9c08d1fa 9475 }
9476 /* The only case that falls through to here is when both ops 1 & 2
674a8f0b 9477 are constants. */
9c08d1fa 9478 }
0438d37f 9479 if (CONST_INT_P (operands[4])
9c08d1fa 9480 && !const_ok_for_arm (INTVAL (operands[4])))
e2348bcb 9481 output_asm_insn (\"cmn\\t%3, #%n4\", operands);
9c08d1fa 9482 else
e2348bcb 9483 output_asm_insn (\"cmp\\t%3, %4\", operands);
9c08d1fa 9484 if (which_alternative != 0)
e2348bcb 9485 output_asm_insn (\"mov%d5\\t%0, %1\", operands);
9c08d1fa 9486 if (which_alternative != 1)
e2348bcb 9487 output_asm_insn (\"mov%D5\\t%0, %2\", operands);
9c08d1fa 9488 return \"\";
215b30b3 9489 "
8fa3ba89 9490 [(set_attr "conds" "clob")
1b7da4ac 9491 (set_attr "length" "8,8,12")
9492 (set_attr "type" "multiple")]
8fa3ba89 9493)
9c08d1fa 9494
25f905c2 9495;; ??? The patterns below need checking for Thumb-2 usefulness.
9496
8a18b90c 9497(define_insn "*ifcompare_plus_move"
9498 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8fa3ba89 9499 (if_then_else:SI (match_operator 6 "arm_comparison_operator"
8a18b90c 9500 [(match_operand:SI 4 "s_register_operand" "r,r")
9501 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
9502 (plus:SI
9503 (match_operand:SI 2 "s_register_operand" "r,r")
9504 (match_operand:SI 3 "arm_add_operand" "rIL,rIL"))
129a2fe4 9505 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))
bd5b4116 9506 (clobber (reg:CC CC_REGNUM))]
cffb2a26 9507 "TARGET_ARM"
8a18b90c 9508 "#"
8fa3ba89 9509 [(set_attr "conds" "clob")
1b7da4ac 9510 (set_attr "length" "8,12")
9511 (set_attr "type" "multiple")]
8fa3ba89 9512)
8a18b90c 9513
9514(define_insn "*if_plus_move"
129a2fe4 9515 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r")
8a18b90c 9516 (if_then_else:SI
8fa3ba89 9517 (match_operator 4 "arm_comparison_operator"
8a18b90c 9518 [(match_operand 5 "cc_register" "") (const_int 0)])
9519 (plus:SI
129a2fe4 9520 (match_operand:SI 2 "s_register_operand" "r,r,r,r")
9521 (match_operand:SI 3 "arm_add_operand" "rI,L,rI,L"))
9522 (match_operand:SI 1 "arm_rhs_operand" "0,0,?rI,?rI")))]
cffb2a26 9523 "TARGET_ARM"
8a18b90c 9524 "@
9525 add%d4\\t%0, %2, %3
9526 sub%d4\\t%0, %2, #%n3
9527 add%d4\\t%0, %2, %3\;mov%D4\\t%0, %1
129a2fe4 9528 sub%d4\\t%0, %2, #%n3\;mov%D4\\t%0, %1"
8fa3ba89 9529 [(set_attr "conds" "use")
9530 (set_attr "length" "4,4,8,8")
65f68e55 9531 (set_attr_alternative "type"
9532 [(if_then_else (match_operand 3 "const_int_operand" "")
d82e788e 9533 (const_string "alu_imm" )
112eda6f 9534 (const_string "alu_sreg"))
d82e788e 9535 (const_string "alu_imm")
282b4c75 9536 (const_string "multiple")
9537 (const_string "multiple")])]
8fa3ba89 9538)
8a18b90c 9539
9540(define_insn "*ifcompare_move_plus"
5565501b 9541 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8fa3ba89 9542 (if_then_else:SI (match_operator 6 "arm_comparison_operator"
8a18b90c 9543 [(match_operand:SI 4 "s_register_operand" "r,r")
9544 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
129a2fe4 9545 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
8a18b90c 9546 (plus:SI
9547 (match_operand:SI 2 "s_register_operand" "r,r")
9548 (match_operand:SI 3 "arm_add_operand" "rIL,rIL"))))
bd5b4116 9549 (clobber (reg:CC CC_REGNUM))]
cffb2a26 9550 "TARGET_ARM"
8a18b90c 9551 "#"
8fa3ba89 9552 [(set_attr "conds" "clob")
1b7da4ac 9553 (set_attr "length" "8,12")
9554 (set_attr "type" "multiple")]
8fa3ba89 9555)
8a18b90c 9556
9557(define_insn "*if_move_plus"
129a2fe4 9558 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r")
8a18b90c 9559 (if_then_else:SI
8fa3ba89 9560 (match_operator 4 "arm_comparison_operator"
8a18b90c 9561 [(match_operand 5 "cc_register" "") (const_int 0)])
129a2fe4 9562 (match_operand:SI 1 "arm_rhs_operand" "0,0,?rI,?rI")
8a18b90c 9563 (plus:SI
129a2fe4 9564 (match_operand:SI 2 "s_register_operand" "r,r,r,r")
9565 (match_operand:SI 3 "arm_add_operand" "rI,L,rI,L"))))]
cffb2a26 9566 "TARGET_ARM"
8a18b90c 9567 "@
9568 add%D4\\t%0, %2, %3
9569 sub%D4\\t%0, %2, #%n3
9570 add%D4\\t%0, %2, %3\;mov%d4\\t%0, %1
129a2fe4 9571 sub%D4\\t%0, %2, #%n3\;mov%d4\\t%0, %1"
8fa3ba89 9572 [(set_attr "conds" "use")
9573 (set_attr "length" "4,4,8,8")
282b4c75 9574 (set_attr_alternative "type"
9575 [(if_then_else (match_operand 3 "const_int_operand" "")
9576 (const_string "alu_imm" )
9577 (const_string "alu_sreg"))
9578 (const_string "alu_imm")
9579 (const_string "multiple")
9580 (const_string "multiple")])]
8fa3ba89 9581)
8a18b90c 9582
9583(define_insn "*ifcompare_arith_arith"
9584 [(set (match_operand:SI 0 "s_register_operand" "=r")
8fa3ba89 9585 (if_then_else:SI (match_operator 9 "arm_comparison_operator"
8a18b90c 9586 [(match_operand:SI 5 "s_register_operand" "r")
9587 (match_operand:SI 6 "arm_add_operand" "rIL")])
9c08d1fa 9588 (match_operator:SI 8 "shiftable_operator"
8a18b90c 9589 [(match_operand:SI 1 "s_register_operand" "r")
9590 (match_operand:SI 2 "arm_rhs_operand" "rI")])
9c08d1fa 9591 (match_operator:SI 7 "shiftable_operator"
8a18b90c 9592 [(match_operand:SI 3 "s_register_operand" "r")
9593 (match_operand:SI 4 "arm_rhs_operand" "rI")])))
bd5b4116 9594 (clobber (reg:CC CC_REGNUM))]
cffb2a26 9595 "TARGET_ARM"
8a18b90c 9596 "#"
8fa3ba89 9597 [(set_attr "conds" "clob")
1b7da4ac 9598 (set_attr "length" "12")
9599 (set_attr "type" "multiple")]
8fa3ba89 9600)
9c08d1fa 9601
8a18b90c 9602(define_insn "*if_arith_arith"
9603 [(set (match_operand:SI 0 "s_register_operand" "=r")
8fa3ba89 9604 (if_then_else:SI (match_operator 5 "arm_comparison_operator"
8a18b90c 9605 [(match_operand 8 "cc_register" "") (const_int 0)])
9606 (match_operator:SI 6 "shiftable_operator"
9607 [(match_operand:SI 1 "s_register_operand" "r")
9608 (match_operand:SI 2 "arm_rhs_operand" "rI")])
9609 (match_operator:SI 7 "shiftable_operator"
9610 [(match_operand:SI 3 "s_register_operand" "r")
9611 (match_operand:SI 4 "arm_rhs_operand" "rI")])))]
cffb2a26 9612 "TARGET_ARM"
8a18b90c 9613 "%I6%d5\\t%0, %1, %2\;%I7%D5\\t%0, %3, %4"
8fa3ba89 9614 [(set_attr "conds" "use")
1b7da4ac 9615 (set_attr "length" "8")
9616 (set_attr "type" "multiple")]
8fa3ba89 9617)
8a18b90c 9618
f7fbdd4a 9619(define_insn "*ifcompare_arith_move"
9c08d1fa 9620 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8fa3ba89 9621 (if_then_else:SI (match_operator 6 "arm_comparison_operator"
9c08d1fa 9622 [(match_operand:SI 2 "s_register_operand" "r,r")
5565501b 9623 (match_operand:SI 3 "arm_add_operand" "rIL,rIL")])
9c08d1fa 9624 (match_operator:SI 7 "shiftable_operator"
9625 [(match_operand:SI 4 "s_register_operand" "r,r")
9626 (match_operand:SI 5 "arm_rhs_operand" "rI,rI")])
129a2fe4 9627 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))
bd5b4116 9628 (clobber (reg:CC CC_REGNUM))]
cffb2a26 9629 "TARGET_ARM"
9c08d1fa 9630 "*
9c08d1fa 9631 /* If we have an operation where (op x 0) is the identity operation and
01cc3b75 9632 the conditional operator is LT or GE and we are comparing against zero and
674a8f0b 9633 everything is in registers then we can do this in two instructions. */
9c08d1fa 9634 if (operands[3] == const0_rtx
9635 && GET_CODE (operands[7]) != AND
0438d37f 9636 && REG_P (operands[5])
9637 && REG_P (operands[1])
9c08d1fa 9638 && REGNO (operands[1]) == REGNO (operands[4])
9639 && REGNO (operands[4]) != REGNO (operands[0]))
9640 {
9641 if (GET_CODE (operands[6]) == LT)
40dbec34 9642 return \"and\\t%0, %5, %2, asr #31\;%I7\\t%0, %4, %0\";
9c08d1fa 9643 else if (GET_CODE (operands[6]) == GE)
40dbec34 9644 return \"bic\\t%0, %5, %2, asr #31\;%I7\\t%0, %4, %0\";
9c08d1fa 9645 }
0438d37f 9646 if (CONST_INT_P (operands[3])
9c08d1fa 9647 && !const_ok_for_arm (INTVAL (operands[3])))
e2348bcb 9648 output_asm_insn (\"cmn\\t%2, #%n3\", operands);
9c08d1fa 9649 else
e2348bcb 9650 output_asm_insn (\"cmp\\t%2, %3\", operands);
40dbec34 9651 output_asm_insn (\"%I7%d6\\t%0, %4, %5\", operands);
9c08d1fa 9652 if (which_alternative != 0)
129a2fe4 9653 return \"mov%D6\\t%0, %1\";
9c08d1fa 9654 return \"\";
215b30b3 9655 "
8fa3ba89 9656 [(set_attr "conds" "clob")
1b7da4ac 9657 (set_attr "length" "8,12")
9658 (set_attr "type" "multiple")]
8fa3ba89 9659)
9c08d1fa 9660
8a18b90c 9661(define_insn "*if_arith_move"
129a2fe4 9662 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8fa3ba89 9663 (if_then_else:SI (match_operator 4 "arm_comparison_operator"
8a18b90c 9664 [(match_operand 6 "cc_register" "") (const_int 0)])
9665 (match_operator:SI 5 "shiftable_operator"
129a2fe4 9666 [(match_operand:SI 2 "s_register_operand" "r,r")
9667 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
9668 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))]
cffb2a26 9669 "TARGET_ARM"
8a18b90c 9670 "@
9671 %I5%d4\\t%0, %2, %3
129a2fe4 9672 %I5%d4\\t%0, %2, %3\;mov%D4\\t%0, %1"
8fa3ba89 9673 [(set_attr "conds" "use")
9674 (set_attr "length" "4,8")
282b4c75 9675 (set_attr_alternative "type"
9676 [(if_then_else (match_operand 3 "const_int_operand" "")
9677 (const_string "alu_shift_imm" )
9678 (const_string "alu_shift_reg"))
9679 (const_string "multiple")])]
8fa3ba89 9680)
8a18b90c 9681
f7fbdd4a 9682(define_insn "*ifcompare_move_arith"
9c08d1fa 9683 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8fa3ba89 9684 (if_then_else:SI (match_operator 6 "arm_comparison_operator"
9c08d1fa 9685 [(match_operand:SI 4 "s_register_operand" "r,r")
5565501b 9686 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
129a2fe4 9687 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
9c08d1fa 9688 (match_operator:SI 7 "shiftable_operator"
9689 [(match_operand:SI 2 "s_register_operand" "r,r")
9690 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))
bd5b4116 9691 (clobber (reg:CC CC_REGNUM))]
cffb2a26 9692 "TARGET_ARM"
9c08d1fa 9693 "*
9c08d1fa 9694 /* If we have an operation where (op x 0) is the identity operation and
01cc3b75 9695 the conditional operator is LT or GE and we are comparing against zero and
9c08d1fa 9696 everything is in registers then we can do this in two instructions */
9697 if (operands[5] == const0_rtx
9698 && GET_CODE (operands[7]) != AND
0438d37f 9699 && REG_P (operands[3])
9700 && REG_P (operands[1])
9c08d1fa 9701 && REGNO (operands[1]) == REGNO (operands[2])
9702 && REGNO (operands[2]) != REGNO (operands[0]))
9703 {
9704 if (GET_CODE (operands[6]) == GE)
40dbec34 9705 return \"and\\t%0, %3, %4, asr #31\;%I7\\t%0, %2, %0\";
9c08d1fa 9706 else if (GET_CODE (operands[6]) == LT)
40dbec34 9707 return \"bic\\t%0, %3, %4, asr #31\;%I7\\t%0, %2, %0\";
9c08d1fa 9708 }
40dbec34 9709
0438d37f 9710 if (CONST_INT_P (operands[5])
9c08d1fa 9711 && !const_ok_for_arm (INTVAL (operands[5])))
e2348bcb 9712 output_asm_insn (\"cmn\\t%4, #%n5\", operands);
9c08d1fa 9713 else
e2348bcb 9714 output_asm_insn (\"cmp\\t%4, %5\", operands);
40dbec34 9715
9c08d1fa 9716 if (which_alternative != 0)
129a2fe4 9717 output_asm_insn (\"mov%d6\\t%0, %1\", operands);
40dbec34 9718 return \"%I7%D6\\t%0, %2, %3\";
215b30b3 9719 "
8fa3ba89 9720 [(set_attr "conds" "clob")
1b7da4ac 9721 (set_attr "length" "8,12")
9722 (set_attr "type" "multiple")]
8fa3ba89 9723)
9c08d1fa 9724
8a18b90c 9725(define_insn "*if_move_arith"
129a2fe4 9726 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8a18b90c 9727 (if_then_else:SI
8fa3ba89 9728 (match_operator 4 "arm_comparison_operator"
8a18b90c 9729 [(match_operand 6 "cc_register" "") (const_int 0)])
129a2fe4 9730 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
8a18b90c 9731 (match_operator:SI 5 "shiftable_operator"
129a2fe4 9732 [(match_operand:SI 2 "s_register_operand" "r,r")
9733 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))]
cffb2a26 9734 "TARGET_ARM"
8a18b90c 9735 "@
9736 %I5%D4\\t%0, %2, %3
129a2fe4 9737 %I5%D4\\t%0, %2, %3\;mov%d4\\t%0, %1"
8fa3ba89 9738 [(set_attr "conds" "use")
9739 (set_attr "length" "4,8")
282b4c75 9740 (set_attr_alternative "type"
9741 [(if_then_else (match_operand 3 "const_int_operand" "")
9742 (const_string "alu_shift_imm" )
9743 (const_string "alu_shift_reg"))
9744 (const_string "multiple")])]
8fa3ba89 9745)
8a18b90c 9746
9747(define_insn "*ifcompare_move_not"
9c08d1fa 9748 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8a18b90c 9749 (if_then_else:SI
8fa3ba89 9750 (match_operator 5 "arm_comparison_operator"
8a18b90c 9751 [(match_operand:SI 3 "s_register_operand" "r,r")
9752 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
9753 (match_operand:SI 1 "arm_not_operand" "0,?rIK")
9754 (not:SI
9755 (match_operand:SI 2 "s_register_operand" "r,r"))))
bd5b4116 9756 (clobber (reg:CC CC_REGNUM))]
cffb2a26 9757 "TARGET_ARM"
8a18b90c 9758 "#"
8fa3ba89 9759 [(set_attr "conds" "clob")
1b7da4ac 9760 (set_attr "length" "8,12")
9761 (set_attr "type" "multiple")]
8fa3ba89 9762)
9c08d1fa 9763
8a18b90c 9764(define_insn "*if_move_not"
9765 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9766 (if_then_else:SI
8fa3ba89 9767 (match_operator 4 "arm_comparison_operator"
8a18b90c 9768 [(match_operand 3 "cc_register" "") (const_int 0)])
9769 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")
9770 (not:SI (match_operand:SI 2 "s_register_operand" "r,r,r"))))]
cffb2a26 9771 "TARGET_ARM"
8a18b90c 9772 "@
9773 mvn%D4\\t%0, %2
9774 mov%d4\\t%0, %1\;mvn%D4\\t%0, %2
9775 mvn%d4\\t%0, #%B1\;mvn%D4\\t%0, %2"
8fa3ba89 9776 [(set_attr "conds" "use")
1aed5204 9777 (set_attr "type" "mvn_reg")
1b7da4ac 9778 (set_attr "length" "4,8,8")
9779 (set_attr "type" "mvn_reg,multiple,multiple")]
8fa3ba89 9780)
8a18b90c 9781
9782(define_insn "*ifcompare_not_move"
9c08d1fa 9783 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8a18b90c 9784 (if_then_else:SI
8fa3ba89 9785 (match_operator 5 "arm_comparison_operator"
8a18b90c 9786 [(match_operand:SI 3 "s_register_operand" "r,r")
9787 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
9788 (not:SI
9789 (match_operand:SI 2 "s_register_operand" "r,r"))
9790 (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
bd5b4116 9791 (clobber (reg:CC CC_REGNUM))]
cffb2a26 9792 "TARGET_ARM"
8a18b90c 9793 "#"
8fa3ba89 9794 [(set_attr "conds" "clob")
1b7da4ac 9795 (set_attr "length" "8,12")
9796 (set_attr "type" "multiple")]
8fa3ba89 9797)
9c08d1fa 9798
8a18b90c 9799(define_insn "*if_not_move"
9800 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9801 (if_then_else:SI
8fa3ba89 9802 (match_operator 4 "arm_comparison_operator"
8a18b90c 9803 [(match_operand 3 "cc_register" "") (const_int 0)])
9804 (not:SI (match_operand:SI 2 "s_register_operand" "r,r,r"))
9805 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")))]
cffb2a26 9806 "TARGET_ARM"
8a18b90c 9807 "@
9808 mvn%d4\\t%0, %2
9809 mov%D4\\t%0, %1\;mvn%d4\\t%0, %2
9810 mvn%D4\\t%0, #%B1\;mvn%d4\\t%0, %2"
8fa3ba89 9811 [(set_attr "conds" "use")
1b7da4ac 9812 (set_attr "type" "mvn_reg,multiple,multiple")
8fa3ba89 9813 (set_attr "length" "4,8,8")]
9814)
8a18b90c 9815
9816(define_insn "*ifcompare_shift_move"
9c08d1fa 9817 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8a18b90c 9818 (if_then_else:SI
8fa3ba89 9819 (match_operator 6 "arm_comparison_operator"
8a18b90c 9820 [(match_operand:SI 4 "s_register_operand" "r,r")
9821 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
9822 (match_operator:SI 7 "shift_operator"
9823 [(match_operand:SI 2 "s_register_operand" "r,r")
9824 (match_operand:SI 3 "arm_rhs_operand" "rM,rM")])
9825 (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
bd5b4116 9826 (clobber (reg:CC CC_REGNUM))]
cffb2a26 9827 "TARGET_ARM"
9c08d1fa 9828 "#"
8fa3ba89 9829 [(set_attr "conds" "clob")
1b7da4ac 9830 (set_attr "length" "8,12")
9831 (set_attr "type" "multiple")]
8fa3ba89 9832)
9c08d1fa 9833
8a18b90c 9834(define_insn "*if_shift_move"
9835 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9836 (if_then_else:SI
8fa3ba89 9837 (match_operator 5 "arm_comparison_operator"
8a18b90c 9838 [(match_operand 6 "cc_register" "") (const_int 0)])
9839 (match_operator:SI 4 "shift_operator"
9840 [(match_operand:SI 2 "s_register_operand" "r,r,r")
9841 (match_operand:SI 3 "arm_rhs_operand" "rM,rM,rM")])
9842 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")))]
cffb2a26 9843 "TARGET_ARM"
5565501b 9844 "@
8a18b90c 9845 mov%d5\\t%0, %2%S4
9846 mov%D5\\t%0, %1\;mov%d5\\t%0, %2%S4
9847 mvn%D5\\t%0, #%B1\;mov%d5\\t%0, %2%S4"
8fa3ba89 9848 [(set_attr "conds" "use")
331beb1a 9849 (set_attr "shift" "2")
a2cd141b 9850 (set_attr "length" "4,8,8")
282b4c75 9851 (set_attr_alternative "type"
9852 [(if_then_else (match_operand 3 "const_int_operand" "")
9853 (const_string "mov_shift" )
9854 (const_string "mov_shift_reg"))
9855 (const_string "multiple")
9856 (const_string "multiple")])]
8fa3ba89 9857)
5565501b 9858
8a18b90c 9859(define_insn "*ifcompare_move_shift"
9860 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5565501b 9861 (if_then_else:SI
8fa3ba89 9862 (match_operator 6 "arm_comparison_operator"
8a18b90c 9863 [(match_operand:SI 4 "s_register_operand" "r,r")
9864 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
9865 (match_operand:SI 1 "arm_not_operand" "0,?rIK")
5565501b 9866 (match_operator:SI 7 "shift_operator"
8a18b90c 9867 [(match_operand:SI 2 "s_register_operand" "r,r")
9868 (match_operand:SI 3 "arm_rhs_operand" "rM,rM")])))
bd5b4116 9869 (clobber (reg:CC CC_REGNUM))]
cffb2a26 9870 "TARGET_ARM"
8a18b90c 9871 "#"
8fa3ba89 9872 [(set_attr "conds" "clob")
1b7da4ac 9873 (set_attr "length" "8,12")
9874 (set_attr "type" "multiple")]
8fa3ba89 9875)
5565501b 9876
8a18b90c 9877(define_insn "*if_move_shift"
9878 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
5565501b 9879 (if_then_else:SI
8fa3ba89 9880 (match_operator 5 "arm_comparison_operator"
8a18b90c 9881 [(match_operand 6 "cc_register" "") (const_int 0)])
9882 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")
9883 (match_operator:SI 4 "shift_operator"
9884 [(match_operand:SI 2 "s_register_operand" "r,r,r")
9885 (match_operand:SI 3 "arm_rhs_operand" "rM,rM,rM")])))]
cffb2a26 9886 "TARGET_ARM"
5565501b 9887 "@
8a18b90c 9888 mov%D5\\t%0, %2%S4
9889 mov%d5\\t%0, %1\;mov%D5\\t%0, %2%S4
9890 mvn%d5\\t%0, #%B1\;mov%D5\\t%0, %2%S4"
8fa3ba89 9891 [(set_attr "conds" "use")
331beb1a 9892 (set_attr "shift" "2")
a2cd141b 9893 (set_attr "length" "4,8,8")
282b4c75 9894 (set_attr_alternative "type"
9895 [(if_then_else (match_operand 3 "const_int_operand" "")
9896 (const_string "mov_shift" )
9897 (const_string "mov_shift_reg"))
9898 (const_string "multiple")
9899 (const_string "multiple")])]
8fa3ba89 9900)
9c08d1fa 9901
f7fbdd4a 9902(define_insn "*ifcompare_shift_shift"
8a18b90c 9903 [(set (match_operand:SI 0 "s_register_operand" "=r")
5565501b 9904 (if_then_else:SI
8fa3ba89 9905 (match_operator 7 "arm_comparison_operator"
8a18b90c 9906 [(match_operand:SI 5 "s_register_operand" "r")
9907 (match_operand:SI 6 "arm_add_operand" "rIL")])
5565501b 9908 (match_operator:SI 8 "shift_operator"
8a18b90c 9909 [(match_operand:SI 1 "s_register_operand" "r")
9910 (match_operand:SI 2 "arm_rhs_operand" "rM")])
5565501b 9911 (match_operator:SI 9 "shift_operator"
8a18b90c 9912 [(match_operand:SI 3 "s_register_operand" "r")
9913 (match_operand:SI 4 "arm_rhs_operand" "rM")])))
bd5b4116 9914 (clobber (reg:CC CC_REGNUM))]
cffb2a26 9915 "TARGET_ARM"
8a18b90c 9916 "#"
8fa3ba89 9917 [(set_attr "conds" "clob")
1b7da4ac 9918 (set_attr "length" "12")
9919 (set_attr "type" "multiple")]
8fa3ba89 9920)
9c08d1fa 9921
8a18b90c 9922(define_insn "*if_shift_shift"
9923 [(set (match_operand:SI 0 "s_register_operand" "=r")
9924 (if_then_else:SI
8fa3ba89 9925 (match_operator 5 "arm_comparison_operator"
8a18b90c 9926 [(match_operand 8 "cc_register" "") (const_int 0)])
9927 (match_operator:SI 6 "shift_operator"
9928 [(match_operand:SI 1 "s_register_operand" "r")
9929 (match_operand:SI 2 "arm_rhs_operand" "rM")])
9930 (match_operator:SI 7 "shift_operator"
9931 [(match_operand:SI 3 "s_register_operand" "r")
9932 (match_operand:SI 4 "arm_rhs_operand" "rM")])))]
cffb2a26 9933 "TARGET_ARM"
8a18b90c 9934 "mov%d5\\t%0, %1%S6\;mov%D5\\t%0, %3%S7"
8fa3ba89 9935 [(set_attr "conds" "use")
331beb1a 9936 (set_attr "shift" "1")
a2cd141b 9937 (set_attr "length" "8")
9938 (set (attr "type") (if_then_else
9939 (and (match_operand 2 "const_int_operand" "")
9940 (match_operand 4 "const_int_operand" ""))
1aed5204 9941 (const_string "mov_shift")
9942 (const_string "mov_shift_reg")))]
8fa3ba89 9943)
8a18b90c 9944
f7fbdd4a 9945(define_insn "*ifcompare_not_arith"
8a18b90c 9946 [(set (match_operand:SI 0 "s_register_operand" "=r")
5565501b 9947 (if_then_else:SI
8fa3ba89 9948 (match_operator 6 "arm_comparison_operator"
8a18b90c 9949 [(match_operand:SI 4 "s_register_operand" "r")
9950 (match_operand:SI 5 "arm_add_operand" "rIL")])
9951 (not:SI (match_operand:SI 1 "s_register_operand" "r"))
5565501b 9952 (match_operator:SI 7 "shiftable_operator"
8a18b90c 9953 [(match_operand:SI 2 "s_register_operand" "r")
9954 (match_operand:SI 3 "arm_rhs_operand" "rI")])))
bd5b4116 9955 (clobber (reg:CC CC_REGNUM))]
cffb2a26 9956 "TARGET_ARM"
8a18b90c 9957 "#"
8fa3ba89 9958 [(set_attr "conds" "clob")
1b7da4ac 9959 (set_attr "length" "12")
9960 (set_attr "type" "multiple")]
8fa3ba89 9961)
9c08d1fa 9962
8a18b90c 9963(define_insn "*if_not_arith"
9964 [(set (match_operand:SI 0 "s_register_operand" "=r")
9965 (if_then_else:SI
8fa3ba89 9966 (match_operator 5 "arm_comparison_operator"
8a18b90c 9967 [(match_operand 4 "cc_register" "") (const_int 0)])
9968 (not:SI (match_operand:SI 1 "s_register_operand" "r"))
9969 (match_operator:SI 6 "shiftable_operator"
9970 [(match_operand:SI 2 "s_register_operand" "r")
9971 (match_operand:SI 3 "arm_rhs_operand" "rI")])))]
cffb2a26 9972 "TARGET_ARM"
8a18b90c 9973 "mvn%d5\\t%0, %1\;%I6%D5\\t%0, %2, %3"
8fa3ba89 9974 [(set_attr "conds" "use")
1aed5204 9975 (set_attr "type" "mvn_reg")
8fa3ba89 9976 (set_attr "length" "8")]
9977)
8a18b90c 9978
9979(define_insn "*ifcompare_arith_not"
9980 [(set (match_operand:SI 0 "s_register_operand" "=r")
5565501b 9981 (if_then_else:SI
8fa3ba89 9982 (match_operator 6 "arm_comparison_operator"
8a18b90c 9983 [(match_operand:SI 4 "s_register_operand" "r")
9984 (match_operand:SI 5 "arm_add_operand" "rIL")])
5565501b 9985 (match_operator:SI 7 "shiftable_operator"
8a18b90c 9986 [(match_operand:SI 2 "s_register_operand" "r")
9987 (match_operand:SI 3 "arm_rhs_operand" "rI")])
9988 (not:SI (match_operand:SI 1 "s_register_operand" "r"))))
bd5b4116 9989 (clobber (reg:CC CC_REGNUM))]
cffb2a26 9990 "TARGET_ARM"
8a18b90c 9991 "#"
8fa3ba89 9992 [(set_attr "conds" "clob")
1b7da4ac 9993 (set_attr "length" "12")
9994 (set_attr "type" "multiple")]
8fa3ba89 9995)
9c08d1fa 9996
8a18b90c 9997(define_insn "*if_arith_not"
9998 [(set (match_operand:SI 0 "s_register_operand" "=r")
9999 (if_then_else:SI
8fa3ba89 10000 (match_operator 5 "arm_comparison_operator"
8a18b90c 10001 [(match_operand 4 "cc_register" "") (const_int 0)])
10002 (match_operator:SI 6 "shiftable_operator"
10003 [(match_operand:SI 2 "s_register_operand" "r")
10004 (match_operand:SI 3 "arm_rhs_operand" "rI")])
10005 (not:SI (match_operand:SI 1 "s_register_operand" "r"))))]
cffb2a26 10006 "TARGET_ARM"
8a18b90c 10007 "mvn%D5\\t%0, %1\;%I6%d5\\t%0, %2, %3"
8fa3ba89 10008 [(set_attr "conds" "use")
1b7da4ac 10009 (set_attr "type" "multiple")
8fa3ba89 10010 (set_attr "length" "8")]
10011)
8a18b90c 10012
f7fbdd4a 10013(define_insn "*ifcompare_neg_move"
8a18b90c 10014 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5565501b 10015 (if_then_else:SI
8fa3ba89 10016 (match_operator 5 "arm_comparison_operator"
8a18b90c 10017 [(match_operand:SI 3 "s_register_operand" "r,r")
10018 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
10019 (neg:SI (match_operand:SI 2 "s_register_operand" "r,r"))
10020 (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
bd5b4116 10021 (clobber (reg:CC CC_REGNUM))]
cffb2a26 10022 "TARGET_ARM"
8a18b90c 10023 "#"
8fa3ba89 10024 [(set_attr "conds" "clob")
1b7da4ac 10025 (set_attr "length" "8,12")
10026 (set_attr "type" "multiple")]
8fa3ba89 10027)
8a18b90c 10028
530bb693 10029(define_insn_and_split "*if_neg_move"
10030 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
8a18b90c 10031 (if_then_else:SI
8fa3ba89 10032 (match_operator 4 "arm_comparison_operator"
8a18b90c 10033 [(match_operand 3 "cc_register" "") (const_int 0)])
530bb693 10034 (neg:SI (match_operand:SI 2 "s_register_operand" "l,r"))
10035 (match_operand:SI 1 "s_register_operand" "0,0")))]
10036 "TARGET_32BIT"
10037 "#"
10038 "&& reload_completed"
10039 [(cond_exec (match_op_dup 4 [(match_dup 3) (const_int 0)])
10040 (set (match_dup 0) (neg:SI (match_dup 2))))]
10041 ""
8fa3ba89 10042 [(set_attr "conds" "use")
530bb693 10043 (set_attr "length" "4")
10044 (set_attr "arch" "t2,32")
10045 (set_attr "enabled_for_depr_it" "yes,no")
10046 (set_attr "type" "logic_shift_imm")]
8fa3ba89 10047)
9c08d1fa 10048
f7fbdd4a 10049(define_insn "*ifcompare_move_neg"
8a18b90c 10050 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5565501b 10051 (if_then_else:SI
8fa3ba89 10052 (match_operator 5 "arm_comparison_operator"
8a18b90c 10053 [(match_operand:SI 3 "s_register_operand" "r,r")
10054 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
10055 (match_operand:SI 1 "arm_not_operand" "0,?rIK")
10056 (neg:SI (match_operand:SI 2 "s_register_operand" "r,r"))))
bd5b4116 10057 (clobber (reg:CC CC_REGNUM))]
cffb2a26 10058 "TARGET_ARM"
8a18b90c 10059 "#"
8fa3ba89 10060 [(set_attr "conds" "clob")
1b7da4ac 10061 (set_attr "length" "8,12")
10062 (set_attr "type" "multiple")]
8fa3ba89 10063)
8a18b90c 10064
530bb693 10065(define_insn_and_split "*if_move_neg"
10066 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
8a18b90c 10067 (if_then_else:SI
8fa3ba89 10068 (match_operator 4 "arm_comparison_operator"
8a18b90c 10069 [(match_operand 3 "cc_register" "") (const_int 0)])
530bb693 10070 (match_operand:SI 1 "s_register_operand" "0,0")
10071 (neg:SI (match_operand:SI 2 "s_register_operand" "l,r"))))]
10072 "TARGET_32BIT"
10073 "#"
10074 "&& reload_completed"
10075 [(cond_exec (match_dup 5)
10076 (set (match_dup 0) (neg:SI (match_dup 2))))]
10077 {
10078 machine_mode mode = GET_MODE (operands[3]);
10079 rtx_code rc = GET_CODE (operands[4]);
10080
10081 if (mode == CCFPmode || mode == CCFPEmode)
10082 rc = reverse_condition_maybe_unordered (rc);
10083 else
10084 rc = reverse_condition (rc);
10085
10086 operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, operands[3], const0_rtx);
10087 }
0d66636f 10088 [(set_attr "conds" "use")
530bb693 10089 (set_attr "length" "4")
10090 (set_attr "arch" "t2,32")
10091 (set_attr "enabled_for_depr_it" "yes,no")
10092 (set_attr "type" "logic_shift_imm")]
0d66636f 10093)
9c08d1fa 10094
f7fbdd4a 10095(define_insn "*arith_adjacentmem"
9c08d1fa 10096 [(set (match_operand:SI 0 "s_register_operand" "=r")
10097 (match_operator:SI 1 "shiftable_operator"
10098 [(match_operand:SI 2 "memory_operand" "m")
10099 (match_operand:SI 3 "memory_operand" "m")]))
10100 (clobber (match_scratch:SI 4 "=r"))]
cffb2a26 10101 "TARGET_ARM && adjacent_mem_locations (operands[2], operands[3])"
9c08d1fa 10102 "*
215b30b3 10103 {
10104 rtx ldm[3];
10105 rtx arith[4];
94dee231 10106 rtx base_reg;
10107 HOST_WIDE_INT val1 = 0, val2 = 0;
9c08d1fa 10108
215b30b3 10109 if (REGNO (operands[0]) > REGNO (operands[4]))
10110 {
10111 ldm[1] = operands[4];
10112 ldm[2] = operands[0];
10113 }
10114 else
10115 {
10116 ldm[1] = operands[0];
10117 ldm[2] = operands[4];
10118 }
94dee231 10119
10120 base_reg = XEXP (operands[2], 0);
10121
10122 if (!REG_P (base_reg))
10123 {
10124 val1 = INTVAL (XEXP (base_reg, 1));
10125 base_reg = XEXP (base_reg, 0);
10126 }
10127
10128 if (!REG_P (XEXP (operands[3], 0)))
215b30b3 10129 val2 = INTVAL (XEXP (XEXP (operands[3], 0), 1));
94dee231 10130
215b30b3 10131 arith[0] = operands[0];
10132 arith[3] = operands[1];
94dee231 10133
215b30b3 10134 if (val1 < val2)
10135 {
10136 arith[1] = ldm[1];
10137 arith[2] = ldm[2];
10138 }
10139 else
10140 {
10141 arith[1] = ldm[2];
10142 arith[2] = ldm[1];
10143 }
94dee231 10144
10145 ldm[0] = base_reg;
10146 if (val1 !=0 && val2 != 0)
215b30b3 10147 {
cdb1295a 10148 rtx ops[3];
10149
94dee231 10150 if (val1 == 4 || val2 == 4)
10151 /* Other val must be 8, since we know they are adjacent and neither
10152 is zero. */
3ef90e77 10153 output_asm_insn (\"ldmib%?\\t%0, {%1, %2}\", ldm);
cdb1295a 10154 else if (const_ok_for_arm (val1) || const_ok_for_arm (-val1))
94dee231 10155 {
94dee231 10156 ldm[0] = ops[0] = operands[4];
10157 ops[1] = base_reg;
10158 ops[2] = GEN_INT (val1);
10159 output_add_immediate (ops);
10160 if (val1 < val2)
3ef90e77 10161 output_asm_insn (\"ldmia%?\\t%0, {%1, %2}\", ldm);
94dee231 10162 else
3ef90e77 10163 output_asm_insn (\"ldmda%?\\t%0, {%1, %2}\", ldm);
94dee231 10164 }
cdb1295a 10165 else
10166 {
10167 /* Offset is out of range for a single add, so use two ldr. */
10168 ops[0] = ldm[1];
10169 ops[1] = base_reg;
10170 ops[2] = GEN_INT (val1);
10171 output_asm_insn (\"ldr%?\\t%0, [%1, %2]\", ops);
10172 ops[0] = ldm[2];
10173 ops[2] = GEN_INT (val2);
10174 output_asm_insn (\"ldr%?\\t%0, [%1, %2]\", ops);
10175 }
215b30b3 10176 }
94dee231 10177 else if (val1 != 0)
215b30b3 10178 {
215b30b3 10179 if (val1 < val2)
3ef90e77 10180 output_asm_insn (\"ldmda%?\\t%0, {%1, %2}\", ldm);
215b30b3 10181 else
3ef90e77 10182 output_asm_insn (\"ldmia%?\\t%0, {%1, %2}\", ldm);
215b30b3 10183 }
10184 else
10185 {
215b30b3 10186 if (val1 < val2)
3ef90e77 10187 output_asm_insn (\"ldmia%?\\t%0, {%1, %2}\", ldm);
215b30b3 10188 else
3ef90e77 10189 output_asm_insn (\"ldmda%?\\t%0, {%1, %2}\", ldm);
215b30b3 10190 }
10191 output_asm_insn (\"%I3%?\\t%0, %1, %2\", arith);
10192 return \"\";
10193 }"
10194 [(set_attr "length" "12")
10195 (set_attr "predicable" "yes")
a2cd141b 10196 (set_attr "type" "load1")]
215b30b3 10197)
9c08d1fa 10198
9c08d1fa 10199; This pattern is never tried by combine, so do it as a peephole
10200
a0f94409 10201(define_peephole2
372575c7 10202 [(set (match_operand:SI 0 "arm_general_register_operand" "")
10203 (match_operand:SI 1 "arm_general_register_operand" ""))
bd5b4116 10204 (set (reg:CC CC_REGNUM)
aea4c774 10205 (compare:CC (match_dup 1) (const_int 0)))]
372575c7 10206 "TARGET_ARM"
a0f94409 10207 [(parallel [(set (reg:CC CC_REGNUM) (compare:CC (match_dup 1) (const_int 0)))
10208 (set (match_dup 0) (match_dup 1))])]
10209 ""
0d66636f 10210)
9c08d1fa 10211
9c08d1fa 10212(define_split
10213 [(set (match_operand:SI 0 "s_register_operand" "")
10214 (and:SI (ge:SI (match_operand:SI 1 "s_register_operand" "")
10215 (const_int 0))
8fa3ba89 10216 (neg:SI (match_operator:SI 2 "arm_comparison_operator"
9c08d1fa 10217 [(match_operand:SI 3 "s_register_operand" "")
10218 (match_operand:SI 4 "arm_rhs_operand" "")]))))
10219 (clobber (match_operand:SI 5 "s_register_operand" ""))]
cffb2a26 10220 "TARGET_ARM"
9c08d1fa 10221 [(set (match_dup 5) (not:SI (ashiftrt:SI (match_dup 1) (const_int 31))))
10222 (set (match_dup 0) (and:SI (match_op_dup 2 [(match_dup 3) (match_dup 4)])
10223 (match_dup 5)))]
215b30b3 10224 ""
10225)
9c08d1fa 10226
aea4c774 10227;; This split can be used because CC_Z mode implies that the following
10228;; branch will be an equality, or an unsigned inequality, so the sign
10229;; extension is not needed.
9c08d1fa 10230
aea4c774 10231(define_split
bd5b4116 10232 [(set (reg:CC_Z CC_REGNUM)
aea4c774 10233 (compare:CC_Z
10234 (ashift:SI (subreg:SI (match_operand:QI 0 "memory_operand" "") 0)
9c08d1fa 10235 (const_int 24))
aea4c774 10236 (match_operand 1 "const_int_operand" "")))
10237 (clobber (match_scratch:SI 2 ""))]
cffb2a26 10238 "TARGET_ARM
10239 && (((unsigned HOST_WIDE_INT) INTVAL (operands[1]))
10240 == (((unsigned HOST_WIDE_INT) INTVAL (operands[1])) >> 24) << 24)"
aea4c774 10241 [(set (match_dup 2) (zero_extend:SI (match_dup 0)))
bd5b4116 10242 (set (reg:CC CC_REGNUM) (compare:CC (match_dup 2) (match_dup 1)))]
aea4c774 10243 "
9c08d1fa 10244 operands[1] = GEN_INT (((unsigned long) INTVAL (operands[1])) >> 24);
215b30b3 10245 "
10246)
25f905c2 10247;; ??? Check the patterns above for Thumb-2 usefulness
9c08d1fa 10248
87b22bf7 10249(define_expand "prologue"
10250 [(clobber (const_int 0))]
cffb2a26 10251 "TARGET_EITHER"
25f905c2 10252 "if (TARGET_32BIT)
cffb2a26 10253 arm_expand_prologue ();
10254 else
25f905c2 10255 thumb1_expand_prologue ();
87b22bf7 10256 DONE;
cffb2a26 10257 "
10258)
87b22bf7 10259
56d27660 10260(define_expand "epilogue"
4c44712e 10261 [(clobber (const_int 0))]
cffb2a26 10262 "TARGET_EITHER"
56d27660 10263 "
18d50ae6 10264 if (crtl->calls_eh_return)
fb94f18b 10265 emit_insn (gen_force_register_use (gen_rtx_REG (Pmode, 2)));
25f905c2 10266 if (TARGET_THUMB1)
c3635784 10267 {
10268 thumb1_expand_epilogue ();
10269 emit_jump_insn (gen_rtx_UNSPEC_VOLATILE (VOIDmode,
10270 gen_rtvec (1, ret_rtx), VUNSPEC_EPILOGUE));
10271 }
10272 else if (HAVE_return)
10273 {
10274 /* HAVE_return is testing for USE_RETURN_INSN (FALSE). Hence,
10275 no need for explicit testing again. */
10276 emit_jump_insn (gen_return ());
10277 }
10278 else if (TARGET_32BIT)
10279 {
10280 arm_expand_epilogue (true);
10281 }
cffb2a26 10282 DONE;
10283 "
10284)
56d27660 10285
ef5651d0 10286;; Note - although unspec_volatile's USE all hard registers,
10287;; USEs are ignored after relaod has completed. Thus we need
10288;; to add an unspec of the link register to ensure that flow
10289;; does not think that it is unused by the sibcall branch that
10290;; will replace the standard function epilogue.
c3635784 10291(define_expand "sibcall_epilogue"
fb94f18b 10292 [(parallel [(unspec:SI [(reg:SI LR_REGNUM)] UNSPEC_REGISTER_USE)
c3635784 10293 (unspec_volatile [(return)] VUNSPEC_EPILOGUE)])]
10294 "TARGET_32BIT"
10295 "
10296 arm_expand_epilogue (false);
10297 DONE;
10298 "
1c494086 10299)
10300
cffb2a26 10301(define_expand "eh_epilogue"
7db9af5d 10302 [(use (match_operand:SI 0 "register_operand" ""))
10303 (use (match_operand:SI 1 "register_operand" ""))
10304 (use (match_operand:SI 2 "register_operand" ""))]
cffb2a26 10305 "TARGET_EITHER"
10306 "
215b30b3 10307 {
10308 cfun->machine->eh_epilogue_sp_ofs = operands[1];
0438d37f 10309 if (!REG_P (operands[2]) || REGNO (operands[2]) != 2)
215b30b3 10310 {
10311 rtx ra = gen_rtx_REG (Pmode, 2);
10312
10313 emit_move_insn (ra, operands[2]);
10314 operands[2] = ra;
10315 }
5cf3595a 10316 /* This is a hack -- we may have crystalized the function type too
10317 early. */
10318 cfun->machine->func_type = 0;
215b30b3 10319 }"
10320)
56d27660 10321
9c08d1fa 10322;; This split is only used during output to reduce the number of patterns
10323;; that need assembler instructions adding to them. We allowed the setting
10324;; of the conditions to be implicit during rtl generation so that
10325;; the conditional compare patterns would work. However this conflicts to
8a18b90c 10326;; some extent with the conditional data operations, so we have to split them
9c08d1fa 10327;; up again here.
10328
25f905c2 10329;; ??? Need to audit these splitters for Thumb-2. Why isn't normal
10330;; conditional execution sufficient?
10331
9c08d1fa 10332(define_split
10333 [(set (match_operand:SI 0 "s_register_operand" "")
8fa3ba89 10334 (if_then_else:SI (match_operator 1 "arm_comparison_operator"
10335 [(match_operand 2 "" "") (match_operand 3 "" "")])
10336 (match_dup 0)
10337 (match_operand 4 "" "")))
bd5b4116 10338 (clobber (reg:CC CC_REGNUM))]
ac8b093b 10339 "TARGET_ARM && reload_completed"
8fa3ba89 10340 [(set (match_dup 5) (match_dup 6))
10341 (cond_exec (match_dup 7)
10342 (set (match_dup 0) (match_dup 4)))]
10343 "
10344 {
3754d046 10345 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
8fa3ba89 10346 operands[2], operands[3]);
10347 enum rtx_code rc = GET_CODE (operands[1]);
10348
bd5b4116 10349 operands[5] = gen_rtx_REG (mode, CC_REGNUM);
8fa3ba89 10350 operands[6] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
10351 if (mode == CCFPmode || mode == CCFPEmode)
10352 rc = reverse_condition_maybe_unordered (rc);
10353 else
10354 rc = reverse_condition (rc);
10355
10356 operands[7] = gen_rtx_fmt_ee (rc, VOIDmode, operands[5], const0_rtx);
10357 }"
10358)
10359
10360(define_split
10361 [(set (match_operand:SI 0 "s_register_operand" "")
10362 (if_then_else:SI (match_operator 1 "arm_comparison_operator"
10363 [(match_operand 2 "" "") (match_operand 3 "" "")])
10364 (match_operand 4 "" "")
10365 (match_dup 0)))
bd5b4116 10366 (clobber (reg:CC CC_REGNUM))]
ac8b093b 10367 "TARGET_ARM && reload_completed"
8fa3ba89 10368 [(set (match_dup 5) (match_dup 6))
10369 (cond_exec (match_op_dup 1 [(match_dup 5) (const_int 0)])
10370 (set (match_dup 0) (match_dup 4)))]
10371 "
10372 {
3754d046 10373 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
8fa3ba89 10374 operands[2], operands[3]);
10375
bd5b4116 10376 operands[5] = gen_rtx_REG (mode, CC_REGNUM);
8fa3ba89 10377 operands[6] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
10378 }"
10379)
10380
10381(define_split
10382 [(set (match_operand:SI 0 "s_register_operand" "")
10383 (if_then_else:SI (match_operator 1 "arm_comparison_operator"
9c08d1fa 10384 [(match_operand 2 "" "") (match_operand 3 "" "")])
10385 (match_operand 4 "" "")
10386 (match_operand 5 "" "")))
bd5b4116 10387 (clobber (reg:CC CC_REGNUM))]
ac8b093b 10388 "TARGET_ARM && reload_completed"
8fa3ba89 10389 [(set (match_dup 6) (match_dup 7))
10390 (cond_exec (match_op_dup 1 [(match_dup 6) (const_int 0)])
10391 (set (match_dup 0) (match_dup 4)))
10392 (cond_exec (match_dup 8)
10393 (set (match_dup 0) (match_dup 5)))]
10394 "
10395 {
3754d046 10396 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
8fa3ba89 10397 operands[2], operands[3]);
10398 enum rtx_code rc = GET_CODE (operands[1]);
10399
bd5b4116 10400 operands[6] = gen_rtx_REG (mode, CC_REGNUM);
8fa3ba89 10401 operands[7] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
10402 if (mode == CCFPmode || mode == CCFPEmode)
10403 rc = reverse_condition_maybe_unordered (rc);
10404 else
10405 rc = reverse_condition (rc);
10406
10407 operands[8] = gen_rtx_fmt_ee (rc, VOIDmode, operands[6], const0_rtx);
10408 }"
10409)
10410
cffb2a26 10411(define_split
10412 [(set (match_operand:SI 0 "s_register_operand" "")
8fa3ba89 10413 (if_then_else:SI (match_operator 1 "arm_comparison_operator"
cffb2a26 10414 [(match_operand:SI 2 "s_register_operand" "")
10415 (match_operand:SI 3 "arm_add_operand" "")])
10416 (match_operand:SI 4 "arm_rhs_operand" "")
10417 (not:SI
10418 (match_operand:SI 5 "s_register_operand" ""))))
bd5b4116 10419 (clobber (reg:CC CC_REGNUM))]
ac8b093b 10420 "TARGET_ARM && reload_completed"
cffb2a26 10421 [(set (match_dup 6) (match_dup 7))
f6c53574 10422 (cond_exec (match_op_dup 1 [(match_dup 6) (const_int 0)])
10423 (set (match_dup 0) (match_dup 4)))
10424 (cond_exec (match_dup 8)
10425 (set (match_dup 0) (not:SI (match_dup 5))))]
cffb2a26 10426 "
215b30b3 10427 {
3754d046 10428 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
215b30b3 10429 operands[2], operands[3]);
f6c53574 10430 enum rtx_code rc = GET_CODE (operands[1]);
cffb2a26 10431
bd5b4116 10432 operands[6] = gen_rtx_REG (mode, CC_REGNUM);
1a83b3ff 10433 operands[7] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
f6c53574 10434 if (mode == CCFPmode || mode == CCFPEmode)
10435 rc = reverse_condition_maybe_unordered (rc);
10436 else
10437 rc = reverse_condition (rc);
10438
10439 operands[8] = gen_rtx_fmt_ee (rc, VOIDmode, operands[6], const0_rtx);
215b30b3 10440 }"
10441)
cffb2a26 10442
10443(define_insn "*cond_move_not"
10444 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8fa3ba89 10445 (if_then_else:SI (match_operator 4 "arm_comparison_operator"
cffb2a26 10446 [(match_operand 3 "cc_register" "") (const_int 0)])
10447 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
10448 (not:SI
10449 (match_operand:SI 2 "s_register_operand" "r,r"))))]
10450 "TARGET_ARM"
10451 "@
10452 mvn%D4\\t%0, %2
10453 mov%d4\\t%0, %1\;mvn%D4\\t%0, %2"
0d66636f 10454 [(set_attr "conds" "use")
1b7da4ac 10455 (set_attr "type" "mvn_reg,multiple")
0d66636f 10456 (set_attr "length" "4,8")]
10457)
cffb2a26 10458
9c08d1fa 10459;; The next two patterns occur when an AND operation is followed by a
10460;; scc insn sequence
10461
f7fbdd4a 10462(define_insn "*sign_extract_onebit"
9c08d1fa 10463 [(set (match_operand:SI 0 "s_register_operand" "=r")
10464 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
10465 (const_int 1)
ed750274 10466 (match_operand:SI 2 "const_int_operand" "n")))
10467 (clobber (reg:CC CC_REGNUM))]
cffb2a26 10468 "TARGET_ARM"
9c08d1fa 10469 "*
0d66636f 10470 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
10471 output_asm_insn (\"ands\\t%0, %1, %2\", operands);
10472 return \"mvnne\\t%0, #0\";
10473 "
10474 [(set_attr "conds" "clob")
1b7da4ac 10475 (set_attr "length" "8")
10476 (set_attr "type" "multiple")]
0d66636f 10477)
9c08d1fa 10478
f7fbdd4a 10479(define_insn "*not_signextract_onebit"
9c08d1fa 10480 [(set (match_operand:SI 0 "s_register_operand" "=r")
10481 (not:SI
10482 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
10483 (const_int 1)
ed750274 10484 (match_operand:SI 2 "const_int_operand" "n"))))
10485 (clobber (reg:CC CC_REGNUM))]
cffb2a26 10486 "TARGET_ARM"
9c08d1fa 10487 "*
0d66636f 10488 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
10489 output_asm_insn (\"tst\\t%1, %2\", operands);
10490 output_asm_insn (\"mvneq\\t%0, #0\", operands);
10491 return \"movne\\t%0, #0\";
10492 "
10493 [(set_attr "conds" "clob")
1b7da4ac 10494 (set_attr "length" "12")
10495 (set_attr "type" "multiple")]
0d66636f 10496)
25f905c2 10497;; ??? The above patterns need auditing for Thumb-2
87b22bf7 10498
0d66636f 10499;; Push multiple registers to the stack. Registers are in parallel (use ...)
10500;; expressions. For simplicity, the first register is also in the unspec
10501;; part.
08508cbf 10502;; To avoid the usage of GNU extension, the length attribute is computed
10503;; in a C function arm_attr_length_push_multi.
f7fbdd4a 10504(define_insn "*push_multi"
87b22bf7 10505 [(match_parallel 2 "multi_register_push"
7571d3f7 10506 [(set (match_operand:BLK 0 "push_mult_memory_operand" "")
3cc80a30 10507 (unspec:BLK [(match_operand:SI 1 "s_register_operand" "")]
e1159bbe 10508 UNSPEC_PUSH_MULT))])]
7571d3f7 10509 ""
87b22bf7 10510 "*
215b30b3 10511 {
10512 int num_saves = XVECLEN (operands[2], 0);
ed593f11 10513
215b30b3 10514 /* For the StrongARM at least it is faster to
25f905c2 10515 use STR to store only a single register.
542d5028 10516 In Thumb mode always use push, and the assembler will pick
10517 something appropriate. */
25f905c2 10518 if (num_saves == 1 && TARGET_ARM)
61309563 10519 output_asm_insn (\"str%?\\t%1, [%m0, #-4]!\", operands);
215b30b3 10520 else
10521 {
10522 int i;
10523 char pattern[100];
ed593f11 10524
3ef90e77 10525 if (TARGET_32BIT)
61309563 10526 strcpy (pattern, \"push%?\\t{%1\");
25f905c2 10527 else
10528 strcpy (pattern, \"push\\t{%1\");
215b30b3 10529
6079f055 10530 for (i = 1; i < num_saves; i++)
215b30b3 10531 {
10532 strcat (pattern, \", %|\");
10533 strcat (pattern,
10534 reg_names[REGNO (XEXP (XVECEXP (operands[2], 0, i), 0))]);
10535 }
10536
10537 strcat (pattern, \"}\");
10538 output_asm_insn (pattern, operands);
10539 }
10540
10541 return \"\";
10542 }"
a6864a24 10543 [(set_attr "type" "store4")
10544 (set (attr "length")
08508cbf 10545 (symbol_ref "arm_attr_length_push_multi (operands[2], operands[1])"))]
215b30b3 10546)
f7fbdd4a 10547
4c58c898 10548(define_insn "stack_tie"
10549 [(set (mem:BLK (scratch))
aaa37ad6 10550 (unspec:BLK [(match_operand:SI 0 "s_register_operand" "rk")
10551 (match_operand:SI 1 "s_register_operand" "rk")]
4c58c898 10552 UNSPEC_PRLG_STK))]
10553 ""
10554 ""
1b7da4ac 10555 [(set_attr "length" "0")
10556 (set_attr "type" "block")]
4c58c898 10557)
10558
426be8c5 10559;; Pop (as used in epilogue RTL)
10560;;
10561(define_insn "*load_multiple_with_writeback"
10562 [(match_parallel 0 "load_multiple_operation"
10563 [(set (match_operand:SI 1 "s_register_operand" "+rk")
10564 (plus:SI (match_dup 1)
809003b3 10565 (match_operand:SI 2 "const_int_I_operand" "I")))
426be8c5 10566 (set (match_operand:SI 3 "s_register_operand" "=rk")
10567 (mem:SI (match_dup 1)))
10568 ])]
10569 "TARGET_32BIT && (reload_in_progress || reload_completed)"
10570 "*
10571 {
10572 arm_output_multireg_pop (operands, /*return_pc=*/false,
10573 /*cond=*/const_true_rtx,
10574 /*reverse=*/false,
10575 /*update=*/true);
10576 return \"\";
10577 }
10578 "
10579 [(set_attr "type" "load4")
10580 (set_attr "predicable" "yes")]
10581)
10582
10583;; Pop with return (as used in epilogue RTL)
10584;;
10585;; This instruction is generated when the registers are popped at the end of
10586;; epilogue. Here, instead of popping the value into LR and then generating
10587;; jump to LR, value is popped into PC directly. Hence, the pattern is combined
10588;; with (return).
10589(define_insn "*pop_multiple_with_writeback_and_return"
10590 [(match_parallel 0 "pop_multiple_return"
10591 [(return)
10592 (set (match_operand:SI 1 "s_register_operand" "+rk")
10593 (plus:SI (match_dup 1)
809003b3 10594 (match_operand:SI 2 "const_int_I_operand" "I")))
426be8c5 10595 (set (match_operand:SI 3 "s_register_operand" "=rk")
10596 (mem:SI (match_dup 1)))
10597 ])]
10598 "TARGET_32BIT && (reload_in_progress || reload_completed)"
10599 "*
10600 {
10601 arm_output_multireg_pop (operands, /*return_pc=*/true,
10602 /*cond=*/const_true_rtx,
10603 /*reverse=*/false,
10604 /*update=*/true);
10605 return \"\";
10606 }
10607 "
10608 [(set_attr "type" "load4")
10609 (set_attr "predicable" "yes")]
10610)
10611
10612(define_insn "*pop_multiple_with_return"
10613 [(match_parallel 0 "pop_multiple_return"
10614 [(return)
10615 (set (match_operand:SI 2 "s_register_operand" "=rk")
10616 (mem:SI (match_operand:SI 1 "s_register_operand" "rk")))
10617 ])]
10618 "TARGET_32BIT && (reload_in_progress || reload_completed)"
10619 "*
10620 {
10621 arm_output_multireg_pop (operands, /*return_pc=*/true,
10622 /*cond=*/const_true_rtx,
10623 /*reverse=*/false,
10624 /*update=*/false);
10625 return \"\";
10626 }
10627 "
10628 [(set_attr "type" "load4")
10629 (set_attr "predicable" "yes")]
10630)
10631
10632;; Load into PC and return
10633(define_insn "*ldr_with_return"
10634 [(return)
10635 (set (reg:SI PC_REGNUM)
10636 (mem:SI (post_inc:SI (match_operand:SI 0 "s_register_operand" "+rk"))))]
10637 "TARGET_32BIT && (reload_in_progress || reload_completed)"
10638 "ldr%?\t%|pc, [%0], #4"
10639 [(set_attr "type" "load1")
10640 (set_attr "predicable" "yes")]
10641)
1a0b0f12 10642;; Pop for floating point registers (as used in epilogue RTL)
10643(define_insn "*vfp_pop_multiple_with_writeback"
10644 [(match_parallel 0 "pop_multiple_fp"
10645 [(set (match_operand:SI 1 "s_register_operand" "+rk")
10646 (plus:SI (match_dup 1)
809003b3 10647 (match_operand:SI 2 "const_int_I_operand" "I")))
2f2163a4 10648 (set (match_operand:DF 3 "vfp_hard_register_operand" "")
1a0b0f12 10649 (mem:DF (match_dup 1)))])]
10650 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
10651 "*
10652 {
10653 int num_regs = XVECLEN (operands[0], 0);
10654 char pattern[100];
10655 rtx op_list[2];
b34d8dac 10656 strcpy (pattern, \"vldm\\t\");
1a0b0f12 10657 strcat (pattern, reg_names[REGNO (SET_DEST (XVECEXP (operands[0], 0, 0)))]);
10658 strcat (pattern, \"!, {\");
10659 op_list[0] = XEXP (XVECEXP (operands[0], 0, 1), 0);
10660 strcat (pattern, \"%P0\");
10661 if ((num_regs - 1) > 1)
10662 {
10663 strcat (pattern, \"-%P1\");
10664 op_list [1] = XEXP (XVECEXP (operands[0], 0, num_regs - 1), 0);
10665 }
10666
10667 strcat (pattern, \"}\");
10668 output_asm_insn (pattern, op_list);
10669 return \"\";
10670 }
10671 "
10672 [(set_attr "type" "load4")
10673 (set_attr "conds" "unconditional")
10674 (set_attr "predicable" "no")]
10675)
10676
f7fbdd4a 10677;; Special patterns for dealing with the constant pool
10678
cffb2a26 10679(define_insn "align_4"
e1159bbe 10680 [(unspec_volatile [(const_int 0)] VUNSPEC_ALIGN)]
cffb2a26 10681 "TARGET_EITHER"
f7fbdd4a 10682 "*
cffb2a26 10683 assemble_align (32);
f7fbdd4a 10684 return \"\";
cffb2a26 10685 "
1b7da4ac 10686 [(set_attr "type" "no_insn")]
cffb2a26 10687)
f7fbdd4a 10688
755eb2b4 10689(define_insn "align_8"
10690 [(unspec_volatile [(const_int 0)] VUNSPEC_ALIGN8)]
f9273c43 10691 "TARGET_EITHER"
755eb2b4 10692 "*
10693 assemble_align (64);
10694 return \"\";
10695 "
1b7da4ac 10696 [(set_attr "type" "no_insn")]
755eb2b4 10697)
10698
cffb2a26 10699(define_insn "consttable_end"
e1159bbe 10700 [(unspec_volatile [(const_int 0)] VUNSPEC_POOL_END)]
cffb2a26 10701 "TARGET_EITHER"
f7fbdd4a 10702 "*
cffb2a26 10703 making_const_table = FALSE;
f7fbdd4a 10704 return \"\";
cffb2a26 10705 "
1b7da4ac 10706 [(set_attr "type" "no_insn")]
cffb2a26 10707)
f7fbdd4a 10708
0e207eb8 10709(define_insn "consttable_1"
10710 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_1)]
10711 "TARGET_EITHER"
10712 "*
10713 making_const_table = TRUE;
10714 assemble_integer (operands[0], 1, BITS_PER_WORD, 1);
10715 assemble_zeros (3);
10716 return \"\";
10717 "
10718 [(set_attr "length" "4")
10719 (set_attr "type" "no_insn")]
10720)
10721
10722(define_insn "consttable_2"
10723 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_2)]
10724 "TARGET_EITHER"
10725 "*
10726 {
10727 rtx x = operands[0];
10728 making_const_table = TRUE;
10729 switch (GET_MODE_CLASS (GET_MODE (x)))
10730 {
10731 case MODE_FLOAT:
10732 arm_emit_fp16_const (x);
10733 break;
10734 default:
10735 assemble_integer (operands[0], 2, BITS_PER_WORD, 1);
10736 assemble_zeros (2);
10737 break;
10738 }
10739 return \"\";
10740 }"
10741 [(set_attr "length" "4")
10742 (set_attr "type" "no_insn")]
10743)
10744
cffb2a26 10745(define_insn "consttable_4"
e1159bbe 10746 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_4)]
cffb2a26 10747 "TARGET_EITHER"
10748 "*
10749 {
9b8516be 10750 rtx x = operands[0];
cffb2a26 10751 making_const_table = TRUE;
9b8516be 10752 switch (GET_MODE_CLASS (GET_MODE (x)))
cffb2a26 10753 {
10754 case MODE_FLOAT:
945f7b03 10755 assemble_real (*CONST_DOUBLE_REAL_VALUE (x), GET_MODE (x),
10756 BITS_PER_WORD);
10757 break;
cffb2a26 10758 default:
7b04c5d5 10759 /* XXX: Sometimes gcc does something really dumb and ends up with
10760 a HIGH in a constant pool entry, usually because it's trying to
10761 load into a VFP register. We know this will always be used in
10762 combination with a LO_SUM which ignores the high bits, so just
10763 strip off the HIGH. */
10764 if (GET_CODE (x) == HIGH)
10765 x = XEXP (x, 0);
9b8516be 10766 assemble_integer (x, 4, BITS_PER_WORD, 1);
10767 mark_symbol_refs_as_used (x);
cffb2a26 10768 break;
10769 }
10770 return \"\";
10771 }"
1b7da4ac 10772 [(set_attr "length" "4")
10773 (set_attr "type" "no_insn")]
cffb2a26 10774)
10775
10776(define_insn "consttable_8"
e1159bbe 10777 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_8)]
cffb2a26 10778 "TARGET_EITHER"
10779 "*
10780 {
10781 making_const_table = TRUE;
10782 switch (GET_MODE_CLASS (GET_MODE (operands[0])))
10783 {
945f7b03 10784 case MODE_FLOAT:
10785 assemble_real (*CONST_DOUBLE_REAL_VALUE (operands[0]),
10786 GET_MODE (operands[0]), BITS_PER_WORD);
10787 break;
cffb2a26 10788 default:
09d688ff 10789 assemble_integer (operands[0], 8, BITS_PER_WORD, 1);
cffb2a26 10790 break;
10791 }
10792 return \"\";
10793 }"
1b7da4ac 10794 [(set_attr "length" "8")
10795 (set_attr "type" "no_insn")]
cffb2a26 10796)
10797
d98a3884 10798(define_insn "consttable_16"
10799 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_16)]
10800 "TARGET_EITHER"
10801 "*
10802 {
10803 making_const_table = TRUE;
10804 switch (GET_MODE_CLASS (GET_MODE (operands[0])))
10805 {
945f7b03 10806 case MODE_FLOAT:
10807 assemble_real (*CONST_DOUBLE_REAL_VALUE (operands[0]),
10808 GET_MODE (operands[0]), BITS_PER_WORD);
10809 break;
d98a3884 10810 default:
10811 assemble_integer (operands[0], 16, BITS_PER_WORD, 1);
10812 break;
10813 }
10814 return \"\";
10815 }"
1b7da4ac 10816 [(set_attr "length" "16")
10817 (set_attr "type" "no_insn")]
d98a3884 10818)
10819
331beb1a 10820;; V5 Instructions,
10821
8f4be2be 10822(define_insn "clzsi2"
10823 [(set (match_operand:SI 0 "s_register_operand" "=r")
10824 (clz:SI (match_operand:SI 1 "s_register_operand" "r")))]
25f905c2 10825 "TARGET_32BIT && arm_arch5"
ee7cbe0e 10826 "clz%?\\t%0, %1"
bcaec148 10827 [(set_attr "predicable" "yes")
4a510717 10828 (set_attr "predicable_short_it" "no")
bebe9bbb 10829 (set_attr "type" "clz")])
331beb1a 10830
099ad98b 10831(define_insn "rbitsi2"
10832 [(set (match_operand:SI 0 "s_register_operand" "=r")
10833 (unspec:SI [(match_operand:SI 1 "s_register_operand" "r")] UNSPEC_RBIT))]
10834 "TARGET_32BIT && arm_arch_thumb2"
10835 "rbit%?\\t%0, %1"
10836 [(set_attr "predicable" "yes")
4a510717 10837 (set_attr "predicable_short_it" "no")
bebe9bbb 10838 (set_attr "type" "clz")])
099ad98b 10839
10840(define_expand "ctzsi2"
10841 [(set (match_operand:SI 0 "s_register_operand" "")
10842 (ctz:SI (match_operand:SI 1 "s_register_operand" "")))]
10843 "TARGET_32BIT && arm_arch_thumb2"
10844 "
30191172 10845 {
10846 rtx tmp = gen_reg_rtx (SImode);
10847 emit_insn (gen_rbitsi2 (tmp, operands[1]));
10848 emit_insn (gen_clzsi2 (operands[0], tmp));
10849 }
099ad98b 10850 DONE;
10851 "
10852)
10853
e1159bbe 10854;; V5E instructions.
331beb1a 10855
10856(define_insn "prefetch"
f4e79814 10857 [(prefetch (match_operand:SI 0 "address_operand" "p")
10858 (match_operand:SI 1 "" "")
10859 (match_operand:SI 2 "" ""))]
25f905c2 10860 "TARGET_32BIT && arm_arch5e"
1b7da4ac 10861 "pld\\t%a0"
10862 [(set_attr "type" "load1")]
10863)
331beb1a 10864
0d66636f 10865;; General predication pattern
10866
10867(define_cond_exec
10868 [(match_operator 0 "arm_comparison_operator"
10869 [(match_operand 1 "cc_register" "")
10870 (const_int 0)])]
580f4c48 10871 "TARGET_32BIT
10872 && (!TARGET_NO_VOLATILE_CE || !volatile_refs_p (PATTERN (insn)))"
0d66636f 10873 ""
c7a58118 10874[(set_attr "predicated" "yes")]
0d66636f 10875)
10876
fb94f18b 10877(define_insn "force_register_use"
10878 [(unspec:SI [(match_operand:SI 0 "register_operand" "")] UNSPEC_REGISTER_USE)]
063a05c7 10879 ""
fb94f18b 10880 "%@ %0 needed"
1b7da4ac 10881 [(set_attr "length" "0")
10882 (set_attr "type" "no_insn")]
063a05c7 10883)
7db9af5d 10884
4c44712e 10885
10886;; Patterns for exception handling
10887
10888(define_expand "eh_return"
10889 [(use (match_operand 0 "general_operand" ""))]
10890 "TARGET_EITHER"
10891 "
10892 {
25f905c2 10893 if (TARGET_32BIT)
4c44712e 10894 emit_insn (gen_arm_eh_return (operands[0]));
10895 else
10896 emit_insn (gen_thumb_eh_return (operands[0]));
10897 DONE;
10898 }"
10899)
10900
10901;; We can't expand this before we know where the link register is stored.
10902(define_insn_and_split "arm_eh_return"
10903 [(unspec_volatile [(match_operand:SI 0 "s_register_operand" "r")]
10904 VUNSPEC_EH_RETURN)
10905 (clobber (match_scratch:SI 1 "=&r"))]
10906 "TARGET_ARM"
10907 "#"
10908 "&& reload_completed"
10909 [(const_int 0)]
10910 "
10911 {
10912 arm_set_return_address (operands[0], operands[1]);
10913 DONE;
10914 }"
10915)
10916
f655717d 10917\f
10918;; TLS support
10919
10920(define_insn "load_tp_hard"
10921 [(set (match_operand:SI 0 "register_operand" "=r")
10922 (unspec:SI [(const_int 0)] UNSPEC_TLS))]
10923 "TARGET_HARD_TP"
10924 "mrc%?\\tp15, 0, %0, c13, c0, 3\\t@ load_tp_hard"
1b7da4ac 10925 [(set_attr "predicable" "yes")
4b5d7374 10926 (set_attr "type" "mrs")]
f655717d 10927)
10928
10929;; Doesn't clobber R1-R3. Must use r0 for the first operand.
10930(define_insn "load_tp_soft"
10931 [(set (reg:SI 0) (unspec:SI [(const_int 0)] UNSPEC_TLS))
10932 (clobber (reg:SI LR_REGNUM))
10933 (clobber (reg:SI IP_REGNUM))
10934 (clobber (reg:CC CC_REGNUM))]
10935 "TARGET_SOFT_TP"
10936 "bl\\t__aeabi_read_tp\\t@ load_tp_soft"
1b7da4ac 10937 [(set_attr "conds" "clob")
10938 (set_attr "type" "branch")]
f655717d 10939)
10940
f41e4452 10941;; tls descriptor call
10942(define_insn "tlscall"
10943 [(set (reg:SI R0_REGNUM)
10944 (unspec:SI [(reg:SI R0_REGNUM)
10945 (match_operand:SI 0 "" "X")
10946 (match_operand 1 "" "")] UNSPEC_TLS))
10947 (clobber (reg:SI R1_REGNUM))
10948 (clobber (reg:SI LR_REGNUM))
10949 (clobber (reg:SI CC_REGNUM))]
10950 "TARGET_GNU2_TLS"
10951 {
10952 targetm.asm_out.internal_label (asm_out_file, "LPIC",
10953 INTVAL (operands[1]));
10954 return "bl\\t%c0(tlscall)";
10955 }
10956 [(set_attr "conds" "clob")
1b7da4ac 10957 (set_attr "length" "4")
10958 (set_attr "type" "branch")]
f41e4452 10959)
10960
1fe0edab 10961;; For thread pointer builtin
10962(define_expand "get_thread_pointersi"
10963 [(match_operand:SI 0 "s_register_operand" "=r")]
10964 ""
10965 "
10966 {
10967 arm_load_tp (operands[0]);
10968 DONE;
10969 }")
10970
f41e4452 10971;;
10972
aabe09ac 10973;; We only care about the lower 16 bits of the constant
10974;; being inserted into the upper 16 bits of the register.
eca5c984 10975(define_insn "*arm_movtas_ze"
10976 [(set (zero_extract:SI (match_operand:SI 0 "s_register_operand" "+r")
10977 (const_int 16)
10978 (const_int 16))
10979 (match_operand:SI 1 "const_int_operand" ""))]
181ab277 10980 "arm_arch_thumb2"
aabe09ac 10981 "movt%?\t%0, %L1"
eca5c984 10982 [(set_attr "predicable" "yes")
7c36fe71 10983 (set_attr "predicable_short_it" "no")
1b7da4ac 10984 (set_attr "length" "4")
282b4c75 10985 (set_attr "type" "alu_sreg")]
eca5c984 10986)
10987
c0fc3696 10988(define_insn "*arm_rev"
a486b499 10989 [(set (match_operand:SI 0 "s_register_operand" "=l,l,r")
10990 (bswap:SI (match_operand:SI 1 "s_register_operand" "l,l,r")))]
10991 "arm_arch6"
10992 "@
10993 rev\t%0, %1
10994 rev%?\t%0, %1
10995 rev%?\t%0, %1"
10996 [(set_attr "arch" "t1,t2,32")
1b7da4ac 10997 (set_attr "length" "2,2,4")
4a510717 10998 (set_attr "predicable" "no,yes,yes")
10999 (set_attr "predicable_short_it" "no")
1b7da4ac 11000 (set_attr "type" "rev")]
ff82f757 11001)
11002
11003(define_expand "arm_legacy_rev"
11004 [(set (match_operand:SI 2 "s_register_operand" "")
11005 (xor:SI (rotatert:SI (match_operand:SI 1 "s_register_operand" "")
11006 (const_int 16))
11007 (match_dup 1)))
11008 (set (match_dup 2)
11009 (lshiftrt:SI (match_dup 2)
11010 (const_int 8)))
11011 (set (match_operand:SI 3 "s_register_operand" "")
11012 (rotatert:SI (match_dup 1)
11013 (const_int 8)))
11014 (set (match_dup 2)
11015 (and:SI (match_dup 2)
11016 (const_int -65281)))
11017 (set (match_operand:SI 0 "s_register_operand" "")
11018 (xor:SI (match_dup 3)
11019 (match_dup 2)))]
11020 "TARGET_32BIT"
11021 ""
11022)
11023
11024;; Reuse temporaries to keep register pressure down.
11025(define_expand "thumb_legacy_rev"
11026 [(set (match_operand:SI 2 "s_register_operand" "")
11027 (ashift:SI (match_operand:SI 1 "s_register_operand" "")
11028 (const_int 24)))
11029 (set (match_operand:SI 3 "s_register_operand" "")
11030 (lshiftrt:SI (match_dup 1)
11031 (const_int 24)))
11032 (set (match_dup 3)
11033 (ior:SI (match_dup 3)
11034 (match_dup 2)))
11035 (set (match_operand:SI 4 "s_register_operand" "")
11036 (const_int 16))
11037 (set (match_operand:SI 5 "s_register_operand" "")
11038 (rotatert:SI (match_dup 1)
11039 (match_dup 4)))
11040 (set (match_dup 2)
11041 (ashift:SI (match_dup 5)
11042 (const_int 24)))
11043 (set (match_dup 5)
11044 (lshiftrt:SI (match_dup 5)
11045 (const_int 24)))
11046 (set (match_dup 5)
11047 (ior:SI (match_dup 5)
11048 (match_dup 2)))
11049 (set (match_dup 5)
11050 (rotatert:SI (match_dup 5)
11051 (match_dup 4)))
11052 (set (match_operand:SI 0 "s_register_operand" "")
11053 (ior:SI (match_dup 5)
11054 (match_dup 3)))]
11055 "TARGET_THUMB"
11056 ""
11057)
11058
62e39b06 11059;; ARM-specific expansion of signed mod by power of 2
11060;; using conditional negate.
11061;; For r0 % n where n is a power of 2 produce:
11062;; rsbs r1, r0, #0
11063;; and r0, r0, #(n - 1)
11064;; and r1, r1, #(n - 1)
11065;; rsbpl r0, r1, #0
11066
11067(define_expand "modsi3"
11068 [(match_operand:SI 0 "register_operand" "")
11069 (match_operand:SI 1 "register_operand" "")
11070 (match_operand:SI 2 "const_int_operand" "")]
11071 "TARGET_32BIT"
11072 {
11073 HOST_WIDE_INT val = INTVAL (operands[2]);
11074
11075 if (val <= 0
11076 || exact_log2 (val) <= 0)
11077 FAIL;
11078
11079 rtx mask = GEN_INT (val - 1);
11080
11081 /* In the special case of x0 % 2 we can do the even shorter:
11082 cmp r0, #0
11083 and r0, r0, #1
11084 rsblt r0, r0, #0. */
11085
11086 if (val == 2)
11087 {
11088 rtx cc_reg = arm_gen_compare_reg (LT,
11089 operands[1], const0_rtx, NULL_RTX);
11090 rtx cond = gen_rtx_LT (SImode, cc_reg, const0_rtx);
11091 rtx masked = gen_reg_rtx (SImode);
11092
11093 emit_insn (gen_andsi3 (masked, operands[1], mask));
11094 emit_move_insn (operands[0],
11095 gen_rtx_IF_THEN_ELSE (SImode, cond,
11096 gen_rtx_NEG (SImode,
11097 masked),
11098 masked));
11099 DONE;
11100 }
11101
11102 rtx neg_op = gen_reg_rtx (SImode);
11103 rtx_insn *insn = emit_insn (gen_subsi3_compare0 (neg_op, const0_rtx,
11104 operands[1]));
11105
11106 /* Extract the condition register and mode. */
11107 rtx cmp = XVECEXP (PATTERN (insn), 0, 0);
11108 rtx cc_reg = SET_DEST (cmp);
11109 rtx cond = gen_rtx_GE (SImode, cc_reg, const0_rtx);
11110
11111 emit_insn (gen_andsi3 (operands[0], operands[1], mask));
11112
11113 rtx masked_neg = gen_reg_rtx (SImode);
11114 emit_insn (gen_andsi3 (masked_neg, neg_op, mask));
11115
11116 /* We want a conditional negate here, but emitting COND_EXEC rtxes
11117 during expand does not always work. Do an IF_THEN_ELSE instead. */
11118 emit_move_insn (operands[0],
11119 gen_rtx_IF_THEN_ELSE (SImode, cond,
11120 gen_rtx_NEG (SImode, masked_neg),
11121 operands[0]));
11122
11123
11124 DONE;
11125 }
11126)
11127
ff82f757 11128(define_expand "bswapsi2"
11129 [(set (match_operand:SI 0 "s_register_operand" "=r")
11130 (bswap:SI (match_operand:SI 1 "s_register_operand" "r")))]
8d1af482 11131"TARGET_EITHER && (arm_arch6 || !optimize_size)"
ff82f757 11132"
8d1af482 11133 if (!arm_arch6)
11134 {
11135 rtx op2 = gen_reg_rtx (SImode);
11136 rtx op3 = gen_reg_rtx (SImode);
ff82f757 11137
8d1af482 11138 if (TARGET_THUMB)
11139 {
11140 rtx op4 = gen_reg_rtx (SImode);
11141 rtx op5 = gen_reg_rtx (SImode);
ff82f757 11142
8d1af482 11143 emit_insn (gen_thumb_legacy_rev (operands[0], operands[1],
11144 op2, op3, op4, op5));
11145 }
11146 else
11147 {
11148 emit_insn (gen_arm_legacy_rev (operands[0], operands[1],
11149 op2, op3));
11150 }
ff82f757 11151
8d1af482 11152 DONE;
11153 }
ff82f757 11154 "
11155)
11156
a486b499 11157;; bswap16 patterns: use revsh and rev16 instructions for the signed
11158;; and unsigned variants, respectively. For rev16, expose
11159;; byte-swapping in the lower 16 bits only.
11160(define_insn "*arm_revsh"
11161 [(set (match_operand:SI 0 "s_register_operand" "=l,l,r")
11162 (sign_extend:SI (bswap:HI (match_operand:HI 1 "s_register_operand" "l,l,r"))))]
11163 "arm_arch6"
11164 "@
11165 revsh\t%0, %1
11166 revsh%?\t%0, %1
11167 revsh%?\t%0, %1"
11168 [(set_attr "arch" "t1,t2,32")
1b7da4ac 11169 (set_attr "length" "2,2,4")
11170 (set_attr "type" "rev")]
a486b499 11171)
11172
11173(define_insn "*arm_rev16"
11174 [(set (match_operand:HI 0 "s_register_operand" "=l,l,r")
11175 (bswap:HI (match_operand:HI 1 "s_register_operand" "l,l,r")))]
11176 "arm_arch6"
11177 "@
11178 rev16\t%0, %1
11179 rev16%?\t%0, %1
11180 rev16%?\t%0, %1"
11181 [(set_attr "arch" "t1,t2,32")
1b7da4ac 11182 (set_attr "length" "2,2,4")
11183 (set_attr "type" "rev")]
09f69e55 11184)
11185
11186;; There are no canonicalisation rules for the position of the lshiftrt, ashift
11187;; operations within an IOR/AND RTX, therefore we have two patterns matching
11188;; each valid permutation.
11189
11190(define_insn "arm_rev16si2"
11191 [(set (match_operand:SI 0 "register_operand" "=l,l,r")
11192 (ior:SI (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "l,l,r")
11193 (const_int 8))
11194 (match_operand:SI 3 "const_int_operand" "n,n,n"))
11195 (and:SI (lshiftrt:SI (match_dup 1)
11196 (const_int 8))
11197 (match_operand:SI 2 "const_int_operand" "n,n,n"))))]
11198 "arm_arch6
11199 && aarch_rev16_shleft_mask_imm_p (operands[3], SImode)
11200 && aarch_rev16_shright_mask_imm_p (operands[2], SImode)"
11201 "rev16\\t%0, %1"
11202 [(set_attr "arch" "t1,t2,32")
11203 (set_attr "length" "2,2,4")
11204 (set_attr "type" "rev")]
11205)
11206
11207(define_insn "arm_rev16si2_alt"
11208 [(set (match_operand:SI 0 "register_operand" "=l,l,r")
11209 (ior:SI (and:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" "l,l,r")
11210 (const_int 8))
11211 (match_operand:SI 2 "const_int_operand" "n,n,n"))
11212 (and:SI (ashift:SI (match_dup 1)
11213 (const_int 8))
11214 (match_operand:SI 3 "const_int_operand" "n,n,n"))))]
11215 "arm_arch6
11216 && aarch_rev16_shleft_mask_imm_p (operands[3], SImode)
11217 && aarch_rev16_shright_mask_imm_p (operands[2], SImode)"
11218 "rev16\\t%0, %1"
11219 [(set_attr "arch" "t1,t2,32")
11220 (set_attr "length" "2,2,4")
11221 (set_attr "type" "rev")]
a486b499 11222)
11223
11224(define_expand "bswaphi2"
11225 [(set (match_operand:HI 0 "s_register_operand" "=r")
11226 (bswap:HI (match_operand:HI 1 "s_register_operand" "r")))]
11227"arm_arch6"
11228""
11229)
11230
1653cf17 11231;; Patterns for LDRD/STRD in Thumb2 mode
11232
11233(define_insn "*thumb2_ldrd"
11234 [(set (match_operand:SI 0 "s_register_operand" "=r")
11235 (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "rk")
11236 (match_operand:SI 2 "ldrd_strd_offset_operand" "Do"))))
11237 (set (match_operand:SI 3 "s_register_operand" "=r")
11238 (mem:SI (plus:SI (match_dup 1)
11239 (match_operand:SI 4 "const_int_operand" ""))))]
11240 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11241 && current_tune->prefer_ldrd_strd
11242 && ((INTVAL (operands[2]) + 4) == INTVAL (operands[4]))
11243 && (operands_ok_ldrd_strd (operands[0], operands[3],
11244 operands[1], INTVAL (operands[2]),
11245 false, true))"
11246 "ldrd%?\t%0, %3, [%1, %2]"
11247 [(set_attr "type" "load2")
d952d547 11248 (set_attr "predicable" "yes")
11249 (set_attr "predicable_short_it" "no")])
1653cf17 11250
11251(define_insn "*thumb2_ldrd_base"
11252 [(set (match_operand:SI 0 "s_register_operand" "=r")
11253 (mem:SI (match_operand:SI 1 "s_register_operand" "rk")))
11254 (set (match_operand:SI 2 "s_register_operand" "=r")
11255 (mem:SI (plus:SI (match_dup 1)
11256 (const_int 4))))]
11257 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11258 && current_tune->prefer_ldrd_strd
11259 && (operands_ok_ldrd_strd (operands[0], operands[2],
11260 operands[1], 0, false, true))"
11261 "ldrd%?\t%0, %2, [%1]"
11262 [(set_attr "type" "load2")
d952d547 11263 (set_attr "predicable" "yes")
11264 (set_attr "predicable_short_it" "no")])
1653cf17 11265
11266(define_insn "*thumb2_ldrd_base_neg"
11267 [(set (match_operand:SI 0 "s_register_operand" "=r")
11268 (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "rk")
11269 (const_int -4))))
11270 (set (match_operand:SI 2 "s_register_operand" "=r")
11271 (mem:SI (match_dup 1)))]
11272 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11273 && current_tune->prefer_ldrd_strd
11274 && (operands_ok_ldrd_strd (operands[0], operands[2],
11275 operands[1], -4, false, true))"
11276 "ldrd%?\t%0, %2, [%1, #-4]"
11277 [(set_attr "type" "load2")
d952d547 11278 (set_attr "predicable" "yes")
11279 (set_attr "predicable_short_it" "no")])
1653cf17 11280
11281(define_insn "*thumb2_strd"
11282 [(set (mem:SI (plus:SI (match_operand:SI 0 "s_register_operand" "rk")
11283 (match_operand:SI 1 "ldrd_strd_offset_operand" "Do")))
11284 (match_operand:SI 2 "s_register_operand" "r"))
11285 (set (mem:SI (plus:SI (match_dup 0)
11286 (match_operand:SI 3 "const_int_operand" "")))
11287 (match_operand:SI 4 "s_register_operand" "r"))]
11288 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11289 && current_tune->prefer_ldrd_strd
11290 && ((INTVAL (operands[1]) + 4) == INTVAL (operands[3]))
11291 && (operands_ok_ldrd_strd (operands[2], operands[4],
11292 operands[0], INTVAL (operands[1]),
11293 false, false))"
11294 "strd%?\t%2, %4, [%0, %1]"
11295 [(set_attr "type" "store2")
d952d547 11296 (set_attr "predicable" "yes")
11297 (set_attr "predicable_short_it" "no")])
1653cf17 11298
11299(define_insn "*thumb2_strd_base"
11300 [(set (mem:SI (match_operand:SI 0 "s_register_operand" "rk"))
11301 (match_operand:SI 1 "s_register_operand" "r"))
11302 (set (mem:SI (plus:SI (match_dup 0)
11303 (const_int 4)))
11304 (match_operand:SI 2 "s_register_operand" "r"))]
11305 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11306 && current_tune->prefer_ldrd_strd
11307 && (operands_ok_ldrd_strd (operands[1], operands[2],
11308 operands[0], 0, false, false))"
11309 "strd%?\t%1, %2, [%0]"
11310 [(set_attr "type" "store2")
d952d547 11311 (set_attr "predicable" "yes")
11312 (set_attr "predicable_short_it" "no")])
1653cf17 11313
11314(define_insn "*thumb2_strd_base_neg"
11315 [(set (mem:SI (plus:SI (match_operand:SI 0 "s_register_operand" "rk")
11316 (const_int -4)))
11317 (match_operand:SI 1 "s_register_operand" "r"))
11318 (set (mem:SI (match_dup 0))
11319 (match_operand:SI 2 "s_register_operand" "r"))]
11320 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11321 && current_tune->prefer_ldrd_strd
11322 && (operands_ok_ldrd_strd (operands[1], operands[2],
11323 operands[0], -4, false, false))"
11324 "strd%?\t%1, %2, [%0, #-4]"
11325 [(set_attr "type" "store2")
d952d547 11326 (set_attr "predicable" "yes")
11327 (set_attr "predicable_short_it" "no")])
1653cf17 11328
2a0c73f2 11329;; ARMv8 CRC32 instructions.
11330(define_insn "<crc_variant>"
11331 [(set (match_operand:SI 0 "s_register_operand" "=r")
11332 (unspec:SI [(match_operand:SI 1 "s_register_operand" "r")
11333 (match_operand:<crc_mode> 2 "s_register_operand" "r")]
11334 CRC))]
11335 "TARGET_CRC32"
11336 "<crc_variant>\\t%0, %1, %2"
11337 [(set_attr "type" "crc")
11338 (set_attr "conds" "unconditional")]
11339)
1653cf17 11340
353cf59a 11341;; Load the load/store double peephole optimizations.
11342(include "ldrdstrd.md")
11343
320ea44d 11344;; Load the load/store multiple patterns
11345(include "ldmstm.md")
426be8c5 11346
11347;; Patterns in ldmstm.md don't cover more than 4 registers. This pattern covers
11348;; large lists without explicit writeback generated for APCS_FRAME epilogue.
11349(define_insn "*load_multiple"
11350 [(match_parallel 0 "load_multiple_operation"
11351 [(set (match_operand:SI 2 "s_register_operand" "=rk")
11352 (mem:SI (match_operand:SI 1 "s_register_operand" "rk")))
11353 ])]
11354 "TARGET_32BIT"
11355 "*
11356 {
11357 arm_output_multireg_pop (operands, /*return_pc=*/false,
11358 /*cond=*/const_true_rtx,
11359 /*reverse=*/false,
11360 /*update=*/false);
11361 return \"\";
11362 }
11363 "
11364 [(set_attr "predicable" "yes")]
11365)
11366
84450ddc 11367(define_expand "copysignsf3"
11368 [(match_operand:SF 0 "register_operand")
11369 (match_operand:SF 1 "register_operand")
11370 (match_operand:SF 2 "register_operand")]
11371 "TARGET_SOFT_FLOAT && arm_arch_thumb2"
11372 "{
11373 emit_move_insn (operands[0], operands[2]);
11374 emit_insn (gen_insv_t2 (simplify_gen_subreg (SImode, operands[0], SFmode, 0),
11375 GEN_INT (31), GEN_INT (0),
11376 simplify_gen_subreg (SImode, operands[1], SFmode, 0)));
11377 DONE;
11378 }"
11379)
11380
11381(define_expand "copysigndf3"
11382 [(match_operand:DF 0 "register_operand")
11383 (match_operand:DF 1 "register_operand")
11384 (match_operand:DF 2 "register_operand")]
11385 "TARGET_SOFT_FLOAT && arm_arch_thumb2"
11386 "{
11387 rtx op0_low = gen_lowpart (SImode, operands[0]);
11388 rtx op0_high = gen_highpart (SImode, operands[0]);
11389 rtx op1_low = gen_lowpart (SImode, operands[1]);
11390 rtx op1_high = gen_highpart (SImode, operands[1]);
11391 rtx op2_high = gen_highpart (SImode, operands[2]);
11392
11393 rtx scratch1 = gen_reg_rtx (SImode);
11394 rtx scratch2 = gen_reg_rtx (SImode);
11395 emit_move_insn (scratch1, op2_high);
11396 emit_move_insn (scratch2, op1_high);
11397
d1f9b275 11398 emit_insn(gen_rtx_SET(scratch1,
84450ddc 11399 gen_rtx_LSHIFTRT (SImode, op2_high, GEN_INT(31))));
11400 emit_insn(gen_insv_t2(scratch2, GEN_INT(1), GEN_INT(31), scratch1));
11401 emit_move_insn (op0_low, op1_low);
11402 emit_move_insn (op0_high, scratch2);
11403
11404 DONE;
11405 }"
11406)
11407
115857ef 11408;; movmisalign patterns for HImode and SImode.
11409(define_expand "movmisalign<mode>"
11410 [(match_operand:HSI 0 "general_operand")
11411 (match_operand:HSI 1 "general_operand")]
11412 "unaligned_access"
11413{
11414 /* This pattern is not permitted to fail during expansion: if both arguments
11415 are non-registers (e.g. memory := constant), force operand 1 into a
11416 register. */
11417 rtx (* gen_unaligned_load)(rtx, rtx);
11418 rtx tmp_dest = operands[0];
11419 if (!s_register_operand (operands[0], <MODE>mode)
11420 && !s_register_operand (operands[1], <MODE>mode))
11421 operands[1] = force_reg (<MODE>mode, operands[1]);
11422
11423 if (<MODE>mode == HImode)
11424 {
11425 gen_unaligned_load = gen_unaligned_loadhiu;
11426 tmp_dest = gen_reg_rtx (SImode);
11427 }
11428 else
11429 gen_unaligned_load = gen_unaligned_loadsi;
11430
11431 if (MEM_P (operands[1]))
11432 {
11433 emit_insn (gen_unaligned_load (tmp_dest, operands[1]));
11434 if (<MODE>mode == HImode)
11435 emit_move_insn (operands[0], gen_lowpart (HImode, tmp_dest));
11436 }
11437 else
11438 emit_insn (gen_unaligned_store<mode> (operands[0], operands[1]));
11439
11440 DONE;
11441})
11442
d98a3884 11443;; Vector bits common to IWMMXT and Neon
11444(include "vec-common.md")
755eb2b4 11445;; Load the Intel Wireless Multimedia Extension patterns
11446(include "iwmmxt.md")
a2cd141b 11447;; Load the VFP co-processor patterns
11448(include "vfp.md")
bc360af8 11449;; Thumb-1 patterns
11450(include "thumb1.md")
25f905c2 11451;; Thumb-2 patterns
11452(include "thumb2.md")
d98a3884 11453;; Neon patterns
11454(include "neon.md")
e84fdf6e 11455;; Crypto patterns
11456(include "crypto.md")
06df6b17 11457;; Synchronization Primitives
11458(include "sync.md")
bbbe4599 11459;; Fixed-point patterns
11460(include "arm-fixed.md")