1 ;;- Machine description for ARM for GNU compiler
2 ;; Copyright (C) 1991-2013 Free Software Foundation, Inc.
3 ;; Contributed by Pieter `Tiggr' Schoenmakers (rcpieter@win.tue.nl)
4 ;; and Martin Simmons (@harleqn.co.uk).
5 ;; More major hacks by Richard Earnshaw (rearnsha@arm.com).
7 ;; This file is part of GCC.
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
11 ;; by the Free Software Foundation; either version 3, or (at your
12 ;; option) any later version.
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.
19 ;; You should have received a copy of the GNU General Public License
20 ;; along with GCC; see the file COPYING3. If not see
21 ;; <http://www.gnu.org/licenses/>.
23 ;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
25 ;; Beware of splitting Thumb1 patterns that output multiple
26 ;; assembly instructions, in particular instruction such as SBC and
27 ;; ADC which consume flags. For example, in the pattern thumb_subdi3
28 ;; below, the output SUB implicitly sets the flags (assembled to SUBS)
29 ;; and then the Carry flag is used by SBC to compute the correct
30 ;; result. If we split thumb_subdi3 pattern into two separate RTL
31 ;; insns (using define_insn_and_split), the scheduler might place
32 ;; other RTL insns between SUB and SBC, possibly modifying the Carry
33 ;; flag used by SBC. This might happen because most Thumb1 patterns
34 ;; for flag-setting instructions do not have explicit RTL for setting
35 ;; or clobbering the flags. Instead, they have the attribute "conds"
36 ;; with value "set" or "clob". However, this attribute is not used to
37 ;; identify dependencies and therefore the scheduler might reorder
38 ;; these instruction. Currenly, this problem cannot happen because
39 ;; there are no separate Thumb1 patterns for individual instruction
40 ;; that consume flags (except conditional execution, which is treated
41 ;; differently). In particular there is no Thumb1 armv6-m pattern for
45 ;;---------------------------------------------------------------------------
48 ;; Register numbers -- All machine registers should be defined here
50 [(R0_REGNUM 0) ; First CORE register
51 (R1_REGNUM 1) ; Second CORE register
52 (IP_REGNUM 12) ; Scratch register
53 (SP_REGNUM 13) ; Stack pointer
54 (LR_REGNUM 14) ; Return address register
55 (PC_REGNUM 15) ; Program counter
56 (LAST_ARM_REGNUM 15) ;
57 (CC_REGNUM 100) ; Condition code pseudo register
58 (VFPCC_REGNUM 101) ; VFP Condition code pseudo register
61 ;; 3rd operand to select_dominance_cc_mode
68 ;; conditional compare combination
79 ;;---------------------------------------------------------------------------
82 ;; Processor type. This is created automatically from arm-cores.def.
83 (include "arm-tune.md")
85 ;; Instruction classification types
88 ; IS_THUMB is set to 'yes' when we are generating Thumb code, and 'no' when
89 ; generating ARM code. This is used to control the length of some insn
90 ; patterns that share the same RTL in both ARM and Thumb code.
91 (define_attr "is_thumb" "no,yes" (const (symbol_ref "thumb_code")))
93 ; IS_ARCH6 is set to 'yes' when we are generating code form ARMv6.
94 (define_attr "is_arch6" "no,yes" (const (symbol_ref "arm_arch6")))
96 ; IS_THUMB1 is set to 'yes' iff we are generating Thumb-1 code.
97 (define_attr "is_thumb1" "no,yes" (const (symbol_ref "thumb1_code")))
99 ; We use this attribute to disable alternatives that can produce 32-bit
100 ; instructions inside an IT-block in Thumb2 state. ARMv8 deprecates IT blocks
101 ; that contain 32-bit instructions.
102 (define_attr "enabled_for_depr_it" "no,yes" (const_string "yes"))
104 ; This attribute is used to disable a predicated alternative when we have
106 (define_attr "predicable_short_it" "no,yes" (const_string "yes"))
108 ;; Operand number of an input operand that is shifted. Zero if the
109 ;; given instruction does not shift one of its input operands.
110 (define_attr "shift" "" (const_int 0))
112 ; Floating Point Unit. If we only have floating point emulation, then there
113 ; is no point in scheduling the floating point insns. (Well, for best
114 ; performance we should try and group them together).
115 (define_attr "fpu" "none,vfp"
116 (const (symbol_ref "arm_fpu_attr")))
118 (define_attr "predicated" "yes,no" (const_string "no"))
120 ; LENGTH of an instruction (in bytes)
121 (define_attr "length" ""
124 ; The architecture which supports the instruction (or alternative).
125 ; This can be "a" for ARM, "t" for either of the Thumbs, "32" for
126 ; TARGET_32BIT, "t1" or "t2" to specify a specific Thumb mode. "v6"
127 ; for ARM or Thumb-2 with arm_arch6, and nov6 for ARM without
128 ; arm_arch6. This attribute is used to compute attribute "enabled",
129 ; use type "any" to enable an alternative in all cases.
130 (define_attr "arch" "any,a,t,32,t1,t2,v6,nov6,neon_for_64bits,avoid_neon_for_64bits,iwmmxt,iwmmxt2"
131 (const_string "any"))
133 (define_attr "arch_enabled" "no,yes"
134 (cond [(eq_attr "arch" "any")
137 (and (eq_attr "arch" "a")
138 (match_test "TARGET_ARM"))
141 (and (eq_attr "arch" "t")
142 (match_test "TARGET_THUMB"))
145 (and (eq_attr "arch" "t1")
146 (match_test "TARGET_THUMB1"))
149 (and (eq_attr "arch" "t2")
150 (match_test "TARGET_THUMB2"))
153 (and (eq_attr "arch" "32")
154 (match_test "TARGET_32BIT"))
157 (and (eq_attr "arch" "v6")
158 (match_test "TARGET_32BIT && arm_arch6"))
161 (and (eq_attr "arch" "nov6")
162 (match_test "TARGET_32BIT && !arm_arch6"))
165 (and (eq_attr "arch" "avoid_neon_for_64bits")
166 (match_test "TARGET_NEON")
167 (not (match_test "TARGET_PREFER_NEON_64BITS")))
170 (and (eq_attr "arch" "neon_for_64bits")
171 (match_test "TARGET_NEON")
172 (match_test "TARGET_PREFER_NEON_64BITS"))
175 (and (eq_attr "arch" "iwmmxt2")
176 (match_test "TARGET_REALLY_IWMMXT2"))
177 (const_string "yes")]
179 (const_string "no")))
181 (define_attr "opt" "any,speed,size"
182 (const_string "any"))
184 (define_attr "opt_enabled" "no,yes"
185 (cond [(eq_attr "opt" "any")
188 (and (eq_attr "opt" "speed")
189 (match_test "optimize_function_for_speed_p (cfun)"))
192 (and (eq_attr "opt" "size")
193 (match_test "optimize_function_for_size_p (cfun)"))
194 (const_string "yes")]
195 (const_string "no")))
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")))
203 ; Allows an insn to disable certain alternatives for reasons other than
205 (define_attr "insn_enabled" "no,yes"
206 (const_string "yes"))
208 ; Enable all alternatives that are both arch_enabled and insn_enabled.
209 (define_attr "enabled" "no,yes"
210 (cond [(eq_attr "insn_enabled" "no")
213 (and (eq_attr "predicable_short_it" "no")
214 (and (eq_attr "predicated" "yes")
215 (match_test "arm_restrict_it")))
218 (and (eq_attr "enabled_for_depr_it" "no")
219 (match_test "arm_restrict_it"))
222 (and (eq_attr "use_literal_pool" "yes")
223 (match_test "arm_disable_literal_pool"))
226 (eq_attr "arch_enabled" "no")
229 (eq_attr "opt_enabled" "no")
231 (const_string "yes")))
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.
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.
239 ; NEG_POOL_RANGE is nonzero for insns that can reference a constant pool entry
240 ; before its address. It is set to <max_range> - (8 + <data_size>).
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))
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")))
253 ; An assembler sequence may clobber the condition codes without us knowing.
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.
256 (define_asm_attributes
257 [(set_attr "conds" "clob")
258 (set_attr "length" "4")
259 (set_attr "pool_range" "250")])
261 ; Load scheduling, set from the arm_ld_sched variable
262 ; initialized by arm_option_override()
263 (define_attr "ldsched" "no,yes" (const (symbol_ref "arm_ld_sched")))
265 ; YES if the "type" attribute assigned to the insn denotes an
266 ; Advanced SIMD instruction, NO otherwise.
267 (define_attr "is_neon_type" "yes,no"
268 (if_then_else (eq_attr "type"
269 "neon_add, neon_add_q, neon_add_widen, neon_add_long,\
270 neon_qadd, neon_qadd_q, neon_add_halve, neon_add_halve_q,\
271 neon_add_halve_narrow_q,\
272 neon_sub, neon_sub_q, neon_sub_widen, neon_sub_long, neon_qsub,\
273 neon_qsub_q, neon_sub_halve, neon_sub_halve_q,\
274 neon_sub_halve_narrow_q,\
275 neon_abs, neon_abs_q, neon_neg, neon_neg_q, neon_qneg,\
276 neon_qneg_q, neon_qabs, neon_qabs_q, neon_abd, neon_abd_q,\
277 neon_abd_long, neon_minmax, neon_minmax_q, neon_compare,\
278 neon_compare_q, neon_compare_zero, neon_compare_zero_q,\
279 neon_arith_acc, neon_arith_acc_q, neon_reduc_add,\
280 neon_reduc_add_q, neon_reduc_add_long, neon_reduc_add_acc,\
281 neon_reduc_add_acc_q, neon_reduc_minmax, neon_reduc_minmax_q,\
282 neon_logic, neon_logic_q, neon_tst, neon_tst_q,\
283 neon_shift_imm, neon_shift_imm_q, neon_shift_imm_narrow_q,\
284 neon_shift_imm_long, neon_shift_reg, neon_shift_reg_q,\
285 neon_shift_acc, neon_shift_acc_q, neon_sat_shift_imm,\
286 neon_sat_shift_imm_q, neon_sat_shift_imm_narrow_q,\
287 neon_sat_shift_reg, neon_sat_shift_reg_q,\
288 neon_ins, neon_ins_q, neon_move, neon_move_q, neon_move_narrow_q,\
289 neon_permute, neon_permute_q, neon_zip, neon_zip_q, neon_tbl1,\
290 neon_tbl1_q, neon_tbl2, neon_tbl2_q, neon_tbl3, neon_tbl3_q,\
291 neon_tbl4, neon_tbl4_q, neon_bsl, neon_bsl_q, neon_cls,\
292 neon_cls_q, neon_cnt, neon_cnt_q, neon_dup, neon_dup_q,\
293 neon_ext, neon_ext_q, neon_rbit, neon_rbit_q,\
294 neon_rev, neon_rev_q, neon_mul_b, neon_mul_b_q, neon_mul_h,\
295 neon_mul_h_q, neon_mul_s, neon_mul_s_q, neon_mul_b_long,\
296 neon_mul_h_long, neon_mul_s_long, neon_mul_h_scalar,\
297 neon_mul_h_scalar_q, neon_mul_s_scalar, neon_mul_s_scalar_q,\
298 neon_mul_h_scalar_long, neon_mul_s_scalar_long, neon_sat_mul_b,\
299 neon_sat_mul_b_q, neon_sat_mul_h, neon_sat_mul_h_q,\
300 neon_sat_mul_s, neon_sat_mul_s_q, neon_sat_mul_b_long,\
301 neon_sat_mul_h_long, neon_sat_mul_s_long, neon_sat_mul_h_scalar,\
302 neon_sat_mul_h_scalar_q, neon_sat_mul_s_scalar,\
303 neon_sat_mul_s_scalar_q, neon_sat_mul_h_scalar_long,\
304 neon_sat_mul_s_scalar_long, neon_mla_b, neon_mla_b_q, neon_mla_h,\
305 neon_mla_h_q, neon_mla_s, neon_mla_s_q, neon_mla_b_long,\
306 neon_mla_h_long, neon_mla_s_long, neon_mla_h_scalar,\
307 neon_mla_h_scalar_q, neon_mla_s_scalar, neon_mla_s_scalar_q,\
308 neon_mla_h_scalar_long, neon_mla_s_scalar_long,\
309 neon_sat_mla_b_long, neon_sat_mla_h_long,\
310 neon_sat_mla_s_long, neon_sat_mla_h_scalar_long,\
311 neon_sat_mla_s_scalar_long,\
312 neon_to_gp, neon_to_gp_q, neon_from_gp, neon_from_gp_q,\
313 neon_ldr, neon_load1_1reg, neon_load1_1reg_q, neon_load1_2reg,\
314 neon_load1_2reg_q, neon_load1_3reg, neon_load1_3reg_q,\
315 neon_load1_4reg, neon_load1_4reg_q, neon_load1_all_lanes,\
316 neon_load1_all_lanes_q, neon_load1_one_lane, neon_load1_one_lane_q,\
317 neon_load2_2reg, neon_load2_2reg_q, neon_load2_4reg,\
318 neon_load2_4reg_q, neon_load2_all_lanes, neon_load2_all_lanes_q,\
319 neon_load2_one_lane, neon_load2_one_lane_q,\
320 neon_load3_3reg, neon_load3_3reg_q, neon_load3_all_lanes,\
321 neon_load3_all_lanes_q, neon_load3_one_lane, neon_load3_one_lane_q,\
322 neon_load4_4reg, neon_load4_4reg_q, neon_load4_all_lanes,\
323 neon_load4_all_lanes_q, neon_load4_one_lane, neon_load4_one_lane_q,\
324 neon_str, neon_store1_1reg, neon_store1_1reg_q, neon_store1_2reg,\
325 neon_store1_2reg_q, neon_store1_3reg, neon_store1_3reg_q,\
326 neon_store1_4reg, neon_store1_4reg_q, neon_store1_one_lane,\
327 neon_store1_one_lane_q, neon_store2_2reg, neon_store2_2reg_q,\
328 neon_store2_4reg, neon_store2_4reg_q, neon_store2_one_lane,\
329 neon_store2_one_lane_q, neon_store3_3reg, neon_store3_3reg_q,\
330 neon_store3_one_lane, neon_store3_one_lane_q, neon_store4_4reg,\
331 neon_store4_4reg_q, neon_store4_one_lane, neon_store4_one_lane_q,\
332 neon_fp_abd_s, neon_fp_abd_s_q, neon_fp_abd_d, neon_fp_abd_d_q,\
333 neon_fp_addsub_s, neon_fp_addsub_s_q, neon_fp_addsub_d,\
334 neon_fp_addsub_d_q, neon_fp_compare_s, neon_fp_compare_s_q,\
335 neon_fp_compare_d, neon_fp_compare_d_q, neon_fp_minmax_s,\
336 neon_fp_minmax_s_q, neon_fp_minmax_d, neon_fp_minmax_d_q,\
337 neon_fp_reduc_add_s, neon_fp_reduc_add_s_q, neon_fp_reduc_add_d,\
338 neon_fp_reduc_add_d_q, neon_fp_reduc_minmax_s,
339 neon_fp_reduc_minmax_s_q, neon_fp_reduc_minmax_d,\
340 neon_fp_reduc_minmax_d_q,\
341 neon_fp_cvt_narrow_s_q, neon_fp_cvt_narrow_d_q,\
342 neon_fp_cvt_widen_h, neon_fp_cvt_widen_s, neon_fp_to_int_s,\
343 neon_fp_to_int_s_q, neon_int_to_fp_s, neon_int_to_fp_s_q,\
344 neon_fp_round_s, neon_fp_round_s_q, neon_fp_recpe_s,\
346 neon_fp_recpe_d, neon_fp_recpe_d_q, neon_fp_recps_s,\
347 neon_fp_recps_s_q, neon_fp_recps_d, neon_fp_recps_d_q,\
348 neon_fp_recpx_s, neon_fp_recpx_s_q, neon_fp_recpx_d,\
349 neon_fp_recpx_d_q, neon_fp_rsqrte_s, neon_fp_rsqrte_s_q,\
350 neon_fp_rsqrte_d, neon_fp_rsqrte_d_q, neon_fp_rsqrts_s,\
351 neon_fp_rsqrts_s_q, neon_fp_rsqrts_d, neon_fp_rsqrts_d_q,\
352 neon_fp_mul_s, neon_fp_mul_s_q, neon_fp_mul_s_scalar,\
353 neon_fp_mul_s_scalar_q, neon_fp_mul_d, neon_fp_mul_d_q,\
354 neon_fp_mul_d_scalar_q, neon_fp_mla_s, neon_fp_mla_s_q,\
355 neon_fp_mla_s_scalar, neon_fp_mla_s_scalar_q, neon_fp_mla_d,\
356 neon_fp_mla_d_q, neon_fp_mla_d_scalar_q, neon_fp_sqrt_s,\
357 neon_fp_sqrt_s_q, neon_fp_sqrt_d, neon_fp_sqrt_d_q,\
358 neon_fp_div_s, neon_fp_div_s_q, neon_fp_div_d, neon_fp_div_d_q")
360 (const_string "no")))
362 ; condition codes: this one is used by final_prescan_insn to speed up
363 ; conditionalizing instructions. It saves having to scan the rtl to see if
364 ; it uses or alters the condition codes.
366 ; USE means that the condition codes are used by the insn in the process of
367 ; outputting code, this means (at present) that we can't use the insn in
370 ; SET means that the purpose of the insn is to set the condition codes in a
371 ; well defined manner.
373 ; CLOB means that the condition codes are altered in an undefined manner, if
374 ; they are altered at all
376 ; UNCONDITIONAL means the instruction can not be conditionally executed and
377 ; that the instruction does not use or alter the condition codes.
379 ; NOCOND means that the instruction does not use or alter the condition
380 ; codes but can be converted into a conditionally exectuted instruction.
382 (define_attr "conds" "use,set,clob,unconditional,nocond"
384 (ior (eq_attr "is_thumb1" "yes")
385 (eq_attr "type" "call"))
386 (const_string "clob")
387 (if_then_else (eq_attr "is_neon_type" "no")
388 (const_string "nocond")
389 (const_string "unconditional"))))
391 ; Predicable means that the insn can be conditionally executed based on
392 ; an automatically added predicate (additional patterns are generated by
393 ; gen...). We default to 'no' because no Thumb patterns match this rule
394 ; and not all ARM patterns do.
395 (define_attr "predicable" "no,yes" (const_string "no"))
397 ; Only model the write buffer for ARM6 and ARM7. Earlier processors don't
398 ; have one. Later ones, such as StrongARM, have write-back caches, so don't
399 ; suffer blockages enough to warrant modelling this (and it can adversely
400 ; affect the schedule).
401 (define_attr "model_wbuf" "no,yes" (const (symbol_ref "arm_tune_wbuf")))
403 ; WRITE_CONFLICT implies that a read following an unrelated write is likely
404 ; to stall the processor. Used with model_wbuf above.
405 (define_attr "write_conflict" "no,yes"
406 (if_then_else (eq_attr "type"
409 (const_string "no")))
411 ; Classify the insns into those that take one cycle and those that take more
412 ; than one on the main cpu execution unit.
413 (define_attr "core_cycles" "single,multi"
414 (if_then_else (eq_attr "type"
415 "adc_imm, adc_reg, adcs_imm, adcs_reg, adr, alu_ext, alu_imm, alu_reg,\
416 alu_shift_imm, alu_shift_reg, alus_ext, alus_imm, alus_reg,\
417 alus_shift_imm, alus_shift_reg, bfm, csel, rev, logic_imm, logic_reg,\
418 logic_shift_imm, logic_shift_reg, logics_imm, logics_reg,\
419 logics_shift_imm, logics_shift_reg, extend, shift_imm, float, fcsel,\
420 wmmx_wor, wmmx_wxor, wmmx_wand, wmmx_wandn, wmmx_wmov, wmmx_tmcrr,\
421 wmmx_tmrrc, wmmx_wldr, wmmx_wstr, wmmx_tmcr, wmmx_tmrc, wmmx_wadd,\
422 wmmx_wsub, wmmx_wmul, wmmx_wmac, wmmx_wavg2, wmmx_tinsr, wmmx_textrm,\
423 wmmx_wshufh, wmmx_wcmpeq, wmmx_wcmpgt, wmmx_wmax, wmmx_wmin, wmmx_wpack,\
424 wmmx_wunpckih, wmmx_wunpckil, wmmx_wunpckeh, wmmx_wunpckel, wmmx_wror,\
425 wmmx_wsra, wmmx_wsrl, wmmx_wsll, wmmx_wmadd, wmmx_tmia, wmmx_tmiaph,\
426 wmmx_tmiaxy, wmmx_tbcst, wmmx_tmovmsk, wmmx_wacc, wmmx_waligni,\
427 wmmx_walignr, wmmx_tandc, wmmx_textrc, wmmx_torc, wmmx_torvsc, wmmx_wsad,\
428 wmmx_wabs, wmmx_wabsdiff, wmmx_waddsubhx, wmmx_wsubaddhx, wmmx_wavg4,\
429 wmmx_wmulw, wmmx_wqmulm, wmmx_wqmulwm, wmmx_waddbhus, wmmx_wqmiaxy,\
430 wmmx_wmiaxy, wmmx_wmiawxy, wmmx_wmerge")
431 (const_string "single")
432 (const_string "multi")))
434 ;; FAR_JUMP is "yes" if a BL instruction is used to generate a branch to a
435 ;; distant label. Only applicable to Thumb code.
436 (define_attr "far_jump" "yes,no" (const_string "no"))
439 ;; The number of machine instructions this pattern expands to.
440 ;; Used for Thumb-2 conditional execution.
441 (define_attr "ce_count" "" (const_int 1))
443 ;;---------------------------------------------------------------------------
446 (include "unspecs.md")
448 ;;---------------------------------------------------------------------------
451 (include "iterators.md")
453 ;;---------------------------------------------------------------------------
456 (include "predicates.md")
457 (include "constraints.md")
459 ;;---------------------------------------------------------------------------
460 ;; Pipeline descriptions
462 (define_attr "tune_cortexr4" "yes,no"
464 (eq_attr "tune" "cortexr4,cortexr4f,cortexr5")
466 (const_string "no"))))
468 ;; True if the generic scheduling description should be used.
470 (define_attr "generic_sched" "yes,no"
472 (ior (eq_attr "tune" "fa526,fa626,fa606te,fa626te,fmp626,fa726te,arm926ejs,arm1020e,arm1026ejs,arm1136js,arm1136jfs,cortexa5,cortexa7,cortexa8,cortexa9,cortexa12,cortexa15,cortexa53,cortexm4,marvell_pj4")
473 (eq_attr "tune_cortexr4" "yes"))
475 (const_string "yes"))))
477 (define_attr "generic_vfp" "yes,no"
479 (and (eq_attr "fpu" "vfp")
480 (eq_attr "tune" "!arm1020e,arm1022e,cortexa5,cortexa7,cortexa8,cortexa9,cortexa12,cortexa53,cortexm4,marvell_pj4")
481 (eq_attr "tune_cortexr4" "no"))
483 (const_string "no"))))
485 (include "marvell-f-iwmmxt.md")
486 (include "arm-generic.md")
487 (include "arm926ejs.md")
488 (include "arm1020e.md")
489 (include "arm1026ejs.md")
490 (include "arm1136jfs.md")
492 (include "fa606te.md")
493 (include "fa626te.md")
494 (include "fmp626.md")
495 (include "fa726te.md")
496 (include "cortex-a5.md")
497 (include "cortex-a7.md")
498 (include "cortex-a8.md")
499 (include "cortex-a9.md")
500 (include "cortex-a15.md")
501 (include "cortex-a53.md")
502 (include "cortex-r4.md")
503 (include "cortex-r4f.md")
504 (include "cortex-m4.md")
505 (include "cortex-m4-fpu.md")
507 (include "marvell-pj4.md")
510 ;;---------------------------------------------------------------------------
515 ;; Note: For DImode insns, there is normally no reason why operands should
516 ;; not be in the same register, what we don't want is for something being
517 ;; written to partially overlap something that is an input.
519 (define_expand "adddi3"
521 [(set (match_operand:DI 0 "s_register_operand" "")
522 (plus:DI (match_operand:DI 1 "s_register_operand" "")
523 (match_operand:DI 2 "arm_adddi_operand" "")))
524 (clobber (reg:CC CC_REGNUM))])]
529 if (!REG_P (operands[1]))
530 operands[1] = force_reg (DImode, operands[1]);
531 if (!REG_P (operands[2]))
532 operands[2] = force_reg (DImode, operands[2]);
537 (define_insn "*thumb1_adddi3"
538 [(set (match_operand:DI 0 "register_operand" "=l")
539 (plus:DI (match_operand:DI 1 "register_operand" "%0")
540 (match_operand:DI 2 "register_operand" "l")))
541 (clobber (reg:CC CC_REGNUM))
544 "add\\t%Q0, %Q0, %Q2\;adc\\t%R0, %R0, %R2"
545 [(set_attr "length" "4")
546 (set_attr "type" "multiple")]
549 (define_insn_and_split "*arm_adddi3"
550 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r,&r,&r,&r")
551 (plus:DI (match_operand:DI 1 "s_register_operand" "%0, 0, r, 0, r")
552 (match_operand:DI 2 "arm_adddi_operand" "r, 0, r, Dd, Dd")))
553 (clobber (reg:CC CC_REGNUM))]
554 "TARGET_32BIT && !TARGET_NEON"
556 "TARGET_32BIT && reload_completed
557 && ! (TARGET_NEON && IS_VFP_REGNUM (REGNO (operands[0])))"
558 [(parallel [(set (reg:CC_C CC_REGNUM)
559 (compare:CC_C (plus:SI (match_dup 1) (match_dup 2))
561 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
562 (set (match_dup 3) (plus:SI (plus:SI (match_dup 4) (match_dup 5))
563 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
566 operands[3] = gen_highpart (SImode, operands[0]);
567 operands[0] = gen_lowpart (SImode, operands[0]);
568 operands[4] = gen_highpart (SImode, operands[1]);
569 operands[1] = gen_lowpart (SImode, operands[1]);
570 operands[5] = gen_highpart_mode (SImode, DImode, operands[2]);
571 operands[2] = gen_lowpart (SImode, operands[2]);
573 [(set_attr "conds" "clob")
574 (set_attr "length" "8")
575 (set_attr "type" "multiple")]
578 (define_insn_and_split "*adddi_sesidi_di"
579 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
580 (plus:DI (sign_extend:DI
581 (match_operand:SI 2 "s_register_operand" "r,r"))
582 (match_operand:DI 1 "s_register_operand" "0,r")))
583 (clobber (reg:CC CC_REGNUM))]
586 "TARGET_32BIT && reload_completed"
587 [(parallel [(set (reg:CC_C CC_REGNUM)
588 (compare:CC_C (plus:SI (match_dup 1) (match_dup 2))
590 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
591 (set (match_dup 3) (plus:SI (plus:SI (ashiftrt:SI (match_dup 2)
594 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
597 operands[3] = gen_highpart (SImode, operands[0]);
598 operands[0] = gen_lowpart (SImode, operands[0]);
599 operands[4] = gen_highpart (SImode, operands[1]);
600 operands[1] = gen_lowpart (SImode, operands[1]);
601 operands[2] = gen_lowpart (SImode, operands[2]);
603 [(set_attr "conds" "clob")
604 (set_attr "length" "8")
605 (set_attr "type" "multiple")]
608 (define_insn_and_split "*adddi_zesidi_di"
609 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
610 (plus:DI (zero_extend:DI
611 (match_operand:SI 2 "s_register_operand" "r,r"))
612 (match_operand:DI 1 "s_register_operand" "0,r")))
613 (clobber (reg:CC CC_REGNUM))]
616 "TARGET_32BIT && reload_completed"
617 [(parallel [(set (reg:CC_C CC_REGNUM)
618 (compare:CC_C (plus:SI (match_dup 1) (match_dup 2))
620 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
621 (set (match_dup 3) (plus:SI (plus:SI (match_dup 4) (const_int 0))
622 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
625 operands[3] = gen_highpart (SImode, operands[0]);
626 operands[0] = gen_lowpart (SImode, operands[0]);
627 operands[4] = gen_highpart (SImode, operands[1]);
628 operands[1] = gen_lowpart (SImode, operands[1]);
629 operands[2] = gen_lowpart (SImode, operands[2]);
631 [(set_attr "conds" "clob")
632 (set_attr "length" "8")
633 (set_attr "type" "multiple")]
636 (define_expand "addsi3"
637 [(set (match_operand:SI 0 "s_register_operand" "")
638 (plus:SI (match_operand:SI 1 "s_register_operand" "")
639 (match_operand:SI 2 "reg_or_int_operand" "")))]
642 if (TARGET_32BIT && CONST_INT_P (operands[2]))
644 arm_split_constant (PLUS, SImode, NULL_RTX,
645 INTVAL (operands[2]), operands[0], operands[1],
646 optimize && can_create_pseudo_p ());
652 ; If there is a scratch available, this will be faster than synthesizing the
655 [(match_scratch:SI 3 "r")
656 (set (match_operand:SI 0 "arm_general_register_operand" "")
657 (plus:SI (match_operand:SI 1 "arm_general_register_operand" "")
658 (match_operand:SI 2 "const_int_operand" "")))]
660 !(const_ok_for_arm (INTVAL (operands[2]))
661 || const_ok_for_arm (-INTVAL (operands[2])))
662 && const_ok_for_arm (~INTVAL (operands[2]))"
663 [(set (match_dup 3) (match_dup 2))
664 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 3)))]
668 ;; The r/r/k alternative is required when reloading the address
669 ;; (plus (reg rN) (reg sp)) into (reg rN). In this case reload will
670 ;; put the duplicated register first, and not try the commutative version.
671 (define_insn_and_split "*arm_addsi3"
672 [(set (match_operand:SI 0 "s_register_operand" "=rk,l,l ,l ,r ,k ,r,r ,k ,r ,k,k,r ,k ,r")
673 (plus:SI (match_operand:SI 1 "s_register_operand" "%0 ,l,0 ,l ,rk,k ,r,rk,k ,rk,k,r,rk,k ,rk")
674 (match_operand:SI 2 "reg_or_int_operand" "rk ,l,Py,Pd,rI,rI,k,Pj,Pj,L ,L,L,PJ,PJ,?n")))]
689 subw%?\\t%0, %1, #%n2
690 subw%?\\t%0, %1, #%n2
693 && CONST_INT_P (operands[2])
694 && !const_ok_for_op (INTVAL (operands[2]), PLUS)
695 && (reload_completed || !arm_eliminable_register (operands[1]))"
696 [(clobber (const_int 0))]
698 arm_split_constant (PLUS, SImode, curr_insn,
699 INTVAL (operands[2]), operands[0],
703 [(set_attr "length" "2,4,4,4,4,4,4,4,4,4,4,4,4,4,16")
704 (set_attr "predicable" "yes")
705 (set_attr "predicable_short_it" "yes,yes,yes,yes,no,no,no,no,no,no,no,no,no,no,no")
706 (set_attr "arch" "t2,t2,t2,t2,*,*,*,t2,t2,*,*,a,t2,t2,*")
707 (set (attr "type") (if_then_else (match_operand 2 "const_int_operand" "")
708 (const_string "alu_imm")
709 (const_string "alu_reg")))
713 (define_insn_and_split "*thumb1_addsi3"
714 [(set (match_operand:SI 0 "register_operand" "=l,l,l,*rk,*hk,l,k,l,l,l")
715 (plus:SI (match_operand:SI 1 "register_operand" "%0,0,l,*0,*0,k,k,0,l,k")
716 (match_operand:SI 2 "nonmemory_operand" "I,J,lL,*hk,*rk,M,O,Pa,Pb,Pc")))]
719 static const char * const asms[] =
721 \"add\\t%0, %0, %2\",
722 \"sub\\t%0, %0, #%n2\",
723 \"add\\t%0, %1, %2\",
724 \"add\\t%0, %0, %2\",
725 \"add\\t%0, %0, %2\",
726 \"add\\t%0, %1, %2\",
727 \"add\\t%0, %1, %2\",
732 if ((which_alternative == 2 || which_alternative == 6)
733 && CONST_INT_P (operands[2])
734 && INTVAL (operands[2]) < 0)
735 return \"sub\\t%0, %1, #%n2\";
736 return asms[which_alternative];
738 "&& reload_completed && CONST_INT_P (operands[2])
739 && ((operands[1] != stack_pointer_rtx
740 && (INTVAL (operands[2]) > 255 || INTVAL (operands[2]) < -255))
741 || (operands[1] == stack_pointer_rtx
742 && INTVAL (operands[2]) > 1020))"
743 [(set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))
744 (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 3)))]
746 HOST_WIDE_INT offset = INTVAL (operands[2]);
747 if (operands[1] == stack_pointer_rtx)
753 else if (offset < -255)
756 operands[3] = GEN_INT (offset);
757 operands[2] = GEN_INT (INTVAL (operands[2]) - offset);
759 [(set_attr "length" "2,2,2,2,2,2,2,4,4,4")
760 (set_attr "type" "alus_imm,alus_imm,alus_reg,alus_reg,alus_reg,
761 alus_reg,alus_reg,multiple,multiple,multiple")]
764 ;; Reloading and elimination of the frame pointer can
765 ;; sometimes cause this optimization to be missed.
767 [(set (match_operand:SI 0 "arm_general_register_operand" "")
768 (match_operand:SI 1 "const_int_operand" ""))
770 (plus:SI (match_dup 0) (reg:SI SP_REGNUM)))]
772 && (unsigned HOST_WIDE_INT) (INTVAL (operands[1])) < 1024
773 && (INTVAL (operands[1]) & 3) == 0"
774 [(set (match_dup 0) (plus:SI (reg:SI SP_REGNUM) (match_dup 1)))]
778 (define_insn "addsi3_compare0"
779 [(set (reg:CC_NOOV CC_REGNUM)
781 (plus:SI (match_operand:SI 1 "s_register_operand" "r, r,r")
782 (match_operand:SI 2 "arm_add_operand" "I,L,r"))
784 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
785 (plus:SI (match_dup 1) (match_dup 2)))]
791 [(set_attr "conds" "set")
792 (set_attr "type" "alus_imm,alus_imm,alus_reg")]
795 (define_insn "*addsi3_compare0_scratch"
796 [(set (reg:CC_NOOV CC_REGNUM)
798 (plus:SI (match_operand:SI 0 "s_register_operand" "r, r, r")
799 (match_operand:SI 1 "arm_add_operand" "I,L, r"))
806 [(set_attr "conds" "set")
807 (set_attr "predicable" "yes")
808 (set_attr "type" "alus_imm,alus_imm,alus_reg")]
811 (define_insn "*compare_negsi_si"
812 [(set (reg:CC_Z CC_REGNUM)
814 (neg:SI (match_operand:SI 0 "s_register_operand" "l,r"))
815 (match_operand:SI 1 "s_register_operand" "l,r")))]
818 [(set_attr "conds" "set")
819 (set_attr "predicable" "yes")
820 (set_attr "arch" "t2,*")
821 (set_attr "length" "2,4")
822 (set_attr "predicable_short_it" "yes,no")
823 (set_attr "type" "alus_reg")]
826 ;; This is the canonicalization of addsi3_compare0_for_combiner when the
827 ;; addend is a constant.
828 (define_insn "cmpsi2_addneg"
829 [(set (reg:CC CC_REGNUM)
831 (match_operand:SI 1 "s_register_operand" "r,r")
832 (match_operand:SI 2 "arm_addimm_operand" "L,I")))
833 (set (match_operand:SI 0 "s_register_operand" "=r,r")
834 (plus:SI (match_dup 1)
835 (match_operand:SI 3 "arm_addimm_operand" "I,L")))]
836 "TARGET_32BIT && INTVAL (operands[2]) == -INTVAL (operands[3])"
839 sub%.\\t%0, %1, #%n3"
840 [(set_attr "conds" "set")
841 (set_attr "type" "alus_reg")]
844 ;; Convert the sequence
846 ;; cmn rd, #1 (equivalent to cmp rd, #-1)
850 ;; bcs dest ((unsigned)rn >= 1)
851 ;; similarly for the beq variant using bcc.
852 ;; This is a common looping idiom (while (n--))
854 [(set (match_operand:SI 0 "arm_general_register_operand" "")
855 (plus:SI (match_operand:SI 1 "arm_general_register_operand" "")
857 (set (match_operand 2 "cc_register" "")
858 (compare (match_dup 0) (const_int -1)))
860 (if_then_else (match_operator 3 "equality_operator"
861 [(match_dup 2) (const_int 0)])
862 (match_operand 4 "" "")
863 (match_operand 5 "" "")))]
864 "TARGET_32BIT && peep2_reg_dead_p (3, operands[2])"
868 (match_dup 1) (const_int 1)))
869 (set (match_dup 0) (plus:SI (match_dup 1) (const_int -1)))])
871 (if_then_else (match_op_dup 3 [(match_dup 2) (const_int 0)])
874 "operands[2] = gen_rtx_REG (CCmode, CC_REGNUM);
875 operands[3] = gen_rtx_fmt_ee ((GET_CODE (operands[3]) == NE
878 operands[2], const0_rtx);"
881 ;; The next four insns work because they compare the result with one of
882 ;; the operands, and we know that the use of the condition code is
883 ;; either GEU or LTU, so we can use the carry flag from the addition
884 ;; instead of doing the compare a second time.
885 (define_insn "*addsi3_compare_op1"
886 [(set (reg:CC_C CC_REGNUM)
888 (plus:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
889 (match_operand:SI 2 "arm_add_operand" "I,L,r"))
891 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
892 (plus:SI (match_dup 1) (match_dup 2)))]
898 [(set_attr "conds" "set")
899 (set_attr "type" "alus_imm,alus_imm,alus_reg")]
902 (define_insn "*addsi3_compare_op2"
903 [(set (reg:CC_C CC_REGNUM)
905 (plus:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
906 (match_operand:SI 2 "arm_add_operand" "I,L,r"))
908 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
909 (plus:SI (match_dup 1) (match_dup 2)))]
914 sub%.\\t%0, %1, #%n2"
915 [(set_attr "conds" "set")
916 (set_attr "type" "alus_imm,alus_imm,alus_reg")]
919 (define_insn "*compare_addsi2_op0"
920 [(set (reg:CC_C CC_REGNUM)
922 (plus:SI (match_operand:SI 0 "s_register_operand" "l,l,r,r,r")
923 (match_operand:SI 1 "arm_add_operand" "Pv,l,I,L,r"))
932 [(set_attr "conds" "set")
933 (set_attr "predicable" "yes")
934 (set_attr "arch" "t2,t2,*,*,*")
935 (set_attr "predicable_short_it" "yes,yes,no,no,no")
936 (set_attr "length" "2,2,4,4,4")
937 (set_attr "type" "alus_imm,alus_reg,alus_imm,alus_imm,alus_reg")]
940 (define_insn "*compare_addsi2_op1"
941 [(set (reg:CC_C CC_REGNUM)
943 (plus:SI (match_operand:SI 0 "s_register_operand" "l,l,r,r,r")
944 (match_operand:SI 1 "arm_add_operand" "Pv,l,I,L,r"))
953 [(set_attr "conds" "set")
954 (set_attr "predicable" "yes")
955 (set_attr "arch" "t2,t2,*,*,*")
956 (set_attr "predicable_short_it" "yes,yes,no,no,no")
957 (set_attr "length" "2,2,4,4,4")
958 (set_attr "type" "alus_imm,alus_reg,alus_imm,alus_imm,alus_reg")]
961 (define_insn "*addsi3_carryin_<optab>"
962 [(set (match_operand:SI 0 "s_register_operand" "=l,r,r")
963 (plus:SI (plus:SI (match_operand:SI 1 "s_register_operand" "%l,r,r")
964 (match_operand:SI 2 "arm_not_operand" "0,rI,K"))
965 (LTUGEU:SI (reg:<cnb> CC_REGNUM) (const_int 0))))]
970 sbc%?\\t%0, %1, #%B2"
971 [(set_attr "conds" "use")
972 (set_attr "predicable" "yes")
973 (set_attr "arch" "t2,*,*")
974 (set_attr "length" "4")
975 (set_attr "predicable_short_it" "yes,no,no")
976 (set_attr "type" "adc_reg,adc_reg,adc_imm")]
979 (define_insn "*addsi3_carryin_alt2_<optab>"
980 [(set (match_operand:SI 0 "s_register_operand" "=l,r,r")
981 (plus:SI (plus:SI (LTUGEU:SI (reg:<cnb> CC_REGNUM) (const_int 0))
982 (match_operand:SI 1 "s_register_operand" "%l,r,r"))
983 (match_operand:SI 2 "arm_rhs_operand" "l,rI,K")))]
988 sbc%?\\t%0, %1, #%B2"
989 [(set_attr "conds" "use")
990 (set_attr "predicable" "yes")
991 (set_attr "arch" "t2,*,*")
992 (set_attr "length" "4")
993 (set_attr "predicable_short_it" "yes,no,no")
994 (set_attr "type" "adc_reg,adc_reg,adc_imm")]
997 (define_insn "*addsi3_carryin_shift_<optab>"
998 [(set (match_operand:SI 0 "s_register_operand" "=r")
1000 (match_operator:SI 2 "shift_operator"
1001 [(match_operand:SI 3 "s_register_operand" "r")
1002 (match_operand:SI 4 "reg_or_int_operand" "rM")])
1003 (match_operand:SI 1 "s_register_operand" "r"))
1004 (LTUGEU:SI (reg:<cnb> CC_REGNUM) (const_int 0))))]
1006 "adc%?\\t%0, %1, %3%S2"
1007 [(set_attr "conds" "use")
1008 (set_attr "predicable" "yes")
1009 (set_attr "predicable_short_it" "no")
1010 (set (attr "type") (if_then_else (match_operand 4 "const_int_operand" "")
1011 (const_string "alu_shift_imm")
1012 (const_string "alu_shift_reg")))]
1015 (define_insn "*addsi3_carryin_clobercc_<optab>"
1016 [(set (match_operand:SI 0 "s_register_operand" "=r")
1017 (plus:SI (plus:SI (match_operand:SI 1 "s_register_operand" "%r")
1018 (match_operand:SI 2 "arm_rhs_operand" "rI"))
1019 (LTUGEU:SI (reg:<cnb> CC_REGNUM) (const_int 0))))
1020 (clobber (reg:CC CC_REGNUM))]
1022 "adc%.\\t%0, %1, %2"
1023 [(set_attr "conds" "set")
1024 (set_attr "type" "adcs_reg")]
1027 (define_insn "*subsi3_carryin"
1028 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
1029 (minus:SI (minus:SI (match_operand:SI 1 "reg_or_int_operand" "r,I")
1030 (match_operand:SI 2 "s_register_operand" "r,r"))
1031 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1036 [(set_attr "conds" "use")
1037 (set_attr "arch" "*,a")
1038 (set_attr "predicable" "yes")
1039 (set_attr "predicable_short_it" "no")
1040 (set_attr "type" "adc_reg,adc_imm")]
1043 (define_insn "*subsi3_carryin_const"
1044 [(set (match_operand:SI 0 "s_register_operand" "=r")
1045 (minus:SI (plus:SI (match_operand:SI 1 "reg_or_int_operand" "r")
1046 (match_operand:SI 2 "arm_not_operand" "K"))
1047 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1049 "sbc\\t%0, %1, #%B2"
1050 [(set_attr "conds" "use")
1051 (set_attr "type" "adc_imm")]
1054 (define_insn "*subsi3_carryin_compare"
1055 [(set (reg:CC CC_REGNUM)
1056 (compare:CC (match_operand:SI 1 "s_register_operand" "r")
1057 (match_operand:SI 2 "s_register_operand" "r")))
1058 (set (match_operand:SI 0 "s_register_operand" "=r")
1059 (minus:SI (minus:SI (match_dup 1)
1061 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1064 [(set_attr "conds" "set")
1065 (set_attr "type" "adcs_reg")]
1068 (define_insn "*subsi3_carryin_compare_const"
1069 [(set (reg:CC CC_REGNUM)
1070 (compare:CC (match_operand:SI 1 "reg_or_int_operand" "r")
1071 (match_operand:SI 2 "arm_not_operand" "K")))
1072 (set (match_operand:SI 0 "s_register_operand" "=r")
1073 (minus:SI (plus:SI (match_dup 1)
1075 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1077 "sbcs\\t%0, %1, #%B2"
1078 [(set_attr "conds" "set")
1079 (set_attr "type" "adcs_imm")]
1082 (define_insn "*subsi3_carryin_shift"
1083 [(set (match_operand:SI 0 "s_register_operand" "=r")
1085 (match_operand:SI 1 "s_register_operand" "r")
1086 (match_operator:SI 2 "shift_operator"
1087 [(match_operand:SI 3 "s_register_operand" "r")
1088 (match_operand:SI 4 "reg_or_int_operand" "rM")]))
1089 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1091 "sbc%?\\t%0, %1, %3%S2"
1092 [(set_attr "conds" "use")
1093 (set_attr "predicable" "yes")
1094 (set (attr "type") (if_then_else (match_operand 4 "const_int_operand" "")
1095 (const_string "alu_shift_imm")
1096 (const_string "alu_shift_reg")))]
1099 (define_insn "*rsbsi3_carryin_shift"
1100 [(set (match_operand:SI 0 "s_register_operand" "=r")
1102 (match_operator:SI 2 "shift_operator"
1103 [(match_operand:SI 3 "s_register_operand" "r")
1104 (match_operand:SI 4 "reg_or_int_operand" "rM")])
1105 (match_operand:SI 1 "s_register_operand" "r"))
1106 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1108 "rsc%?\\t%0, %1, %3%S2"
1109 [(set_attr "conds" "use")
1110 (set_attr "predicable" "yes")
1111 (set (attr "type") (if_then_else (match_operand 4 "const_int_operand" "")
1112 (const_string "alu_shift_imm")
1113 (const_string "alu_shift_reg")))]
1116 ; transform ((x << y) - 1) to ~(~(x-1) << y) Where X is a constant.
1118 [(set (match_operand:SI 0 "s_register_operand" "")
1119 (plus:SI (ashift:SI (match_operand:SI 1 "const_int_operand" "")
1120 (match_operand:SI 2 "s_register_operand" ""))
1122 (clobber (match_operand:SI 3 "s_register_operand" ""))]
1124 [(set (match_dup 3) (match_dup 1))
1125 (set (match_dup 0) (not:SI (ashift:SI (match_dup 3) (match_dup 2))))]
1127 operands[1] = GEN_INT (~(INTVAL (operands[1]) - 1));
1130 (define_expand "addsf3"
1131 [(set (match_operand:SF 0 "s_register_operand" "")
1132 (plus:SF (match_operand:SF 1 "s_register_operand" "")
1133 (match_operand:SF 2 "s_register_operand" "")))]
1134 "TARGET_32BIT && TARGET_HARD_FLOAT"
1138 (define_expand "adddf3"
1139 [(set (match_operand:DF 0 "s_register_operand" "")
1140 (plus:DF (match_operand:DF 1 "s_register_operand" "")
1141 (match_operand:DF 2 "s_register_operand" "")))]
1142 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
1146 (define_expand "subdi3"
1148 [(set (match_operand:DI 0 "s_register_operand" "")
1149 (minus:DI (match_operand:DI 1 "s_register_operand" "")
1150 (match_operand:DI 2 "s_register_operand" "")))
1151 (clobber (reg:CC CC_REGNUM))])]
1156 if (!REG_P (operands[1]))
1157 operands[1] = force_reg (DImode, operands[1]);
1158 if (!REG_P (operands[2]))
1159 operands[2] = force_reg (DImode, operands[2]);
1164 (define_insn_and_split "*arm_subdi3"
1165 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r,&r")
1166 (minus:DI (match_operand:DI 1 "s_register_operand" "0,r,0")
1167 (match_operand:DI 2 "s_register_operand" "r,0,0")))
1168 (clobber (reg:CC CC_REGNUM))]
1169 "TARGET_32BIT && !TARGET_NEON"
1170 "#" ; "subs\\t%Q0, %Q1, %Q2\;sbc\\t%R0, %R1, %R2"
1171 "&& reload_completed"
1172 [(parallel [(set (reg:CC CC_REGNUM)
1173 (compare:CC (match_dup 1) (match_dup 2)))
1174 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
1175 (set (match_dup 3) (minus:SI (minus:SI (match_dup 4) (match_dup 5))
1176 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1178 operands[3] = gen_highpart (SImode, operands[0]);
1179 operands[0] = gen_lowpart (SImode, operands[0]);
1180 operands[4] = gen_highpart (SImode, operands[1]);
1181 operands[1] = gen_lowpart (SImode, operands[1]);
1182 operands[5] = gen_highpart (SImode, operands[2]);
1183 operands[2] = gen_lowpart (SImode, operands[2]);
1185 [(set_attr "conds" "clob")
1186 (set_attr "length" "8")
1187 (set_attr "type" "multiple")]
1190 (define_insn "*thumb_subdi3"
1191 [(set (match_operand:DI 0 "register_operand" "=l")
1192 (minus:DI (match_operand:DI 1 "register_operand" "0")
1193 (match_operand:DI 2 "register_operand" "l")))
1194 (clobber (reg:CC CC_REGNUM))]
1196 "sub\\t%Q0, %Q0, %Q2\;sbc\\t%R0, %R0, %R2"
1197 [(set_attr "length" "4")
1198 (set_attr "type" "multiple")]
1201 (define_insn_and_split "*subdi_di_zesidi"
1202 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1203 (minus:DI (match_operand:DI 1 "s_register_operand" "0,r")
1205 (match_operand:SI 2 "s_register_operand" "r,r"))))
1206 (clobber (reg:CC CC_REGNUM))]
1208 "#" ; "subs\\t%Q0, %Q1, %2\;sbc\\t%R0, %R1, #0"
1209 "&& reload_completed"
1210 [(parallel [(set (reg:CC CC_REGNUM)
1211 (compare:CC (match_dup 1) (match_dup 2)))
1212 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
1213 (set (match_dup 3) (minus:SI (plus:SI (match_dup 4) (match_dup 5))
1214 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1216 operands[3] = gen_highpart (SImode, operands[0]);
1217 operands[0] = gen_lowpart (SImode, operands[0]);
1218 operands[4] = gen_highpart (SImode, operands[1]);
1219 operands[1] = gen_lowpart (SImode, operands[1]);
1220 operands[5] = GEN_INT (~0);
1222 [(set_attr "conds" "clob")
1223 (set_attr "length" "8")
1224 (set_attr "type" "multiple")]
1227 (define_insn_and_split "*subdi_di_sesidi"
1228 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1229 (minus:DI (match_operand:DI 1 "s_register_operand" "0,r")
1231 (match_operand:SI 2 "s_register_operand" "r,r"))))
1232 (clobber (reg:CC CC_REGNUM))]
1234 "#" ; "subs\\t%Q0, %Q1, %2\;sbc\\t%R0, %R1, %2, asr #31"
1235 "&& reload_completed"
1236 [(parallel [(set (reg:CC CC_REGNUM)
1237 (compare:CC (match_dup 1) (match_dup 2)))
1238 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
1239 (set (match_dup 3) (minus:SI (minus:SI (match_dup 4)
1240 (ashiftrt:SI (match_dup 2)
1242 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1244 operands[3] = gen_highpart (SImode, operands[0]);
1245 operands[0] = gen_lowpart (SImode, operands[0]);
1246 operands[4] = gen_highpart (SImode, operands[1]);
1247 operands[1] = gen_lowpart (SImode, operands[1]);
1249 [(set_attr "conds" "clob")
1250 (set_attr "length" "8")
1251 (set_attr "type" "multiple")]
1254 (define_insn_and_split "*subdi_zesidi_di"
1255 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1256 (minus:DI (zero_extend:DI
1257 (match_operand:SI 2 "s_register_operand" "r,r"))
1258 (match_operand:DI 1 "s_register_operand" "0,r")))
1259 (clobber (reg:CC CC_REGNUM))]
1261 "#" ; "rsbs\\t%Q0, %Q1, %2\;rsc\\t%R0, %R1, #0"
1263 ; "subs\\t%Q0, %2, %Q1\;rsc\\t%R0, %R1, #0"
1264 "&& reload_completed"
1265 [(parallel [(set (reg:CC CC_REGNUM)
1266 (compare:CC (match_dup 2) (match_dup 1)))
1267 (set (match_dup 0) (minus:SI (match_dup 2) (match_dup 1)))])
1268 (set (match_dup 3) (minus:SI (minus:SI (const_int 0) (match_dup 4))
1269 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1271 operands[3] = gen_highpart (SImode, operands[0]);
1272 operands[0] = gen_lowpart (SImode, operands[0]);
1273 operands[4] = gen_highpart (SImode, operands[1]);
1274 operands[1] = gen_lowpart (SImode, operands[1]);
1276 [(set_attr "conds" "clob")
1277 (set_attr "length" "8")
1278 (set_attr "type" "multiple")]
1281 (define_insn_and_split "*subdi_sesidi_di"
1282 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1283 (minus:DI (sign_extend:DI
1284 (match_operand:SI 2 "s_register_operand" "r,r"))
1285 (match_operand:DI 1 "s_register_operand" "0,r")))
1286 (clobber (reg:CC CC_REGNUM))]
1288 "#" ; "rsbs\\t%Q0, %Q1, %2\;rsc\\t%R0, %R1, %2, asr #31"
1290 ; "subs\\t%Q0, %2, %Q1\;rsc\\t%R0, %R1, %2, asr #31"
1291 "&& reload_completed"
1292 [(parallel [(set (reg:CC CC_REGNUM)
1293 (compare:CC (match_dup 2) (match_dup 1)))
1294 (set (match_dup 0) (minus:SI (match_dup 2) (match_dup 1)))])
1295 (set (match_dup 3) (minus:SI (minus:SI
1296 (ashiftrt:SI (match_dup 2)
1299 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1301 operands[3] = gen_highpart (SImode, operands[0]);
1302 operands[0] = gen_lowpart (SImode, operands[0]);
1303 operands[4] = gen_highpart (SImode, operands[1]);
1304 operands[1] = gen_lowpart (SImode, operands[1]);
1306 [(set_attr "conds" "clob")
1307 (set_attr "length" "8")
1308 (set_attr "type" "multiple")]
1311 (define_insn_and_split "*subdi_zesidi_zesidi"
1312 [(set (match_operand:DI 0 "s_register_operand" "=r")
1313 (minus:DI (zero_extend:DI
1314 (match_operand:SI 1 "s_register_operand" "r"))
1316 (match_operand:SI 2 "s_register_operand" "r"))))
1317 (clobber (reg:CC CC_REGNUM))]
1319 "#" ; "subs\\t%Q0, %1, %2\;sbc\\t%R0, %1, %1"
1320 "&& reload_completed"
1321 [(parallel [(set (reg:CC CC_REGNUM)
1322 (compare:CC (match_dup 1) (match_dup 2)))
1323 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
1324 (set (match_dup 3) (minus:SI (minus:SI (match_dup 1) (match_dup 1))
1325 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1327 operands[3] = gen_highpart (SImode, operands[0]);
1328 operands[0] = gen_lowpart (SImode, operands[0]);
1330 [(set_attr "conds" "clob")
1331 (set_attr "length" "8")
1332 (set_attr "type" "multiple")]
1335 (define_expand "subsi3"
1336 [(set (match_operand:SI 0 "s_register_operand" "")
1337 (minus:SI (match_operand:SI 1 "reg_or_int_operand" "")
1338 (match_operand:SI 2 "s_register_operand" "")))]
1341 if (CONST_INT_P (operands[1]))
1345 arm_split_constant (MINUS, SImode, NULL_RTX,
1346 INTVAL (operands[1]), operands[0],
1347 operands[2], optimize && can_create_pseudo_p ());
1350 else /* TARGET_THUMB1 */
1351 operands[1] = force_reg (SImode, operands[1]);
1356 (define_insn "thumb1_subsi3_insn"
1357 [(set (match_operand:SI 0 "register_operand" "=l")
1358 (minus:SI (match_operand:SI 1 "register_operand" "l")
1359 (match_operand:SI 2 "reg_or_int_operand" "lPd")))]
1362 [(set_attr "length" "2")
1363 (set_attr "conds" "set")
1364 (set_attr "type" "alus_reg")]
1367 ; ??? Check Thumb-2 split length
1368 (define_insn_and_split "*arm_subsi3_insn"
1369 [(set (match_operand:SI 0 "s_register_operand" "=l,l ,l ,l ,r ,r,r,rk,r")
1370 (minus:SI (match_operand:SI 1 "reg_or_int_operand" "l ,0 ,l ,Pz,rI,r,r,k ,?n")
1371 (match_operand:SI 2 "reg_or_int_operand" "l ,Py,Pd,l ,r ,I,r,r ,r")))]
1383 "&& (CONST_INT_P (operands[1])
1384 && !const_ok_for_arm (INTVAL (operands[1])))"
1385 [(clobber (const_int 0))]
1387 arm_split_constant (MINUS, SImode, curr_insn,
1388 INTVAL (operands[1]), operands[0], operands[2], 0);
1391 [(set_attr "length" "4,4,4,4,4,4,4,4,16")
1392 (set_attr "arch" "t2,t2,t2,t2,*,*,*,*,*")
1393 (set_attr "predicable" "yes")
1394 (set_attr "predicable_short_it" "yes,yes,yes,yes,no,no,no,no,no")
1395 (set_attr "type" "alu_reg,alu_reg,alu_reg,alu_reg,alu_imm,alu_imm,alu_reg,alu_reg,multiple")]
1399 [(match_scratch:SI 3 "r")
1400 (set (match_operand:SI 0 "arm_general_register_operand" "")
1401 (minus:SI (match_operand:SI 1 "const_int_operand" "")
1402 (match_operand:SI 2 "arm_general_register_operand" "")))]
1404 && !const_ok_for_arm (INTVAL (operands[1]))
1405 && const_ok_for_arm (~INTVAL (operands[1]))"
1406 [(set (match_dup 3) (match_dup 1))
1407 (set (match_dup 0) (minus:SI (match_dup 3) (match_dup 2)))]
1411 (define_insn "*subsi3_compare0"
1412 [(set (reg:CC_NOOV CC_REGNUM)
1414 (minus:SI (match_operand:SI 1 "arm_rhs_operand" "r,r,I")
1415 (match_operand:SI 2 "arm_rhs_operand" "I,r,r"))
1417 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
1418 (minus:SI (match_dup 1) (match_dup 2)))]
1424 [(set_attr "conds" "set")
1425 (set_attr "type" "alus_imm,alus_reg,alus_reg")]
1428 (define_insn "subsi3_compare"
1429 [(set (reg:CC CC_REGNUM)
1430 (compare:CC (match_operand:SI 1 "arm_rhs_operand" "r,r,I")
1431 (match_operand:SI 2 "arm_rhs_operand" "I,r,r")))
1432 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
1433 (minus:SI (match_dup 1) (match_dup 2)))]
1439 [(set_attr "conds" "set")
1440 (set_attr "type" "alus_imm,alus_reg,alus_reg")]
1443 (define_expand "subsf3"
1444 [(set (match_operand:SF 0 "s_register_operand" "")
1445 (minus:SF (match_operand:SF 1 "s_register_operand" "")
1446 (match_operand:SF 2 "s_register_operand" "")))]
1447 "TARGET_32BIT && TARGET_HARD_FLOAT"
1451 (define_expand "subdf3"
1452 [(set (match_operand:DF 0 "s_register_operand" "")
1453 (minus:DF (match_operand:DF 1 "s_register_operand" "")
1454 (match_operand:DF 2 "s_register_operand" "")))]
1455 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
1460 ;; Multiplication insns
1462 (define_expand "mulhi3"
1463 [(set (match_operand:HI 0 "s_register_operand" "")
1464 (mult:HI (match_operand:HI 1 "s_register_operand" "")
1465 (match_operand:HI 2 "s_register_operand" "")))]
1466 "TARGET_DSP_MULTIPLY"
1469 rtx result = gen_reg_rtx (SImode);
1470 emit_insn (gen_mulhisi3 (result, operands[1], operands[2]));
1471 emit_move_insn (operands[0], gen_lowpart (HImode, result));
1476 (define_expand "mulsi3"
1477 [(set (match_operand:SI 0 "s_register_operand" "")
1478 (mult:SI (match_operand:SI 2 "s_register_operand" "")
1479 (match_operand:SI 1 "s_register_operand" "")))]
1484 ;; Use `&' and then `0' to prevent the operands 0 and 1 being the same
1485 (define_insn "*arm_mulsi3"
1486 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r")
1487 (mult:SI (match_operand:SI 2 "s_register_operand" "r,r")
1488 (match_operand:SI 1 "s_register_operand" "%0,r")))]
1489 "TARGET_32BIT && !arm_arch6"
1490 "mul%?\\t%0, %2, %1"
1491 [(set_attr "type" "mul")
1492 (set_attr "predicable" "yes")]
1495 (define_insn "*arm_mulsi3_v6"
1496 [(set (match_operand:SI 0 "s_register_operand" "=l,l,r")
1497 (mult:SI (match_operand:SI 1 "s_register_operand" "0,l,r")
1498 (match_operand:SI 2 "s_register_operand" "l,0,r")))]
1499 "TARGET_32BIT && arm_arch6"
1500 "mul%?\\t%0, %1, %2"
1501 [(set_attr "type" "mul")
1502 (set_attr "predicable" "yes")
1503 (set_attr "arch" "t2,t2,*")
1504 (set_attr "length" "4")
1505 (set_attr "predicable_short_it" "yes,yes,no")]
1508 ; Unfortunately with the Thumb the '&'/'0' trick can fails when operands
1509 ; 1 and 2; are the same, because reload will make operand 0 match
1510 ; operand 1 without realizing that this conflicts with operand 2. We fix
1511 ; this by adding another alternative to match this case, and then `reload'
1512 ; it ourselves. This alternative must come first.
1513 (define_insn "*thumb_mulsi3"
1514 [(set (match_operand:SI 0 "register_operand" "=&l,&l,&l")
1515 (mult:SI (match_operand:SI 1 "register_operand" "%l,*h,0")
1516 (match_operand:SI 2 "register_operand" "l,l,l")))]
1517 "TARGET_THUMB1 && !arm_arch6"
1519 if (which_alternative < 2)
1520 return \"mov\\t%0, %1\;mul\\t%0, %2\";
1522 return \"mul\\t%0, %2\";
1524 [(set_attr "length" "4,4,2")
1525 (set_attr "type" "muls")]
1528 (define_insn "*thumb_mulsi3_v6"
1529 [(set (match_operand:SI 0 "register_operand" "=l,l,l")
1530 (mult:SI (match_operand:SI 1 "register_operand" "0,l,0")
1531 (match_operand:SI 2 "register_operand" "l,0,0")))]
1532 "TARGET_THUMB1 && arm_arch6"
1537 [(set_attr "length" "2")
1538 (set_attr "type" "muls")]
1541 (define_insn "*mulsi3_compare0"
1542 [(set (reg:CC_NOOV CC_REGNUM)
1543 (compare:CC_NOOV (mult:SI
1544 (match_operand:SI 2 "s_register_operand" "r,r")
1545 (match_operand:SI 1 "s_register_operand" "%0,r"))
1547 (set (match_operand:SI 0 "s_register_operand" "=&r,&r")
1548 (mult:SI (match_dup 2) (match_dup 1)))]
1549 "TARGET_ARM && !arm_arch6"
1550 "mul%.\\t%0, %2, %1"
1551 [(set_attr "conds" "set")
1552 (set_attr "type" "muls")]
1555 (define_insn "*mulsi3_compare0_v6"
1556 [(set (reg:CC_NOOV CC_REGNUM)
1557 (compare:CC_NOOV (mult:SI
1558 (match_operand:SI 2 "s_register_operand" "r")
1559 (match_operand:SI 1 "s_register_operand" "r"))
1561 (set (match_operand:SI 0 "s_register_operand" "=r")
1562 (mult:SI (match_dup 2) (match_dup 1)))]
1563 "TARGET_ARM && arm_arch6 && optimize_size"
1564 "mul%.\\t%0, %2, %1"
1565 [(set_attr "conds" "set")
1566 (set_attr "type" "muls")]
1569 (define_insn "*mulsi_compare0_scratch"
1570 [(set (reg:CC_NOOV CC_REGNUM)
1571 (compare:CC_NOOV (mult:SI
1572 (match_operand:SI 2 "s_register_operand" "r,r")
1573 (match_operand:SI 1 "s_register_operand" "%0,r"))
1575 (clobber (match_scratch:SI 0 "=&r,&r"))]
1576 "TARGET_ARM && !arm_arch6"
1577 "mul%.\\t%0, %2, %1"
1578 [(set_attr "conds" "set")
1579 (set_attr "type" "muls")]
1582 (define_insn "*mulsi_compare0_scratch_v6"
1583 [(set (reg:CC_NOOV CC_REGNUM)
1584 (compare:CC_NOOV (mult:SI
1585 (match_operand:SI 2 "s_register_operand" "r")
1586 (match_operand:SI 1 "s_register_operand" "r"))
1588 (clobber (match_scratch:SI 0 "=r"))]
1589 "TARGET_ARM && arm_arch6 && optimize_size"
1590 "mul%.\\t%0, %2, %1"
1591 [(set_attr "conds" "set")
1592 (set_attr "type" "muls")]
1595 ;; Unnamed templates to match MLA instruction.
1597 (define_insn "*mulsi3addsi"
1598 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r,&r")
1600 (mult:SI (match_operand:SI 2 "s_register_operand" "r,r,r,r")
1601 (match_operand:SI 1 "s_register_operand" "%0,r,0,r"))
1602 (match_operand:SI 3 "s_register_operand" "r,r,0,0")))]
1603 "TARGET_32BIT && !arm_arch6"
1604 "mla%?\\t%0, %2, %1, %3"
1605 [(set_attr "type" "mla")
1606 (set_attr "predicable" "yes")]
1609 (define_insn "*mulsi3addsi_v6"
1610 [(set (match_operand:SI 0 "s_register_operand" "=r")
1612 (mult:SI (match_operand:SI 2 "s_register_operand" "r")
1613 (match_operand:SI 1 "s_register_operand" "r"))
1614 (match_operand:SI 3 "s_register_operand" "r")))]
1615 "TARGET_32BIT && arm_arch6"
1616 "mla%?\\t%0, %2, %1, %3"
1617 [(set_attr "type" "mla")
1618 (set_attr "predicable" "yes")
1619 (set_attr "predicable_short_it" "no")]
1622 (define_insn "*mulsi3addsi_compare0"
1623 [(set (reg:CC_NOOV CC_REGNUM)
1626 (match_operand:SI 2 "s_register_operand" "r,r,r,r")
1627 (match_operand:SI 1 "s_register_operand" "%0,r,0,r"))
1628 (match_operand:SI 3 "s_register_operand" "r,r,0,0"))
1630 (set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r,&r")
1631 (plus:SI (mult:SI (match_dup 2) (match_dup 1))
1633 "TARGET_ARM && arm_arch6"
1634 "mla%.\\t%0, %2, %1, %3"
1635 [(set_attr "conds" "set")
1636 (set_attr "type" "mlas")]
1639 (define_insn "*mulsi3addsi_compare0_v6"
1640 [(set (reg:CC_NOOV CC_REGNUM)
1643 (match_operand:SI 2 "s_register_operand" "r")
1644 (match_operand:SI 1 "s_register_operand" "r"))
1645 (match_operand:SI 3 "s_register_operand" "r"))
1647 (set (match_operand:SI 0 "s_register_operand" "=r")
1648 (plus:SI (mult:SI (match_dup 2) (match_dup 1))
1650 "TARGET_ARM && arm_arch6 && optimize_size"
1651 "mla%.\\t%0, %2, %1, %3"
1652 [(set_attr "conds" "set")
1653 (set_attr "type" "mlas")]
1656 (define_insn "*mulsi3addsi_compare0_scratch"
1657 [(set (reg:CC_NOOV CC_REGNUM)
1660 (match_operand:SI 2 "s_register_operand" "r,r,r,r")
1661 (match_operand:SI 1 "s_register_operand" "%0,r,0,r"))
1662 (match_operand:SI 3 "s_register_operand" "?r,r,0,0"))
1664 (clobber (match_scratch:SI 0 "=&r,&r,&r,&r"))]
1665 "TARGET_ARM && !arm_arch6"
1666 "mla%.\\t%0, %2, %1, %3"
1667 [(set_attr "conds" "set")
1668 (set_attr "type" "mlas")]
1671 (define_insn "*mulsi3addsi_compare0_scratch_v6"
1672 [(set (reg:CC_NOOV CC_REGNUM)
1675 (match_operand:SI 2 "s_register_operand" "r")
1676 (match_operand:SI 1 "s_register_operand" "r"))
1677 (match_operand:SI 3 "s_register_operand" "r"))
1679 (clobber (match_scratch:SI 0 "=r"))]
1680 "TARGET_ARM && arm_arch6 && optimize_size"
1681 "mla%.\\t%0, %2, %1, %3"
1682 [(set_attr "conds" "set")
1683 (set_attr "type" "mlas")]
1686 (define_insn "*mulsi3subsi"
1687 [(set (match_operand:SI 0 "s_register_operand" "=r")
1689 (match_operand:SI 3 "s_register_operand" "r")
1690 (mult:SI (match_operand:SI 2 "s_register_operand" "r")
1691 (match_operand:SI 1 "s_register_operand" "r"))))]
1692 "TARGET_32BIT && arm_arch_thumb2"
1693 "mls%?\\t%0, %2, %1, %3"
1694 [(set_attr "type" "mla")
1695 (set_attr "predicable" "yes")
1696 (set_attr "predicable_short_it" "no")]
1699 (define_expand "maddsidi4"
1700 [(set (match_operand:DI 0 "s_register_operand" "")
1703 (sign_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1704 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "")))
1705 (match_operand:DI 3 "s_register_operand" "")))]
1706 "TARGET_32BIT && arm_arch3m"
1709 (define_insn "*mulsidi3adddi"
1710 [(set (match_operand:DI 0 "s_register_operand" "=&r")
1713 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "%r"))
1714 (sign_extend:DI (match_operand:SI 3 "s_register_operand" "r")))
1715 (match_operand:DI 1 "s_register_operand" "0")))]
1716 "TARGET_32BIT && arm_arch3m && !arm_arch6"
1717 "smlal%?\\t%Q0, %R0, %3, %2"
1718 [(set_attr "type" "smlal")
1719 (set_attr "predicable" "yes")]
1722 (define_insn "*mulsidi3adddi_v6"
1723 [(set (match_operand:DI 0 "s_register_operand" "=r")
1726 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r"))
1727 (sign_extend:DI (match_operand:SI 3 "s_register_operand" "r")))
1728 (match_operand:DI 1 "s_register_operand" "0")))]
1729 "TARGET_32BIT && arm_arch6"
1730 "smlal%?\\t%Q0, %R0, %3, %2"
1731 [(set_attr "type" "smlal")
1732 (set_attr "predicable" "yes")
1733 (set_attr "predicable_short_it" "no")]
1736 ;; 32x32->64 widening multiply.
1737 ;; As with mulsi3, the only difference between the v3-5 and v6+
1738 ;; versions of these patterns is the requirement that the output not
1739 ;; overlap the inputs, but that still means we have to have a named
1740 ;; expander and two different starred insns.
1742 (define_expand "mulsidi3"
1743 [(set (match_operand:DI 0 "s_register_operand" "")
1745 (sign_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1746 (sign_extend:DI (match_operand:SI 2 "s_register_operand" ""))))]
1747 "TARGET_32BIT && arm_arch3m"
1751 (define_insn "*mulsidi3_nov6"
1752 [(set (match_operand:DI 0 "s_register_operand" "=&r")
1754 (sign_extend:DI (match_operand:SI 1 "s_register_operand" "%r"))
1755 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))]
1756 "TARGET_32BIT && arm_arch3m && !arm_arch6"
1757 "smull%?\\t%Q0, %R0, %1, %2"
1758 [(set_attr "type" "smull")
1759 (set_attr "predicable" "yes")]
1762 (define_insn "*mulsidi3_v6"
1763 [(set (match_operand:DI 0 "s_register_operand" "=r")
1765 (sign_extend:DI (match_operand:SI 1 "s_register_operand" "r"))
1766 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))]
1767 "TARGET_32BIT && arm_arch6"
1768 "smull%?\\t%Q0, %R0, %1, %2"
1769 [(set_attr "type" "smull")
1770 (set_attr "predicable" "yes")
1771 (set_attr "predicable_short_it" "no")]
1774 (define_expand "umulsidi3"
1775 [(set (match_operand:DI 0 "s_register_operand" "")
1777 (zero_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1778 (zero_extend:DI (match_operand:SI 2 "s_register_operand" ""))))]
1779 "TARGET_32BIT && arm_arch3m"
1783 (define_insn "*umulsidi3_nov6"
1784 [(set (match_operand:DI 0 "s_register_operand" "=&r")
1786 (zero_extend:DI (match_operand:SI 1 "s_register_operand" "%r"))
1787 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))]
1788 "TARGET_32BIT && arm_arch3m && !arm_arch6"
1789 "umull%?\\t%Q0, %R0, %1, %2"
1790 [(set_attr "type" "umull")
1791 (set_attr "predicable" "yes")]
1794 (define_insn "*umulsidi3_v6"
1795 [(set (match_operand:DI 0 "s_register_operand" "=r")
1797 (zero_extend:DI (match_operand:SI 1 "s_register_operand" "r"))
1798 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))]
1799 "TARGET_32BIT && arm_arch6"
1800 "umull%?\\t%Q0, %R0, %1, %2"
1801 [(set_attr "type" "umull")
1802 (set_attr "predicable" "yes")
1803 (set_attr "predicable_short_it" "no")]
1806 (define_expand "umaddsidi4"
1807 [(set (match_operand:DI 0 "s_register_operand" "")
1810 (zero_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1811 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "")))
1812 (match_operand:DI 3 "s_register_operand" "")))]
1813 "TARGET_32BIT && arm_arch3m"
1816 (define_insn "*umulsidi3adddi"
1817 [(set (match_operand:DI 0 "s_register_operand" "=&r")
1820 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "%r"))
1821 (zero_extend:DI (match_operand:SI 3 "s_register_operand" "r")))
1822 (match_operand:DI 1 "s_register_operand" "0")))]
1823 "TARGET_32BIT && arm_arch3m && !arm_arch6"
1824 "umlal%?\\t%Q0, %R0, %3, %2"
1825 [(set_attr "type" "umlal")
1826 (set_attr "predicable" "yes")]
1829 (define_insn "*umulsidi3adddi_v6"
1830 [(set (match_operand:DI 0 "s_register_operand" "=r")
1833 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r"))
1834 (zero_extend:DI (match_operand:SI 3 "s_register_operand" "r")))
1835 (match_operand:DI 1 "s_register_operand" "0")))]
1836 "TARGET_32BIT && arm_arch6"
1837 "umlal%?\\t%Q0, %R0, %3, %2"
1838 [(set_attr "type" "umlal")
1839 (set_attr "predicable" "yes")
1840 (set_attr "predicable_short_it" "no")]
1843 (define_expand "smulsi3_highpart"
1845 [(set (match_operand:SI 0 "s_register_operand" "")
1849 (sign_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1850 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "")))
1852 (clobber (match_scratch:SI 3 ""))])]
1853 "TARGET_32BIT && arm_arch3m"
1857 (define_insn "*smulsi3_highpart_nov6"
1858 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r")
1862 (sign_extend:DI (match_operand:SI 1 "s_register_operand" "%0,r"))
1863 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r,r")))
1865 (clobber (match_scratch:SI 3 "=&r,&r"))]
1866 "TARGET_32BIT && arm_arch3m && !arm_arch6"
1867 "smull%?\\t%3, %0, %2, %1"
1868 [(set_attr "type" "smull")
1869 (set_attr "predicable" "yes")]
1872 (define_insn "*smulsi3_highpart_v6"
1873 [(set (match_operand:SI 0 "s_register_operand" "=r")
1877 (sign_extend:DI (match_operand:SI 1 "s_register_operand" "r"))
1878 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r")))
1880 (clobber (match_scratch:SI 3 "=r"))]
1881 "TARGET_32BIT && arm_arch6"
1882 "smull%?\\t%3, %0, %2, %1"
1883 [(set_attr "type" "smull")
1884 (set_attr "predicable" "yes")
1885 (set_attr "predicable_short_it" "no")]
1888 (define_expand "umulsi3_highpart"
1890 [(set (match_operand:SI 0 "s_register_operand" "")
1894 (zero_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1895 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "")))
1897 (clobber (match_scratch:SI 3 ""))])]
1898 "TARGET_32BIT && arm_arch3m"
1902 (define_insn "*umulsi3_highpart_nov6"
1903 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r")
1907 (zero_extend:DI (match_operand:SI 1 "s_register_operand" "%0,r"))
1908 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r,r")))
1910 (clobber (match_scratch:SI 3 "=&r,&r"))]
1911 "TARGET_32BIT && arm_arch3m && !arm_arch6"
1912 "umull%?\\t%3, %0, %2, %1"
1913 [(set_attr "type" "umull")
1914 (set_attr "predicable" "yes")]
1917 (define_insn "*umulsi3_highpart_v6"
1918 [(set (match_operand:SI 0 "s_register_operand" "=r")
1922 (zero_extend:DI (match_operand:SI 1 "s_register_operand" "r"))
1923 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r")))
1925 (clobber (match_scratch:SI 3 "=r"))]
1926 "TARGET_32BIT && arm_arch6"
1927 "umull%?\\t%3, %0, %2, %1"
1928 [(set_attr "type" "umull")
1929 (set_attr "predicable" "yes")
1930 (set_attr "predicable_short_it" "no")]
1933 (define_insn "mulhisi3"
1934 [(set (match_operand:SI 0 "s_register_operand" "=r")
1935 (mult:SI (sign_extend:SI
1936 (match_operand:HI 1 "s_register_operand" "%r"))
1938 (match_operand:HI 2 "s_register_operand" "r"))))]
1939 "TARGET_DSP_MULTIPLY"
1940 "smulbb%?\\t%0, %1, %2"
1941 [(set_attr "type" "smulxy")
1942 (set_attr "predicable" "yes")]
1945 (define_insn "*mulhisi3tb"
1946 [(set (match_operand:SI 0 "s_register_operand" "=r")
1947 (mult:SI (ashiftrt:SI
1948 (match_operand:SI 1 "s_register_operand" "r")
1951 (match_operand:HI 2 "s_register_operand" "r"))))]
1952 "TARGET_DSP_MULTIPLY"
1953 "smultb%?\\t%0, %1, %2"
1954 [(set_attr "type" "smulxy")
1955 (set_attr "predicable" "yes")
1956 (set_attr "predicable_short_it" "no")]
1959 (define_insn "*mulhisi3bt"
1960 [(set (match_operand:SI 0 "s_register_operand" "=r")
1961 (mult:SI (sign_extend:SI
1962 (match_operand:HI 1 "s_register_operand" "r"))
1964 (match_operand:SI 2 "s_register_operand" "r")
1966 "TARGET_DSP_MULTIPLY"
1967 "smulbt%?\\t%0, %1, %2"
1968 [(set_attr "type" "smulxy")
1969 (set_attr "predicable" "yes")
1970 (set_attr "predicable_short_it" "no")]
1973 (define_insn "*mulhisi3tt"
1974 [(set (match_operand:SI 0 "s_register_operand" "=r")
1975 (mult:SI (ashiftrt:SI
1976 (match_operand:SI 1 "s_register_operand" "r")
1979 (match_operand:SI 2 "s_register_operand" "r")
1981 "TARGET_DSP_MULTIPLY"
1982 "smultt%?\\t%0, %1, %2"
1983 [(set_attr "type" "smulxy")
1984 (set_attr "predicable" "yes")
1985 (set_attr "predicable_short_it" "no")]
1988 (define_insn "maddhisi4"
1989 [(set (match_operand:SI 0 "s_register_operand" "=r")
1990 (plus:SI (mult:SI (sign_extend:SI
1991 (match_operand:HI 1 "s_register_operand" "r"))
1993 (match_operand:HI 2 "s_register_operand" "r")))
1994 (match_operand:SI 3 "s_register_operand" "r")))]
1995 "TARGET_DSP_MULTIPLY"
1996 "smlabb%?\\t%0, %1, %2, %3"
1997 [(set_attr "type" "smlaxy")
1998 (set_attr "predicable" "yes")
1999 (set_attr "predicable_short_it" "no")]
2002 ;; Note: there is no maddhisi4ibt because this one is canonical form
2003 (define_insn "*maddhisi4tb"
2004 [(set (match_operand:SI 0 "s_register_operand" "=r")
2005 (plus:SI (mult:SI (ashiftrt:SI
2006 (match_operand:SI 1 "s_register_operand" "r")
2009 (match_operand:HI 2 "s_register_operand" "r")))
2010 (match_operand:SI 3 "s_register_operand" "r")))]
2011 "TARGET_DSP_MULTIPLY"
2012 "smlatb%?\\t%0, %1, %2, %3"
2013 [(set_attr "type" "smlaxy")
2014 (set_attr "predicable" "yes")
2015 (set_attr "predicable_short_it" "no")]
2018 (define_insn "*maddhisi4tt"
2019 [(set (match_operand:SI 0 "s_register_operand" "=r")
2020 (plus:SI (mult:SI (ashiftrt:SI
2021 (match_operand:SI 1 "s_register_operand" "r")
2024 (match_operand:SI 2 "s_register_operand" "r")
2026 (match_operand:SI 3 "s_register_operand" "r")))]
2027 "TARGET_DSP_MULTIPLY"
2028 "smlatt%?\\t%0, %1, %2, %3"
2029 [(set_attr "type" "smlaxy")
2030 (set_attr "predicable" "yes")
2031 (set_attr "predicable_short_it" "no")]
2034 (define_insn "maddhidi4"
2035 [(set (match_operand:DI 0 "s_register_operand" "=r")
2037 (mult:DI (sign_extend:DI
2038 (match_operand:HI 1 "s_register_operand" "r"))
2040 (match_operand:HI 2 "s_register_operand" "r")))
2041 (match_operand:DI 3 "s_register_operand" "0")))]
2042 "TARGET_DSP_MULTIPLY"
2043 "smlalbb%?\\t%Q0, %R0, %1, %2"
2044 [(set_attr "type" "smlalxy")
2045 (set_attr "predicable" "yes")
2046 (set_attr "predicable_short_it" "no")])
2048 ;; Note: there is no maddhidi4ibt because this one is canonical form
2049 (define_insn "*maddhidi4tb"
2050 [(set (match_operand:DI 0 "s_register_operand" "=r")
2052 (mult:DI (sign_extend:DI
2054 (match_operand:SI 1 "s_register_operand" "r")
2057 (match_operand:HI 2 "s_register_operand" "r")))
2058 (match_operand:DI 3 "s_register_operand" "0")))]
2059 "TARGET_DSP_MULTIPLY"
2060 "smlaltb%?\\t%Q0, %R0, %1, %2"
2061 [(set_attr "type" "smlalxy")
2062 (set_attr "predicable" "yes")
2063 (set_attr "predicable_short_it" "no")])
2065 (define_insn "*maddhidi4tt"
2066 [(set (match_operand:DI 0 "s_register_operand" "=r")
2068 (mult:DI (sign_extend:DI
2070 (match_operand:SI 1 "s_register_operand" "r")
2074 (match_operand:SI 2 "s_register_operand" "r")
2076 (match_operand:DI 3 "s_register_operand" "0")))]
2077 "TARGET_DSP_MULTIPLY"
2078 "smlaltt%?\\t%Q0, %R0, %1, %2"
2079 [(set_attr "type" "smlalxy")
2080 (set_attr "predicable" "yes")
2081 (set_attr "predicable_short_it" "no")])
2083 (define_expand "mulsf3"
2084 [(set (match_operand:SF 0 "s_register_operand" "")
2085 (mult:SF (match_operand:SF 1 "s_register_operand" "")
2086 (match_operand:SF 2 "s_register_operand" "")))]
2087 "TARGET_32BIT && TARGET_HARD_FLOAT"
2091 (define_expand "muldf3"
2092 [(set (match_operand:DF 0 "s_register_operand" "")
2093 (mult:DF (match_operand:DF 1 "s_register_operand" "")
2094 (match_operand:DF 2 "s_register_operand" "")))]
2095 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
2101 (define_expand "divsf3"
2102 [(set (match_operand:SF 0 "s_register_operand" "")
2103 (div:SF (match_operand:SF 1 "s_register_operand" "")
2104 (match_operand:SF 2 "s_register_operand" "")))]
2105 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
2108 (define_expand "divdf3"
2109 [(set (match_operand:DF 0 "s_register_operand" "")
2110 (div:DF (match_operand:DF 1 "s_register_operand" "")
2111 (match_operand:DF 2 "s_register_operand" "")))]
2112 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
2115 ;; Boolean and,ior,xor insns
2117 ;; Split up double word logical operations
2119 ;; Split up simple DImode logical operations. Simply perform the logical
2120 ;; operation on the upper and lower halves of the registers.
2122 [(set (match_operand:DI 0 "s_register_operand" "")
2123 (match_operator:DI 6 "logical_binary_operator"
2124 [(match_operand:DI 1 "s_register_operand" "")
2125 (match_operand:DI 2 "s_register_operand" "")]))]
2126 "TARGET_32BIT && reload_completed
2127 && ! (TARGET_NEON && IS_VFP_REGNUM (REGNO (operands[0])))
2128 && ! IS_IWMMXT_REGNUM (REGNO (operands[0]))"
2129 [(set (match_dup 0) (match_op_dup:SI 6 [(match_dup 1) (match_dup 2)]))
2130 (set (match_dup 3) (match_op_dup:SI 6 [(match_dup 4) (match_dup 5)]))]
2133 operands[3] = gen_highpart (SImode, operands[0]);
2134 operands[0] = gen_lowpart (SImode, operands[0]);
2135 operands[4] = gen_highpart (SImode, operands[1]);
2136 operands[1] = gen_lowpart (SImode, operands[1]);
2137 operands[5] = gen_highpart (SImode, operands[2]);
2138 operands[2] = gen_lowpart (SImode, operands[2]);
2143 [(set (match_operand:DI 0 "s_register_operand" "")
2144 (match_operator:DI 6 "logical_binary_operator"
2145 [(sign_extend:DI (match_operand:SI 2 "s_register_operand" ""))
2146 (match_operand:DI 1 "s_register_operand" "")]))]
2147 "TARGET_32BIT && reload_completed"
2148 [(set (match_dup 0) (match_op_dup:SI 6 [(match_dup 1) (match_dup 2)]))
2149 (set (match_dup 3) (match_op_dup:SI 6
2150 [(ashiftrt:SI (match_dup 2) (const_int 31))
2154 operands[3] = gen_highpart (SImode, operands[0]);
2155 operands[0] = gen_lowpart (SImode, operands[0]);
2156 operands[4] = gen_highpart (SImode, operands[1]);
2157 operands[1] = gen_lowpart (SImode, operands[1]);
2158 operands[5] = gen_highpart (SImode, operands[2]);
2159 operands[2] = gen_lowpart (SImode, operands[2]);
2163 ;; The zero extend of operand 2 means we can just copy the high part of
2164 ;; operand1 into operand0.
2166 [(set (match_operand:DI 0 "s_register_operand" "")
2168 (zero_extend:DI (match_operand:SI 2 "s_register_operand" ""))
2169 (match_operand:DI 1 "s_register_operand" "")))]
2170 "TARGET_32BIT && operands[0] != operands[1] && reload_completed"
2171 [(set (match_dup 0) (ior:SI (match_dup 1) (match_dup 2)))
2172 (set (match_dup 3) (match_dup 4))]
2175 operands[4] = gen_highpart (SImode, operands[1]);
2176 operands[3] = gen_highpart (SImode, operands[0]);
2177 operands[0] = gen_lowpart (SImode, operands[0]);
2178 operands[1] = gen_lowpart (SImode, operands[1]);
2182 ;; The zero extend of operand 2 means we can just copy the high part of
2183 ;; operand1 into operand0.
2185 [(set (match_operand:DI 0 "s_register_operand" "")
2187 (zero_extend:DI (match_operand:SI 2 "s_register_operand" ""))
2188 (match_operand:DI 1 "s_register_operand" "")))]
2189 "TARGET_32BIT && operands[0] != operands[1] && reload_completed"
2190 [(set (match_dup 0) (xor:SI (match_dup 1) (match_dup 2)))
2191 (set (match_dup 3) (match_dup 4))]
2194 operands[4] = gen_highpart (SImode, operands[1]);
2195 operands[3] = gen_highpart (SImode, operands[0]);
2196 operands[0] = gen_lowpart (SImode, operands[0]);
2197 operands[1] = gen_lowpart (SImode, operands[1]);
2201 (define_expand "anddi3"
2202 [(set (match_operand:DI 0 "s_register_operand" "")
2203 (and:DI (match_operand:DI 1 "s_register_operand" "")
2204 (match_operand:DI 2 "neon_inv_logic_op2" "")))]
2209 (define_insn_and_split "*anddi3_insn"
2210 [(set (match_operand:DI 0 "s_register_operand" "=w,w ,&r,&r,&r,&r,?w,?w")
2211 (and:DI (match_operand:DI 1 "s_register_operand" "%w,0 ,0 ,r ,0 ,r ,w ,0")
2212 (match_operand:DI 2 "arm_anddi_operand_neon" "w ,DL,r ,r ,De,De,w ,DL")))]
2213 "TARGET_32BIT && !TARGET_IWMMXT"
2215 switch (which_alternative)
2217 case 0: /* fall through */
2218 case 6: return "vand\t%P0, %P1, %P2";
2219 case 1: /* fall through */
2220 case 7: return neon_output_logic_immediate ("vand", &operands[2],
2221 DImode, 1, VALID_NEON_QREG_MODE (DImode));
2225 case 5: /* fall through */
2227 default: gcc_unreachable ();
2230 "TARGET_32BIT && !TARGET_IWMMXT && reload_completed
2231 && !(IS_VFP_REGNUM (REGNO (operands[0])))"
2232 [(set (match_dup 3) (match_dup 4))
2233 (set (match_dup 5) (match_dup 6))]
2236 operands[3] = gen_lowpart (SImode, operands[0]);
2237 operands[5] = gen_highpart (SImode, operands[0]);
2239 operands[4] = simplify_gen_binary (AND, SImode,
2240 gen_lowpart (SImode, operands[1]),
2241 gen_lowpart (SImode, operands[2]));
2242 operands[6] = simplify_gen_binary (AND, SImode,
2243 gen_highpart (SImode, operands[1]),
2244 gen_highpart_mode (SImode, DImode, operands[2]));
2247 [(set_attr "type" "neon_logic,neon_logic,multiple,multiple,\
2248 multiple,multiple,neon_logic,neon_logic")
2249 (set_attr "arch" "neon_for_64bits,neon_for_64bits,*,*,*,*,
2250 avoid_neon_for_64bits,avoid_neon_for_64bits")
2251 (set_attr "length" "*,*,8,8,8,8,*,*")
2255 (define_insn_and_split "*anddi_zesidi_di"
2256 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2257 (and:DI (zero_extend:DI
2258 (match_operand:SI 2 "s_register_operand" "r,r"))
2259 (match_operand:DI 1 "s_register_operand" "0,r")))]
2262 "TARGET_32BIT && reload_completed"
2263 ; The zero extend of operand 2 clears the high word of the output
2265 [(set (match_dup 0) (and:SI (match_dup 1) (match_dup 2)))
2266 (set (match_dup 3) (const_int 0))]
2269 operands[3] = gen_highpart (SImode, operands[0]);
2270 operands[0] = gen_lowpart (SImode, operands[0]);
2271 operands[1] = gen_lowpart (SImode, operands[1]);
2273 [(set_attr "length" "8")
2274 (set_attr "type" "multiple")]
2277 (define_insn "*anddi_sesdi_di"
2278 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2279 (and:DI (sign_extend:DI
2280 (match_operand:SI 2 "s_register_operand" "r,r"))
2281 (match_operand:DI 1 "s_register_operand" "0,r")))]
2284 [(set_attr "length" "8")
2285 (set_attr "type" "multiple")]
2288 (define_expand "andsi3"
2289 [(set (match_operand:SI 0 "s_register_operand" "")
2290 (and:SI (match_operand:SI 1 "s_register_operand" "")
2291 (match_operand:SI 2 "reg_or_int_operand" "")))]
2296 if (CONST_INT_P (operands[2]))
2298 if (INTVAL (operands[2]) == 255 && arm_arch6)
2300 operands[1] = convert_to_mode (QImode, operands[1], 1);
2301 emit_insn (gen_thumb2_zero_extendqisi2_v6 (operands[0],
2305 arm_split_constant (AND, SImode, NULL_RTX,
2306 INTVAL (operands[2]), operands[0],
2308 optimize && can_create_pseudo_p ());
2313 else /* TARGET_THUMB1 */
2315 if (!CONST_INT_P (operands[2]))
2317 rtx tmp = force_reg (SImode, operands[2]);
2318 if (rtx_equal_p (operands[0], operands[1]))
2322 operands[2] = operands[1];
2330 if (((unsigned HOST_WIDE_INT) ~INTVAL (operands[2])) < 256)
2332 operands[2] = force_reg (SImode,
2333 GEN_INT (~INTVAL (operands[2])));
2335 emit_insn (gen_thumb1_bicsi3 (operands[0], operands[2], operands[1]));
2340 for (i = 9; i <= 31; i++)
2342 if ((((HOST_WIDE_INT) 1) << i) - 1 == INTVAL (operands[2]))
2344 emit_insn (gen_extzv (operands[0], operands[1], GEN_INT (i),
2348 else if ((((HOST_WIDE_INT) 1) << i) - 1
2349 == ~INTVAL (operands[2]))
2351 rtx shift = GEN_INT (i);
2352 rtx reg = gen_reg_rtx (SImode);
2354 emit_insn (gen_lshrsi3 (reg, operands[1], shift));
2355 emit_insn (gen_ashlsi3 (operands[0], reg, shift));
2361 operands[2] = force_reg (SImode, operands[2]);
2367 ; ??? Check split length for Thumb-2
2368 (define_insn_and_split "*arm_andsi3_insn"
2369 [(set (match_operand:SI 0 "s_register_operand" "=r,l,r,r,r")
2370 (and:SI (match_operand:SI 1 "s_register_operand" "%r,0,r,r,r")
2371 (match_operand:SI 2 "reg_or_int_operand" "I,l,K,r,?n")))]
2376 bic%?\\t%0, %1, #%B2
2380 && CONST_INT_P (operands[2])
2381 && !(const_ok_for_arm (INTVAL (operands[2]))
2382 || const_ok_for_arm (~INTVAL (operands[2])))"
2383 [(clobber (const_int 0))]
2385 arm_split_constant (AND, SImode, curr_insn,
2386 INTVAL (operands[2]), operands[0], operands[1], 0);
2389 [(set_attr "length" "4,4,4,4,16")
2390 (set_attr "predicable" "yes")
2391 (set_attr "predicable_short_it" "no,yes,no,no,no")
2392 (set_attr "type" "logic_imm,logic_imm,logic_reg,logic_reg,logic_imm")]
2395 (define_insn "*thumb1_andsi3_insn"
2396 [(set (match_operand:SI 0 "register_operand" "=l")
2397 (and:SI (match_operand:SI 1 "register_operand" "%0")
2398 (match_operand:SI 2 "register_operand" "l")))]
2401 [(set_attr "length" "2")
2402 (set_attr "type" "logic_imm")
2403 (set_attr "conds" "set")])
2405 (define_insn "*andsi3_compare0"
2406 [(set (reg:CC_NOOV CC_REGNUM)
2408 (and:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
2409 (match_operand:SI 2 "arm_not_operand" "I,K,r"))
2411 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
2412 (and:SI (match_dup 1) (match_dup 2)))]
2416 bic%.\\t%0, %1, #%B2
2418 [(set_attr "conds" "set")
2419 (set_attr "type" "logics_imm,logics_imm,logics_reg")]
2422 (define_insn "*andsi3_compare0_scratch"
2423 [(set (reg:CC_NOOV CC_REGNUM)
2425 (and:SI (match_operand:SI 0 "s_register_operand" "r,r,r")
2426 (match_operand:SI 1 "arm_not_operand" "I,K,r"))
2428 (clobber (match_scratch:SI 2 "=X,r,X"))]
2432 bic%.\\t%2, %0, #%B1
2434 [(set_attr "conds" "set")
2435 (set_attr "type" "logics_imm,logics_imm,logics_reg")]
2438 (define_insn "*zeroextractsi_compare0_scratch"
2439 [(set (reg:CC_NOOV CC_REGNUM)
2440 (compare:CC_NOOV (zero_extract:SI
2441 (match_operand:SI 0 "s_register_operand" "r")
2442 (match_operand 1 "const_int_operand" "n")
2443 (match_operand 2 "const_int_operand" "n"))
2446 && (INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) < 32
2447 && INTVAL (operands[1]) > 0
2448 && INTVAL (operands[1]) + (INTVAL (operands[2]) & 1) <= 8
2449 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32)"
2451 operands[1] = GEN_INT (((1 << INTVAL (operands[1])) - 1)
2452 << INTVAL (operands[2]));
2453 output_asm_insn (\"tst%?\\t%0, %1\", operands);
2456 [(set_attr "conds" "set")
2457 (set_attr "predicable" "yes")
2458 (set_attr "predicable_short_it" "no")
2459 (set_attr "type" "logics_imm")]
2462 (define_insn_and_split "*ne_zeroextractsi"
2463 [(set (match_operand:SI 0 "s_register_operand" "=r")
2464 (ne:SI (zero_extract:SI
2465 (match_operand:SI 1 "s_register_operand" "r")
2466 (match_operand:SI 2 "const_int_operand" "n")
2467 (match_operand:SI 3 "const_int_operand" "n"))
2469 (clobber (reg:CC CC_REGNUM))]
2471 && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
2472 && INTVAL (operands[2]) > 0
2473 && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
2474 && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)"
2477 && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
2478 && INTVAL (operands[2]) > 0
2479 && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
2480 && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)"
2481 [(parallel [(set (reg:CC_NOOV CC_REGNUM)
2482 (compare:CC_NOOV (and:SI (match_dup 1) (match_dup 2))
2484 (set (match_dup 0) (and:SI (match_dup 1) (match_dup 2)))])
2486 (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
2487 (match_dup 0) (const_int 1)))]
2489 operands[2] = GEN_INT (((1 << INTVAL (operands[2])) - 1)
2490 << INTVAL (operands[3]));
2492 [(set_attr "conds" "clob")
2493 (set (attr "length")
2494 (if_then_else (eq_attr "is_thumb" "yes")
2497 (set_attr "type" "multiple")]
2500 (define_insn_and_split "*ne_zeroextractsi_shifted"
2501 [(set (match_operand:SI 0 "s_register_operand" "=r")
2502 (ne:SI (zero_extract:SI
2503 (match_operand:SI 1 "s_register_operand" "r")
2504 (match_operand:SI 2 "const_int_operand" "n")
2507 (clobber (reg:CC CC_REGNUM))]
2511 [(parallel [(set (reg:CC_NOOV CC_REGNUM)
2512 (compare:CC_NOOV (ashift:SI (match_dup 1) (match_dup 2))
2514 (set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 2)))])
2516 (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
2517 (match_dup 0) (const_int 1)))]
2519 operands[2] = GEN_INT (32 - INTVAL (operands[2]));
2521 [(set_attr "conds" "clob")
2522 (set_attr "length" "8")
2523 (set_attr "type" "multiple")]
2526 (define_insn_and_split "*ite_ne_zeroextractsi"
2527 [(set (match_operand:SI 0 "s_register_operand" "=r")
2528 (if_then_else:SI (ne (zero_extract:SI
2529 (match_operand:SI 1 "s_register_operand" "r")
2530 (match_operand:SI 2 "const_int_operand" "n")
2531 (match_operand:SI 3 "const_int_operand" "n"))
2533 (match_operand:SI 4 "arm_not_operand" "rIK")
2535 (clobber (reg:CC CC_REGNUM))]
2537 && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
2538 && INTVAL (operands[2]) > 0
2539 && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
2540 && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)
2541 && !reg_overlap_mentioned_p (operands[0], operands[4])"
2544 && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
2545 && INTVAL (operands[2]) > 0
2546 && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
2547 && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)
2548 && !reg_overlap_mentioned_p (operands[0], operands[4])"
2549 [(parallel [(set (reg:CC_NOOV CC_REGNUM)
2550 (compare:CC_NOOV (and:SI (match_dup 1) (match_dup 2))
2552 (set (match_dup 0) (and:SI (match_dup 1) (match_dup 2)))])
2554 (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
2555 (match_dup 0) (match_dup 4)))]
2557 operands[2] = GEN_INT (((1 << INTVAL (operands[2])) - 1)
2558 << INTVAL (operands[3]));
2560 [(set_attr "conds" "clob")
2561 (set_attr "length" "8")
2562 (set_attr "type" "multiple")]
2565 (define_insn_and_split "*ite_ne_zeroextractsi_shifted"
2566 [(set (match_operand:SI 0 "s_register_operand" "=r")
2567 (if_then_else:SI (ne (zero_extract:SI
2568 (match_operand:SI 1 "s_register_operand" "r")
2569 (match_operand:SI 2 "const_int_operand" "n")
2572 (match_operand:SI 3 "arm_not_operand" "rIK")
2574 (clobber (reg:CC CC_REGNUM))]
2575 "TARGET_ARM && !reg_overlap_mentioned_p (operands[0], operands[3])"
2577 "TARGET_ARM && !reg_overlap_mentioned_p (operands[0], operands[3])"
2578 [(parallel [(set (reg:CC_NOOV CC_REGNUM)
2579 (compare:CC_NOOV (ashift:SI (match_dup 1) (match_dup 2))
2581 (set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 2)))])
2583 (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
2584 (match_dup 0) (match_dup 3)))]
2586 operands[2] = GEN_INT (32 - INTVAL (operands[2]));
2588 [(set_attr "conds" "clob")
2589 (set_attr "length" "8")
2590 (set_attr "type" "multiple")]
2594 [(set (match_operand:SI 0 "s_register_operand" "")
2595 (zero_extract:SI (match_operand:SI 1 "s_register_operand" "")
2596 (match_operand:SI 2 "const_int_operand" "")
2597 (match_operand:SI 3 "const_int_operand" "")))
2598 (clobber (match_operand:SI 4 "s_register_operand" ""))]
2600 [(set (match_dup 4) (ashift:SI (match_dup 1) (match_dup 2)))
2601 (set (match_dup 0) (lshiftrt:SI (match_dup 4) (match_dup 3)))]
2603 HOST_WIDE_INT temp = INTVAL (operands[2]);
2605 operands[2] = GEN_INT (32 - temp - INTVAL (operands[3]));
2606 operands[3] = GEN_INT (32 - temp);
2610 ;; ??? Use Thumb-2 has bitfield insert/extract instructions.
2612 [(set (match_operand:SI 0 "s_register_operand" "")
2613 (match_operator:SI 1 "shiftable_operator"
2614 [(zero_extract:SI (match_operand:SI 2 "s_register_operand" "")
2615 (match_operand:SI 3 "const_int_operand" "")
2616 (match_operand:SI 4 "const_int_operand" ""))
2617 (match_operand:SI 5 "s_register_operand" "")]))
2618 (clobber (match_operand:SI 6 "s_register_operand" ""))]
2620 [(set (match_dup 6) (ashift:SI (match_dup 2) (match_dup 3)))
2623 [(lshiftrt:SI (match_dup 6) (match_dup 4))
2626 HOST_WIDE_INT temp = INTVAL (operands[3]);
2628 operands[3] = GEN_INT (32 - temp - INTVAL (operands[4]));
2629 operands[4] = GEN_INT (32 - temp);
2634 [(set (match_operand:SI 0 "s_register_operand" "")
2635 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "")
2636 (match_operand:SI 2 "const_int_operand" "")
2637 (match_operand:SI 3 "const_int_operand" "")))]
2639 [(set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 2)))
2640 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (match_dup 3)))]
2642 HOST_WIDE_INT temp = INTVAL (operands[2]);
2644 operands[2] = GEN_INT (32 - temp - INTVAL (operands[3]));
2645 operands[3] = GEN_INT (32 - temp);
2650 [(set (match_operand:SI 0 "s_register_operand" "")
2651 (match_operator:SI 1 "shiftable_operator"
2652 [(sign_extract:SI (match_operand:SI 2 "s_register_operand" "")
2653 (match_operand:SI 3 "const_int_operand" "")
2654 (match_operand:SI 4 "const_int_operand" ""))
2655 (match_operand:SI 5 "s_register_operand" "")]))
2656 (clobber (match_operand:SI 6 "s_register_operand" ""))]
2658 [(set (match_dup 6) (ashift:SI (match_dup 2) (match_dup 3)))
2661 [(ashiftrt:SI (match_dup 6) (match_dup 4))
2664 HOST_WIDE_INT temp = INTVAL (operands[3]);
2666 operands[3] = GEN_INT (32 - temp - INTVAL (operands[4]));
2667 operands[4] = GEN_INT (32 - temp);
2671 ;;; ??? This pattern is bogus. If operand3 has bits outside the range
2672 ;;; represented by the bitfield, then this will produce incorrect results.
2673 ;;; Somewhere, the value needs to be truncated. On targets like the m68k,
2674 ;;; which have a real bit-field insert instruction, the truncation happens
2675 ;;; in the bit-field insert instruction itself. Since arm does not have a
2676 ;;; bit-field insert instruction, we would have to emit code here to truncate
2677 ;;; the value before we insert. This loses some of the advantage of having
2678 ;;; this insv pattern, so this pattern needs to be reevalutated.
2680 (define_expand "insv"
2681 [(set (zero_extract (match_operand 0 "nonimmediate_operand" "")
2682 (match_operand 1 "general_operand" "")
2683 (match_operand 2 "general_operand" ""))
2684 (match_operand 3 "reg_or_int_operand" ""))]
2685 "TARGET_ARM || arm_arch_thumb2"
2688 int start_bit = INTVAL (operands[2]);
2689 int width = INTVAL (operands[1]);
2690 HOST_WIDE_INT mask = (((HOST_WIDE_INT)1) << width) - 1;
2691 rtx target, subtarget;
2693 if (arm_arch_thumb2)
2695 if (unaligned_access && MEM_P (operands[0])
2696 && s_register_operand (operands[3], GET_MODE (operands[3]))
2697 && (width == 16 || width == 32) && (start_bit % BITS_PER_UNIT) == 0)
2701 if (BYTES_BIG_ENDIAN)
2702 start_bit = GET_MODE_BITSIZE (GET_MODE (operands[3])) - width
2707 base_addr = adjust_address (operands[0], SImode,
2708 start_bit / BITS_PER_UNIT);
2709 emit_insn (gen_unaligned_storesi (base_addr, operands[3]));
2713 rtx tmp = gen_reg_rtx (HImode);
2715 base_addr = adjust_address (operands[0], HImode,
2716 start_bit / BITS_PER_UNIT);
2717 emit_move_insn (tmp, gen_lowpart (HImode, operands[3]));
2718 emit_insn (gen_unaligned_storehi (base_addr, tmp));
2722 else if (s_register_operand (operands[0], GET_MODE (operands[0])))
2724 bool use_bfi = TRUE;
2726 if (CONST_INT_P (operands[3]))
2728 HOST_WIDE_INT val = INTVAL (operands[3]) & mask;
2732 emit_insn (gen_insv_zero (operands[0], operands[1],
2737 /* See if the set can be done with a single orr instruction. */
2738 if (val == mask && const_ok_for_arm (val << start_bit))
2744 if (!REG_P (operands[3]))
2745 operands[3] = force_reg (SImode, operands[3]);
2747 emit_insn (gen_insv_t2 (operands[0], operands[1], operands[2],
2756 if (!s_register_operand (operands[0], GET_MODE (operands[0])))
2759 target = copy_rtx (operands[0]);
2760 /* Avoid using a subreg as a subtarget, and avoid writing a paradoxical
2761 subreg as the final target. */
2762 if (GET_CODE (target) == SUBREG)
2764 subtarget = gen_reg_rtx (SImode);
2765 if (GET_MODE_SIZE (GET_MODE (SUBREG_REG (target)))
2766 < GET_MODE_SIZE (SImode))
2767 target = SUBREG_REG (target);
2772 if (CONST_INT_P (operands[3]))
2774 /* Since we are inserting a known constant, we may be able to
2775 reduce the number of bits that we have to clear so that
2776 the mask becomes simple. */
2777 /* ??? This code does not check to see if the new mask is actually
2778 simpler. It may not be. */
2779 rtx op1 = gen_reg_rtx (SImode);
2780 /* ??? Truncate operand3 to fit in the bitfield. See comment before
2781 start of this pattern. */
2782 HOST_WIDE_INT op3_value = mask & INTVAL (operands[3]);
2783 HOST_WIDE_INT mask2 = ((mask & ~op3_value) << start_bit);
2785 emit_insn (gen_andsi3 (op1, operands[0],
2786 gen_int_mode (~mask2, SImode)));
2787 emit_insn (gen_iorsi3 (subtarget, op1,
2788 gen_int_mode (op3_value << start_bit, SImode)));
2790 else if (start_bit == 0
2791 && !(const_ok_for_arm (mask)
2792 || const_ok_for_arm (~mask)))
2794 /* A Trick, since we are setting the bottom bits in the word,
2795 we can shift operand[3] up, operand[0] down, OR them together
2796 and rotate the result back again. This takes 3 insns, and
2797 the third might be mergeable into another op. */
2798 /* The shift up copes with the possibility that operand[3] is
2799 wider than the bitfield. */
2800 rtx op0 = gen_reg_rtx (SImode);
2801 rtx op1 = gen_reg_rtx (SImode);
2803 emit_insn (gen_ashlsi3 (op0, operands[3], GEN_INT (32 - width)));
2804 emit_insn (gen_lshrsi3 (op1, operands[0], operands[1]));
2805 emit_insn (gen_iorsi3 (op1, op1, op0));
2806 emit_insn (gen_rotlsi3 (subtarget, op1, operands[1]));
2808 else if ((width + start_bit == 32)
2809 && !(const_ok_for_arm (mask)
2810 || const_ok_for_arm (~mask)))
2812 /* Similar trick, but slightly less efficient. */
2814 rtx op0 = gen_reg_rtx (SImode);
2815 rtx op1 = gen_reg_rtx (SImode);
2817 emit_insn (gen_ashlsi3 (op0, operands[3], GEN_INT (32 - width)));
2818 emit_insn (gen_ashlsi3 (op1, operands[0], operands[1]));
2819 emit_insn (gen_lshrsi3 (op1, op1, operands[1]));
2820 emit_insn (gen_iorsi3 (subtarget, op1, op0));
2824 rtx op0 = gen_int_mode (mask, SImode);
2825 rtx op1 = gen_reg_rtx (SImode);
2826 rtx op2 = gen_reg_rtx (SImode);
2828 if (!(const_ok_for_arm (mask) || const_ok_for_arm (~mask)))
2830 rtx tmp = gen_reg_rtx (SImode);
2832 emit_insn (gen_movsi (tmp, op0));
2836 /* Mask out any bits in operand[3] that are not needed. */
2837 emit_insn (gen_andsi3 (op1, operands[3], op0));
2839 if (CONST_INT_P (op0)
2840 && (const_ok_for_arm (mask << start_bit)
2841 || const_ok_for_arm (~(mask << start_bit))))
2843 op0 = gen_int_mode (~(mask << start_bit), SImode);
2844 emit_insn (gen_andsi3 (op2, operands[0], op0));
2848 if (CONST_INT_P (op0))
2850 rtx tmp = gen_reg_rtx (SImode);
2852 emit_insn (gen_movsi (tmp, op0));
2857 emit_insn (gen_ashlsi3 (op0, op0, operands[2]));
2859 emit_insn (gen_andsi_notsi_si (op2, operands[0], op0));
2863 emit_insn (gen_ashlsi3 (op1, op1, operands[2]));
2865 emit_insn (gen_iorsi3 (subtarget, op1, op2));
2868 if (subtarget != target)
2870 /* If TARGET is still a SUBREG, then it must be wider than a word,
2871 so we must be careful only to set the subword we were asked to. */
2872 if (GET_CODE (target) == SUBREG)
2873 emit_move_insn (target, subtarget);
2875 emit_move_insn (target, gen_lowpart (GET_MODE (target), subtarget));
2882 (define_insn "insv_zero"
2883 [(set (zero_extract:SI (match_operand:SI 0 "s_register_operand" "+r")
2884 (match_operand:SI 1 "const_int_operand" "M")
2885 (match_operand:SI 2 "const_int_operand" "M"))
2889 [(set_attr "length" "4")
2890 (set_attr "predicable" "yes")
2891 (set_attr "predicable_short_it" "no")
2892 (set_attr "type" "bfm")]
2895 (define_insn "insv_t2"
2896 [(set (zero_extract:SI (match_operand:SI 0 "s_register_operand" "+r")
2897 (match_operand:SI 1 "const_int_operand" "M")
2898 (match_operand:SI 2 "const_int_operand" "M"))
2899 (match_operand:SI 3 "s_register_operand" "r"))]
2901 "bfi%?\t%0, %3, %2, %1"
2902 [(set_attr "length" "4")
2903 (set_attr "predicable" "yes")
2904 (set_attr "predicable_short_it" "no")
2905 (set_attr "type" "bfm")]
2908 ; constants for op 2 will never be given to these patterns.
2909 (define_insn_and_split "*anddi_notdi_di"
2910 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2911 (and:DI (not:DI (match_operand:DI 1 "s_register_operand" "0,r"))
2912 (match_operand:DI 2 "s_register_operand" "r,0")))]
2915 "TARGET_32BIT && reload_completed
2916 && ! (TARGET_NEON && IS_VFP_REGNUM (REGNO (operands[0])))
2917 && ! IS_IWMMXT_REGNUM (REGNO (operands[0]))"
2918 [(set (match_dup 0) (and:SI (not:SI (match_dup 1)) (match_dup 2)))
2919 (set (match_dup 3) (and:SI (not:SI (match_dup 4)) (match_dup 5)))]
2922 operands[3] = gen_highpart (SImode, operands[0]);
2923 operands[0] = gen_lowpart (SImode, operands[0]);
2924 operands[4] = gen_highpart (SImode, operands[1]);
2925 operands[1] = gen_lowpart (SImode, operands[1]);
2926 operands[5] = gen_highpart (SImode, operands[2]);
2927 operands[2] = gen_lowpart (SImode, operands[2]);
2929 [(set_attr "length" "8")
2930 (set_attr "predicable" "yes")
2931 (set_attr "type" "multiple")]
2934 (define_insn_and_split "*anddi_notzesidi_di"
2935 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2936 (and:DI (not:DI (zero_extend:DI
2937 (match_operand:SI 2 "s_register_operand" "r,r")))
2938 (match_operand:DI 1 "s_register_operand" "0,?r")))]
2941 bic%?\\t%Q0, %Q1, %2
2943 ; (not (zero_extend ...)) allows us to just copy the high word from
2944 ; operand1 to operand0.
2947 && operands[0] != operands[1]"
2948 [(set (match_dup 0) (and:SI (not:SI (match_dup 2)) (match_dup 1)))
2949 (set (match_dup 3) (match_dup 4))]
2952 operands[3] = gen_highpart (SImode, operands[0]);
2953 operands[0] = gen_lowpart (SImode, operands[0]);
2954 operands[4] = gen_highpart (SImode, operands[1]);
2955 operands[1] = gen_lowpart (SImode, operands[1]);
2957 [(set_attr "length" "4,8")
2958 (set_attr "predicable" "yes")
2959 (set_attr "predicable_short_it" "no")
2960 (set_attr "type" "multiple")]
2963 (define_insn_and_split "*anddi_notsesidi_di"
2964 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2965 (and:DI (not:DI (sign_extend:DI
2966 (match_operand:SI 2 "s_register_operand" "r,r")))
2967 (match_operand:DI 1 "s_register_operand" "0,r")))]
2970 "TARGET_32BIT && reload_completed"
2971 [(set (match_dup 0) (and:SI (not:SI (match_dup 2)) (match_dup 1)))
2972 (set (match_dup 3) (and:SI (not:SI
2973 (ashiftrt:SI (match_dup 2) (const_int 31)))
2977 operands[3] = gen_highpart (SImode, operands[0]);
2978 operands[0] = gen_lowpart (SImode, operands[0]);
2979 operands[4] = gen_highpart (SImode, operands[1]);
2980 operands[1] = gen_lowpart (SImode, operands[1]);
2982 [(set_attr "length" "8")
2983 (set_attr "predicable" "yes")
2984 (set_attr "predicable_short_it" "no")
2985 (set_attr "type" "multiple")]
2988 (define_insn "andsi_notsi_si"
2989 [(set (match_operand:SI 0 "s_register_operand" "=r")
2990 (and:SI (not:SI (match_operand:SI 2 "s_register_operand" "r"))
2991 (match_operand:SI 1 "s_register_operand" "r")))]
2993 "bic%?\\t%0, %1, %2"
2994 [(set_attr "predicable" "yes")
2995 (set_attr "predicable_short_it" "no")
2996 (set_attr "type" "logic_reg")]
2999 (define_insn "thumb1_bicsi3"
3000 [(set (match_operand:SI 0 "register_operand" "=l")
3001 (and:SI (not:SI (match_operand:SI 1 "register_operand" "l"))
3002 (match_operand:SI 2 "register_operand" "0")))]
3005 [(set_attr "length" "2")
3006 (set_attr "conds" "set")
3007 (set_attr "type" "logics_reg")]
3010 (define_insn "andsi_not_shiftsi_si"
3011 [(set (match_operand:SI 0 "s_register_operand" "=r")
3012 (and:SI (not:SI (match_operator:SI 4 "shift_operator"
3013 [(match_operand:SI 2 "s_register_operand" "r")
3014 (match_operand:SI 3 "arm_rhs_operand" "rM")]))
3015 (match_operand:SI 1 "s_register_operand" "r")))]
3017 "bic%?\\t%0, %1, %2%S4"
3018 [(set_attr "predicable" "yes")
3019 (set_attr "shift" "2")
3020 (set (attr "type") (if_then_else (match_operand 3 "const_int_operand" "")
3021 (const_string "logic_shift_imm")
3022 (const_string "logic_shift_reg")))]
3025 (define_insn "*andsi_notsi_si_compare0"
3026 [(set (reg:CC_NOOV CC_REGNUM)
3028 (and:SI (not:SI (match_operand:SI 2 "s_register_operand" "r"))
3029 (match_operand:SI 1 "s_register_operand" "r"))
3031 (set (match_operand:SI 0 "s_register_operand" "=r")
3032 (and:SI (not:SI (match_dup 2)) (match_dup 1)))]
3034 "bic%.\\t%0, %1, %2"
3035 [(set_attr "conds" "set")
3036 (set_attr "type" "logics_shift_reg")]
3039 (define_insn "*andsi_notsi_si_compare0_scratch"
3040 [(set (reg:CC_NOOV CC_REGNUM)
3042 (and:SI (not:SI (match_operand:SI 2 "s_register_operand" "r"))
3043 (match_operand:SI 1 "s_register_operand" "r"))
3045 (clobber (match_scratch:SI 0 "=r"))]
3047 "bic%.\\t%0, %1, %2"
3048 [(set_attr "conds" "set")
3049 (set_attr "type" "logics_shift_reg")]
3052 (define_expand "iordi3"
3053 [(set (match_operand:DI 0 "s_register_operand" "")
3054 (ior:DI (match_operand:DI 1 "s_register_operand" "")
3055 (match_operand:DI 2 "neon_logic_op2" "")))]
3060 (define_insn_and_split "*iordi3_insn"
3061 [(set (match_operand:DI 0 "s_register_operand" "=w,w ,&r,&r,&r,&r,?w,?w")
3062 (ior:DI (match_operand:DI 1 "s_register_operand" "%w,0 ,0 ,r ,0 ,r ,w ,0")
3063 (match_operand:DI 2 "arm_iordi_operand_neon" "w ,Dl,r ,r ,Df,Df,w ,Dl")))]
3064 "TARGET_32BIT && !TARGET_IWMMXT"
3066 switch (which_alternative)
3068 case 0: /* fall through */
3069 case 6: return "vorr\t%P0, %P1, %P2";
3070 case 1: /* fall through */
3071 case 7: return neon_output_logic_immediate ("vorr", &operands[2],
3072 DImode, 0, VALID_NEON_QREG_MODE (DImode));
3078 default: gcc_unreachable ();
3081 "TARGET_32BIT && !TARGET_IWMMXT && reload_completed
3082 && !(IS_VFP_REGNUM (REGNO (operands[0])))"
3083 [(set (match_dup 3) (match_dup 4))
3084 (set (match_dup 5) (match_dup 6))]
3087 operands[3] = gen_lowpart (SImode, operands[0]);
3088 operands[5] = gen_highpart (SImode, operands[0]);
3090 operands[4] = simplify_gen_binary (IOR, SImode,
3091 gen_lowpart (SImode, operands[1]),
3092 gen_lowpart (SImode, operands[2]));
3093 operands[6] = simplify_gen_binary (IOR, SImode,
3094 gen_highpart (SImode, operands[1]),
3095 gen_highpart_mode (SImode, DImode, operands[2]));
3098 [(set_attr "type" "neon_logic,neon_logic,multiple,multiple,multiple,\
3099 multiple,neon_logic,neon_logic")
3100 (set_attr "length" "*,*,8,8,8,8,*,*")
3101 (set_attr "arch" "neon_for_64bits,neon_for_64bits,*,*,*,*,avoid_neon_for_64bits,avoid_neon_for_64bits")]
3104 (define_insn "*iordi_zesidi_di"
3105 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
3106 (ior:DI (zero_extend:DI
3107 (match_operand:SI 2 "s_register_operand" "r,r"))
3108 (match_operand:DI 1 "s_register_operand" "0,?r")))]
3111 orr%?\\t%Q0, %Q1, %2
3113 [(set_attr "length" "4,8")
3114 (set_attr "predicable" "yes")
3115 (set_attr "predicable_short_it" "no")
3116 (set_attr "type" "logic_reg,multiple")]
3119 (define_insn "*iordi_sesidi_di"
3120 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
3121 (ior:DI (sign_extend:DI
3122 (match_operand:SI 2 "s_register_operand" "r,r"))
3123 (match_operand:DI 1 "s_register_operand" "0,r")))]
3126 [(set_attr "length" "8")
3127 (set_attr "predicable" "yes")
3128 (set_attr "type" "multiple")]
3131 (define_expand "iorsi3"
3132 [(set (match_operand:SI 0 "s_register_operand" "")
3133 (ior:SI (match_operand:SI 1 "s_register_operand" "")
3134 (match_operand:SI 2 "reg_or_int_operand" "")))]
3137 if (CONST_INT_P (operands[2]))
3141 arm_split_constant (IOR, SImode, NULL_RTX,
3142 INTVAL (operands[2]), operands[0], operands[1],
3143 optimize && can_create_pseudo_p ());
3146 else /* TARGET_THUMB1 */
3148 rtx tmp = force_reg (SImode, operands[2]);
3149 if (rtx_equal_p (operands[0], operands[1]))
3153 operands[2] = operands[1];
3161 (define_insn_and_split "*iorsi3_insn"
3162 [(set (match_operand:SI 0 "s_register_operand" "=r,l,r,r,r")
3163 (ior:SI (match_operand:SI 1 "s_register_operand" "%r,0,r,r,r")
3164 (match_operand:SI 2 "reg_or_int_operand" "I,l,K,r,?n")))]
3169 orn%?\\t%0, %1, #%B2
3173 && CONST_INT_P (operands[2])
3174 && !(const_ok_for_arm (INTVAL (operands[2]))
3175 || (TARGET_THUMB2 && const_ok_for_arm (~INTVAL (operands[2]))))"
3176 [(clobber (const_int 0))]
3178 arm_split_constant (IOR, SImode, curr_insn,
3179 INTVAL (operands[2]), operands[0], operands[1], 0);
3182 [(set_attr "length" "4,4,4,4,16")
3183 (set_attr "arch" "32,t2,t2,32,32")
3184 (set_attr "predicable" "yes")
3185 (set_attr "predicable_short_it" "no,yes,no,no,no")
3186 (set_attr "type" "logic_imm,logic_reg,logic_imm,logic_reg,logic_reg")]
3189 (define_insn "*thumb1_iorsi3_insn"
3190 [(set (match_operand:SI 0 "register_operand" "=l")
3191 (ior:SI (match_operand:SI 1 "register_operand" "%0")
3192 (match_operand:SI 2 "register_operand" "l")))]
3195 [(set_attr "length" "2")
3196 (set_attr "conds" "set")
3197 (set_attr "type" "logics_reg")])
3200 [(match_scratch:SI 3 "r")
3201 (set (match_operand:SI 0 "arm_general_register_operand" "")
3202 (ior:SI (match_operand:SI 1 "arm_general_register_operand" "")
3203 (match_operand:SI 2 "const_int_operand" "")))]
3205 && !const_ok_for_arm (INTVAL (operands[2]))
3206 && const_ok_for_arm (~INTVAL (operands[2]))"
3207 [(set (match_dup 3) (match_dup 2))
3208 (set (match_dup 0) (ior:SI (match_dup 1) (match_dup 3)))]
3212 (define_insn "*iorsi3_compare0"
3213 [(set (reg:CC_NOOV CC_REGNUM)
3214 (compare:CC_NOOV (ior:SI (match_operand:SI 1 "s_register_operand" "%r,r")
3215 (match_operand:SI 2 "arm_rhs_operand" "I,r"))
3217 (set (match_operand:SI 0 "s_register_operand" "=r,r")
3218 (ior:SI (match_dup 1) (match_dup 2)))]
3220 "orr%.\\t%0, %1, %2"
3221 [(set_attr "conds" "set")
3222 (set_attr "type" "logics_imm,logics_reg")]
3225 (define_insn "*iorsi3_compare0_scratch"
3226 [(set (reg:CC_NOOV CC_REGNUM)
3227 (compare:CC_NOOV (ior:SI (match_operand:SI 1 "s_register_operand" "%r,r")
3228 (match_operand:SI 2 "arm_rhs_operand" "I,r"))
3230 (clobber (match_scratch:SI 0 "=r,r"))]
3232 "orr%.\\t%0, %1, %2"
3233 [(set_attr "conds" "set")
3234 (set_attr "type" "logics_imm,logics_reg")]
3237 (define_expand "xordi3"
3238 [(set (match_operand:DI 0 "s_register_operand" "")
3239 (xor:DI (match_operand:DI 1 "s_register_operand" "")
3240 (match_operand:DI 2 "arm_xordi_operand" "")))]
3245 (define_insn_and_split "*xordi3_insn"
3246 [(set (match_operand:DI 0 "s_register_operand" "=w,&r,&r,&r,&r,?w")
3247 (xor:DI (match_operand:DI 1 "s_register_operand" "w ,%0,r ,0 ,r ,w")
3248 (match_operand:DI 2 "arm_xordi_operand" "w ,r ,r ,Dg,Dg,w")))]
3249 "TARGET_32BIT && !TARGET_IWMMXT"
3251 switch (which_alternative)
3256 case 4: /* fall through */
3258 case 0: /* fall through */
3259 case 5: return "veor\t%P0, %P1, %P2";
3260 default: gcc_unreachable ();
3263 "TARGET_32BIT && !TARGET_IWMMXT && reload_completed
3264 && !(IS_VFP_REGNUM (REGNO (operands[0])))"
3265 [(set (match_dup 3) (match_dup 4))
3266 (set (match_dup 5) (match_dup 6))]
3269 operands[3] = gen_lowpart (SImode, operands[0]);
3270 operands[5] = gen_highpart (SImode, operands[0]);
3272 operands[4] = simplify_gen_binary (XOR, SImode,
3273 gen_lowpart (SImode, operands[1]),
3274 gen_lowpart (SImode, operands[2]));
3275 operands[6] = simplify_gen_binary (XOR, SImode,
3276 gen_highpart (SImode, operands[1]),
3277 gen_highpart_mode (SImode, DImode, operands[2]));
3280 [(set_attr "length" "*,8,8,8,8,*")
3281 (set_attr "type" "neon_logic,multiple,multiple,multiple,multiple,neon_logic")
3282 (set_attr "arch" "neon_for_64bits,*,*,*,*,avoid_neon_for_64bits")]
3285 (define_insn "*xordi_zesidi_di"
3286 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
3287 (xor:DI (zero_extend:DI
3288 (match_operand:SI 2 "s_register_operand" "r,r"))
3289 (match_operand:DI 1 "s_register_operand" "0,?r")))]
3292 eor%?\\t%Q0, %Q1, %2
3294 [(set_attr "length" "4,8")
3295 (set_attr "predicable" "yes")
3296 (set_attr "predicable_short_it" "no")
3297 (set_attr "type" "logic_reg")]
3300 (define_insn "*xordi_sesidi_di"
3301 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
3302 (xor:DI (sign_extend:DI
3303 (match_operand:SI 2 "s_register_operand" "r,r"))
3304 (match_operand:DI 1 "s_register_operand" "0,r")))]
3307 [(set_attr "length" "8")
3308 (set_attr "predicable" "yes")
3309 (set_attr "type" "multiple")]
3312 (define_expand "xorsi3"
3313 [(set (match_operand:SI 0 "s_register_operand" "")
3314 (xor:SI (match_operand:SI 1 "s_register_operand" "")
3315 (match_operand:SI 2 "reg_or_int_operand" "")))]
3317 "if (CONST_INT_P (operands[2]))
3321 arm_split_constant (XOR, SImode, NULL_RTX,
3322 INTVAL (operands[2]), operands[0], operands[1],
3323 optimize && can_create_pseudo_p ());
3326 else /* TARGET_THUMB1 */
3328 rtx tmp = force_reg (SImode, operands[2]);
3329 if (rtx_equal_p (operands[0], operands[1]))
3333 operands[2] = operands[1];
3340 (define_insn_and_split "*arm_xorsi3"
3341 [(set (match_operand:SI 0 "s_register_operand" "=r,l,r,r")
3342 (xor:SI (match_operand:SI 1 "s_register_operand" "%r,0,r,r")
3343 (match_operand:SI 2 "reg_or_int_operand" "I,l,r,?n")))]
3351 && CONST_INT_P (operands[2])
3352 && !const_ok_for_arm (INTVAL (operands[2]))"
3353 [(clobber (const_int 0))]
3355 arm_split_constant (XOR, SImode, curr_insn,
3356 INTVAL (operands[2]), operands[0], operands[1], 0);
3359 [(set_attr "length" "4,4,4,16")
3360 (set_attr "predicable" "yes")
3361 (set_attr "predicable_short_it" "no,yes,no,no")
3362 (set_attr "type" "logic_imm,logic_reg,logic_reg,multiple")]
3365 (define_insn "*thumb1_xorsi3_insn"
3366 [(set (match_operand:SI 0 "register_operand" "=l")
3367 (xor:SI (match_operand:SI 1 "register_operand" "%0")
3368 (match_operand:SI 2 "register_operand" "l")))]
3371 [(set_attr "length" "2")
3372 (set_attr "conds" "set")
3373 (set_attr "type" "logics_reg")]
3376 (define_insn "*xorsi3_compare0"
3377 [(set (reg:CC_NOOV CC_REGNUM)
3378 (compare:CC_NOOV (xor:SI (match_operand:SI 1 "s_register_operand" "r,r")
3379 (match_operand:SI 2 "arm_rhs_operand" "I,r"))
3381 (set (match_operand:SI 0 "s_register_operand" "=r,r")
3382 (xor:SI (match_dup 1) (match_dup 2)))]
3384 "eor%.\\t%0, %1, %2"
3385 [(set_attr "conds" "set")
3386 (set_attr "type" "logics_imm,logics_reg")]
3389 (define_insn "*xorsi3_compare0_scratch"
3390 [(set (reg:CC_NOOV CC_REGNUM)
3391 (compare:CC_NOOV (xor:SI (match_operand:SI 0 "s_register_operand" "r,r")
3392 (match_operand:SI 1 "arm_rhs_operand" "I,r"))
3396 [(set_attr "conds" "set")
3397 (set_attr "type" "logics_imm,logics_reg")]
3400 ; By splitting (IOR (AND (NOT A) (NOT B)) C) as D = AND (IOR A B) (NOT C),
3401 ; (NOT D) we can sometimes merge the final NOT into one of the following
3405 [(set (match_operand:SI 0 "s_register_operand" "")
3406 (ior:SI (and:SI (not:SI (match_operand:SI 1 "s_register_operand" ""))
3407 (not:SI (match_operand:SI 2 "arm_rhs_operand" "")))
3408 (match_operand:SI 3 "arm_rhs_operand" "")))
3409 (clobber (match_operand:SI 4 "s_register_operand" ""))]
3411 [(set (match_dup 4) (and:SI (ior:SI (match_dup 1) (match_dup 2))
3412 (not:SI (match_dup 3))))
3413 (set (match_dup 0) (not:SI (match_dup 4)))]
3417 (define_insn_and_split "*andsi_iorsi3_notsi"
3418 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r")
3419 (and:SI (ior:SI (match_operand:SI 1 "s_register_operand" "%0,r,r")
3420 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI"))
3421 (not:SI (match_operand:SI 3 "arm_rhs_operand" "rI,rI,rI"))))]
3423 "#" ; "orr%?\\t%0, %1, %2\;bic%?\\t%0, %0, %3"
3424 "&& reload_completed"
3425 [(set (match_dup 0) (ior:SI (match_dup 1) (match_dup 2)))
3426 (set (match_dup 0) (and:SI (not:SI (match_dup 3)) (match_dup 0)))]
3428 [(set_attr "length" "8")
3429 (set_attr "ce_count" "2")
3430 (set_attr "predicable" "yes")
3431 (set_attr "predicable_short_it" "no")
3432 (set_attr "type" "multiple")]
3435 ; ??? Are these four splitters still beneficial when the Thumb-2 bitfield
3436 ; insns are available?
3438 [(set (match_operand:SI 0 "s_register_operand" "")
3439 (match_operator:SI 1 "logical_binary_operator"
3440 [(zero_extract:SI (match_operand:SI 2 "s_register_operand" "")
3441 (match_operand:SI 3 "const_int_operand" "")
3442 (match_operand:SI 4 "const_int_operand" ""))
3443 (match_operator:SI 9 "logical_binary_operator"
3444 [(lshiftrt:SI (match_operand:SI 5 "s_register_operand" "")
3445 (match_operand:SI 6 "const_int_operand" ""))
3446 (match_operand:SI 7 "s_register_operand" "")])]))
3447 (clobber (match_operand:SI 8 "s_register_operand" ""))]
3449 && GET_CODE (operands[1]) == GET_CODE (operands[9])
3450 && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
3453 [(ashift:SI (match_dup 2) (match_dup 4))
3457 [(lshiftrt:SI (match_dup 8) (match_dup 6))
3460 operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
3464 [(set (match_operand:SI 0 "s_register_operand" "")
3465 (match_operator:SI 1 "logical_binary_operator"
3466 [(match_operator:SI 9 "logical_binary_operator"
3467 [(lshiftrt:SI (match_operand:SI 5 "s_register_operand" "")
3468 (match_operand:SI 6 "const_int_operand" ""))
3469 (match_operand:SI 7 "s_register_operand" "")])
3470 (zero_extract:SI (match_operand:SI 2 "s_register_operand" "")
3471 (match_operand:SI 3 "const_int_operand" "")
3472 (match_operand:SI 4 "const_int_operand" ""))]))
3473 (clobber (match_operand:SI 8 "s_register_operand" ""))]
3475 && GET_CODE (operands[1]) == GET_CODE (operands[9])
3476 && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
3479 [(ashift:SI (match_dup 2) (match_dup 4))
3483 [(lshiftrt:SI (match_dup 8) (match_dup 6))
3486 operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
3490 [(set (match_operand:SI 0 "s_register_operand" "")
3491 (match_operator:SI 1 "logical_binary_operator"
3492 [(sign_extract:SI (match_operand:SI 2 "s_register_operand" "")
3493 (match_operand:SI 3 "const_int_operand" "")
3494 (match_operand:SI 4 "const_int_operand" ""))
3495 (match_operator:SI 9 "logical_binary_operator"
3496 [(ashiftrt:SI (match_operand:SI 5 "s_register_operand" "")
3497 (match_operand:SI 6 "const_int_operand" ""))
3498 (match_operand:SI 7 "s_register_operand" "")])]))
3499 (clobber (match_operand:SI 8 "s_register_operand" ""))]
3501 && GET_CODE (operands[1]) == GET_CODE (operands[9])
3502 && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
3505 [(ashift:SI (match_dup 2) (match_dup 4))
3509 [(ashiftrt:SI (match_dup 8) (match_dup 6))
3512 operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
3516 [(set (match_operand:SI 0 "s_register_operand" "")
3517 (match_operator:SI 1 "logical_binary_operator"
3518 [(match_operator:SI 9 "logical_binary_operator"
3519 [(ashiftrt:SI (match_operand:SI 5 "s_register_operand" "")
3520 (match_operand:SI 6 "const_int_operand" ""))
3521 (match_operand:SI 7 "s_register_operand" "")])
3522 (sign_extract:SI (match_operand:SI 2 "s_register_operand" "")
3523 (match_operand:SI 3 "const_int_operand" "")
3524 (match_operand:SI 4 "const_int_operand" ""))]))
3525 (clobber (match_operand:SI 8 "s_register_operand" ""))]
3527 && GET_CODE (operands[1]) == GET_CODE (operands[9])
3528 && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
3531 [(ashift:SI (match_dup 2) (match_dup 4))
3535 [(ashiftrt:SI (match_dup 8) (match_dup 6))
3538 operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
3542 ;; Minimum and maximum insns
3544 (define_expand "smaxsi3"
3546 (set (match_operand:SI 0 "s_register_operand" "")
3547 (smax:SI (match_operand:SI 1 "s_register_operand" "")
3548 (match_operand:SI 2 "arm_rhs_operand" "")))
3549 (clobber (reg:CC CC_REGNUM))])]
3552 if (operands[2] == const0_rtx || operands[2] == constm1_rtx)
3554 /* No need for a clobber of the condition code register here. */
3555 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
3556 gen_rtx_SMAX (SImode, operands[1],
3562 (define_insn "*smax_0"
3563 [(set (match_operand:SI 0 "s_register_operand" "=r")
3564 (smax:SI (match_operand:SI 1 "s_register_operand" "r")
3567 "bic%?\\t%0, %1, %1, asr #31"
3568 [(set_attr "predicable" "yes")
3569 (set_attr "predicable_short_it" "no")
3570 (set_attr "type" "logic_shift_reg")]
3573 (define_insn "*smax_m1"
3574 [(set (match_operand:SI 0 "s_register_operand" "=r")
3575 (smax:SI (match_operand:SI 1 "s_register_operand" "r")
3578 "orr%?\\t%0, %1, %1, asr #31"
3579 [(set_attr "predicable" "yes")
3580 (set_attr "predicable_short_it" "no")
3581 (set_attr "type" "logic_shift_reg")]
3584 (define_insn_and_split "*arm_smax_insn"
3585 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
3586 (smax:SI (match_operand:SI 1 "s_register_operand" "%0,?r")
3587 (match_operand:SI 2 "arm_rhs_operand" "rI,rI")))
3588 (clobber (reg:CC CC_REGNUM))]
3591 ; cmp\\t%1, %2\;movlt\\t%0, %2
3592 ; cmp\\t%1, %2\;movge\\t%0, %1\;movlt\\t%0, %2"
3594 [(set (reg:CC CC_REGNUM)
3595 (compare:CC (match_dup 1) (match_dup 2)))
3597 (if_then_else:SI (ge:SI (reg:CC CC_REGNUM) (const_int 0))
3601 [(set_attr "conds" "clob")
3602 (set_attr "length" "8,12")
3603 (set_attr "type" "multiple")]
3606 (define_expand "sminsi3"
3608 (set (match_operand:SI 0 "s_register_operand" "")
3609 (smin:SI (match_operand:SI 1 "s_register_operand" "")
3610 (match_operand:SI 2 "arm_rhs_operand" "")))
3611 (clobber (reg:CC CC_REGNUM))])]
3614 if (operands[2] == const0_rtx)
3616 /* No need for a clobber of the condition code register here. */
3617 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
3618 gen_rtx_SMIN (SImode, operands[1],
3624 (define_insn "*smin_0"
3625 [(set (match_operand:SI 0 "s_register_operand" "=r")
3626 (smin:SI (match_operand:SI 1 "s_register_operand" "r")
3629 "and%?\\t%0, %1, %1, asr #31"
3630 [(set_attr "predicable" "yes")
3631 (set_attr "predicable_short_it" "no")
3632 (set_attr "type" "logic_shift_reg")]
3635 (define_insn_and_split "*arm_smin_insn"
3636 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
3637 (smin:SI (match_operand:SI 1 "s_register_operand" "%0,?r")
3638 (match_operand:SI 2 "arm_rhs_operand" "rI,rI")))
3639 (clobber (reg:CC CC_REGNUM))]
3642 ; cmp\\t%1, %2\;movge\\t%0, %2
3643 ; cmp\\t%1, %2\;movlt\\t%0, %1\;movge\\t%0, %2"
3645 [(set (reg:CC CC_REGNUM)
3646 (compare:CC (match_dup 1) (match_dup 2)))
3648 (if_then_else:SI (lt:SI (reg:CC CC_REGNUM) (const_int 0))
3652 [(set_attr "conds" "clob")
3653 (set_attr "length" "8,12")
3654 (set_attr "type" "multiple,multiple")]
3657 (define_expand "umaxsi3"
3659 (set (match_operand:SI 0 "s_register_operand" "")
3660 (umax:SI (match_operand:SI 1 "s_register_operand" "")
3661 (match_operand:SI 2 "arm_rhs_operand" "")))
3662 (clobber (reg:CC CC_REGNUM))])]
3667 (define_insn_and_split "*arm_umaxsi3"
3668 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
3669 (umax:SI (match_operand:SI 1 "s_register_operand" "0,r,?r")
3670 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
3671 (clobber (reg:CC CC_REGNUM))]
3674 ; cmp\\t%1, %2\;movcc\\t%0, %2
3675 ; cmp\\t%1, %2\;movcs\\t%0, %1
3676 ; cmp\\t%1, %2\;movcs\\t%0, %1\;movcc\\t%0, %2"
3678 [(set (reg:CC CC_REGNUM)
3679 (compare:CC (match_dup 1) (match_dup 2)))
3681 (if_then_else:SI (geu:SI (reg:CC CC_REGNUM) (const_int 0))
3685 [(set_attr "conds" "clob")
3686 (set_attr "length" "8,8,12")
3687 (set_attr "type" "store1")]
3690 (define_expand "uminsi3"
3692 (set (match_operand:SI 0 "s_register_operand" "")
3693 (umin:SI (match_operand:SI 1 "s_register_operand" "")
3694 (match_operand:SI 2 "arm_rhs_operand" "")))
3695 (clobber (reg:CC CC_REGNUM))])]
3700 (define_insn_and_split "*arm_uminsi3"
3701 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
3702 (umin:SI (match_operand:SI 1 "s_register_operand" "0,r,?r")
3703 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
3704 (clobber (reg:CC CC_REGNUM))]
3707 ; cmp\\t%1, %2\;movcs\\t%0, %2
3708 ; cmp\\t%1, %2\;movcc\\t%0, %1
3709 ; cmp\\t%1, %2\;movcc\\t%0, %1\;movcs\\t%0, %2"
3711 [(set (reg:CC CC_REGNUM)
3712 (compare:CC (match_dup 1) (match_dup 2)))
3714 (if_then_else:SI (ltu:SI (reg:CC CC_REGNUM) (const_int 0))
3718 [(set_attr "conds" "clob")
3719 (set_attr "length" "8,8,12")
3720 (set_attr "type" "store1")]
3723 (define_insn "*store_minmaxsi"
3724 [(set (match_operand:SI 0 "memory_operand" "=m")
3725 (match_operator:SI 3 "minmax_operator"
3726 [(match_operand:SI 1 "s_register_operand" "r")
3727 (match_operand:SI 2 "s_register_operand" "r")]))
3728 (clobber (reg:CC CC_REGNUM))]
3729 "TARGET_32BIT && optimize_function_for_size_p (cfun)"
3731 operands[3] = gen_rtx_fmt_ee (minmax_code (operands[3]), SImode,
3732 operands[1], operands[2]);
3733 output_asm_insn (\"cmp\\t%1, %2\", operands);
3735 output_asm_insn (\"ite\t%d3\", operands);
3736 output_asm_insn (\"str%d3\\t%1, %0\", operands);
3737 output_asm_insn (\"str%D3\\t%2, %0\", operands);
3740 [(set_attr "conds" "clob")
3741 (set (attr "length")
3742 (if_then_else (eq_attr "is_thumb" "yes")
3745 (set_attr "type" "store1")]
3748 ; Reject the frame pointer in operand[1], since reloading this after
3749 ; it has been eliminated can cause carnage.
3750 (define_insn "*minmax_arithsi"
3751 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
3752 (match_operator:SI 4 "shiftable_operator"
3753 [(match_operator:SI 5 "minmax_operator"
3754 [(match_operand:SI 2 "s_register_operand" "r,r")
3755 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
3756 (match_operand:SI 1 "s_register_operand" "0,?r")]))
3757 (clobber (reg:CC CC_REGNUM))]
3758 "TARGET_32BIT && !arm_eliminable_register (operands[1]) && !arm_restrict_it"
3761 enum rtx_code code = GET_CODE (operands[4]);
3764 if (which_alternative != 0 || operands[3] != const0_rtx
3765 || (code != PLUS && code != IOR && code != XOR))
3770 operands[5] = gen_rtx_fmt_ee (minmax_code (operands[5]), SImode,
3771 operands[2], operands[3]);
3772 output_asm_insn (\"cmp\\t%2, %3\", operands);
3776 output_asm_insn (\"ite\\t%d5\", operands);
3778 output_asm_insn (\"it\\t%d5\", operands);
3780 output_asm_insn (\"%i4%d5\\t%0, %1, %2\", operands);
3782 output_asm_insn (\"%i4%D5\\t%0, %1, %3\", operands);
3785 [(set_attr "conds" "clob")
3786 (set (attr "length")
3787 (if_then_else (eq_attr "is_thumb" "yes")
3790 (set_attr "type" "multiple")]
3793 ; Reject the frame pointer in operand[1], since reloading this after
3794 ; it has been eliminated can cause carnage.
3795 (define_insn_and_split "*minmax_arithsi_non_canon"
3796 [(set (match_operand:SI 0 "s_register_operand" "=Ts,Ts")
3798 (match_operand:SI 1 "s_register_operand" "0,?Ts")
3799 (match_operator:SI 4 "minmax_operator"
3800 [(match_operand:SI 2 "s_register_operand" "Ts,Ts")
3801 (match_operand:SI 3 "arm_rhs_operand" "TsI,TsI")])))
3802 (clobber (reg:CC CC_REGNUM))]
3803 "TARGET_32BIT && !arm_eliminable_register (operands[1])
3804 && !(arm_restrict_it && CONST_INT_P (operands[3]))"
3806 "TARGET_32BIT && !arm_eliminable_register (operands[1]) && reload_completed"
3807 [(set (reg:CC CC_REGNUM)
3808 (compare:CC (match_dup 2) (match_dup 3)))
3810 (cond_exec (match_op_dup 4 [(reg:CC CC_REGNUM) (const_int 0)])
3812 (minus:SI (match_dup 1)
3814 (cond_exec (match_op_dup 5 [(reg:CC CC_REGNUM) (const_int 0)])
3818 enum machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
3819 operands[2], operands[3]);
3820 enum rtx_code rc = minmax_code (operands[4]);
3821 operands[4] = gen_rtx_fmt_ee (rc, VOIDmode,
3822 operands[2], operands[3]);
3824 if (mode == CCFPmode || mode == CCFPEmode)
3825 rc = reverse_condition_maybe_unordered (rc);
3827 rc = reverse_condition (rc);
3828 operands[5] = gen_rtx_fmt_ee (rc, SImode, operands[2], operands[3]);
3829 if (CONST_INT_P (operands[3]))
3830 operands[6] = plus_constant (SImode, operands[1], -INTVAL (operands[3]));
3832 operands[6] = gen_rtx_MINUS (SImode, operands[1], operands[3]);
3834 [(set_attr "conds" "clob")
3835 (set (attr "length")
3836 (if_then_else (eq_attr "is_thumb" "yes")
3839 (set_attr "type" "multiple")]
3842 (define_code_iterator SAT [smin smax])
3843 (define_code_iterator SATrev [smin smax])
3844 (define_code_attr SATlo [(smin "1") (smax "2")])
3845 (define_code_attr SAThi [(smin "2") (smax "1")])
3847 (define_insn "*satsi_<SAT:code>"
3848 [(set (match_operand:SI 0 "s_register_operand" "=r")
3849 (SAT:SI (SATrev:SI (match_operand:SI 3 "s_register_operand" "r")
3850 (match_operand:SI 1 "const_int_operand" "i"))
3851 (match_operand:SI 2 "const_int_operand" "i")))]
3852 "TARGET_32BIT && arm_arch6 && <SAT:CODE> != <SATrev:CODE>
3853 && arm_sat_operator_match (operands[<SAT:SATlo>], operands[<SAT:SAThi>], NULL, NULL)"
3857 if (!arm_sat_operator_match (operands[<SAT:SATlo>], operands[<SAT:SAThi>],
3858 &mask, &signed_sat))
3861 operands[1] = GEN_INT (mask);
3863 return "ssat%?\t%0, %1, %3";
3865 return "usat%?\t%0, %1, %3";
3867 [(set_attr "predicable" "yes")
3868 (set_attr "predicable_short_it" "no")
3869 (set_attr "type" "alus_imm")]
3872 (define_insn "*satsi_<SAT:code>_shift"
3873 [(set (match_operand:SI 0 "s_register_operand" "=r")
3874 (SAT:SI (SATrev:SI (match_operator:SI 3 "sat_shift_operator"
3875 [(match_operand:SI 4 "s_register_operand" "r")
3876 (match_operand:SI 5 "const_int_operand" "i")])
3877 (match_operand:SI 1 "const_int_operand" "i"))
3878 (match_operand:SI 2 "const_int_operand" "i")))]
3879 "TARGET_32BIT && arm_arch6 && <SAT:CODE> != <SATrev:CODE>
3880 && arm_sat_operator_match (operands[<SAT:SATlo>], operands[<SAT:SAThi>], NULL, NULL)"
3884 if (!arm_sat_operator_match (operands[<SAT:SATlo>], operands[<SAT:SAThi>],
3885 &mask, &signed_sat))
3888 operands[1] = GEN_INT (mask);
3890 return "ssat%?\t%0, %1, %4%S3";
3892 return "usat%?\t%0, %1, %4%S3";
3894 [(set_attr "predicable" "yes")
3895 (set_attr "predicable_short_it" "no")
3896 (set_attr "shift" "3")
3897 (set_attr "type" "logic_shift_reg")])
3899 ;; Shift and rotation insns
3901 (define_expand "ashldi3"
3902 [(set (match_operand:DI 0 "s_register_operand" "")
3903 (ashift:DI (match_operand:DI 1 "s_register_operand" "")
3904 (match_operand:SI 2 "general_operand" "")))]
3909 /* Delay the decision whether to use NEON or core-regs until
3910 register allocation. */
3911 emit_insn (gen_ashldi3_neon (operands[0], operands[1], operands[2]));
3916 /* Only the NEON case can handle in-memory shift counts. */
3917 if (!reg_or_int_operand (operands[2], SImode))
3918 operands[2] = force_reg (SImode, operands[2]);
3921 if (!CONST_INT_P (operands[2]) && TARGET_REALLY_IWMMXT)
3922 ; /* No special preparation statements; expand pattern as above. */
3925 rtx scratch1, scratch2;
3927 if (CONST_INT_P (operands[2])
3928 && (HOST_WIDE_INT) INTVAL (operands[2]) == 1)
3930 emit_insn (gen_arm_ashldi3_1bit (operands[0], operands[1]));
3934 /* Ideally we should use iwmmxt here if we could know that operands[1]
3935 ends up already living in an iwmmxt register. Otherwise it's
3936 cheaper to have the alternate code being generated than moving
3937 values to iwmmxt regs and back. */
3939 /* If we're optimizing for size, we prefer the libgcc calls. */
3940 if (optimize_function_for_size_p (cfun))
3943 /* Expand operation using core-registers.
3944 'FAIL' would achieve the same thing, but this is a bit smarter. */
3945 scratch1 = gen_reg_rtx (SImode);
3946 scratch2 = gen_reg_rtx (SImode);
3947 arm_emit_coreregs_64bit_shift (ASHIFT, operands[0], operands[1],
3948 operands[2], scratch1, scratch2);
3954 (define_insn "arm_ashldi3_1bit"
3955 [(set (match_operand:DI 0 "s_register_operand" "=r,&r")
3956 (ashift:DI (match_operand:DI 1 "s_register_operand" "0,r")
3958 (clobber (reg:CC CC_REGNUM))]
3960 "movs\\t%Q0, %Q1, asl #1\;adc\\t%R0, %R1, %R1"
3961 [(set_attr "conds" "clob")
3962 (set_attr "length" "8")
3963 (set_attr "type" "multiple")]
3966 (define_expand "ashlsi3"
3967 [(set (match_operand:SI 0 "s_register_operand" "")
3968 (ashift:SI (match_operand:SI 1 "s_register_operand" "")
3969 (match_operand:SI 2 "arm_rhs_operand" "")))]
3972 if (CONST_INT_P (operands[2])
3973 && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) > 31)
3975 emit_insn (gen_movsi (operands[0], const0_rtx));
3981 (define_insn "*thumb1_ashlsi3"
3982 [(set (match_operand:SI 0 "register_operand" "=l,l")
3983 (ashift:SI (match_operand:SI 1 "register_operand" "l,0")
3984 (match_operand:SI 2 "nonmemory_operand" "N,l")))]
3987 [(set_attr "length" "2")
3988 (set_attr "type" "shift_imm,shift_reg")
3989 (set_attr "conds" "set")])
3991 (define_expand "ashrdi3"
3992 [(set (match_operand:DI 0 "s_register_operand" "")
3993 (ashiftrt:DI (match_operand:DI 1 "s_register_operand" "")
3994 (match_operand:SI 2 "reg_or_int_operand" "")))]
3999 /* Delay the decision whether to use NEON or core-regs until
4000 register allocation. */
4001 emit_insn (gen_ashrdi3_neon (operands[0], operands[1], operands[2]));
4005 if (!CONST_INT_P (operands[2]) && TARGET_REALLY_IWMMXT)
4006 ; /* No special preparation statements; expand pattern as above. */
4009 rtx scratch1, scratch2;
4011 if (CONST_INT_P (operands[2])
4012 && (HOST_WIDE_INT) INTVAL (operands[2]) == 1)
4014 emit_insn (gen_arm_ashrdi3_1bit (operands[0], operands[1]));
4018 /* Ideally we should use iwmmxt here if we could know that operands[1]
4019 ends up already living in an iwmmxt register. Otherwise it's
4020 cheaper to have the alternate code being generated than moving
4021 values to iwmmxt regs and back. */
4023 /* If we're optimizing for size, we prefer the libgcc calls. */
4024 if (optimize_function_for_size_p (cfun))
4027 /* Expand operation using core-registers.
4028 'FAIL' would achieve the same thing, but this is a bit smarter. */
4029 scratch1 = gen_reg_rtx (SImode);
4030 scratch2 = gen_reg_rtx (SImode);
4031 arm_emit_coreregs_64bit_shift (ASHIFTRT, operands[0], operands[1],
4032 operands[2], scratch1, scratch2);
4038 (define_insn "arm_ashrdi3_1bit"
4039 [(set (match_operand:DI 0 "s_register_operand" "=r,&r")
4040 (ashiftrt:DI (match_operand:DI 1 "s_register_operand" "0,r")
4042 (clobber (reg:CC CC_REGNUM))]
4044 "movs\\t%R0, %R1, asr #1\;mov\\t%Q0, %Q1, rrx"
4045 [(set_attr "conds" "clob")
4046 (set_attr "length" "8")
4047 (set_attr "type" "multiple")]
4050 (define_expand "ashrsi3"
4051 [(set (match_operand:SI 0 "s_register_operand" "")
4052 (ashiftrt:SI (match_operand:SI 1 "s_register_operand" "")
4053 (match_operand:SI 2 "arm_rhs_operand" "")))]
4056 if (CONST_INT_P (operands[2])
4057 && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) > 31)
4058 operands[2] = GEN_INT (31);
4062 (define_insn "*thumb1_ashrsi3"
4063 [(set (match_operand:SI 0 "register_operand" "=l,l")
4064 (ashiftrt:SI (match_operand:SI 1 "register_operand" "l,0")
4065 (match_operand:SI 2 "nonmemory_operand" "N,l")))]
4068 [(set_attr "length" "2")
4069 (set_attr "type" "shift_imm,shift_reg")
4070 (set_attr "conds" "set")])
4072 (define_expand "lshrdi3"
4073 [(set (match_operand:DI 0 "s_register_operand" "")
4074 (lshiftrt:DI (match_operand:DI 1 "s_register_operand" "")
4075 (match_operand:SI 2 "reg_or_int_operand" "")))]
4080 /* Delay the decision whether to use NEON or core-regs until
4081 register allocation. */
4082 emit_insn (gen_lshrdi3_neon (operands[0], operands[1], operands[2]));
4086 if (!CONST_INT_P (operands[2]) && TARGET_REALLY_IWMMXT)
4087 ; /* No special preparation statements; expand pattern as above. */
4090 rtx scratch1, scratch2;
4092 if (CONST_INT_P (operands[2])
4093 && (HOST_WIDE_INT) INTVAL (operands[2]) == 1)
4095 emit_insn (gen_arm_lshrdi3_1bit (operands[0], operands[1]));
4099 /* Ideally we should use iwmmxt here if we could know that operands[1]
4100 ends up already living in an iwmmxt register. Otherwise it's
4101 cheaper to have the alternate code being generated than moving
4102 values to iwmmxt regs and back. */
4104 /* If we're optimizing for size, we prefer the libgcc calls. */
4105 if (optimize_function_for_size_p (cfun))
4108 /* Expand operation using core-registers.
4109 'FAIL' would achieve the same thing, but this is a bit smarter. */
4110 scratch1 = gen_reg_rtx (SImode);
4111 scratch2 = gen_reg_rtx (SImode);
4112 arm_emit_coreregs_64bit_shift (LSHIFTRT, operands[0], operands[1],
4113 operands[2], scratch1, scratch2);
4119 (define_insn "arm_lshrdi3_1bit"
4120 [(set (match_operand:DI 0 "s_register_operand" "=r,&r")
4121 (lshiftrt:DI (match_operand:DI 1 "s_register_operand" "0,r")
4123 (clobber (reg:CC CC_REGNUM))]
4125 "movs\\t%R0, %R1, lsr #1\;mov\\t%Q0, %Q1, rrx"
4126 [(set_attr "conds" "clob")
4127 (set_attr "length" "8")
4128 (set_attr "type" "multiple")]
4131 (define_expand "lshrsi3"
4132 [(set (match_operand:SI 0 "s_register_operand" "")
4133 (lshiftrt:SI (match_operand:SI 1 "s_register_operand" "")
4134 (match_operand:SI 2 "arm_rhs_operand" "")))]
4137 if (CONST_INT_P (operands[2])
4138 && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) > 31)
4140 emit_insn (gen_movsi (operands[0], const0_rtx));
4146 (define_insn "*thumb1_lshrsi3"
4147 [(set (match_operand:SI 0 "register_operand" "=l,l")
4148 (lshiftrt:SI (match_operand:SI 1 "register_operand" "l,0")
4149 (match_operand:SI 2 "nonmemory_operand" "N,l")))]
4152 [(set_attr "length" "2")
4153 (set_attr "type" "shift_imm,shift_reg")
4154 (set_attr "conds" "set")])
4156 (define_expand "rotlsi3"
4157 [(set (match_operand:SI 0 "s_register_operand" "")
4158 (rotatert:SI (match_operand:SI 1 "s_register_operand" "")
4159 (match_operand:SI 2 "reg_or_int_operand" "")))]
4162 if (CONST_INT_P (operands[2]))
4163 operands[2] = GEN_INT ((32 - INTVAL (operands[2])) % 32);
4166 rtx reg = gen_reg_rtx (SImode);
4167 emit_insn (gen_subsi3 (reg, GEN_INT (32), operands[2]));
4173 (define_expand "rotrsi3"
4174 [(set (match_operand:SI 0 "s_register_operand" "")
4175 (rotatert:SI (match_operand:SI 1 "s_register_operand" "")
4176 (match_operand:SI 2 "arm_rhs_operand" "")))]
4181 if (CONST_INT_P (operands[2])
4182 && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) > 31)
4183 operands[2] = GEN_INT (INTVAL (operands[2]) % 32);
4185 else /* TARGET_THUMB1 */
4187 if (CONST_INT_P (operands [2]))
4188 operands [2] = force_reg (SImode, operands[2]);
4193 (define_insn "*thumb1_rotrsi3"
4194 [(set (match_operand:SI 0 "register_operand" "=l")
4195 (rotatert:SI (match_operand:SI 1 "register_operand" "0")
4196 (match_operand:SI 2 "register_operand" "l")))]
4199 [(set_attr "type" "shift_reg")
4200 (set_attr "length" "2")]
4203 (define_insn "*arm_shiftsi3"
4204 [(set (match_operand:SI 0 "s_register_operand" "=l,l,r,r")
4205 (match_operator:SI 3 "shift_operator"
4206 [(match_operand:SI 1 "s_register_operand" "0,l,r,r")
4207 (match_operand:SI 2 "reg_or_int_operand" "l,M,M,r")]))]
4209 "* return arm_output_shift(operands, 0);"
4210 [(set_attr "predicable" "yes")
4211 (set_attr "arch" "t2,t2,*,*")
4212 (set_attr "predicable_short_it" "yes,yes,no,no")
4213 (set_attr "length" "4")
4214 (set_attr "shift" "1")
4215 (set_attr "type" "alu_shift_reg,alu_shift_imm,alu_shift_imm,alu_shift_reg")]
4218 (define_insn "*shiftsi3_compare0"
4219 [(set (reg:CC_NOOV CC_REGNUM)
4220 (compare:CC_NOOV (match_operator:SI 3 "shift_operator"
4221 [(match_operand:SI 1 "s_register_operand" "r,r")
4222 (match_operand:SI 2 "arm_rhs_operand" "M,r")])
4224 (set (match_operand:SI 0 "s_register_operand" "=r,r")
4225 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))]
4227 "* return arm_output_shift(operands, 1);"
4228 [(set_attr "conds" "set")
4229 (set_attr "shift" "1")
4230 (set_attr "type" "alus_shift_imm,alus_shift_reg")]
4233 (define_insn "*shiftsi3_compare0_scratch"
4234 [(set (reg:CC_NOOV CC_REGNUM)
4235 (compare:CC_NOOV (match_operator:SI 3 "shift_operator"
4236 [(match_operand:SI 1 "s_register_operand" "r,r")
4237 (match_operand:SI 2 "arm_rhs_operand" "M,r")])
4239 (clobber (match_scratch:SI 0 "=r,r"))]
4241 "* return arm_output_shift(operands, 1);"
4242 [(set_attr "conds" "set")
4243 (set_attr "shift" "1")
4244 (set_attr "type" "shift_imm,shift_reg")]
4247 (define_insn "*not_shiftsi"
4248 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4249 (not:SI (match_operator:SI 3 "shift_operator"
4250 [(match_operand:SI 1 "s_register_operand" "r,r")
4251 (match_operand:SI 2 "shift_amount_operand" "M,rM")])))]
4254 [(set_attr "predicable" "yes")
4255 (set_attr "predicable_short_it" "no")
4256 (set_attr "shift" "1")
4257 (set_attr "arch" "32,a")
4258 (set_attr "type" "mvn_shift,mvn_shift_reg")])
4260 (define_insn "*not_shiftsi_compare0"
4261 [(set (reg:CC_NOOV CC_REGNUM)
4263 (not:SI (match_operator:SI 3 "shift_operator"
4264 [(match_operand:SI 1 "s_register_operand" "r,r")
4265 (match_operand:SI 2 "shift_amount_operand" "M,rM")]))
4267 (set (match_operand:SI 0 "s_register_operand" "=r,r")
4268 (not:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)])))]
4271 [(set_attr "conds" "set")
4272 (set_attr "shift" "1")
4273 (set_attr "arch" "32,a")
4274 (set_attr "type" "mvn_shift,mvn_shift_reg")])
4276 (define_insn "*not_shiftsi_compare0_scratch"
4277 [(set (reg:CC_NOOV CC_REGNUM)
4279 (not:SI (match_operator:SI 3 "shift_operator"
4280 [(match_operand:SI 1 "s_register_operand" "r,r")
4281 (match_operand:SI 2 "shift_amount_operand" "M,rM")]))
4283 (clobber (match_scratch:SI 0 "=r,r"))]
4286 [(set_attr "conds" "set")
4287 (set_attr "shift" "1")
4288 (set_attr "arch" "32,a")
4289 (set_attr "type" "mvn_shift,mvn_shift_reg")])
4291 ;; We don't really have extzv, but defining this using shifts helps
4292 ;; to reduce register pressure later on.
4294 (define_expand "extzv"
4295 [(set (match_operand 0 "s_register_operand" "")
4296 (zero_extract (match_operand 1 "nonimmediate_operand" "")
4297 (match_operand 2 "const_int_operand" "")
4298 (match_operand 3 "const_int_operand" "")))]
4299 "TARGET_THUMB1 || arm_arch_thumb2"
4302 HOST_WIDE_INT lshift = 32 - INTVAL (operands[2]) - INTVAL (operands[3]);
4303 HOST_WIDE_INT rshift = 32 - INTVAL (operands[2]);
4305 if (arm_arch_thumb2)
4307 HOST_WIDE_INT width = INTVAL (operands[2]);
4308 HOST_WIDE_INT bitpos = INTVAL (operands[3]);
4310 if (unaligned_access && MEM_P (operands[1])
4311 && (width == 16 || width == 32) && (bitpos % BITS_PER_UNIT) == 0)
4315 if (BYTES_BIG_ENDIAN)
4316 bitpos = GET_MODE_BITSIZE (GET_MODE (operands[0])) - width
4321 base_addr = adjust_address (operands[1], SImode,
4322 bitpos / BITS_PER_UNIT);
4323 emit_insn (gen_unaligned_loadsi (operands[0], base_addr));
4327 rtx dest = operands[0];
4328 rtx tmp = gen_reg_rtx (SImode);
4330 /* We may get a paradoxical subreg here. Strip it off. */
4331 if (GET_CODE (dest) == SUBREG
4332 && GET_MODE (dest) == SImode
4333 && GET_MODE (SUBREG_REG (dest)) == HImode)
4334 dest = SUBREG_REG (dest);
4336 if (GET_MODE_BITSIZE (GET_MODE (dest)) != width)
4339 base_addr = adjust_address (operands[1], HImode,
4340 bitpos / BITS_PER_UNIT);
4341 emit_insn (gen_unaligned_loadhiu (tmp, base_addr));
4342 emit_move_insn (gen_lowpart (SImode, dest), tmp);
4346 else if (s_register_operand (operands[1], GET_MODE (operands[1])))
4348 emit_insn (gen_extzv_t2 (operands[0], operands[1], operands[2],
4356 if (!s_register_operand (operands[1], GET_MODE (operands[1])))
4359 operands[3] = GEN_INT (rshift);
4363 emit_insn (gen_lshrsi3 (operands[0], operands[1], operands[3]));
4367 emit_insn (gen_extzv_t1 (operands[0], operands[1], GEN_INT (lshift),
4368 operands[3], gen_reg_rtx (SImode)));
4373 ;; Helper for extzv, for the Thumb-1 register-shifts case.
4375 (define_expand "extzv_t1"
4376 [(set (match_operand:SI 4 "s_register_operand" "")
4377 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
4378 (match_operand:SI 2 "const_int_operand" "")))
4379 (set (match_operand:SI 0 "s_register_operand" "")
4380 (lshiftrt:SI (match_dup 4)
4381 (match_operand:SI 3 "const_int_operand" "")))]
4385 (define_expand "extv"
4386 [(set (match_operand 0 "s_register_operand" "")
4387 (sign_extract (match_operand 1 "nonimmediate_operand" "")
4388 (match_operand 2 "const_int_operand" "")
4389 (match_operand 3 "const_int_operand" "")))]
4392 HOST_WIDE_INT width = INTVAL (operands[2]);
4393 HOST_WIDE_INT bitpos = INTVAL (operands[3]);
4395 if (unaligned_access && MEM_P (operands[1]) && (width == 16 || width == 32)
4396 && (bitpos % BITS_PER_UNIT) == 0)
4400 if (BYTES_BIG_ENDIAN)
4401 bitpos = GET_MODE_BITSIZE (GET_MODE (operands[0])) - width - bitpos;
4405 base_addr = adjust_address (operands[1], SImode,
4406 bitpos / BITS_PER_UNIT);
4407 emit_insn (gen_unaligned_loadsi (operands[0], base_addr));
4411 rtx dest = operands[0];
4412 rtx tmp = gen_reg_rtx (SImode);
4414 /* We may get a paradoxical subreg here. Strip it off. */
4415 if (GET_CODE (dest) == SUBREG
4416 && GET_MODE (dest) == SImode
4417 && GET_MODE (SUBREG_REG (dest)) == HImode)
4418 dest = SUBREG_REG (dest);
4420 if (GET_MODE_BITSIZE (GET_MODE (dest)) != width)
4423 base_addr = adjust_address (operands[1], HImode,
4424 bitpos / BITS_PER_UNIT);
4425 emit_insn (gen_unaligned_loadhis (tmp, base_addr));
4426 emit_move_insn (gen_lowpart (SImode, dest), tmp);
4431 else if (!s_register_operand (operands[1], GET_MODE (operands[1])))
4433 else if (GET_MODE (operands[0]) == SImode
4434 && GET_MODE (operands[1]) == SImode)
4436 emit_insn (gen_extv_regsi (operands[0], operands[1], operands[2],
4444 ; Helper to expand register forms of extv with the proper modes.
4446 (define_expand "extv_regsi"
4447 [(set (match_operand:SI 0 "s_register_operand" "")
4448 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "")
4449 (match_operand 2 "const_int_operand" "")
4450 (match_operand 3 "const_int_operand" "")))]
4455 ; ARMv6+ unaligned load/store instructions (used for packed structure accesses).
4457 (define_insn "unaligned_loadsi"
4458 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
4459 (unspec:SI [(match_operand:SI 1 "memory_operand" "Uw,m")]
4460 UNSPEC_UNALIGNED_LOAD))]
4461 "unaligned_access && TARGET_32BIT"
4462 "ldr%?\t%0, %1\t@ unaligned"
4463 [(set_attr "arch" "t2,any")
4464 (set_attr "length" "2,4")
4465 (set_attr "predicable" "yes")
4466 (set_attr "predicable_short_it" "yes,no")
4467 (set_attr "type" "load1")])
4469 (define_insn "unaligned_loadhis"
4470 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
4472 (unspec:HI [(match_operand:HI 1 "memory_operand" "Uw,m")]
4473 UNSPEC_UNALIGNED_LOAD)))]
4474 "unaligned_access && TARGET_32BIT"
4475 "ldr%(sh%)\t%0, %1\t@ unaligned"
4476 [(set_attr "arch" "t2,any")
4477 (set_attr "length" "2,4")
4478 (set_attr "predicable" "yes")
4479 (set_attr "predicable_short_it" "yes,no")
4480 (set_attr "type" "load_byte")])
4482 (define_insn "unaligned_loadhiu"
4483 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
4485 (unspec:HI [(match_operand:HI 1 "memory_operand" "Uw,m")]
4486 UNSPEC_UNALIGNED_LOAD)))]
4487 "unaligned_access && TARGET_32BIT"
4488 "ldr%(h%)\t%0, %1\t@ unaligned"
4489 [(set_attr "arch" "t2,any")
4490 (set_attr "length" "2,4")
4491 (set_attr "predicable" "yes")
4492 (set_attr "predicable_short_it" "yes,no")
4493 (set_attr "type" "load_byte")])
4495 (define_insn "unaligned_storesi"
4496 [(set (match_operand:SI 0 "memory_operand" "=Uw,m")
4497 (unspec:SI [(match_operand:SI 1 "s_register_operand" "l,r")]
4498 UNSPEC_UNALIGNED_STORE))]
4499 "unaligned_access && TARGET_32BIT"
4500 "str%?\t%1, %0\t@ unaligned"
4501 [(set_attr "arch" "t2,any")
4502 (set_attr "length" "2,4")
4503 (set_attr "predicable" "yes")
4504 (set_attr "predicable_short_it" "yes,no")
4505 (set_attr "type" "store1")])
4507 (define_insn "unaligned_storehi"
4508 [(set (match_operand:HI 0 "memory_operand" "=Uw,m")
4509 (unspec:HI [(match_operand:HI 1 "s_register_operand" "l,r")]
4510 UNSPEC_UNALIGNED_STORE))]
4511 "unaligned_access && TARGET_32BIT"
4512 "str%(h%)\t%1, %0\t@ unaligned"
4513 [(set_attr "arch" "t2,any")
4514 (set_attr "length" "2,4")
4515 (set_attr "predicable" "yes")
4516 (set_attr "predicable_short_it" "yes,no")
4517 (set_attr "type" "store1")])
4519 ;; Unaligned double-word load and store.
4520 ;; Split after reload into two unaligned single-word accesses.
4521 ;; It prevents lower_subreg from splitting some other aligned
4522 ;; double-word accesses too early. Used for internal memcpy.
4524 (define_insn_and_split "unaligned_loaddi"
4525 [(set (match_operand:DI 0 "s_register_operand" "=l,r")
4526 (unspec:DI [(match_operand:DI 1 "memory_operand" "o,o")]
4527 UNSPEC_UNALIGNED_LOAD))]
4528 "unaligned_access && TARGET_32BIT"
4530 "&& reload_completed"
4531 [(set (match_dup 0) (unspec:SI [(match_dup 1)] UNSPEC_UNALIGNED_LOAD))
4532 (set (match_dup 2) (unspec:SI [(match_dup 3)] UNSPEC_UNALIGNED_LOAD))]
4534 operands[2] = gen_highpart (SImode, operands[0]);
4535 operands[0] = gen_lowpart (SImode, operands[0]);
4536 operands[3] = gen_highpart (SImode, operands[1]);
4537 operands[1] = gen_lowpart (SImode, operands[1]);
4539 /* If the first destination register overlaps with the base address,
4540 swap the order in which the loads are emitted. */
4541 if (reg_overlap_mentioned_p (operands[0], operands[1]))
4543 rtx tmp = operands[1];
4544 operands[1] = operands[3];
4547 operands[0] = operands[2];
4551 [(set_attr "arch" "t2,any")
4552 (set_attr "length" "4,8")
4553 (set_attr "predicable" "yes")
4554 (set_attr "type" "load2")])
4556 (define_insn_and_split "unaligned_storedi"
4557 [(set (match_operand:DI 0 "memory_operand" "=o,o")
4558 (unspec:DI [(match_operand:DI 1 "s_register_operand" "l,r")]
4559 UNSPEC_UNALIGNED_STORE))]
4560 "unaligned_access && TARGET_32BIT"
4562 "&& reload_completed"
4563 [(set (match_dup 0) (unspec:SI [(match_dup 1)] UNSPEC_UNALIGNED_STORE))
4564 (set (match_dup 2) (unspec:SI [(match_dup 3)] UNSPEC_UNALIGNED_STORE))]
4566 operands[2] = gen_highpart (SImode, operands[0]);
4567 operands[0] = gen_lowpart (SImode, operands[0]);
4568 operands[3] = gen_highpart (SImode, operands[1]);
4569 operands[1] = gen_lowpart (SImode, operands[1]);
4571 [(set_attr "arch" "t2,any")
4572 (set_attr "length" "4,8")
4573 (set_attr "predicable" "yes")
4574 (set_attr "type" "store2")])
4577 (define_insn "*extv_reg"
4578 [(set (match_operand:SI 0 "s_register_operand" "=r")
4579 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
4580 (match_operand:SI 2 "const_int_operand" "M")
4581 (match_operand:SI 3 "const_int_operand" "M")))]
4583 "sbfx%?\t%0, %1, %3, %2"
4584 [(set_attr "length" "4")
4585 (set_attr "predicable" "yes")
4586 (set_attr "predicable_short_it" "no")
4587 (set_attr "type" "bfm")]
4590 (define_insn "extzv_t2"
4591 [(set (match_operand:SI 0 "s_register_operand" "=r")
4592 (zero_extract:SI (match_operand:SI 1 "s_register_operand" "r")
4593 (match_operand:SI 2 "const_int_operand" "M")
4594 (match_operand:SI 3 "const_int_operand" "M")))]
4596 "ubfx%?\t%0, %1, %3, %2"
4597 [(set_attr "length" "4")
4598 (set_attr "predicable" "yes")
4599 (set_attr "predicable_short_it" "no")
4600 (set_attr "type" "bfm")]
4604 ;; Division instructions
4605 (define_insn "divsi3"
4606 [(set (match_operand:SI 0 "s_register_operand" "=r")
4607 (div:SI (match_operand:SI 1 "s_register_operand" "r")
4608 (match_operand:SI 2 "s_register_operand" "r")))]
4610 "sdiv%?\t%0, %1, %2"
4611 [(set_attr "predicable" "yes")
4612 (set_attr "predicable_short_it" "no")
4613 (set_attr "type" "sdiv")]
4616 (define_insn "udivsi3"
4617 [(set (match_operand:SI 0 "s_register_operand" "=r")
4618 (udiv:SI (match_operand:SI 1 "s_register_operand" "r")
4619 (match_operand:SI 2 "s_register_operand" "r")))]
4621 "udiv%?\t%0, %1, %2"
4622 [(set_attr "predicable" "yes")
4623 (set_attr "predicable_short_it" "no")
4624 (set_attr "type" "udiv")]
4628 ;; Unary arithmetic insns
4630 (define_expand "negdi2"
4632 [(set (match_operand:DI 0 "s_register_operand" "")
4633 (neg:DI (match_operand:DI 1 "s_register_operand" "")))
4634 (clobber (reg:CC CC_REGNUM))])]
4639 emit_insn (gen_negdi2_neon (operands[0], operands[1]));
4645 ;; The constraints here are to prevent a *partial* overlap (where %Q0 == %R1).
4646 ;; The first alternative allows the common case of a *full* overlap.
4647 (define_insn_and_split "*arm_negdi2"
4648 [(set (match_operand:DI 0 "s_register_operand" "=r,&r")
4649 (neg:DI (match_operand:DI 1 "s_register_operand" "0,r")))
4650 (clobber (reg:CC CC_REGNUM))]
4652 "#" ; "rsbs\\t%Q0, %Q1, #0\;rsc\\t%R0, %R1, #0"
4653 "&& reload_completed"
4654 [(parallel [(set (reg:CC CC_REGNUM)
4655 (compare:CC (const_int 0) (match_dup 1)))
4656 (set (match_dup 0) (minus:SI (const_int 0) (match_dup 1)))])
4657 (set (match_dup 2) (minus:SI (minus:SI (const_int 0) (match_dup 3))
4658 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
4660 operands[2] = gen_highpart (SImode, operands[0]);
4661 operands[0] = gen_lowpart (SImode, operands[0]);
4662 operands[3] = gen_highpart (SImode, operands[1]);
4663 operands[1] = gen_lowpart (SImode, operands[1]);
4665 [(set_attr "conds" "clob")
4666 (set_attr "length" "8")
4667 (set_attr "type" "multiple")]
4670 (define_insn "*thumb1_negdi2"
4671 [(set (match_operand:DI 0 "register_operand" "=&l")
4672 (neg:DI (match_operand:DI 1 "register_operand" "l")))
4673 (clobber (reg:CC CC_REGNUM))]
4675 "mov\\t%R0, #0\;neg\\t%Q0, %Q1\;sbc\\t%R0, %R1"
4676 [(set_attr "length" "6")
4677 (set_attr "type" "multiple")]
4680 (define_expand "negsi2"
4681 [(set (match_operand:SI 0 "s_register_operand" "")
4682 (neg:SI (match_operand:SI 1 "s_register_operand" "")))]
4687 (define_insn "*arm_negsi2"
4688 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
4689 (neg:SI (match_operand:SI 1 "s_register_operand" "l,r")))]
4691 "rsb%?\\t%0, %1, #0"
4692 [(set_attr "predicable" "yes")
4693 (set_attr "predicable_short_it" "yes,no")
4694 (set_attr "arch" "t2,*")
4695 (set_attr "length" "4")
4696 (set_attr "type" "alu_reg")]
4699 (define_insn "*thumb1_negsi2"
4700 [(set (match_operand:SI 0 "register_operand" "=l")
4701 (neg:SI (match_operand:SI 1 "register_operand" "l")))]
4704 [(set_attr "length" "2")
4705 (set_attr "type" "alu_imm")]
4708 (define_expand "negsf2"
4709 [(set (match_operand:SF 0 "s_register_operand" "")
4710 (neg:SF (match_operand:SF 1 "s_register_operand" "")))]
4711 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
4715 (define_expand "negdf2"
4716 [(set (match_operand:DF 0 "s_register_operand" "")
4717 (neg:DF (match_operand:DF 1 "s_register_operand" "")))]
4718 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
4721 (define_insn_and_split "*zextendsidi_negsi"
4722 [(set (match_operand:DI 0 "s_register_operand" "=r")
4723 (zero_extend:DI (neg:SI (match_operand:SI 1 "s_register_operand" "r"))))]
4728 (neg:SI (match_dup 1)))
4732 operands[2] = gen_lowpart (SImode, operands[0]);
4733 operands[3] = gen_highpart (SImode, operands[0]);
4735 [(set_attr "length" "8")
4736 (set_attr "type" "multiple")]
4739 ;; Negate an extended 32-bit value.
4740 (define_insn_and_split "*negdi_extendsidi"
4741 [(set (match_operand:DI 0 "s_register_operand" "=l,r")
4742 (neg:DI (sign_extend:DI
4743 (match_operand:SI 1 "s_register_operand" "l,r"))))
4744 (clobber (reg:CC CC_REGNUM))]
4747 "&& reload_completed"
4750 rtx low = gen_lowpart (SImode, operands[0]);
4751 rtx high = gen_highpart (SImode, operands[0]);
4753 if (reg_overlap_mentioned_p (low, operands[1]))
4755 /* Input overlaps the low word of the output. Use:
4758 rsc Rhi, Rhi, #0 (thumb2: sbc Rhi, Rhi, Rhi, lsl #1). */
4759 rtx cc_reg = gen_rtx_REG (CC_Cmode, CC_REGNUM);
4761 emit_insn (gen_rtx_SET (VOIDmode, high,
4762 gen_rtx_ASHIFTRT (SImode, operands[1],
4765 emit_insn (gen_subsi3_compare (low, const0_rtx, operands[1]));
4767 emit_insn (gen_rtx_SET (VOIDmode, high,
4768 gen_rtx_MINUS (SImode,
4769 gen_rtx_MINUS (SImode,
4772 gen_rtx_LTU (SImode,
4777 rtx two_x = gen_rtx_ASHIFT (SImode, high, GEN_INT (1));
4778 emit_insn (gen_rtx_SET (VOIDmode, high,
4779 gen_rtx_MINUS (SImode,
4780 gen_rtx_MINUS (SImode,
4783 gen_rtx_LTU (SImode,
4790 /* No overlap, or overlap on high word. Use:
4794 Flags not needed for this sequence. */
4795 emit_insn (gen_rtx_SET (VOIDmode, low,
4796 gen_rtx_NEG (SImode, operands[1])));
4797 emit_insn (gen_rtx_SET (VOIDmode, high,
4798 gen_rtx_AND (SImode,
4799 gen_rtx_NOT (SImode, operands[1]),
4801 emit_insn (gen_rtx_SET (VOIDmode, high,
4802 gen_rtx_ASHIFTRT (SImode, high,
4807 [(set_attr "length" "12")
4808 (set_attr "arch" "t2,*")
4809 (set_attr "type" "multiple")]
4812 (define_insn_and_split "*negdi_zero_extendsidi"
4813 [(set (match_operand:DI 0 "s_register_operand" "=r,&r")
4814 (neg:DI (zero_extend:DI (match_operand:SI 1 "s_register_operand" "0,r"))))
4815 (clobber (reg:CC CC_REGNUM))]
4817 "#" ; "rsbs\\t%Q0, %1, #0\;sbc\\t%R0,%R0,%R0"
4818 ;; Don't care what register is input to sbc,
4819 ;; since we just just need to propagate the carry.
4820 "&& reload_completed"
4821 [(parallel [(set (reg:CC CC_REGNUM)
4822 (compare:CC (const_int 0) (match_dup 1)))
4823 (set (match_dup 0) (minus:SI (const_int 0) (match_dup 1)))])
4824 (set (match_dup 2) (minus:SI (minus:SI (match_dup 2) (match_dup 2))
4825 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
4827 operands[2] = gen_highpart (SImode, operands[0]);
4828 operands[0] = gen_lowpart (SImode, operands[0]);
4830 [(set_attr "conds" "clob")
4831 (set_attr "length" "8")
4832 (set_attr "type" "multiple")] ;; length in thumb is 4
4835 ;; abssi2 doesn't really clobber the condition codes if a different register
4836 ;; is being set. To keep things simple, assume during rtl manipulations that
4837 ;; it does, but tell the final scan operator the truth. Similarly for
4840 (define_expand "abssi2"
4842 [(set (match_operand:SI 0 "s_register_operand" "")
4843 (abs:SI (match_operand:SI 1 "s_register_operand" "")))
4844 (clobber (match_dup 2))])]
4848 operands[2] = gen_rtx_SCRATCH (SImode);
4850 operands[2] = gen_rtx_REG (CCmode, CC_REGNUM);
4853 (define_insn_and_split "*arm_abssi2"
4854 [(set (match_operand:SI 0 "s_register_operand" "=r,&r")
4855 (abs:SI (match_operand:SI 1 "s_register_operand" "0,r")))
4856 (clobber (reg:CC CC_REGNUM))]
4859 "&& reload_completed"
4862 /* if (which_alternative == 0) */
4863 if (REGNO(operands[0]) == REGNO(operands[1]))
4865 /* Emit the pattern:
4866 cmp\\t%0, #0\;rsblt\\t%0, %0, #0
4867 [(set (reg:CC CC_REGNUM)
4868 (compare:CC (match_dup 0) (const_int 0)))
4869 (cond_exec (lt:CC (reg:CC CC_REGNUM) (const_int 0))
4870 (set (match_dup 0) (minus:SI (const_int 0) (match_dup 1))))]
4872 emit_insn (gen_rtx_SET (VOIDmode,
4873 gen_rtx_REG (CCmode, CC_REGNUM),
4874 gen_rtx_COMPARE (CCmode, operands[0], const0_rtx)));
4875 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
4876 (gen_rtx_LT (SImode,
4877 gen_rtx_REG (CCmode, CC_REGNUM),
4879 (gen_rtx_SET (VOIDmode,
4881 (gen_rtx_MINUS (SImode,
4888 /* Emit the pattern:
4889 alt1: eor%?\\t%0, %1, %1, asr #31\;sub%?\\t%0, %0, %1, asr #31
4891 (xor:SI (match_dup 1)
4892 (ashiftrt:SI (match_dup 1) (const_int 31))))
4894 (minus:SI (match_dup 0)
4895 (ashiftrt:SI (match_dup 1) (const_int 31))))]
4897 emit_insn (gen_rtx_SET (VOIDmode,
4899 gen_rtx_XOR (SImode,
4900 gen_rtx_ASHIFTRT (SImode,
4904 emit_insn (gen_rtx_SET (VOIDmode,
4906 gen_rtx_MINUS (SImode,
4908 gen_rtx_ASHIFTRT (SImode,
4914 [(set_attr "conds" "clob,*")
4915 (set_attr "shift" "1")
4916 (set_attr "predicable" "no, yes")
4917 (set_attr "length" "8")
4918 (set_attr "type" "multiple")]
4921 (define_insn_and_split "*thumb1_abssi2"
4922 [(set (match_operand:SI 0 "s_register_operand" "=l")
4923 (abs:SI (match_operand:SI 1 "s_register_operand" "l")))
4924 (clobber (match_scratch:SI 2 "=&l"))]
4927 "TARGET_THUMB1 && reload_completed"
4928 [(set (match_dup 2) (ashiftrt:SI (match_dup 1) (const_int 31)))
4929 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))
4930 (set (match_dup 0) (xor:SI (match_dup 0) (match_dup 2)))]
4932 [(set_attr "length" "6")
4933 (set_attr "type" "multiple")]
4936 (define_insn_and_split "*arm_neg_abssi2"
4937 [(set (match_operand:SI 0 "s_register_operand" "=r,&r")
4938 (neg:SI (abs:SI (match_operand:SI 1 "s_register_operand" "0,r"))))
4939 (clobber (reg:CC CC_REGNUM))]
4942 "&& reload_completed"
4945 /* if (which_alternative == 0) */
4946 if (REGNO (operands[0]) == REGNO (operands[1]))
4948 /* Emit the pattern:
4949 cmp\\t%0, #0\;rsbgt\\t%0, %0, #0
4951 emit_insn (gen_rtx_SET (VOIDmode,
4952 gen_rtx_REG (CCmode, CC_REGNUM),
4953 gen_rtx_COMPARE (CCmode, operands[0], const0_rtx)));
4954 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
4956 gen_rtx_REG (CCmode, CC_REGNUM),
4958 gen_rtx_SET (VOIDmode,
4960 (gen_rtx_MINUS (SImode,
4966 /* Emit the pattern:
4967 eor%?\\t%0, %1, %1, asr #31\;rsb%?\\t%0, %0, %1, asr #31
4969 emit_insn (gen_rtx_SET (VOIDmode,
4971 gen_rtx_XOR (SImode,
4972 gen_rtx_ASHIFTRT (SImode,
4976 emit_insn (gen_rtx_SET (VOIDmode,
4978 gen_rtx_MINUS (SImode,
4979 gen_rtx_ASHIFTRT (SImode,
4986 [(set_attr "conds" "clob,*")
4987 (set_attr "shift" "1")
4988 (set_attr "predicable" "no, yes")
4989 (set_attr "length" "8")
4990 (set_attr "type" "multiple")]
4993 (define_insn_and_split "*thumb1_neg_abssi2"
4994 [(set (match_operand:SI 0 "s_register_operand" "=l")
4995 (neg:SI (abs:SI (match_operand:SI 1 "s_register_operand" "l"))))
4996 (clobber (match_scratch:SI 2 "=&l"))]
4999 "TARGET_THUMB1 && reload_completed"
5000 [(set (match_dup 2) (ashiftrt:SI (match_dup 1) (const_int 31)))
5001 (set (match_dup 0) (minus:SI (match_dup 2) (match_dup 1)))
5002 (set (match_dup 0) (xor:SI (match_dup 0) (match_dup 2)))]
5004 [(set_attr "length" "6")
5005 (set_attr "type" "multiple")]
5008 (define_expand "abssf2"
5009 [(set (match_operand:SF 0 "s_register_operand" "")
5010 (abs:SF (match_operand:SF 1 "s_register_operand" "")))]
5011 "TARGET_32BIT && TARGET_HARD_FLOAT"
5014 (define_expand "absdf2"
5015 [(set (match_operand:DF 0 "s_register_operand" "")
5016 (abs:DF (match_operand:DF 1 "s_register_operand" "")))]
5017 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
5020 (define_expand "sqrtsf2"
5021 [(set (match_operand:SF 0 "s_register_operand" "")
5022 (sqrt:SF (match_operand:SF 1 "s_register_operand" "")))]
5023 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
5026 (define_expand "sqrtdf2"
5027 [(set (match_operand:DF 0 "s_register_operand" "")
5028 (sqrt:DF (match_operand:DF 1 "s_register_operand" "")))]
5029 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
5032 (define_insn_and_split "one_cmpldi2"
5033 [(set (match_operand:DI 0 "s_register_operand" "=w,&r,&r,?w")
5034 (not:DI (match_operand:DI 1 "s_register_operand" " w, 0, r, w")))]
5041 "TARGET_32BIT && reload_completed
5042 && arm_general_register_operand (operands[0], DImode)"
5043 [(set (match_dup 0) (not:SI (match_dup 1)))
5044 (set (match_dup 2) (not:SI (match_dup 3)))]
5047 operands[2] = gen_highpart (SImode, operands[0]);
5048 operands[0] = gen_lowpart (SImode, operands[0]);
5049 operands[3] = gen_highpart (SImode, operands[1]);
5050 operands[1] = gen_lowpart (SImode, operands[1]);
5052 [(set_attr "length" "*,8,8,*")
5053 (set_attr "predicable" "no,yes,yes,no")
5054 (set_attr "type" "neon_move,multiple,multiple,neon_move")
5055 (set_attr "arch" "neon_for_64bits,*,*,avoid_neon_for_64bits")]
5058 (define_expand "one_cmplsi2"
5059 [(set (match_operand:SI 0 "s_register_operand" "")
5060 (not:SI (match_operand:SI 1 "s_register_operand" "")))]
5065 (define_insn "*arm_one_cmplsi2"
5066 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
5067 (not:SI (match_operand:SI 1 "s_register_operand" "l,r")))]
5070 [(set_attr "predicable" "yes")
5071 (set_attr "predicable_short_it" "yes,no")
5072 (set_attr "arch" "t2,*")
5073 (set_attr "length" "4")
5074 (set_attr "type" "mvn_reg")]
5077 (define_insn "*thumb1_one_cmplsi2"
5078 [(set (match_operand:SI 0 "register_operand" "=l")
5079 (not:SI (match_operand:SI 1 "register_operand" "l")))]
5082 [(set_attr "length" "2")
5083 (set_attr "type" "mvn_reg")]
5086 (define_insn "*notsi_compare0"
5087 [(set (reg:CC_NOOV CC_REGNUM)
5088 (compare:CC_NOOV (not:SI (match_operand:SI 1 "s_register_operand" "r"))
5090 (set (match_operand:SI 0 "s_register_operand" "=r")
5091 (not:SI (match_dup 1)))]
5094 [(set_attr "conds" "set")
5095 (set_attr "type" "mvn_reg")]
5098 (define_insn "*notsi_compare0_scratch"
5099 [(set (reg:CC_NOOV CC_REGNUM)
5100 (compare:CC_NOOV (not:SI (match_operand:SI 1 "s_register_operand" "r"))
5102 (clobber (match_scratch:SI 0 "=r"))]
5105 [(set_attr "conds" "set")
5106 (set_attr "type" "mvn_reg")]
5109 ;; Fixed <--> Floating conversion insns
5111 (define_expand "floatsihf2"
5112 [(set (match_operand:HF 0 "general_operand" "")
5113 (float:HF (match_operand:SI 1 "general_operand" "")))]
5117 rtx op1 = gen_reg_rtx (SFmode);
5118 expand_float (op1, operands[1], 0);
5119 op1 = convert_to_mode (HFmode, op1, 0);
5120 emit_move_insn (operands[0], op1);
5125 (define_expand "floatdihf2"
5126 [(set (match_operand:HF 0 "general_operand" "")
5127 (float:HF (match_operand:DI 1 "general_operand" "")))]
5131 rtx op1 = gen_reg_rtx (SFmode);
5132 expand_float (op1, operands[1], 0);
5133 op1 = convert_to_mode (HFmode, op1, 0);
5134 emit_move_insn (operands[0], op1);
5139 (define_expand "floatsisf2"
5140 [(set (match_operand:SF 0 "s_register_operand" "")
5141 (float:SF (match_operand:SI 1 "s_register_operand" "")))]
5142 "TARGET_32BIT && TARGET_HARD_FLOAT"
5146 (define_expand "floatsidf2"
5147 [(set (match_operand:DF 0 "s_register_operand" "")
5148 (float:DF (match_operand:SI 1 "s_register_operand" "")))]
5149 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
5153 (define_expand "fix_trunchfsi2"
5154 [(set (match_operand:SI 0 "general_operand" "")
5155 (fix:SI (fix:HF (match_operand:HF 1 "general_operand" ""))))]
5159 rtx op1 = convert_to_mode (SFmode, operands[1], 0);
5160 expand_fix (operands[0], op1, 0);
5165 (define_expand "fix_trunchfdi2"
5166 [(set (match_operand:DI 0 "general_operand" "")
5167 (fix:DI (fix:HF (match_operand:HF 1 "general_operand" ""))))]
5171 rtx op1 = convert_to_mode (SFmode, operands[1], 0);
5172 expand_fix (operands[0], op1, 0);
5177 (define_expand "fix_truncsfsi2"
5178 [(set (match_operand:SI 0 "s_register_operand" "")
5179 (fix:SI (fix:SF (match_operand:SF 1 "s_register_operand" ""))))]
5180 "TARGET_32BIT && TARGET_HARD_FLOAT"
5184 (define_expand "fix_truncdfsi2"
5185 [(set (match_operand:SI 0 "s_register_operand" "")
5186 (fix:SI (fix:DF (match_operand:DF 1 "s_register_operand" ""))))]
5187 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
5193 (define_expand "truncdfsf2"
5194 [(set (match_operand:SF 0 "s_register_operand" "")
5196 (match_operand:DF 1 "s_register_operand" "")))]
5197 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
5201 /* DFmode -> HFmode conversions have to go through SFmode. */
5202 (define_expand "truncdfhf2"
5203 [(set (match_operand:HF 0 "general_operand" "")
5205 (match_operand:DF 1 "general_operand" "")))]
5210 op1 = convert_to_mode (SFmode, operands[1], 0);
5211 op1 = convert_to_mode (HFmode, op1, 0);
5212 emit_move_insn (operands[0], op1);
5217 ;; Zero and sign extension instructions.
5219 (define_insn "zero_extend<mode>di2"
5220 [(set (match_operand:DI 0 "s_register_operand" "=w,r,?r,w")
5221 (zero_extend:DI (match_operand:QHSI 1 "<qhs_zextenddi_op>"
5222 "<qhs_zextenddi_cstr>")))]
5223 "TARGET_32BIT <qhs_zextenddi_cond>"
5225 [(set_attr "length" "8,4,8,8")
5226 (set_attr "arch" "neon_for_64bits,*,*,avoid_neon_for_64bits")
5227 (set_attr "ce_count" "2")
5228 (set_attr "predicable" "yes")
5229 (set_attr "type" "multiple,mov_reg,multiple,multiple")]
5232 (define_insn "extend<mode>di2"
5233 [(set (match_operand:DI 0 "s_register_operand" "=w,r,?r,?r,w")
5234 (sign_extend:DI (match_operand:QHSI 1 "<qhs_extenddi_op>"
5235 "<qhs_extenddi_cstr>")))]
5236 "TARGET_32BIT <qhs_sextenddi_cond>"
5238 [(set_attr "length" "8,4,8,8,8")
5239 (set_attr "ce_count" "2")
5240 (set_attr "shift" "1")
5241 (set_attr "predicable" "yes")
5242 (set_attr "arch" "neon_for_64bits,*,a,t,avoid_neon_for_64bits")
5243 (set_attr "type" "multiple,mov_reg,multiple,multiple,multiple")]
5246 ;; Splits for all extensions to DImode
5248 [(set (match_operand:DI 0 "s_register_operand" "")
5249 (zero_extend:DI (match_operand 1 "nonimmediate_operand" "")))]
5250 "TARGET_32BIT && reload_completed && !IS_VFP_REGNUM (REGNO (operands[0]))"
5251 [(set (match_dup 0) (match_dup 1))]
5253 rtx lo_part = gen_lowpart (SImode, operands[0]);
5254 enum machine_mode src_mode = GET_MODE (operands[1]);
5256 if (REG_P (operands[0])
5257 && !reg_overlap_mentioned_p (operands[0], operands[1]))
5258 emit_clobber (operands[0]);
5259 if (!REG_P (lo_part) || src_mode != SImode
5260 || !rtx_equal_p (lo_part, operands[1]))
5262 if (src_mode == SImode)
5263 emit_move_insn (lo_part, operands[1]);
5265 emit_insn (gen_rtx_SET (VOIDmode, lo_part,
5266 gen_rtx_ZERO_EXTEND (SImode, operands[1])));
5267 operands[1] = lo_part;
5269 operands[0] = gen_highpart (SImode, operands[0]);
5270 operands[1] = const0_rtx;
5274 [(set (match_operand:DI 0 "s_register_operand" "")
5275 (sign_extend:DI (match_operand 1 "nonimmediate_operand" "")))]
5276 "TARGET_32BIT && reload_completed && !IS_VFP_REGNUM (REGNO (operands[0]))"
5277 [(set (match_dup 0) (ashiftrt:SI (match_dup 1) (const_int 31)))]
5279 rtx lo_part = gen_lowpart (SImode, operands[0]);
5280 enum machine_mode src_mode = GET_MODE (operands[1]);
5282 if (REG_P (operands[0])
5283 && !reg_overlap_mentioned_p (operands[0], operands[1]))
5284 emit_clobber (operands[0]);
5286 if (!REG_P (lo_part) || src_mode != SImode
5287 || !rtx_equal_p (lo_part, operands[1]))
5289 if (src_mode == SImode)
5290 emit_move_insn (lo_part, operands[1]);
5292 emit_insn (gen_rtx_SET (VOIDmode, lo_part,
5293 gen_rtx_SIGN_EXTEND (SImode, operands[1])));
5294 operands[1] = lo_part;
5296 operands[0] = gen_highpart (SImode, operands[0]);
5299 (define_expand "zero_extendhisi2"
5300 [(set (match_operand:SI 0 "s_register_operand" "")
5301 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
5304 if (TARGET_ARM && !arm_arch4 && MEM_P (operands[1]))
5306 emit_insn (gen_movhi_bytes (operands[0], operands[1]));
5309 if (!arm_arch6 && !MEM_P (operands[1]))
5311 rtx t = gen_lowpart (SImode, operands[1]);
5312 rtx tmp = gen_reg_rtx (SImode);
5313 emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (16)));
5314 emit_insn (gen_lshrsi3 (operands[0], tmp, GEN_INT (16)));
5320 [(set (match_operand:SI 0 "s_register_operand" "")
5321 (zero_extend:SI (match_operand:HI 1 "s_register_operand" "")))]
5322 "!TARGET_THUMB2 && !arm_arch6"
5323 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
5324 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 16)))]
5326 operands[2] = gen_lowpart (SImode, operands[1]);
5329 (define_insn "*thumb1_zero_extendhisi2"
5330 [(set (match_operand:SI 0 "register_operand" "=l,l")
5331 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "l,m")))]
5336 if (which_alternative == 0 && arm_arch6)
5337 return "uxth\t%0, %1";
5338 if (which_alternative == 0)
5341 mem = XEXP (operands[1], 0);
5343 if (GET_CODE (mem) == CONST)
5344 mem = XEXP (mem, 0);
5346 if (GET_CODE (mem) == PLUS)
5348 rtx a = XEXP (mem, 0);
5350 /* This can happen due to bugs in reload. */
5351 if (REG_P (a) && REGNO (a) == SP_REGNUM)
5354 ops[0] = operands[0];
5357 output_asm_insn ("mov\t%0, %1", ops);
5359 XEXP (mem, 0) = operands[0];
5363 return "ldrh\t%0, %1";
5365 [(set_attr_alternative "length"
5366 [(if_then_else (eq_attr "is_arch6" "yes")
5367 (const_int 2) (const_int 4))
5369 (set_attr "type" "extend,load_byte")]
5372 (define_insn "*arm_zero_extendhisi2"
5373 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5374 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
5375 "TARGET_ARM && arm_arch4 && !arm_arch6"
5379 [(set_attr "type" "alu_shift_reg,load_byte")
5380 (set_attr "predicable" "yes")]
5383 (define_insn "*arm_zero_extendhisi2_v6"
5384 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5385 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
5386 "TARGET_ARM && arm_arch6"
5390 [(set_attr "predicable" "yes")
5391 (set_attr "type" "extend,load_byte")]
5394 (define_insn "*arm_zero_extendhisi2addsi"
5395 [(set (match_operand:SI 0 "s_register_operand" "=r")
5396 (plus:SI (zero_extend:SI (match_operand:HI 1 "s_register_operand" "r"))
5397 (match_operand:SI 2 "s_register_operand" "r")))]
5399 "uxtah%?\\t%0, %2, %1"
5400 [(set_attr "type" "alu_shift_reg")
5401 (set_attr "predicable" "yes")
5402 (set_attr "predicable_short_it" "no")]
5405 (define_expand "zero_extendqisi2"
5406 [(set (match_operand:SI 0 "s_register_operand" "")
5407 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))]
5410 if (TARGET_ARM && !arm_arch6 && !MEM_P (operands[1]))
5412 emit_insn (gen_andsi3 (operands[0],
5413 gen_lowpart (SImode, operands[1]),
5417 if (!arm_arch6 && !MEM_P (operands[1]))
5419 rtx t = gen_lowpart (SImode, operands[1]);
5420 rtx tmp = gen_reg_rtx (SImode);
5421 emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (24)));
5422 emit_insn (gen_lshrsi3 (operands[0], tmp, GEN_INT (24)));
5428 [(set (match_operand:SI 0 "s_register_operand" "")
5429 (zero_extend:SI (match_operand:QI 1 "s_register_operand" "")))]
5431 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 24)))
5432 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 24)))]
5434 operands[2] = simplify_gen_subreg (SImode, operands[1], QImode, 0);
5437 emit_insn (gen_andsi3 (operands[0], operands[2], GEN_INT (255)));
5442 (define_insn "*thumb1_zero_extendqisi2"
5443 [(set (match_operand:SI 0 "register_operand" "=l,l")
5444 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "l,m")))]
5445 "TARGET_THUMB1 && !arm_arch6"
5449 [(set_attr "length" "4,2")
5450 (set_attr "type" "alu_shift_reg,load_byte")
5451 (set_attr "pool_range" "*,32")]
5454 (define_insn "*thumb1_zero_extendqisi2_v6"
5455 [(set (match_operand:SI 0 "register_operand" "=l,l")
5456 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "l,m")))]
5457 "TARGET_THUMB1 && arm_arch6"
5461 [(set_attr "length" "2")
5462 (set_attr "type" "extend,load_byte")]
5465 (define_insn "*arm_zero_extendqisi2"
5466 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5467 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
5468 "TARGET_ARM && !arm_arch6"
5471 ldr%(b%)\\t%0, %1\\t%@ zero_extendqisi2"
5472 [(set_attr "length" "8,4")
5473 (set_attr "type" "alu_shift_reg,load_byte")
5474 (set_attr "predicable" "yes")]
5477 (define_insn "*arm_zero_extendqisi2_v6"
5478 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5479 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
5480 "TARGET_ARM && arm_arch6"
5483 ldr%(b%)\\t%0, %1\\t%@ zero_extendqisi2"
5484 [(set_attr "type" "extend,load_byte")
5485 (set_attr "predicable" "yes")]
5488 (define_insn "*arm_zero_extendqisi2addsi"
5489 [(set (match_operand:SI 0 "s_register_operand" "=r")
5490 (plus:SI (zero_extend:SI (match_operand:QI 1 "s_register_operand" "r"))
5491 (match_operand:SI 2 "s_register_operand" "r")))]
5493 "uxtab%?\\t%0, %2, %1"
5494 [(set_attr "predicable" "yes")
5495 (set_attr "predicable_short_it" "no")
5496 (set_attr "type" "alu_shift_reg")]
5500 [(set (match_operand:SI 0 "s_register_operand" "")
5501 (zero_extend:SI (subreg:QI (match_operand:SI 1 "" "") 0)))
5502 (clobber (match_operand:SI 2 "s_register_operand" ""))]
5503 "TARGET_32BIT && (!MEM_P (operands[1])) && ! BYTES_BIG_ENDIAN"
5504 [(set (match_dup 2) (match_dup 1))
5505 (set (match_dup 0) (and:SI (match_dup 2) (const_int 255)))]
5510 [(set (match_operand:SI 0 "s_register_operand" "")
5511 (zero_extend:SI (subreg:QI (match_operand:SI 1 "" "") 3)))
5512 (clobber (match_operand:SI 2 "s_register_operand" ""))]
5513 "TARGET_32BIT && (!MEM_P (operands[1])) && BYTES_BIG_ENDIAN"
5514 [(set (match_dup 2) (match_dup 1))
5515 (set (match_dup 0) (and:SI (match_dup 2) (const_int 255)))]
5521 [(set (match_operand:SI 0 "s_register_operand" "")
5522 (ior_xor:SI (and:SI (ashift:SI
5523 (match_operand:SI 1 "s_register_operand" "")
5524 (match_operand:SI 2 "const_int_operand" ""))
5525 (match_operand:SI 3 "const_int_operand" ""))
5527 (match_operator 5 "subreg_lowpart_operator"
5528 [(match_operand:SI 4 "s_register_operand" "")]))))]
5530 && ((unsigned HOST_WIDE_INT) INTVAL (operands[3])
5531 == (GET_MODE_MASK (GET_MODE (operands[5]))
5532 & (GET_MODE_MASK (GET_MODE (operands[5]))
5533 << (INTVAL (operands[2])))))"
5534 [(set (match_dup 0) (ior_xor:SI (ashift:SI (match_dup 1) (match_dup 2))
5536 (set (match_dup 0) (zero_extend:SI (match_dup 5)))]
5537 "operands[5] = gen_lowpart (GET_MODE (operands[5]), operands[0]);"
5540 (define_insn "*compareqi_eq0"
5541 [(set (reg:CC_Z CC_REGNUM)
5542 (compare:CC_Z (match_operand:QI 0 "s_register_operand" "r")
5546 [(set_attr "conds" "set")
5547 (set_attr "predicable" "yes")
5548 (set_attr "predicable_short_it" "no")
5549 (set_attr "type" "logic_imm")]
5552 (define_expand "extendhisi2"
5553 [(set (match_operand:SI 0 "s_register_operand" "")
5554 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
5559 emit_insn (gen_thumb1_extendhisi2 (operands[0], operands[1]));
5562 if (MEM_P (operands[1]) && TARGET_ARM && !arm_arch4)
5564 emit_insn (gen_extendhisi2_mem (operands[0], operands[1]));
5568 if (!arm_arch6 && !MEM_P (operands[1]))
5570 rtx t = gen_lowpart (SImode, operands[1]);
5571 rtx tmp = gen_reg_rtx (SImode);
5572 emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (16)));
5573 emit_insn (gen_ashrsi3 (operands[0], tmp, GEN_INT (16)));
5580 [(set (match_operand:SI 0 "register_operand" "")
5581 (sign_extend:SI (match_operand:HI 1 "register_operand" "")))
5582 (clobber (match_scratch:SI 2 ""))])]
5584 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
5585 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 16)))]
5587 operands[2] = simplify_gen_subreg (SImode, operands[1], HImode, 0);
5590 ;; We used to have an early-clobber on the scratch register here.
5591 ;; However, there's a bug somewhere in reload which means that this
5592 ;; can be partially ignored during spill allocation if the memory
5593 ;; address also needs reloading; this causes us to die later on when
5594 ;; we try to verify the operands. Fortunately, we don't really need
5595 ;; the early-clobber: we can always use operand 0 if operand 2
5596 ;; overlaps the address.
5597 (define_insn "thumb1_extendhisi2"
5598 [(set (match_operand:SI 0 "register_operand" "=l,l")
5599 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "l,m")))
5600 (clobber (match_scratch:SI 2 "=X,l"))]
5607 if (which_alternative == 0 && !arm_arch6)
5609 if (which_alternative == 0)
5610 return \"sxth\\t%0, %1\";
5612 mem = XEXP (operands[1], 0);
5614 /* This code used to try to use 'V', and fix the address only if it was
5615 offsettable, but this fails for e.g. REG+48 because 48 is outside the
5616 range of QImode offsets, and offsettable_address_p does a QImode
5619 if (GET_CODE (mem) == CONST)
5620 mem = XEXP (mem, 0);
5622 if (GET_CODE (mem) == LABEL_REF)
5623 return \"ldr\\t%0, %1\";
5625 if (GET_CODE (mem) == PLUS)
5627 rtx a = XEXP (mem, 0);
5628 rtx b = XEXP (mem, 1);
5630 if (GET_CODE (a) == LABEL_REF
5632 return \"ldr\\t%0, %1\";
5635 return \"ldrsh\\t%0, %1\";
5643 ops[2] = const0_rtx;
5646 gcc_assert (REG_P (ops[1]));
5648 ops[0] = operands[0];
5649 if (reg_mentioned_p (operands[2], ops[1]))
5652 ops[3] = operands[2];
5653 output_asm_insn (\"mov\\t%3, %2\;ldrsh\\t%0, [%1, %3]\", ops);
5656 [(set_attr_alternative "length"
5657 [(if_then_else (eq_attr "is_arch6" "yes")
5658 (const_int 2) (const_int 4))
5660 (set_attr "type" "extend,load_byte")
5661 (set_attr "pool_range" "*,1018")]
5664 ;; This pattern will only be used when ldsh is not available
5665 (define_expand "extendhisi2_mem"
5666 [(set (match_dup 2) (zero_extend:SI (match_operand:HI 1 "" "")))
5668 (zero_extend:SI (match_dup 7)))
5669 (set (match_dup 6) (ashift:SI (match_dup 4) (const_int 24)))
5670 (set (match_operand:SI 0 "" "")
5671 (ior:SI (ashiftrt:SI (match_dup 6) (const_int 16)) (match_dup 5)))]
5676 rtx addr = copy_to_mode_reg (SImode, XEXP (operands[1], 0));
5678 mem1 = change_address (operands[1], QImode, addr);
5679 mem2 = change_address (operands[1], QImode,
5680 plus_constant (Pmode, addr, 1));
5681 operands[0] = gen_lowpart (SImode, operands[0]);
5683 operands[2] = gen_reg_rtx (SImode);
5684 operands[3] = gen_reg_rtx (SImode);
5685 operands[6] = gen_reg_rtx (SImode);
5688 if (BYTES_BIG_ENDIAN)
5690 operands[4] = operands[2];
5691 operands[5] = operands[3];
5695 operands[4] = operands[3];
5696 operands[5] = operands[2];
5702 [(set (match_operand:SI 0 "register_operand" "")
5703 (sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
5705 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
5706 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 16)))]
5708 operands[2] = simplify_gen_subreg (SImode, operands[1], HImode, 0);
5711 (define_insn "*arm_extendhisi2"
5712 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5713 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
5714 "TARGET_ARM && arm_arch4 && !arm_arch6"
5718 [(set_attr "length" "8,4")
5719 (set_attr "type" "alu_shift_reg,load_byte")
5720 (set_attr "predicable" "yes")
5721 (set_attr "pool_range" "*,256")
5722 (set_attr "neg_pool_range" "*,244")]
5725 ;; ??? Check Thumb-2 pool range
5726 (define_insn "*arm_extendhisi2_v6"
5727 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5728 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
5729 "TARGET_32BIT && arm_arch6"
5733 [(set_attr "type" "extend,load_byte")
5734 (set_attr "predicable" "yes")
5735 (set_attr "predicable_short_it" "no")
5736 (set_attr "pool_range" "*,256")
5737 (set_attr "neg_pool_range" "*,244")]
5740 (define_insn "*arm_extendhisi2addsi"
5741 [(set (match_operand:SI 0 "s_register_operand" "=r")
5742 (plus:SI (sign_extend:SI (match_operand:HI 1 "s_register_operand" "r"))
5743 (match_operand:SI 2 "s_register_operand" "r")))]
5745 "sxtah%?\\t%0, %2, %1"
5746 [(set_attr "type" "alu_shift_reg")]
5749 (define_expand "extendqihi2"
5751 (ashift:SI (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "")
5753 (set (match_operand:HI 0 "s_register_operand" "")
5754 (ashiftrt:SI (match_dup 2)
5759 if (arm_arch4 && MEM_P (operands[1]))
5761 emit_insn (gen_rtx_SET (VOIDmode,
5763 gen_rtx_SIGN_EXTEND (HImode, operands[1])));
5766 if (!s_register_operand (operands[1], QImode))
5767 operands[1] = copy_to_mode_reg (QImode, operands[1]);
5768 operands[0] = gen_lowpart (SImode, operands[0]);
5769 operands[1] = gen_lowpart (SImode, operands[1]);
5770 operands[2] = gen_reg_rtx (SImode);
5774 (define_insn "*arm_extendqihi_insn"
5775 [(set (match_operand:HI 0 "s_register_operand" "=r")
5776 (sign_extend:HI (match_operand:QI 1 "arm_extendqisi_mem_op" "Uq")))]
5777 "TARGET_ARM && arm_arch4"
5778 "ldr%(sb%)\\t%0, %1"
5779 [(set_attr "type" "load_byte")
5780 (set_attr "predicable" "yes")
5781 (set_attr "pool_range" "256")
5782 (set_attr "neg_pool_range" "244")]
5785 (define_expand "extendqisi2"
5786 [(set (match_operand:SI 0 "s_register_operand" "")
5787 (sign_extend:SI (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "")))]
5790 if (!arm_arch4 && MEM_P (operands[1]))
5791 operands[1] = copy_to_mode_reg (QImode, operands[1]);
5793 if (!arm_arch6 && !MEM_P (operands[1]))
5795 rtx t = gen_lowpart (SImode, operands[1]);
5796 rtx tmp = gen_reg_rtx (SImode);
5797 emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (24)));
5798 emit_insn (gen_ashrsi3 (operands[0], tmp, GEN_INT (24)));
5804 [(set (match_operand:SI 0 "register_operand" "")
5805 (sign_extend:SI (match_operand:QI 1 "register_operand" "")))]
5807 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 24)))
5808 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 24)))]
5810 operands[2] = simplify_gen_subreg (SImode, operands[1], QImode, 0);
5813 (define_insn "*arm_extendqisi"
5814 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5815 (sign_extend:SI (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "r,Uq")))]
5816 "TARGET_ARM && arm_arch4 && !arm_arch6"
5820 [(set_attr "length" "8,4")
5821 (set_attr "type" "alu_shift_reg,load_byte")
5822 (set_attr "predicable" "yes")
5823 (set_attr "pool_range" "*,256")
5824 (set_attr "neg_pool_range" "*,244")]
5827 (define_insn "*arm_extendqisi_v6"
5828 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5830 (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "r,Uq")))]
5831 "TARGET_ARM && arm_arch6"
5835 [(set_attr "type" "extend,load_byte")
5836 (set_attr "predicable" "yes")
5837 (set_attr "pool_range" "*,256")
5838 (set_attr "neg_pool_range" "*,244")]
5841 (define_insn "*arm_extendqisi2addsi"
5842 [(set (match_operand:SI 0 "s_register_operand" "=r")
5843 (plus:SI (sign_extend:SI (match_operand:QI 1 "s_register_operand" "r"))
5844 (match_operand:SI 2 "s_register_operand" "r")))]
5846 "sxtab%?\\t%0, %2, %1"
5847 [(set_attr "type" "alu_shift_reg")
5848 (set_attr "predicable" "yes")
5849 (set_attr "predicable_short_it" "no")]
5853 [(set (match_operand:SI 0 "register_operand" "")
5854 (sign_extend:SI (match_operand:QI 1 "memory_operand" "")))]
5855 "TARGET_THUMB1 && reload_completed"
5856 [(set (match_dup 0) (match_dup 2))
5857 (set (match_dup 0) (sign_extend:SI (match_dup 3)))]
5859 rtx addr = XEXP (operands[1], 0);
5861 if (GET_CODE (addr) == CONST)
5862 addr = XEXP (addr, 0);
5864 if (GET_CODE (addr) == PLUS
5865 && REG_P (XEXP (addr, 0)) && REG_P (XEXP (addr, 1)))
5866 /* No split necessary. */
5869 if (GET_CODE (addr) == PLUS
5870 && !REG_P (XEXP (addr, 0)) && !REG_P (XEXP (addr, 1)))
5873 if (reg_overlap_mentioned_p (operands[0], addr))
5875 rtx t = gen_lowpart (QImode, operands[0]);
5876 emit_move_insn (t, operands[1]);
5877 emit_insn (gen_thumb1_extendqisi2 (operands[0], t));
5883 addr = gen_rtx_PLUS (Pmode, addr, operands[0]);
5884 operands[2] = const0_rtx;
5886 else if (GET_CODE (addr) != PLUS)
5888 else if (REG_P (XEXP (addr, 0)))
5890 operands[2] = XEXP (addr, 1);
5891 addr = gen_rtx_PLUS (Pmode, XEXP (addr, 0), operands[0]);
5895 operands[2] = XEXP (addr, 0);
5896 addr = gen_rtx_PLUS (Pmode, XEXP (addr, 1), operands[0]);
5899 operands[3] = change_address (operands[1], QImode, addr);
5903 [(set (match_operand:SI 0 "register_operand" "")
5904 (plus:SI (match_dup 0) (match_operand 1 "const_int_operand")))
5905 (set (match_operand:SI 2 "register_operand" "") (const_int 0))
5906 (set (match_operand:SI 3 "register_operand" "")
5907 (sign_extend:SI (match_operand:QI 4 "memory_operand" "")))]
5909 && GET_CODE (XEXP (operands[4], 0)) == PLUS
5910 && rtx_equal_p (operands[0], XEXP (XEXP (operands[4], 0), 0))
5911 && rtx_equal_p (operands[2], XEXP (XEXP (operands[4], 0), 1))
5912 && (peep2_reg_dead_p (3, operands[0])
5913 || rtx_equal_p (operands[0], operands[3]))
5914 && (peep2_reg_dead_p (3, operands[2])
5915 || rtx_equal_p (operands[2], operands[3]))"
5916 [(set (match_dup 2) (match_dup 1))
5917 (set (match_dup 3) (sign_extend:SI (match_dup 4)))]
5919 rtx addr = gen_rtx_PLUS (Pmode, operands[0], operands[2]);
5920 operands[4] = change_address (operands[4], QImode, addr);
5923 (define_insn "thumb1_extendqisi2"
5924 [(set (match_operand:SI 0 "register_operand" "=l,l,l")
5925 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "l,V,m")))]
5930 if (which_alternative == 0 && arm_arch6)
5931 return "sxtb\\t%0, %1";
5932 if (which_alternative == 0)
5935 addr = XEXP (operands[1], 0);
5936 if (GET_CODE (addr) == PLUS
5937 && REG_P (XEXP (addr, 0)) && REG_P (XEXP (addr, 1)))
5938 return "ldrsb\\t%0, %1";
5942 [(set_attr_alternative "length"
5943 [(if_then_else (eq_attr "is_arch6" "yes")
5944 (const_int 2) (const_int 4))
5946 (if_then_else (eq_attr "is_arch6" "yes")
5947 (const_int 4) (const_int 6))])
5948 (set_attr "type" "extend,load_byte,load_byte")]
5951 (define_expand "extendsfdf2"
5952 [(set (match_operand:DF 0 "s_register_operand" "")
5953 (float_extend:DF (match_operand:SF 1 "s_register_operand" "")))]
5954 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
5958 /* HFmode -> DFmode conversions have to go through SFmode. */
5959 (define_expand "extendhfdf2"
5960 [(set (match_operand:DF 0 "general_operand" "")
5961 (float_extend:DF (match_operand:HF 1 "general_operand" "")))]
5966 op1 = convert_to_mode (SFmode, operands[1], 0);
5967 op1 = convert_to_mode (DFmode, op1, 0);
5968 emit_insn (gen_movdf (operands[0], op1));
5973 ;; Move insns (including loads and stores)
5975 ;; XXX Just some ideas about movti.
5976 ;; I don't think these are a good idea on the arm, there just aren't enough
5978 ;;(define_expand "loadti"
5979 ;; [(set (match_operand:TI 0 "s_register_operand" "")
5980 ;; (mem:TI (match_operand:SI 1 "address_operand" "")))]
5983 ;;(define_expand "storeti"
5984 ;; [(set (mem:TI (match_operand:TI 0 "address_operand" ""))
5985 ;; (match_operand:TI 1 "s_register_operand" ""))]
5988 ;;(define_expand "movti"
5989 ;; [(set (match_operand:TI 0 "general_operand" "")
5990 ;; (match_operand:TI 1 "general_operand" ""))]
5996 ;; if (MEM_P (operands[0]) && MEM_P (operands[1]))
5997 ;; operands[1] = copy_to_reg (operands[1]);
5998 ;; if (MEM_P (operands[0]))
5999 ;; insn = gen_storeti (XEXP (operands[0], 0), operands[1]);
6000 ;; else if (MEM_P (operands[1]))
6001 ;; insn = gen_loadti (operands[0], XEXP (operands[1], 0));
6005 ;; emit_insn (insn);
6009 ;; Recognize garbage generated above.
6012 ;; [(set (match_operand:TI 0 "general_operand" "=r,r,r,<,>,m")
6013 ;; (match_operand:TI 1 "general_operand" "<,>,m,r,r,r"))]
6017 ;; register mem = (which_alternative < 3);
6018 ;; register const char *template;
6020 ;; operands[mem] = XEXP (operands[mem], 0);
6021 ;; switch (which_alternative)
6023 ;; case 0: template = \"ldmdb\\t%1!, %M0\"; break;
6024 ;; case 1: template = \"ldmia\\t%1!, %M0\"; break;
6025 ;; case 2: template = \"ldmia\\t%1, %M0\"; break;
6026 ;; case 3: template = \"stmdb\\t%0!, %M1\"; break;
6027 ;; case 4: template = \"stmia\\t%0!, %M1\"; break;
6028 ;; case 5: template = \"stmia\\t%0, %M1\"; break;
6030 ;; output_asm_insn (template, operands);
6034 (define_expand "movdi"
6035 [(set (match_operand:DI 0 "general_operand" "")
6036 (match_operand:DI 1 "general_operand" ""))]
6039 if (can_create_pseudo_p ())
6041 if (!REG_P (operands[0]))
6042 operands[1] = force_reg (DImode, operands[1]);
6047 (define_insn "*arm_movdi"
6048 [(set (match_operand:DI 0 "nonimmediate_di_operand" "=r, r, r, q, m")
6049 (match_operand:DI 1 "di_operand" "rDa,Db,Dc,mi,q"))]
6051 && !(TARGET_HARD_FLOAT && TARGET_VFP)
6053 && ( register_operand (operands[0], DImode)
6054 || register_operand (operands[1], DImode))"
6056 switch (which_alternative)
6063 return output_move_double (operands, true, NULL);
6066 [(set_attr "length" "8,12,16,8,8")
6067 (set_attr "type" "multiple,multiple,multiple,load2,store2")
6068 (set_attr "arm_pool_range" "*,*,*,1020,*")
6069 (set_attr "arm_neg_pool_range" "*,*,*,1004,*")
6070 (set_attr "thumb2_pool_range" "*,*,*,4094,*")
6071 (set_attr "thumb2_neg_pool_range" "*,*,*,0,*")]
6075 [(set (match_operand:ANY64 0 "arm_general_register_operand" "")
6076 (match_operand:ANY64 1 "const_double_operand" ""))]
6079 && (arm_const_double_inline_cost (operands[1])
6080 <= arm_max_const_double_inline_cost ())"
6083 arm_split_constant (SET, SImode, curr_insn,
6084 INTVAL (gen_lowpart (SImode, operands[1])),
6085 gen_lowpart (SImode, operands[0]), NULL_RTX, 0);
6086 arm_split_constant (SET, SImode, curr_insn,
6087 INTVAL (gen_highpart_mode (SImode,
6088 GET_MODE (operands[0]),
6090 gen_highpart (SImode, operands[0]), NULL_RTX, 0);
6095 ; If optimizing for size, or if we have load delay slots, then
6096 ; we want to split the constant into two separate operations.
6097 ; In both cases this may split a trivial part into a single data op
6098 ; leaving a single complex constant to load. We can also get longer
6099 ; offsets in a LDR which means we get better chances of sharing the pool
6100 ; entries. Finally, we can normally do a better job of scheduling
6101 ; LDR instructions than we can with LDM.
6102 ; This pattern will only match if the one above did not.
6104 [(set (match_operand:ANY64 0 "arm_general_register_operand" "")
6105 (match_operand:ANY64 1 "const_double_operand" ""))]
6106 "TARGET_ARM && reload_completed
6107 && arm_const_double_by_parts (operands[1])"
6108 [(set (match_dup 0) (match_dup 1))
6109 (set (match_dup 2) (match_dup 3))]
6111 operands[2] = gen_highpart (SImode, operands[0]);
6112 operands[3] = gen_highpart_mode (SImode, GET_MODE (operands[0]),
6114 operands[0] = gen_lowpart (SImode, operands[0]);
6115 operands[1] = gen_lowpart (SImode, operands[1]);
6120 [(set (match_operand:ANY64 0 "arm_general_register_operand" "")
6121 (match_operand:ANY64 1 "arm_general_register_operand" ""))]
6122 "TARGET_EITHER && reload_completed"
6123 [(set (match_dup 0) (match_dup 1))
6124 (set (match_dup 2) (match_dup 3))]
6126 operands[2] = gen_highpart (SImode, operands[0]);
6127 operands[3] = gen_highpart (SImode, operands[1]);
6128 operands[0] = gen_lowpart (SImode, operands[0]);
6129 operands[1] = gen_lowpart (SImode, operands[1]);
6131 /* Handle a partial overlap. */
6132 if (rtx_equal_p (operands[0], operands[3]))
6134 rtx tmp0 = operands[0];
6135 rtx tmp1 = operands[1];
6137 operands[0] = operands[2];
6138 operands[1] = operands[3];
6145 ;; We can't actually do base+index doubleword loads if the index and
6146 ;; destination overlap. Split here so that we at least have chance to
6149 [(set (match_operand:DI 0 "s_register_operand" "")
6150 (mem:DI (plus:SI (match_operand:SI 1 "s_register_operand" "")
6151 (match_operand:SI 2 "s_register_operand" ""))))]
6153 && reg_overlap_mentioned_p (operands[0], operands[1])
6154 && reg_overlap_mentioned_p (operands[0], operands[2])"
6156 (plus:SI (match_dup 1)
6159 (mem:DI (match_dup 4)))]
6161 operands[4] = gen_rtx_REG (SImode, REGNO(operands[0]));
6165 ;;; ??? This should have alternatives for constants.
6166 ;;; ??? This was originally identical to the movdf_insn pattern.
6167 ;;; ??? The 'i' constraint looks funny, but it should always be replaced by
6168 ;;; thumb_reorg with a memory reference.
6169 (define_insn "*thumb1_movdi_insn"
6170 [(set (match_operand:DI 0 "nonimmediate_operand" "=l,l,l,l,>,l, m,*r")
6171 (match_operand:DI 1 "general_operand" "l, I,J,>,l,mi,l,*r"))]
6173 && ( register_operand (operands[0], DImode)
6174 || register_operand (operands[1], DImode))"
6177 switch (which_alternative)
6181 if (REGNO (operands[1]) == REGNO (operands[0]) + 1)
6182 return \"add\\t%0, %1, #0\;add\\t%H0, %H1, #0\";
6183 return \"add\\t%H0, %H1, #0\;add\\t%0, %1, #0\";
6185 return \"mov\\t%Q0, %1\;mov\\t%R0, #0\";
6187 operands[1] = GEN_INT (- INTVAL (operands[1]));
6188 return \"mov\\t%Q0, %1\;neg\\t%Q0, %Q0\;asr\\t%R0, %Q0, #31\";
6190 return \"ldmia\\t%1, {%0, %H0}\";
6192 return \"stmia\\t%0, {%1, %H1}\";
6194 return thumb_load_double_from_address (operands);
6196 operands[2] = gen_rtx_MEM (SImode,
6197 plus_constant (Pmode, XEXP (operands[0], 0), 4));
6198 output_asm_insn (\"str\\t%1, %0\;str\\t%H1, %2\", operands);
6201 if (REGNO (operands[1]) == REGNO (operands[0]) + 1)
6202 return \"mov\\t%0, %1\;mov\\t%H0, %H1\";
6203 return \"mov\\t%H0, %H1\;mov\\t%0, %1\";
6206 [(set_attr "length" "4,4,6,2,2,6,4,4")
6207 (set_attr "type" "multiple,multiple,multiple,load2,store2,load2,store2,multiple")
6208 (set_attr "pool_range" "*,*,*,*,*,1018,*,*")]
6211 (define_expand "movsi"
6212 [(set (match_operand:SI 0 "general_operand" "")
6213 (match_operand:SI 1 "general_operand" ""))]
6217 rtx base, offset, tmp;
6221 /* Everything except mem = const or mem = mem can be done easily. */
6222 if (MEM_P (operands[0]))
6223 operands[1] = force_reg (SImode, operands[1]);
6224 if (arm_general_register_operand (operands[0], SImode)
6225 && CONST_INT_P (operands[1])
6226 && !(const_ok_for_arm (INTVAL (operands[1]))
6227 || const_ok_for_arm (~INTVAL (operands[1]))))
6229 arm_split_constant (SET, SImode, NULL_RTX,
6230 INTVAL (operands[1]), operands[0], NULL_RTX,
6231 optimize && can_create_pseudo_p ());
6235 else /* TARGET_THUMB1... */
6237 if (can_create_pseudo_p ())
6239 if (!REG_P (operands[0]))
6240 operands[1] = force_reg (SImode, operands[1]);
6244 if (ARM_OFFSETS_MUST_BE_WITHIN_SECTIONS_P)
6246 split_const (operands[1], &base, &offset);
6247 if (GET_CODE (base) == SYMBOL_REF
6248 && !offset_within_block_p (base, INTVAL (offset)))
6250 tmp = can_create_pseudo_p () ? gen_reg_rtx (SImode) : operands[0];
6251 emit_move_insn (tmp, base);
6252 emit_insn (gen_addsi3 (operands[0], tmp, offset));
6257 /* Recognize the case where operand[1] is a reference to thread-local
6258 data and load its address to a register. */
6259 if (arm_tls_referenced_p (operands[1]))
6261 rtx tmp = operands[1];
6264 if (GET_CODE (tmp) == CONST && GET_CODE (XEXP (tmp, 0)) == PLUS)
6266 addend = XEXP (XEXP (tmp, 0), 1);
6267 tmp = XEXP (XEXP (tmp, 0), 0);
6270 gcc_assert (GET_CODE (tmp) == SYMBOL_REF);
6271 gcc_assert (SYMBOL_REF_TLS_MODEL (tmp) != 0);
6273 tmp = legitimize_tls_address (tmp,
6274 !can_create_pseudo_p () ? operands[0] : 0);
6277 tmp = gen_rtx_PLUS (SImode, tmp, addend);
6278 tmp = force_operand (tmp, operands[0]);
6283 && (CONSTANT_P (operands[1])
6284 || symbol_mentioned_p (operands[1])
6285 || label_mentioned_p (operands[1])))
6286 operands[1] = legitimize_pic_address (operands[1], SImode,
6287 (!can_create_pseudo_p ()
6294 ;; The ARM LO_SUM and HIGH are backwards - HIGH sets the low bits, and
6295 ;; LO_SUM adds in the high bits. Fortunately these are opaque operations
6296 ;; so this does not matter.
6297 (define_insn "*arm_movt"
6298 [(set (match_operand:SI 0 "nonimmediate_operand" "=r")
6299 (lo_sum:SI (match_operand:SI 1 "nonimmediate_operand" "0")
6300 (match_operand:SI 2 "general_operand" "i")))]
6302 "movt%?\t%0, #:upper16:%c2"
6303 [(set_attr "predicable" "yes")
6304 (set_attr "predicable_short_it" "no")
6305 (set_attr "length" "4")
6306 (set_attr "type" "mov_imm")]
6309 (define_insn "*arm_movsi_insn"
6310 [(set (match_operand:SI 0 "nonimmediate_operand" "=rk,r,r,r,rk,m")
6311 (match_operand:SI 1 "general_operand" "rk, I,K,j,mi,rk"))]
6312 "TARGET_ARM && ! TARGET_IWMMXT
6313 && !(TARGET_HARD_FLOAT && TARGET_VFP)
6314 && ( register_operand (operands[0], SImode)
6315 || register_operand (operands[1], SImode))"
6323 [(set_attr "type" "mov_reg,mov_imm,mvn_imm,mov_imm,load1,store1")
6324 (set_attr "predicable" "yes")
6325 (set_attr "pool_range" "*,*,*,*,4096,*")
6326 (set_attr "neg_pool_range" "*,*,*,*,4084,*")]
6330 [(set (match_operand:SI 0 "arm_general_register_operand" "")
6331 (match_operand:SI 1 "const_int_operand" ""))]
6333 && (!(const_ok_for_arm (INTVAL (operands[1]))
6334 || const_ok_for_arm (~INTVAL (operands[1]))))"
6335 [(clobber (const_int 0))]
6337 arm_split_constant (SET, SImode, NULL_RTX,
6338 INTVAL (operands[1]), operands[0], NULL_RTX, 0);
6343 ;; A normal way to do (symbol + offset) requires three instructions at least
6344 ;; (depends on how big the offset is) as below:
6345 ;; movw r0, #:lower16:g
6346 ;; movw r0, #:upper16:g
6349 ;; A better way would be:
6350 ;; movw r0, #:lower16:g+4
6351 ;; movw r0, #:upper16:g+4
6353 ;; The limitation of this way is that the length of offset should be a 16-bit
6354 ;; signed value, because current assembler only supports REL type relocation for
6355 ;; such case. If the more powerful RELA type is supported in future, we should
6356 ;; update this pattern to go with better way.
6358 [(set (match_operand:SI 0 "arm_general_register_operand" "")
6359 (const:SI (plus:SI (match_operand:SI 1 "general_operand" "")
6360 (match_operand:SI 2 "const_int_operand" ""))))]
6362 && arm_disable_literal_pool
6364 && GET_CODE (operands[1]) == SYMBOL_REF"
6365 [(clobber (const_int 0))]
6367 int offset = INTVAL (operands[2]);
6369 if (offset < -0x8000 || offset > 0x7fff)
6371 arm_emit_movpair (operands[0], operands[1]);
6372 emit_insn (gen_rtx_SET (SImode, operands[0],
6373 gen_rtx_PLUS (SImode, operands[0], operands[2])));
6377 rtx op = gen_rtx_CONST (SImode,
6378 gen_rtx_PLUS (SImode, operands[1], operands[2]));
6379 arm_emit_movpair (operands[0], op);
6384 ;; Split symbol_refs at the later stage (after cprop), instead of generating
6385 ;; movt/movw pair directly at expand. Otherwise corresponding high_sum
6386 ;; and lo_sum would be merged back into memory load at cprop. However,
6387 ;; if the default is to prefer movt/movw rather than a load from the constant
6388 ;; pool, the performance is better.
6390 [(set (match_operand:SI 0 "arm_general_register_operand" "")
6391 (match_operand:SI 1 "general_operand" ""))]
6393 && TARGET_USE_MOVT && GET_CODE (operands[1]) == SYMBOL_REF
6394 && !flag_pic && !target_word_relocations
6395 && !arm_tls_referenced_p (operands[1])"
6396 [(clobber (const_int 0))]
6398 arm_emit_movpair (operands[0], operands[1]);
6402 (define_insn "*thumb1_movsi_insn"
6403 [(set (match_operand:SI 0 "nonimmediate_operand" "=l,l,l,l,l,>,l, m,*l*h*k")
6404 (match_operand:SI 1 "general_operand" "l, I,J,K,>,l,mi,l,*l*h*k"))]
6406 && ( register_operand (operands[0], SImode)
6407 || register_operand (operands[1], SImode))"
6418 [(set_attr "length" "2,2,4,4,2,2,2,2,2")
6419 (set_attr "type" "mov_reg,mov_imm,multiple,multiple,load1,store1,load1,store1,mov_reg")
6420 (set_attr "pool_range" "*,*,*,*,*,*,1018,*,*")
6421 (set_attr "conds" "set,clob,*,*,nocond,nocond,nocond,nocond,nocond")])
6424 [(set (match_operand:SI 0 "register_operand" "")
6425 (match_operand:SI 1 "const_int_operand" ""))]
6426 "TARGET_THUMB1 && satisfies_constraint_J (operands[1])"
6427 [(set (match_dup 2) (match_dup 1))
6428 (set (match_dup 0) (neg:SI (match_dup 2)))]
6431 operands[1] = GEN_INT (- INTVAL (operands[1]));
6432 operands[2] = can_create_pseudo_p () ? gen_reg_rtx (SImode) : operands[0];
6437 [(set (match_operand:SI 0 "register_operand" "")
6438 (match_operand:SI 1 "const_int_operand" ""))]
6439 "TARGET_THUMB1 && satisfies_constraint_K (operands[1])"
6440 [(set (match_dup 2) (match_dup 1))
6441 (set (match_dup 0) (ashift:SI (match_dup 2) (match_dup 3)))]
6444 unsigned HOST_WIDE_INT val = INTVAL (operands[1]) & 0xffffffffu;
6445 unsigned HOST_WIDE_INT mask = 0xff;
6448 for (i = 0; i < 25; i++)
6449 if ((val & (mask << i)) == val)
6452 /* Don't split if the shift is zero. */
6456 operands[1] = GEN_INT (val >> i);
6457 operands[2] = can_create_pseudo_p () ? gen_reg_rtx (SImode) : operands[0];
6458 operands[3] = GEN_INT (i);
6462 ;; For thumb1 split imm move [256-510] into mov [1-255] and add #255
6464 [(set (match_operand:SI 0 "register_operand" "")
6465 (match_operand:SI 1 "const_int_operand" ""))]
6466 "TARGET_THUMB1 && satisfies_constraint_Pe (operands[1])"
6467 [(set (match_dup 2) (match_dup 1))
6468 (set (match_dup 0) (plus:SI (match_dup 2) (match_dup 3)))]
6471 operands[1] = GEN_INT (INTVAL (operands[1]) - 255);
6472 operands[2] = can_create_pseudo_p () ? gen_reg_rtx (SImode) : operands[0];
6473 operands[3] = GEN_INT (255);
6477 ;; When generating pic, we need to load the symbol offset into a register.
6478 ;; So that the optimizer does not confuse this with a normal symbol load
6479 ;; we use an unspec. The offset will be loaded from a constant pool entry,
6480 ;; since that is the only type of relocation we can use.
6482 ;; Wrap calculation of the whole PIC address in a single pattern for the
6483 ;; benefit of optimizers, particularly, PRE and HOIST. Calculation of
6484 ;; a PIC address involves two loads from memory, so we want to CSE it
6485 ;; as often as possible.
6486 ;; This pattern will be split into one of the pic_load_addr_* patterns
6487 ;; and a move after GCSE optimizations.
6489 ;; Note: Update arm.c: legitimize_pic_address() when changing this pattern.
6490 (define_expand "calculate_pic_address"
6491 [(set (match_operand:SI 0 "register_operand" "")
6492 (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "")
6493 (unspec:SI [(match_operand:SI 2 "" "")]
6498 ;; Split calculate_pic_address into pic_load_addr_* and a move.
6500 [(set (match_operand:SI 0 "register_operand" "")
6501 (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "")
6502 (unspec:SI [(match_operand:SI 2 "" "")]
6505 [(set (match_dup 3) (unspec:SI [(match_dup 2)] UNSPEC_PIC_SYM))
6506 (set (match_dup 0) (mem:SI (plus:SI (match_dup 1) (match_dup 3))))]
6507 "operands[3] = can_create_pseudo_p () ? gen_reg_rtx (SImode) : operands[0];"
6510 ;; operand1 is the memory address to go into
6511 ;; pic_load_addr_32bit.
6512 ;; operand2 is the PIC label to be emitted
6513 ;; from pic_add_dot_plus_eight.
6514 ;; We do this to allow hoisting of the entire insn.
6515 (define_insn_and_split "pic_load_addr_unified"
6516 [(set (match_operand:SI 0 "s_register_operand" "=r,r,l")
6517 (unspec:SI [(match_operand:SI 1 "" "mX,mX,mX")
6518 (match_operand:SI 2 "" "")]
6519 UNSPEC_PIC_UNIFIED))]
6522 "&& reload_completed"
6523 [(set (match_dup 0) (unspec:SI [(match_dup 1)] UNSPEC_PIC_SYM))
6524 (set (match_dup 0) (unspec:SI [(match_dup 0) (match_dup 3)
6525 (match_dup 2)] UNSPEC_PIC_BASE))]
6526 "operands[3] = TARGET_THUMB ? GEN_INT (4) : GEN_INT (8);"
6527 [(set_attr "type" "load1,load1,load1")
6528 (set_attr "pool_range" "4096,4094,1022")
6529 (set_attr "neg_pool_range" "4084,0,0")
6530 (set_attr "arch" "a,t2,t1")
6531 (set_attr "length" "8,6,4")]
6534 ;; The rather odd constraints on the following are to force reload to leave
6535 ;; the insn alone, and to force the minipool generation pass to then move
6536 ;; the GOT symbol to memory.
6538 (define_insn "pic_load_addr_32bit"
6539 [(set (match_operand:SI 0 "s_register_operand" "=r")
6540 (unspec:SI [(match_operand:SI 1 "" "mX")] UNSPEC_PIC_SYM))]
6541 "TARGET_32BIT && flag_pic"
6543 [(set_attr "type" "load1")
6544 (set (attr "pool_range")
6545 (if_then_else (eq_attr "is_thumb" "no")
6548 (set (attr "neg_pool_range")
6549 (if_then_else (eq_attr "is_thumb" "no")
6554 (define_insn "pic_load_addr_thumb1"
6555 [(set (match_operand:SI 0 "s_register_operand" "=l")
6556 (unspec:SI [(match_operand:SI 1 "" "mX")] UNSPEC_PIC_SYM))]
6557 "TARGET_THUMB1 && flag_pic"
6559 [(set_attr "type" "load1")
6560 (set (attr "pool_range") (const_int 1018))]
6563 (define_insn "pic_add_dot_plus_four"
6564 [(set (match_operand:SI 0 "register_operand" "=r")
6565 (unspec:SI [(match_operand:SI 1 "register_operand" "0")
6567 (match_operand 2 "" "")]
6571 (*targetm.asm_out.internal_label) (asm_out_file, \"LPIC\",
6572 INTVAL (operands[2]));
6573 return \"add\\t%0, %|pc\";
6575 [(set_attr "length" "2")
6576 (set_attr "type" "alu_reg")]
6579 (define_insn "pic_add_dot_plus_eight"
6580 [(set (match_operand:SI 0 "register_operand" "=r")
6581 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
6583 (match_operand 2 "" "")]
6587 (*targetm.asm_out.internal_label) (asm_out_file, \"LPIC\",
6588 INTVAL (operands[2]));
6589 return \"add%?\\t%0, %|pc, %1\";
6591 [(set_attr "predicable" "yes")
6592 (set_attr "type" "alu_reg")]
6595 (define_insn "tls_load_dot_plus_eight"
6596 [(set (match_operand:SI 0 "register_operand" "=r")
6597 (mem:SI (unspec:SI [(match_operand:SI 1 "register_operand" "r")
6599 (match_operand 2 "" "")]
6603 (*targetm.asm_out.internal_label) (asm_out_file, \"LPIC\",
6604 INTVAL (operands[2]));
6605 return \"ldr%?\\t%0, [%|pc, %1]\t\t@ tls_load_dot_plus_eight\";
6607 [(set_attr "predicable" "yes")
6608 (set_attr "type" "load1")]
6611 ;; PIC references to local variables can generate pic_add_dot_plus_eight
6612 ;; followed by a load. These sequences can be crunched down to
6613 ;; tls_load_dot_plus_eight by a peephole.
6616 [(set (match_operand:SI 0 "register_operand" "")
6617 (unspec:SI [(match_operand:SI 3 "register_operand" "")
6619 (match_operand 1 "" "")]
6621 (set (match_operand:SI 2 "arm_general_register_operand" "")
6622 (mem:SI (match_dup 0)))]
6623 "TARGET_ARM && peep2_reg_dead_p (2, operands[0])"
6625 (mem:SI (unspec:SI [(match_dup 3)
6632 (define_insn "pic_offset_arm"
6633 [(set (match_operand:SI 0 "register_operand" "=r")
6634 (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
6635 (unspec:SI [(match_operand:SI 2 "" "X")]
6636 UNSPEC_PIC_OFFSET))))]
6637 "TARGET_VXWORKS_RTP && TARGET_ARM && flag_pic"
6638 "ldr%?\\t%0, [%1,%2]"
6639 [(set_attr "type" "load1")]
6642 (define_expand "builtin_setjmp_receiver"
6643 [(label_ref (match_operand 0 "" ""))]
6647 /* r3 is clobbered by set/longjmp, so we can use it as a scratch
6649 if (arm_pic_register != INVALID_REGNUM)
6650 arm_load_pic_register (1UL << 3);
6654 ;; If copying one reg to another we can set the condition codes according to
6655 ;; its value. Such a move is common after a return from subroutine and the
6656 ;; result is being tested against zero.
6658 (define_insn "*movsi_compare0"
6659 [(set (reg:CC CC_REGNUM)
6660 (compare:CC (match_operand:SI 1 "s_register_operand" "0,r")
6662 (set (match_operand:SI 0 "s_register_operand" "=r,r")
6668 [(set_attr "conds" "set")
6669 (set_attr "type" "alus_imm,alus_imm")]
6672 ;; Subroutine to store a half word from a register into memory.
6673 ;; Operand 0 is the source register (HImode)
6674 ;; Operand 1 is the destination address in a register (SImode)
6676 ;; In both this routine and the next, we must be careful not to spill
6677 ;; a memory address of reg+large_const into a separate PLUS insn, since this
6678 ;; can generate unrecognizable rtl.
6680 (define_expand "storehi"
6681 [;; store the low byte
6682 (set (match_operand 1 "" "") (match_dup 3))
6683 ;; extract the high byte
6685 (ashiftrt:SI (match_operand 0 "" "") (const_int 8)))
6686 ;; store the high byte
6687 (set (match_dup 4) (match_dup 5))]
6691 rtx op1 = operands[1];
6692 rtx addr = XEXP (op1, 0);
6693 enum rtx_code code = GET_CODE (addr);
6695 if ((code == PLUS && !CONST_INT_P (XEXP (addr, 1)))
6697 op1 = replace_equiv_address (operands[1], force_reg (SImode, addr));
6699 operands[4] = adjust_address (op1, QImode, 1);
6700 operands[1] = adjust_address (operands[1], QImode, 0);
6701 operands[3] = gen_lowpart (QImode, operands[0]);
6702 operands[0] = gen_lowpart (SImode, operands[0]);
6703 operands[2] = gen_reg_rtx (SImode);
6704 operands[5] = gen_lowpart (QImode, operands[2]);
6708 (define_expand "storehi_bigend"
6709 [(set (match_dup 4) (match_dup 3))
6711 (ashiftrt:SI (match_operand 0 "" "") (const_int 8)))
6712 (set (match_operand 1 "" "") (match_dup 5))]
6716 rtx op1 = operands[1];
6717 rtx addr = XEXP (op1, 0);
6718 enum rtx_code code = GET_CODE (addr);
6720 if ((code == PLUS && !CONST_INT_P (XEXP (addr, 1)))
6722 op1 = replace_equiv_address (op1, force_reg (SImode, addr));
6724 operands[4] = adjust_address (op1, QImode, 1);
6725 operands[1] = adjust_address (operands[1], QImode, 0);
6726 operands[3] = gen_lowpart (QImode, operands[0]);
6727 operands[0] = gen_lowpart (SImode, operands[0]);
6728 operands[2] = gen_reg_rtx (SImode);
6729 operands[5] = gen_lowpart (QImode, operands[2]);
6733 ;; Subroutine to store a half word integer constant into memory.
6734 (define_expand "storeinthi"
6735 [(set (match_operand 0 "" "")
6736 (match_operand 1 "" ""))
6737 (set (match_dup 3) (match_dup 2))]
6741 HOST_WIDE_INT value = INTVAL (operands[1]);
6742 rtx addr = XEXP (operands[0], 0);
6743 rtx op0 = operands[0];
6744 enum rtx_code code = GET_CODE (addr);
6746 if ((code == PLUS && !CONST_INT_P (XEXP (addr, 1)))
6748 op0 = replace_equiv_address (op0, force_reg (SImode, addr));
6750 operands[1] = gen_reg_rtx (SImode);
6751 if (BYTES_BIG_ENDIAN)
6753 emit_insn (gen_movsi (operands[1], GEN_INT ((value >> 8) & 255)));
6754 if ((value & 255) == ((value >> 8) & 255))
6755 operands[2] = operands[1];
6758 operands[2] = gen_reg_rtx (SImode);
6759 emit_insn (gen_movsi (operands[2], GEN_INT (value & 255)));
6764 emit_insn (gen_movsi (operands[1], GEN_INT (value & 255)));
6765 if ((value & 255) == ((value >> 8) & 255))
6766 operands[2] = operands[1];
6769 operands[2] = gen_reg_rtx (SImode);
6770 emit_insn (gen_movsi (operands[2], GEN_INT ((value >> 8) & 255)));
6774 operands[3] = adjust_address (op0, QImode, 1);
6775 operands[0] = adjust_address (operands[0], QImode, 0);
6776 operands[2] = gen_lowpart (QImode, operands[2]);
6777 operands[1] = gen_lowpart (QImode, operands[1]);
6781 (define_expand "storehi_single_op"
6782 [(set (match_operand:HI 0 "memory_operand" "")
6783 (match_operand:HI 1 "general_operand" ""))]
6784 "TARGET_32BIT && arm_arch4"
6786 if (!s_register_operand (operands[1], HImode))
6787 operands[1] = copy_to_mode_reg (HImode, operands[1]);
6791 (define_expand "movhi"
6792 [(set (match_operand:HI 0 "general_operand" "")
6793 (match_operand:HI 1 "general_operand" ""))]
6798 if (can_create_pseudo_p ())
6800 if (MEM_P (operands[0]))
6804 emit_insn (gen_storehi_single_op (operands[0], operands[1]));
6807 if (CONST_INT_P (operands[1]))
6808 emit_insn (gen_storeinthi (operands[0], operands[1]));
6811 if (MEM_P (operands[1]))
6812 operands[1] = force_reg (HImode, operands[1]);
6813 if (BYTES_BIG_ENDIAN)
6814 emit_insn (gen_storehi_bigend (operands[1], operands[0]));
6816 emit_insn (gen_storehi (operands[1], operands[0]));
6820 /* Sign extend a constant, and keep it in an SImode reg. */
6821 else if (CONST_INT_P (operands[1]))
6823 rtx reg = gen_reg_rtx (SImode);
6824 HOST_WIDE_INT val = INTVAL (operands[1]) & 0xffff;
6826 /* If the constant is already valid, leave it alone. */
6827 if (!const_ok_for_arm (val))
6829 /* If setting all the top bits will make the constant
6830 loadable in a single instruction, then set them.
6831 Otherwise, sign extend the number. */
6833 if (const_ok_for_arm (~(val | ~0xffff)))
6835 else if (val & 0x8000)
6839 emit_insn (gen_movsi (reg, GEN_INT (val)));
6840 operands[1] = gen_lowpart (HImode, reg);
6842 else if (arm_arch4 && optimize && can_create_pseudo_p ()
6843 && MEM_P (operands[1]))
6845 rtx reg = gen_reg_rtx (SImode);
6847 emit_insn (gen_zero_extendhisi2 (reg, operands[1]));
6848 operands[1] = gen_lowpart (HImode, reg);
6850 else if (!arm_arch4)
6852 if (MEM_P (operands[1]))
6855 rtx offset = const0_rtx;
6856 rtx reg = gen_reg_rtx (SImode);
6858 if ((REG_P (base = XEXP (operands[1], 0))
6859 || (GET_CODE (base) == PLUS
6860 && (CONST_INT_P (offset = XEXP (base, 1)))
6861 && ((INTVAL(offset) & 1) != 1)
6862 && REG_P (base = XEXP (base, 0))))
6863 && REGNO_POINTER_ALIGN (REGNO (base)) >= 32)
6867 new_rtx = widen_memory_access (operands[1], SImode,
6868 ((INTVAL (offset) & ~3)
6869 - INTVAL (offset)));
6870 emit_insn (gen_movsi (reg, new_rtx));
6871 if (((INTVAL (offset) & 2) != 0)
6872 ^ (BYTES_BIG_ENDIAN ? 1 : 0))
6874 rtx reg2 = gen_reg_rtx (SImode);
6876 emit_insn (gen_lshrsi3 (reg2, reg, GEN_INT (16)));
6881 emit_insn (gen_movhi_bytes (reg, operands[1]));
6883 operands[1] = gen_lowpart (HImode, reg);
6887 /* Handle loading a large integer during reload. */
6888 else if (CONST_INT_P (operands[1])
6889 && !const_ok_for_arm (INTVAL (operands[1]))
6890 && !const_ok_for_arm (~INTVAL (operands[1])))
6892 /* Writing a constant to memory needs a scratch, which should
6893 be handled with SECONDARY_RELOADs. */
6894 gcc_assert (REG_P (operands[0]));
6896 operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
6897 emit_insn (gen_movsi (operands[0], operands[1]));
6901 else if (TARGET_THUMB2)
6903 /* Thumb-2 can do everything except mem=mem and mem=const easily. */
6904 if (can_create_pseudo_p ())
6906 if (!REG_P (operands[0]))
6907 operands[1] = force_reg (HImode, operands[1]);
6908 /* Zero extend a constant, and keep it in an SImode reg. */
6909 else if (CONST_INT_P (operands[1]))
6911 rtx reg = gen_reg_rtx (SImode);
6912 HOST_WIDE_INT val = INTVAL (operands[1]) & 0xffff;
6914 emit_insn (gen_movsi (reg, GEN_INT (val)));
6915 operands[1] = gen_lowpart (HImode, reg);
6919 else /* TARGET_THUMB1 */
6921 if (can_create_pseudo_p ())
6923 if (CONST_INT_P (operands[1]))
6925 rtx reg = gen_reg_rtx (SImode);
6927 emit_insn (gen_movsi (reg, operands[1]));
6928 operands[1] = gen_lowpart (HImode, reg);
6931 /* ??? We shouldn't really get invalid addresses here, but this can
6932 happen if we are passed a SP (never OK for HImode/QImode) or
6933 virtual register (also rejected as illegitimate for HImode/QImode)
6934 relative address. */
6935 /* ??? This should perhaps be fixed elsewhere, for instance, in
6936 fixup_stack_1, by checking for other kinds of invalid addresses,
6937 e.g. a bare reference to a virtual register. This may confuse the
6938 alpha though, which must handle this case differently. */
6939 if (MEM_P (operands[0])
6940 && !memory_address_p (GET_MODE (operands[0]),
6941 XEXP (operands[0], 0)))
6943 = replace_equiv_address (operands[0],
6944 copy_to_reg (XEXP (operands[0], 0)));
6946 if (MEM_P (operands[1])
6947 && !memory_address_p (GET_MODE (operands[1]),
6948 XEXP (operands[1], 0)))
6950 = replace_equiv_address (operands[1],
6951 copy_to_reg (XEXP (operands[1], 0)));
6953 if (MEM_P (operands[1]) && optimize > 0)
6955 rtx reg = gen_reg_rtx (SImode);
6957 emit_insn (gen_zero_extendhisi2 (reg, operands[1]));
6958 operands[1] = gen_lowpart (HImode, reg);
6961 if (MEM_P (operands[0]))
6962 operands[1] = force_reg (HImode, operands[1]);
6964 else if (CONST_INT_P (operands[1])
6965 && !satisfies_constraint_I (operands[1]))
6967 /* Handle loading a large integer during reload. */
6969 /* Writing a constant to memory needs a scratch, which should
6970 be handled with SECONDARY_RELOADs. */
6971 gcc_assert (REG_P (operands[0]));
6973 operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
6974 emit_insn (gen_movsi (operands[0], operands[1]));
6981 (define_insn "*thumb1_movhi_insn"
6982 [(set (match_operand:HI 0 "nonimmediate_operand" "=l,l,m,*r,*h,l")
6983 (match_operand:HI 1 "general_operand" "l,m,l,*h,*r,I"))]
6985 && ( register_operand (operands[0], HImode)
6986 || register_operand (operands[1], HImode))"
6988 switch (which_alternative)
6990 case 0: return \"add %0, %1, #0\";
6991 case 2: return \"strh %1, %0\";
6992 case 3: return \"mov %0, %1\";
6993 case 4: return \"mov %0, %1\";
6994 case 5: return \"mov %0, %1\";
6995 default: gcc_unreachable ();
6997 /* The stack pointer can end up being taken as an index register.
6998 Catch this case here and deal with it. */
6999 if (GET_CODE (XEXP (operands[1], 0)) == PLUS
7000 && REG_P (XEXP (XEXP (operands[1], 0), 0))
7001 && REGNO (XEXP (XEXP (operands[1], 0), 0)) == SP_REGNUM)
7004 ops[0] = operands[0];
7005 ops[1] = XEXP (XEXP (operands[1], 0), 0);
7007 output_asm_insn (\"mov %0, %1\", ops);
7009 XEXP (XEXP (operands[1], 0), 0) = operands[0];
7012 return \"ldrh %0, %1\";
7014 [(set_attr "length" "2,4,2,2,2,2")
7015 (set_attr "type" "alus_imm,load1,store1,mov_reg,mov_reg,mov_imm")
7016 (set_attr "conds" "clob,nocond,nocond,nocond,nocond,clob")])
7019 (define_expand "movhi_bytes"
7020 [(set (match_dup 2) (zero_extend:SI (match_operand:HI 1 "" "")))
7022 (zero_extend:SI (match_dup 6)))
7023 (set (match_operand:SI 0 "" "")
7024 (ior:SI (ashift:SI (match_dup 4) (const_int 8)) (match_dup 5)))]
7029 rtx addr = copy_to_mode_reg (SImode, XEXP (operands[1], 0));
7031 mem1 = change_address (operands[1], QImode, addr);
7032 mem2 = change_address (operands[1], QImode,
7033 plus_constant (Pmode, addr, 1));
7034 operands[0] = gen_lowpart (SImode, operands[0]);
7036 operands[2] = gen_reg_rtx (SImode);
7037 operands[3] = gen_reg_rtx (SImode);
7040 if (BYTES_BIG_ENDIAN)
7042 operands[4] = operands[2];
7043 operands[5] = operands[3];
7047 operands[4] = operands[3];
7048 operands[5] = operands[2];
7053 (define_expand "movhi_bigend"
7055 (rotate:SI (subreg:SI (match_operand:HI 1 "memory_operand" "") 0)
7058 (ashiftrt:SI (match_dup 2) (const_int 16)))
7059 (set (match_operand:HI 0 "s_register_operand" "")
7063 operands[2] = gen_reg_rtx (SImode);
7064 operands[3] = gen_reg_rtx (SImode);
7065 operands[4] = gen_lowpart (HImode, operands[3]);
7069 ;; Pattern to recognize insn generated default case above
7070 (define_insn "*movhi_insn_arch4"
7071 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,m,r")
7072 (match_operand:HI 1 "general_operand" "rI,K,r,mi"))]
7075 && (register_operand (operands[0], HImode)
7076 || register_operand (operands[1], HImode))"
7078 mov%?\\t%0, %1\\t%@ movhi
7079 mvn%?\\t%0, #%B1\\t%@ movhi
7080 str%(h%)\\t%1, %0\\t%@ movhi
7081 ldr%(h%)\\t%0, %1\\t%@ movhi"
7082 [(set_attr "predicable" "yes")
7083 (set_attr "pool_range" "*,*,*,256")
7084 (set_attr "neg_pool_range" "*,*,*,244")
7085 (set_attr_alternative "type"
7086 [(if_then_else (match_operand 1 "const_int_operand" "")
7087 (const_string "mov_imm" )
7088 (const_string "mov_reg"))
7089 (const_string "mvn_imm")
7090 (const_string "store1")
7091 (const_string "load1")])]
7094 (define_insn "*movhi_bytes"
7095 [(set (match_operand:HI 0 "s_register_operand" "=r,r,r")
7096 (match_operand:HI 1 "arm_rhs_operand" "I,r,K"))]
7099 mov%?\\t%0, %1\\t%@ movhi
7100 mov%?\\t%0, %1\\t%@ movhi
7101 mvn%?\\t%0, #%B1\\t%@ movhi"
7102 [(set_attr "predicable" "yes")
7103 (set_attr "type" "mov_imm,mov_reg,mvn_imm")]
7106 (define_expand "thumb_movhi_clobber"
7107 [(set (match_operand:HI 0 "memory_operand" "")
7108 (match_operand:HI 1 "register_operand" ""))
7109 (clobber (match_operand:DI 2 "register_operand" ""))]
7112 if (strict_memory_address_p (HImode, XEXP (operands[0], 0))
7113 && REGNO (operands[1]) <= LAST_LO_REGNUM)
7115 emit_insn (gen_movhi (operands[0], operands[1]));
7118 /* XXX Fixme, need to handle other cases here as well. */
7123 ;; We use a DImode scratch because we may occasionally need an additional
7124 ;; temporary if the address isn't offsettable -- push_reload doesn't seem
7125 ;; to take any notice of the "o" constraints on reload_memory_operand operand.
7126 (define_expand "reload_outhi"
7127 [(parallel [(match_operand:HI 0 "arm_reload_memory_operand" "=o")
7128 (match_operand:HI 1 "s_register_operand" "r")
7129 (match_operand:DI 2 "s_register_operand" "=&l")])]
7132 arm_reload_out_hi (operands);
7134 thumb_reload_out_hi (operands);
7139 (define_expand "reload_inhi"
7140 [(parallel [(match_operand:HI 0 "s_register_operand" "=r")
7141 (match_operand:HI 1 "arm_reload_memory_operand" "o")
7142 (match_operand:DI 2 "s_register_operand" "=&r")])]
7146 arm_reload_in_hi (operands);
7148 thumb_reload_out_hi (operands);
7152 (define_expand "movqi"
7153 [(set (match_operand:QI 0 "general_operand" "")
7154 (match_operand:QI 1 "general_operand" ""))]
7157 /* Everything except mem = const or mem = mem can be done easily */
7159 if (can_create_pseudo_p ())
7161 if (CONST_INT_P (operands[1]))
7163 rtx reg = gen_reg_rtx (SImode);
7165 /* For thumb we want an unsigned immediate, then we are more likely
7166 to be able to use a movs insn. */
7168 operands[1] = GEN_INT (INTVAL (operands[1]) & 255);
7170 emit_insn (gen_movsi (reg, operands[1]));
7171 operands[1] = gen_lowpart (QImode, reg);
7176 /* ??? We shouldn't really get invalid addresses here, but this can
7177 happen if we are passed a SP (never OK for HImode/QImode) or
7178 virtual register (also rejected as illegitimate for HImode/QImode)
7179 relative address. */
7180 /* ??? This should perhaps be fixed elsewhere, for instance, in
7181 fixup_stack_1, by checking for other kinds of invalid addresses,
7182 e.g. a bare reference to a virtual register. This may confuse the
7183 alpha though, which must handle this case differently. */
7184 if (MEM_P (operands[0])
7185 && !memory_address_p (GET_MODE (operands[0]),
7186 XEXP (operands[0], 0)))
7188 = replace_equiv_address (operands[0],
7189 copy_to_reg (XEXP (operands[0], 0)));
7190 if (MEM_P (operands[1])
7191 && !memory_address_p (GET_MODE (operands[1]),
7192 XEXP (operands[1], 0)))
7194 = replace_equiv_address (operands[1],
7195 copy_to_reg (XEXP (operands[1], 0)));
7198 if (MEM_P (operands[1]) && optimize > 0)
7200 rtx reg = gen_reg_rtx (SImode);
7202 emit_insn (gen_zero_extendqisi2 (reg, operands[1]));
7203 operands[1] = gen_lowpart (QImode, reg);
7206 if (MEM_P (operands[0]))
7207 operands[1] = force_reg (QImode, operands[1]);
7209 else if (TARGET_THUMB
7210 && CONST_INT_P (operands[1])
7211 && !satisfies_constraint_I (operands[1]))
7213 /* Handle loading a large integer during reload. */
7215 /* Writing a constant to memory needs a scratch, which should
7216 be handled with SECONDARY_RELOADs. */
7217 gcc_assert (REG_P (operands[0]));
7219 operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
7220 emit_insn (gen_movsi (operands[0], operands[1]));
7226 (define_insn "*arm_movqi_insn"
7227 [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,r,l,r,l,Uu,r,m")
7228 (match_operand:QI 1 "general_operand" "r,r,I,Py,K,Uu,l,m,r"))]
7230 && ( register_operand (operands[0], QImode)
7231 || register_operand (operands[1], QImode))"
7242 [(set_attr "type" "mov_reg,mov_reg,mov_imm,mov_imm,mvn_imm,load1,store1,load1,store1")
7243 (set_attr "predicable" "yes")
7244 (set_attr "predicable_short_it" "yes,yes,yes,no,no,no,no,no,no")
7245 (set_attr "arch" "t2,any,any,t2,any,t2,t2,any,any")
7246 (set_attr "length" "2,4,4,2,4,2,2,4,4")]
7249 (define_insn "*thumb1_movqi_insn"
7250 [(set (match_operand:QI 0 "nonimmediate_operand" "=l,l,m,*r,*h,l")
7251 (match_operand:QI 1 "general_operand" "l, m,l,*h,*r,I"))]
7253 && ( register_operand (operands[0], QImode)
7254 || register_operand (operands[1], QImode))"
7262 [(set_attr "length" "2")
7263 (set_attr "type" "alu_imm,load1,store1,mov_reg,mov_imm,mov_imm")
7264 (set_attr "pool_range" "*,32,*,*,*,*")
7265 (set_attr "conds" "clob,nocond,nocond,nocond,nocond,clob")])
7268 (define_expand "movhf"
7269 [(set (match_operand:HF 0 "general_operand" "")
7270 (match_operand:HF 1 "general_operand" ""))]
7275 if (MEM_P (operands[0]))
7276 operands[1] = force_reg (HFmode, operands[1]);
7278 else /* TARGET_THUMB1 */
7280 if (can_create_pseudo_p ())
7282 if (!REG_P (operands[0]))
7283 operands[1] = force_reg (HFmode, operands[1]);
7289 (define_insn "*arm32_movhf"
7290 [(set (match_operand:HF 0 "nonimmediate_operand" "=r,m,r,r")
7291 (match_operand:HF 1 "general_operand" " m,r,r,F"))]
7292 "TARGET_32BIT && !(TARGET_HARD_FLOAT && TARGET_FP16) && !arm_restrict_it
7293 && ( s_register_operand (operands[0], HFmode)
7294 || s_register_operand (operands[1], HFmode))"
7296 switch (which_alternative)
7298 case 0: /* ARM register from memory */
7299 return \"ldr%(h%)\\t%0, %1\\t%@ __fp16\";
7300 case 1: /* memory from ARM register */
7301 return \"str%(h%)\\t%1, %0\\t%@ __fp16\";
7302 case 2: /* ARM register from ARM register */
7303 return \"mov%?\\t%0, %1\\t%@ __fp16\";
7304 case 3: /* ARM register from constant */
7310 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
7311 bits = real_to_target (NULL, &r, HFmode);
7312 ops[0] = operands[0];
7313 ops[1] = GEN_INT (bits);
7314 ops[2] = GEN_INT (bits & 0xff00);
7315 ops[3] = GEN_INT (bits & 0x00ff);
7317 if (arm_arch_thumb2)
7318 output_asm_insn (\"movw%?\\t%0, %1\", ops);
7320 output_asm_insn (\"mov%?\\t%0, %2\;orr%?\\t%0, %0, %3\", ops);
7327 [(set_attr "conds" "unconditional")
7328 (set_attr "type" "load1,store1,mov_reg,multiple")
7329 (set_attr "length" "4,4,4,8")
7330 (set_attr "predicable" "yes")]
7333 (define_insn "*thumb1_movhf"
7334 [(set (match_operand:HF 0 "nonimmediate_operand" "=l,l,m,*r,*h")
7335 (match_operand:HF 1 "general_operand" "l,mF,l,*h,*r"))]
7337 && ( s_register_operand (operands[0], HFmode)
7338 || s_register_operand (operands[1], HFmode))"
7340 switch (which_alternative)
7345 gcc_assert (MEM_P (operands[1]));
7346 addr = XEXP (operands[1], 0);
7347 if (GET_CODE (addr) == LABEL_REF
7348 || (GET_CODE (addr) == CONST
7349 && GET_CODE (XEXP (addr, 0)) == PLUS
7350 && GET_CODE (XEXP (XEXP (addr, 0), 0)) == LABEL_REF
7351 && CONST_INT_P (XEXP (XEXP (addr, 0), 1))))
7353 /* Constant pool entry. */
7354 return \"ldr\\t%0, %1\";
7356 return \"ldrh\\t%0, %1\";
7358 case 2: return \"strh\\t%1, %0\";
7359 default: return \"mov\\t%0, %1\";
7362 [(set_attr "length" "2")
7363 (set_attr "type" "mov_reg,load1,store1,mov_reg,mov_reg")
7364 (set_attr "pool_range" "*,1018,*,*,*")
7365 (set_attr "conds" "clob,nocond,nocond,nocond,nocond")])
7367 (define_expand "movsf"
7368 [(set (match_operand:SF 0 "general_operand" "")
7369 (match_operand:SF 1 "general_operand" ""))]
7374 if (MEM_P (operands[0]))
7375 operands[1] = force_reg (SFmode, operands[1]);
7377 else /* TARGET_THUMB1 */
7379 if (can_create_pseudo_p ())
7381 if (!REG_P (operands[0]))
7382 operands[1] = force_reg (SFmode, operands[1]);
7388 ;; Transform a floating-point move of a constant into a core register into
7389 ;; an SImode operation.
7391 [(set (match_operand:SF 0 "arm_general_register_operand" "")
7392 (match_operand:SF 1 "immediate_operand" ""))]
7395 && CONST_DOUBLE_P (operands[1])"
7396 [(set (match_dup 2) (match_dup 3))]
7398 operands[2] = gen_lowpart (SImode, operands[0]);
7399 operands[3] = gen_lowpart (SImode, operands[1]);
7400 if (operands[2] == 0 || operands[3] == 0)
7405 (define_insn "*arm_movsf_soft_insn"
7406 [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,m")
7407 (match_operand:SF 1 "general_operand" "r,mE,r"))]
7409 && TARGET_SOFT_FLOAT
7410 && (!MEM_P (operands[0])
7411 || register_operand (operands[1], SFmode))"
7414 ldr%?\\t%0, %1\\t%@ float
7415 str%?\\t%1, %0\\t%@ float"
7416 [(set_attr "predicable" "yes")
7417 (set_attr "predicable_short_it" "no")
7418 (set_attr "type" "mov_reg,load1,store1")
7419 (set_attr "arm_pool_range" "*,4096,*")
7420 (set_attr "thumb2_pool_range" "*,4094,*")
7421 (set_attr "arm_neg_pool_range" "*,4084,*")
7422 (set_attr "thumb2_neg_pool_range" "*,0,*")]
7425 ;;; ??? This should have alternatives for constants.
7426 (define_insn "*thumb1_movsf_insn"
7427 [(set (match_operand:SF 0 "nonimmediate_operand" "=l,l,>,l, m,*r,*h")
7428 (match_operand:SF 1 "general_operand" "l, >,l,mF,l,*h,*r"))]
7430 && ( register_operand (operands[0], SFmode)
7431 || register_operand (operands[1], SFmode))"
7440 [(set_attr "length" "2")
7441 (set_attr "type" "alus_imm,load1,store1,load1,store1,mov_reg,mov_reg")
7442 (set_attr "pool_range" "*,*,*,1018,*,*,*")
7443 (set_attr "conds" "clob,nocond,nocond,nocond,nocond,nocond,nocond")]
7446 (define_expand "movdf"
7447 [(set (match_operand:DF 0 "general_operand" "")
7448 (match_operand:DF 1 "general_operand" ""))]
7453 if (MEM_P (operands[0]))
7454 operands[1] = force_reg (DFmode, operands[1]);
7456 else /* TARGET_THUMB */
7458 if (can_create_pseudo_p ())
7460 if (!REG_P (operands[0]))
7461 operands[1] = force_reg (DFmode, operands[1]);
7467 ;; Reloading a df mode value stored in integer regs to memory can require a
7469 (define_expand "reload_outdf"
7470 [(match_operand:DF 0 "arm_reload_memory_operand" "=o")
7471 (match_operand:DF 1 "s_register_operand" "r")
7472 (match_operand:SI 2 "s_register_operand" "=&r")]
7476 enum rtx_code code = GET_CODE (XEXP (operands[0], 0));
7479 operands[2] = XEXP (operands[0], 0);
7480 else if (code == POST_INC || code == PRE_DEC)
7482 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7483 operands[1] = gen_rtx_SUBREG (DImode, operands[1], 0);
7484 emit_insn (gen_movdi (operands[0], operands[1]));
7487 else if (code == PRE_INC)
7489 rtx reg = XEXP (XEXP (operands[0], 0), 0);
7491 emit_insn (gen_addsi3 (reg, reg, GEN_INT (8)));
7494 else if (code == POST_DEC)
7495 operands[2] = XEXP (XEXP (operands[0], 0), 0);
7497 emit_insn (gen_addsi3 (operands[2], XEXP (XEXP (operands[0], 0), 0),
7498 XEXP (XEXP (operands[0], 0), 1)));
7500 emit_insn (gen_rtx_SET (VOIDmode,
7501 replace_equiv_address (operands[0], operands[2]),
7504 if (code == POST_DEC)
7505 emit_insn (gen_addsi3 (operands[2], operands[2], GEN_INT (-8)));
7511 (define_insn "*movdf_soft_insn"
7512 [(set (match_operand:DF 0 "nonimmediate_soft_df_operand" "=r,r,r,q,m")
7513 (match_operand:DF 1 "soft_df_operand" "rDa,Db,Dc,mF,q"))]
7514 "TARGET_32BIT && TARGET_SOFT_FLOAT
7515 && ( register_operand (operands[0], DFmode)
7516 || register_operand (operands[1], DFmode))"
7518 switch (which_alternative)
7525 return output_move_double (operands, true, NULL);
7528 [(set_attr "length" "8,12,16,8,8")
7529 (set_attr "type" "multiple,multiple,multiple,load2,store2")
7530 (set_attr "arm_pool_range" "*,*,*,1020,*")
7531 (set_attr "thumb2_pool_range" "*,*,*,1018,*")
7532 (set_attr "arm_neg_pool_range" "*,*,*,1004,*")
7533 (set_attr "thumb2_neg_pool_range" "*,*,*,0,*")]
7536 ;;; ??? This should have alternatives for constants.
7537 ;;; ??? This was originally identical to the movdi_insn pattern.
7538 ;;; ??? The 'F' constraint looks funny, but it should always be replaced by
7539 ;;; thumb_reorg with a memory reference.
7540 (define_insn "*thumb_movdf_insn"
7541 [(set (match_operand:DF 0 "nonimmediate_operand" "=l,l,>,l, m,*r")
7542 (match_operand:DF 1 "general_operand" "l, >,l,mF,l,*r"))]
7544 && ( register_operand (operands[0], DFmode)
7545 || register_operand (operands[1], DFmode))"
7547 switch (which_alternative)
7551 if (REGNO (operands[1]) == REGNO (operands[0]) + 1)
7552 return \"add\\t%0, %1, #0\;add\\t%H0, %H1, #0\";
7553 return \"add\\t%H0, %H1, #0\;add\\t%0, %1, #0\";
7555 return \"ldmia\\t%1, {%0, %H0}\";
7557 return \"stmia\\t%0, {%1, %H1}\";
7559 return thumb_load_double_from_address (operands);
7561 operands[2] = gen_rtx_MEM (SImode,
7562 plus_constant (Pmode,
7563 XEXP (operands[0], 0), 4));
7564 output_asm_insn (\"str\\t%1, %0\;str\\t%H1, %2\", operands);
7567 if (REGNO (operands[1]) == REGNO (operands[0]) + 1)
7568 return \"mov\\t%0, %1\;mov\\t%H0, %H1\";
7569 return \"mov\\t%H0, %H1\;mov\\t%0, %1\";
7572 [(set_attr "length" "4,2,2,6,4,4")
7573 (set_attr "type" "multiple,load2,store2,load2,store2,multiple")
7574 (set_attr "pool_range" "*,*,*,1018,*,*")]
7578 ;; load- and store-multiple insns
7579 ;; The arm can load/store any set of registers, provided that they are in
7580 ;; ascending order, but these expanders assume a contiguous set.
7582 (define_expand "load_multiple"
7583 [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
7584 (match_operand:SI 1 "" ""))
7585 (use (match_operand:SI 2 "" ""))])]
7588 HOST_WIDE_INT offset = 0;
7590 /* Support only fixed point registers. */
7591 if (!CONST_INT_P (operands[2])
7592 || INTVAL (operands[2]) > 14
7593 || INTVAL (operands[2]) < 2
7594 || !MEM_P (operands[1])
7595 || !REG_P (operands[0])
7596 || REGNO (operands[0]) > (LAST_ARM_REGNUM - 1)
7597 || REGNO (operands[0]) + INTVAL (operands[2]) > LAST_ARM_REGNUM)
7601 = arm_gen_load_multiple (arm_regs_in_sequence + REGNO (operands[0]),
7602 INTVAL (operands[2]),
7603 force_reg (SImode, XEXP (operands[1], 0)),
7604 FALSE, operands[1], &offset);
7607 (define_expand "store_multiple"
7608 [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
7609 (match_operand:SI 1 "" ""))
7610 (use (match_operand:SI 2 "" ""))])]
7613 HOST_WIDE_INT offset = 0;
7615 /* Support only fixed point registers. */
7616 if (!CONST_INT_P (operands[2])
7617 || INTVAL (operands[2]) > 14
7618 || INTVAL (operands[2]) < 2
7619 || !REG_P (operands[1])
7620 || !MEM_P (operands[0])
7621 || REGNO (operands[1]) > (LAST_ARM_REGNUM - 1)
7622 || REGNO (operands[1]) + INTVAL (operands[2]) > LAST_ARM_REGNUM)
7626 = arm_gen_store_multiple (arm_regs_in_sequence + REGNO (operands[1]),
7627 INTVAL (operands[2]),
7628 force_reg (SImode, XEXP (operands[0], 0)),
7629 FALSE, operands[0], &offset);
7633 ;; Move a block of memory if it is word aligned and MORE than 2 words long.
7634 ;; We could let this apply for blocks of less than this, but it clobbers so
7635 ;; many registers that there is then probably a better way.
7637 (define_expand "movmemqi"
7638 [(match_operand:BLK 0 "general_operand" "")
7639 (match_operand:BLK 1 "general_operand" "")
7640 (match_operand:SI 2 "const_int_operand" "")
7641 (match_operand:SI 3 "const_int_operand" "")]
7646 if (TARGET_LDRD && current_tune->prefer_ldrd_strd
7647 && !optimize_function_for_size_p (cfun))
7649 if (gen_movmem_ldrd_strd (operands))
7654 if (arm_gen_movmemqi (operands))
7658 else /* TARGET_THUMB1 */
7660 if ( INTVAL (operands[3]) != 4
7661 || INTVAL (operands[2]) > 48)
7664 thumb_expand_movmemqi (operands);
7670 ;; Thumb block-move insns
7672 (define_insn "movmem12b"
7673 [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
7674 (mem:SI (match_operand:SI 3 "register_operand" "1")))
7675 (set (mem:SI (plus:SI (match_dup 2) (const_int 4)))
7676 (mem:SI (plus:SI (match_dup 3) (const_int 4))))
7677 (set (mem:SI (plus:SI (match_dup 2) (const_int 8)))
7678 (mem:SI (plus:SI (match_dup 3) (const_int 8))))
7679 (set (match_operand:SI 0 "register_operand" "=l")
7680 (plus:SI (match_dup 2) (const_int 12)))
7681 (set (match_operand:SI 1 "register_operand" "=l")
7682 (plus:SI (match_dup 3) (const_int 12)))
7683 (clobber (match_scratch:SI 4 "=&l"))
7684 (clobber (match_scratch:SI 5 "=&l"))
7685 (clobber (match_scratch:SI 6 "=&l"))]
7687 "* return thumb_output_move_mem_multiple (3, operands);"
7688 [(set_attr "length" "4")
7689 ; This isn't entirely accurate... It loads as well, but in terms of
7690 ; scheduling the following insn it is better to consider it as a store
7691 (set_attr "type" "store3")]
7694 (define_insn "movmem8b"
7695 [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
7696 (mem:SI (match_operand:SI 3 "register_operand" "1")))
7697 (set (mem:SI (plus:SI (match_dup 2) (const_int 4)))
7698 (mem:SI (plus:SI (match_dup 3) (const_int 4))))
7699 (set (match_operand:SI 0 "register_operand" "=l")
7700 (plus:SI (match_dup 2) (const_int 8)))
7701 (set (match_operand:SI 1 "register_operand" "=l")
7702 (plus:SI (match_dup 3) (const_int 8)))
7703 (clobber (match_scratch:SI 4 "=&l"))
7704 (clobber (match_scratch:SI 5 "=&l"))]
7706 "* return thumb_output_move_mem_multiple (2, operands);"
7707 [(set_attr "length" "4")
7708 ; This isn't entirely accurate... It loads as well, but in terms of
7709 ; scheduling the following insn it is better to consider it as a store
7710 (set_attr "type" "store2")]
7715 ;; Compare & branch insns
7716 ;; The range calculations are based as follows:
7717 ;; For forward branches, the address calculation returns the address of
7718 ;; the next instruction. This is 2 beyond the branch instruction.
7719 ;; For backward branches, the address calculation returns the address of
7720 ;; the first instruction in this pattern (cmp). This is 2 before the branch
7721 ;; instruction for the shortest sequence, and 4 before the branch instruction
7722 ;; if we have to jump around an unconditional branch.
7723 ;; To the basic branch range the PC offset must be added (this is +4).
7724 ;; So for forward branches we have
7725 ;; (pos_range - pos_base_offs + pc_offs) = (pos_range - 2 + 4).
7726 ;; And for backward branches we have
7727 ;; (neg_range - neg_base_offs + pc_offs) = (neg_range - (-2 or -4) + 4).
7729 ;; For a 'b' pos_range = 2046, neg_range = -2048 giving (-2040->2048).
7730 ;; For a 'b<cond>' pos_range = 254, neg_range = -256 giving (-250 ->256).
7732 (define_expand "cbranchsi4"
7733 [(set (pc) (if_then_else
7734 (match_operator 0 "expandable_comparison_operator"
7735 [(match_operand:SI 1 "s_register_operand" "")
7736 (match_operand:SI 2 "nonmemory_operand" "")])
7737 (label_ref (match_operand 3 "" ""))
7743 if (!arm_validize_comparison (&operands[0], &operands[1], &operands[2]))
7745 emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
7749 if (thumb1_cmpneg_operand (operands[2], SImode))
7751 emit_jump_insn (gen_cbranchsi4_scratch (NULL, operands[1], operands[2],
7752 operands[3], operands[0]));
7755 if (!thumb1_cmp_operand (operands[2], SImode))
7756 operands[2] = force_reg (SImode, operands[2]);
7759 ;; A pattern to recognize a special situation and optimize for it.
7760 ;; On the thumb, zero-extension from memory is preferrable to sign-extension
7761 ;; due to the available addressing modes. Hence, convert a signed comparison
7762 ;; with zero into an unsigned comparison with 127 if possible.
7763 (define_expand "cbranchqi4"
7764 [(set (pc) (if_then_else
7765 (match_operator 0 "lt_ge_comparison_operator"
7766 [(match_operand:QI 1 "memory_operand" "")
7767 (match_operand:QI 2 "const0_operand" "")])
7768 (label_ref (match_operand 3 "" ""))
7773 xops[1] = gen_reg_rtx (SImode);
7774 emit_insn (gen_zero_extendqisi2 (xops[1], operands[1]));
7775 xops[2] = GEN_INT (127);
7776 xops[0] = gen_rtx_fmt_ee (GET_CODE (operands[0]) == GE ? LEU : GTU,
7777 VOIDmode, xops[1], xops[2]);
7778 xops[3] = operands[3];
7779 emit_insn (gen_cbranchsi4 (xops[0], xops[1], xops[2], xops[3]));
7783 (define_expand "cbranchsf4"
7784 [(set (pc) (if_then_else
7785 (match_operator 0 "expandable_comparison_operator"
7786 [(match_operand:SF 1 "s_register_operand" "")
7787 (match_operand:SF 2 "arm_float_compare_operand" "")])
7788 (label_ref (match_operand 3 "" ""))
7790 "TARGET_32BIT && TARGET_HARD_FLOAT"
7791 "emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
7792 operands[3])); DONE;"
7795 (define_expand "cbranchdf4"
7796 [(set (pc) (if_then_else
7797 (match_operator 0 "expandable_comparison_operator"
7798 [(match_operand:DF 1 "s_register_operand" "")
7799 (match_operand:DF 2 "arm_float_compare_operand" "")])
7800 (label_ref (match_operand 3 "" ""))
7802 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
7803 "emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
7804 operands[3])); DONE;"
7807 (define_expand "cbranchdi4"
7808 [(set (pc) (if_then_else
7809 (match_operator 0 "expandable_comparison_operator"
7810 [(match_operand:DI 1 "s_register_operand" "")
7811 (match_operand:DI 2 "cmpdi_operand" "")])
7812 (label_ref (match_operand 3 "" ""))
7816 if (!arm_validize_comparison (&operands[0], &operands[1], &operands[2]))
7818 emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
7824 (define_insn "cbranchsi4_insn"
7825 [(set (pc) (if_then_else
7826 (match_operator 0 "arm_comparison_operator"
7827 [(match_operand:SI 1 "s_register_operand" "l,l*h")
7828 (match_operand:SI 2 "thumb1_cmp_operand" "lI*h,*r")])
7829 (label_ref (match_operand 3 "" ""))
7833 rtx t = cfun->machine->thumb1_cc_insn;
7836 if (!rtx_equal_p (cfun->machine->thumb1_cc_op0, operands[1])
7837 || !rtx_equal_p (cfun->machine->thumb1_cc_op1, operands[2]))
7839 if (cfun->machine->thumb1_cc_mode == CC_NOOVmode)
7841 if (!noov_comparison_operator (operands[0], VOIDmode))
7844 else if (cfun->machine->thumb1_cc_mode != CCmode)
7849 output_asm_insn ("cmp\t%1, %2", operands);
7850 cfun->machine->thumb1_cc_insn = insn;
7851 cfun->machine->thumb1_cc_op0 = operands[1];
7852 cfun->machine->thumb1_cc_op1 = operands[2];
7853 cfun->machine->thumb1_cc_mode = CCmode;
7856 /* Ensure we emit the right type of condition code on the jump. */
7857 XEXP (operands[0], 0) = gen_rtx_REG (cfun->machine->thumb1_cc_mode,
7860 switch (get_attr_length (insn))
7862 case 4: return \"b%d0\\t%l3\";
7863 case 6: return \"b%D0\\t.LCB%=\;b\\t%l3\\t%@long jump\\n.LCB%=:\";
7864 default: return \"b%D0\\t.LCB%=\;bl\\t%l3\\t%@far jump\\n.LCB%=:\";
7867 [(set (attr "far_jump")
7869 (eq_attr "length" "8")
7870 (const_string "yes")
7871 (const_string "no")))
7872 (set (attr "length")
7874 (and (ge (minus (match_dup 3) (pc)) (const_int -250))
7875 (le (minus (match_dup 3) (pc)) (const_int 256)))
7878 (and (ge (minus (match_dup 3) (pc)) (const_int -2040))
7879 (le (minus (match_dup 3) (pc)) (const_int 2048)))
7882 (set_attr "type" "multiple")]
7885 (define_insn "cbranchsi4_scratch"
7886 [(set (pc) (if_then_else
7887 (match_operator 4 "arm_comparison_operator"
7888 [(match_operand:SI 1 "s_register_operand" "l,0")
7889 (match_operand:SI 2 "thumb1_cmpneg_operand" "L,J")])
7890 (label_ref (match_operand 3 "" ""))
7892 (clobber (match_scratch:SI 0 "=l,l"))]
7895 output_asm_insn (\"add\\t%0, %1, #%n2\", operands);
7897 switch (get_attr_length (insn))
7899 case 4: return \"b%d4\\t%l3\";
7900 case 6: return \"b%D4\\t.LCB%=\;b\\t%l3\\t%@long jump\\n.LCB%=:\";
7901 default: return \"b%D4\\t.LCB%=\;bl\\t%l3\\t%@far jump\\n.LCB%=:\";
7904 [(set (attr "far_jump")
7906 (eq_attr "length" "8")
7907 (const_string "yes")
7908 (const_string "no")))
7909 (set (attr "length")
7911 (and (ge (minus (match_dup 3) (pc)) (const_int -250))
7912 (le (minus (match_dup 3) (pc)) (const_int 256)))
7915 (and (ge (minus (match_dup 3) (pc)) (const_int -2040))
7916 (le (minus (match_dup 3) (pc)) (const_int 2048)))
7919 (set_attr "type" "multiple")]
7922 (define_insn "*negated_cbranchsi4"
7925 (match_operator 0 "equality_operator"
7926 [(match_operand:SI 1 "s_register_operand" "l")
7927 (neg:SI (match_operand:SI 2 "s_register_operand" "l"))])
7928 (label_ref (match_operand 3 "" ""))
7932 output_asm_insn (\"cmn\\t%1, %2\", operands);
7933 switch (get_attr_length (insn))
7935 case 4: return \"b%d0\\t%l3\";
7936 case 6: return \"b%D0\\t.LCB%=\;b\\t%l3\\t%@long jump\\n.LCB%=:\";
7937 default: return \"b%D0\\t.LCB%=\;bl\\t%l3\\t%@far jump\\n.LCB%=:\";
7940 [(set (attr "far_jump")
7942 (eq_attr "length" "8")
7943 (const_string "yes")
7944 (const_string "no")))
7945 (set (attr "length")
7947 (and (ge (minus (match_dup 3) (pc)) (const_int -250))
7948 (le (minus (match_dup 3) (pc)) (const_int 256)))
7951 (and (ge (minus (match_dup 3) (pc)) (const_int -2040))
7952 (le (minus (match_dup 3) (pc)) (const_int 2048)))
7955 (set_attr "type" "multiple")]
7958 (define_insn "*tbit_cbranch"
7961 (match_operator 0 "equality_operator"
7962 [(zero_extract:SI (match_operand:SI 1 "s_register_operand" "l")
7964 (match_operand:SI 2 "const_int_operand" "i"))
7966 (label_ref (match_operand 3 "" ""))
7968 (clobber (match_scratch:SI 4 "=l"))]
7973 op[0] = operands[4];
7974 op[1] = operands[1];
7975 op[2] = GEN_INT (32 - 1 - INTVAL (operands[2]));
7977 output_asm_insn (\"lsl\\t%0, %1, %2\", op);
7978 switch (get_attr_length (insn))
7980 case 4: return \"b%d0\\t%l3\";
7981 case 6: return \"b%D0\\t.LCB%=\;b\\t%l3\\t%@long jump\\n.LCB%=:\";
7982 default: return \"b%D0\\t.LCB%=\;bl\\t%l3\\t%@far jump\\n.LCB%=:\";
7985 [(set (attr "far_jump")
7987 (eq_attr "length" "8")
7988 (const_string "yes")
7989 (const_string "no")))
7990 (set (attr "length")
7992 (and (ge (minus (match_dup 3) (pc)) (const_int -250))
7993 (le (minus (match_dup 3) (pc)) (const_int 256)))
7996 (and (ge (minus (match_dup 3) (pc)) (const_int -2040))
7997 (le (minus (match_dup 3) (pc)) (const_int 2048)))
8000 (set_attr "type" "multiple")]
8003 (define_insn "*tlobits_cbranch"
8006 (match_operator 0 "equality_operator"
8007 [(zero_extract:SI (match_operand:SI 1 "s_register_operand" "l")
8008 (match_operand:SI 2 "const_int_operand" "i")
8011 (label_ref (match_operand 3 "" ""))
8013 (clobber (match_scratch:SI 4 "=l"))]
8018 op[0] = operands[4];
8019 op[1] = operands[1];
8020 op[2] = GEN_INT (32 - INTVAL (operands[2]));
8022 output_asm_insn (\"lsl\\t%0, %1, %2\", op);
8023 switch (get_attr_length (insn))
8025 case 4: return \"b%d0\\t%l3\";
8026 case 6: return \"b%D0\\t.LCB%=\;b\\t%l3\\t%@long jump\\n.LCB%=:\";
8027 default: return \"b%D0\\t.LCB%=\;bl\\t%l3\\t%@far jump\\n.LCB%=:\";
8030 [(set (attr "far_jump")
8032 (eq_attr "length" "8")
8033 (const_string "yes")
8034 (const_string "no")))
8035 (set (attr "length")
8037 (and (ge (minus (match_dup 3) (pc)) (const_int -250))
8038 (le (minus (match_dup 3) (pc)) (const_int 256)))
8041 (and (ge (minus (match_dup 3) (pc)) (const_int -2040))
8042 (le (minus (match_dup 3) (pc)) (const_int 2048)))
8045 (set_attr "type" "multiple")]
8048 (define_insn "*tstsi3_cbranch"
8051 (match_operator 3 "equality_operator"
8052 [(and:SI (match_operand:SI 0 "s_register_operand" "%l")
8053 (match_operand:SI 1 "s_register_operand" "l"))
8055 (label_ref (match_operand 2 "" ""))
8060 output_asm_insn (\"tst\\t%0, %1\", operands);
8061 switch (get_attr_length (insn))
8063 case 4: return \"b%d3\\t%l2\";
8064 case 6: return \"b%D3\\t.LCB%=\;b\\t%l2\\t%@long jump\\n.LCB%=:\";
8065 default: return \"b%D3\\t.LCB%=\;bl\\t%l2\\t%@far jump\\n.LCB%=:\";
8068 [(set (attr "far_jump")
8070 (eq_attr "length" "8")
8071 (const_string "yes")
8072 (const_string "no")))
8073 (set (attr "length")
8075 (and (ge (minus (match_dup 2) (pc)) (const_int -250))
8076 (le (minus (match_dup 2) (pc)) (const_int 256)))
8079 (and (ge (minus (match_dup 2) (pc)) (const_int -2040))
8080 (le (minus (match_dup 2) (pc)) (const_int 2048)))
8083 (set_attr "type" "multiple")]
8086 (define_insn "*cbranchne_decr1"
8088 (if_then_else (match_operator 3 "equality_operator"
8089 [(match_operand:SI 2 "s_register_operand" "l,l,1,l")
8091 (label_ref (match_operand 4 "" ""))
8093 (set (match_operand:SI 0 "thumb_cbrch_target_operand" "=l,*?h,*?m,*?m")
8094 (plus:SI (match_dup 2) (const_int -1)))
8095 (clobber (match_scratch:SI 1 "=X,l,&l,&l"))]
8100 cond[0] = gen_rtx_fmt_ee ((GET_CODE (operands[3]) == NE
8102 VOIDmode, operands[2], const1_rtx);
8103 cond[1] = operands[4];
8105 if (which_alternative == 0)
8106 output_asm_insn (\"sub\\t%0, %2, #1\", operands);
8107 else if (which_alternative == 1)
8109 /* We must provide an alternative for a hi reg because reload
8110 cannot handle output reloads on a jump instruction, but we
8111 can't subtract into that. Fortunately a mov from lo to hi
8112 does not clobber the condition codes. */
8113 output_asm_insn (\"sub\\t%1, %2, #1\", operands);
8114 output_asm_insn (\"mov\\t%0, %1\", operands);
8118 /* Similarly, but the target is memory. */
8119 output_asm_insn (\"sub\\t%1, %2, #1\", operands);
8120 output_asm_insn (\"str\\t%1, %0\", operands);
8123 switch (get_attr_length (insn) - (which_alternative ? 2 : 0))
8126 output_asm_insn (\"b%d0\\t%l1\", cond);
8129 output_asm_insn (\"b%D0\\t.LCB%=\", cond);
8130 return \"b\\t%l4\\t%@long jump\\n.LCB%=:\";
8132 output_asm_insn (\"b%D0\\t.LCB%=\", cond);
8133 return \"bl\\t%l4\\t%@far jump\\n.LCB%=:\";
8137 [(set (attr "far_jump")
8139 (ior (and (eq (symbol_ref ("which_alternative"))
8141 (eq_attr "length" "8"))
8142 (eq_attr "length" "10"))
8143 (const_string "yes")
8144 (const_string "no")))
8145 (set_attr_alternative "length"
8149 (and (ge (minus (match_dup 4) (pc)) (const_int -250))
8150 (le (minus (match_dup 4) (pc)) (const_int 256)))
8153 (and (ge (minus (match_dup 4) (pc)) (const_int -2040))
8154 (le (minus (match_dup 4) (pc)) (const_int 2048)))
8159 (and (ge (minus (match_dup 4) (pc)) (const_int -248))
8160 (le (minus (match_dup 4) (pc)) (const_int 256)))
8163 (and (ge (minus (match_dup 4) (pc)) (const_int -2038))
8164 (le (minus (match_dup 4) (pc)) (const_int 2048)))
8169 (and (ge (minus (match_dup 4) (pc)) (const_int -248))
8170 (le (minus (match_dup 4) (pc)) (const_int 256)))
8173 (and (ge (minus (match_dup 4) (pc)) (const_int -2038))
8174 (le (minus (match_dup 4) (pc)) (const_int 2048)))
8179 (and (ge (minus (match_dup 4) (pc)) (const_int -248))
8180 (le (minus (match_dup 4) (pc)) (const_int 256)))
8183 (and (ge (minus (match_dup 4) (pc)) (const_int -2038))
8184 (le (minus (match_dup 4) (pc)) (const_int 2048)))
8187 (set_attr "type" "multiple")]
8190 (define_insn "*addsi3_cbranch"
8193 (match_operator 4 "arm_comparison_operator"
8195 (match_operand:SI 2 "s_register_operand" "%0,l,*l,1,1,1")
8196 (match_operand:SI 3 "reg_or_int_operand" "IJ,lL,*l,lIJ,lIJ,lIJ"))
8198 (label_ref (match_operand 5 "" ""))
8201 (match_operand:SI 0 "thumb_cbrch_target_operand" "=l,l,*!h,*?h,*?m,*?m")
8202 (plus:SI (match_dup 2) (match_dup 3)))
8203 (clobber (match_scratch:SI 1 "=X,X,l,l,&l,&l"))]
8205 && (GET_CODE (operands[4]) == EQ
8206 || GET_CODE (operands[4]) == NE
8207 || GET_CODE (operands[4]) == GE
8208 || GET_CODE (operands[4]) == LT)"
8213 cond[0] = (which_alternative < 2) ? operands[0] : operands[1];
8214 cond[1] = operands[2];
8215 cond[2] = operands[3];
8217 if (CONST_INT_P (cond[2]) && INTVAL (cond[2]) < 0)
8218 output_asm_insn (\"sub\\t%0, %1, #%n2\", cond);
8220 output_asm_insn (\"add\\t%0, %1, %2\", cond);
8222 if (which_alternative >= 2
8223 && which_alternative < 4)
8224 output_asm_insn (\"mov\\t%0, %1\", operands);
8225 else if (which_alternative >= 4)
8226 output_asm_insn (\"str\\t%1, %0\", operands);
8228 switch (get_attr_length (insn) - ((which_alternative >= 2) ? 2 : 0))
8231 return \"b%d4\\t%l5\";
8233 return \"b%D4\\t.LCB%=\;b\\t%l5\\t%@long jump\\n.LCB%=:\";
8235 return \"b%D4\\t.LCB%=\;bl\\t%l5\\t%@far jump\\n.LCB%=:\";
8239 [(set (attr "far_jump")
8241 (ior (and (lt (symbol_ref ("which_alternative"))
8243 (eq_attr "length" "8"))
8244 (eq_attr "length" "10"))
8245 (const_string "yes")
8246 (const_string "no")))
8247 (set (attr "length")
8249 (lt (symbol_ref ("which_alternative"))
8252 (and (ge (minus (match_dup 5) (pc)) (const_int -250))
8253 (le (minus (match_dup 5) (pc)) (const_int 256)))
8256 (and (ge (minus (match_dup 5) (pc)) (const_int -2040))
8257 (le (minus (match_dup 5) (pc)) (const_int 2048)))
8261 (and (ge (minus (match_dup 5) (pc)) (const_int -248))
8262 (le (minus (match_dup 5) (pc)) (const_int 256)))
8265 (and (ge (minus (match_dup 5) (pc)) (const_int -2038))
8266 (le (minus (match_dup 5) (pc)) (const_int 2048)))
8269 (set_attr "type" "multiple")]
8272 (define_insn "*addsi3_cbranch_scratch"
8275 (match_operator 3 "arm_comparison_operator"
8277 (match_operand:SI 1 "s_register_operand" "%l,l,l,0")
8278 (match_operand:SI 2 "reg_or_int_operand" "J,l,L,IJ"))
8280 (label_ref (match_operand 4 "" ""))
8282 (clobber (match_scratch:SI 0 "=X,X,l,l"))]
8284 && (GET_CODE (operands[3]) == EQ
8285 || GET_CODE (operands[3]) == NE
8286 || GET_CODE (operands[3]) == GE
8287 || GET_CODE (operands[3]) == LT)"
8290 switch (which_alternative)
8293 output_asm_insn (\"cmp\t%1, #%n2\", operands);
8296 output_asm_insn (\"cmn\t%1, %2\", operands);
8299 if (INTVAL (operands[2]) < 0)
8300 output_asm_insn (\"sub\t%0, %1, %2\", operands);
8302 output_asm_insn (\"add\t%0, %1, %2\", operands);
8305 if (INTVAL (operands[2]) < 0)
8306 output_asm_insn (\"sub\t%0, %0, %2\", operands);
8308 output_asm_insn (\"add\t%0, %0, %2\", operands);
8312 switch (get_attr_length (insn))
8315 return \"b%d3\\t%l4\";
8317 return \"b%D3\\t.LCB%=\;b\\t%l4\\t%@long jump\\n.LCB%=:\";
8319 return \"b%D3\\t.LCB%=\;bl\\t%l4\\t%@far jump\\n.LCB%=:\";
8323 [(set (attr "far_jump")
8325 (eq_attr "length" "8")
8326 (const_string "yes")
8327 (const_string "no")))
8328 (set (attr "length")
8330 (and (ge (minus (match_dup 4) (pc)) (const_int -250))
8331 (le (minus (match_dup 4) (pc)) (const_int 256)))
8334 (and (ge (minus (match_dup 4) (pc)) (const_int -2040))
8335 (le (minus (match_dup 4) (pc)) (const_int 2048)))
8338 (set_attr "type" "multiple")]
8342 ;; Comparison and test insns
8344 (define_insn "*arm_cmpsi_insn"
8345 [(set (reg:CC CC_REGNUM)
8346 (compare:CC (match_operand:SI 0 "s_register_operand" "l,r,r,r,r")
8347 (match_operand:SI 1 "arm_add_operand" "Py,r,r,I,L")))]
8355 [(set_attr "conds" "set")
8356 (set_attr "arch" "t2,t2,any,any,any")
8357 (set_attr "length" "2,2,4,4,4")
8358 (set_attr "predicable" "yes")
8359 (set_attr "predicable_short_it" "yes,yes,yes,no,no")
8360 (set_attr "type" "alus_imm,alus_reg,alus_reg,alus_imm,alus_imm")]
8363 (define_insn "*cmpsi_shiftsi"
8364 [(set (reg:CC CC_REGNUM)
8365 (compare:CC (match_operand:SI 0 "s_register_operand" "r,r,r")
8366 (match_operator:SI 3 "shift_operator"
8367 [(match_operand:SI 1 "s_register_operand" "r,r,r")
8368 (match_operand:SI 2 "shift_amount_operand" "M,r,M")])))]
8371 [(set_attr "conds" "set")
8372 (set_attr "shift" "1")
8373 (set_attr "arch" "32,a,a")
8374 (set_attr "type" "alus_shift_imm,alu_shift_reg,alus_shift_imm")])
8376 (define_insn "*cmpsi_shiftsi_swp"
8377 [(set (reg:CC_SWP CC_REGNUM)
8378 (compare:CC_SWP (match_operator:SI 3 "shift_operator"
8379 [(match_operand:SI 1 "s_register_operand" "r,r,r")
8380 (match_operand:SI 2 "shift_amount_operand" "M,r,M")])
8381 (match_operand:SI 0 "s_register_operand" "r,r,r")))]
8384 [(set_attr "conds" "set")
8385 (set_attr "shift" "1")
8386 (set_attr "arch" "32,a,a")
8387 (set_attr "type" "alus_shift_imm,alu_shift_reg,alus_shift_imm")])
8389 (define_insn "*arm_cmpsi_negshiftsi_si"
8390 [(set (reg:CC_Z CC_REGNUM)
8392 (neg:SI (match_operator:SI 1 "shift_operator"
8393 [(match_operand:SI 2 "s_register_operand" "r")
8394 (match_operand:SI 3 "reg_or_int_operand" "rM")]))
8395 (match_operand:SI 0 "s_register_operand" "r")))]
8398 [(set_attr "conds" "set")
8399 (set (attr "type") (if_then_else (match_operand 3 "const_int_operand" "")
8400 (const_string "alus_shift_imm")
8401 (const_string "alus_shift_reg")))
8402 (set_attr "predicable" "yes")]
8405 ;; DImode comparisons. The generic code generates branches that
8406 ;; if-conversion can not reduce to a conditional compare, so we do
8409 (define_insn_and_split "*arm_cmpdi_insn"
8410 [(set (reg:CC_NCV CC_REGNUM)
8411 (compare:CC_NCV (match_operand:DI 0 "s_register_operand" "r")
8412 (match_operand:DI 1 "arm_di_operand" "rDi")))
8413 (clobber (match_scratch:SI 2 "=r"))]
8415 "#" ; "cmp\\t%Q0, %Q1\;sbcs\\t%2, %R0, %R1"
8416 "&& reload_completed"
8417 [(set (reg:CC CC_REGNUM)
8418 (compare:CC (match_dup 0) (match_dup 1)))
8419 (parallel [(set (reg:CC CC_REGNUM)
8420 (compare:CC (match_dup 3) (match_dup 4)))
8422 (minus:SI (match_dup 5)
8423 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))])]
8425 operands[3] = gen_highpart (SImode, operands[0]);
8426 operands[0] = gen_lowpart (SImode, operands[0]);
8427 if (CONST_INT_P (operands[1]))
8429 operands[4] = GEN_INT (~INTVAL (gen_highpart_mode (SImode,
8432 operands[5] = gen_rtx_PLUS (SImode, operands[3], operands[4]);
8436 operands[4] = gen_highpart (SImode, operands[1]);
8437 operands[5] = gen_rtx_MINUS (SImode, operands[3], operands[4]);
8439 operands[1] = gen_lowpart (SImode, operands[1]);
8440 operands[2] = gen_lowpart (SImode, operands[2]);
8442 [(set_attr "conds" "set")
8443 (set_attr "length" "8")
8444 (set_attr "type" "multiple")]
8447 (define_insn_and_split "*arm_cmpdi_unsigned"
8448 [(set (reg:CC_CZ CC_REGNUM)
8449 (compare:CC_CZ (match_operand:DI 0 "s_register_operand" "l,r,r")
8450 (match_operand:DI 1 "arm_di_operand" "Py,r,rDi")))]
8453 "#" ; "cmp\\t%R0, %R1\;it eq\;cmpeq\\t%Q0, %Q1"
8454 "&& reload_completed"
8455 [(set (reg:CC CC_REGNUM)
8456 (compare:CC (match_dup 2) (match_dup 3)))
8457 (cond_exec (eq:SI (reg:CC CC_REGNUM) (const_int 0))
8458 (set (reg:CC CC_REGNUM)
8459 (compare:CC (match_dup 0) (match_dup 1))))]
8461 operands[2] = gen_highpart (SImode, operands[0]);
8462 operands[0] = gen_lowpart (SImode, operands[0]);
8463 if (CONST_INT_P (operands[1]))
8464 operands[3] = gen_highpart_mode (SImode, DImode, operands[1]);
8466 operands[3] = gen_highpart (SImode, operands[1]);
8467 operands[1] = gen_lowpart (SImode, operands[1]);
8469 [(set_attr "conds" "set")
8470 (set_attr "enabled_for_depr_it" "yes,yes,no")
8471 (set_attr "arch" "t2,t2,*")
8472 (set_attr "length" "6,6,8")
8473 (set_attr "type" "multiple")]
8476 (define_insn "*arm_cmpdi_zero"
8477 [(set (reg:CC_Z CC_REGNUM)
8478 (compare:CC_Z (match_operand:DI 0 "s_register_operand" "r")
8480 (clobber (match_scratch:SI 1 "=r"))]
8482 "orr%.\\t%1, %Q0, %R0"
8483 [(set_attr "conds" "set")
8484 (set_attr "type" "logics_reg")]
8487 (define_insn "*thumb_cmpdi_zero"
8488 [(set (reg:CC_Z CC_REGNUM)
8489 (compare:CC_Z (match_operand:DI 0 "s_register_operand" "l")
8491 (clobber (match_scratch:SI 1 "=l"))]
8493 "orr\\t%1, %Q0, %R0"
8494 [(set_attr "conds" "set")
8495 (set_attr "length" "2")
8496 (set_attr "type" "logics_reg")]
8499 ; This insn allows redundant compares to be removed by cse, nothing should
8500 ; ever appear in the output file since (set (reg x) (reg x)) is a no-op that
8501 ; is deleted later on. The match_dup will match the mode here, so that
8502 ; mode changes of the condition codes aren't lost by this even though we don't
8503 ; specify what they are.
8505 (define_insn "*deleted_compare"
8506 [(set (match_operand 0 "cc_register" "") (match_dup 0))]
8508 "\\t%@ deleted compare"
8509 [(set_attr "conds" "set")
8510 (set_attr "length" "0")
8511 (set_attr "type" "no_insn")]
8515 ;; Conditional branch insns
8517 (define_expand "cbranch_cc"
8519 (if_then_else (match_operator 0 "" [(match_operand 1 "" "")
8520 (match_operand 2 "" "")])
8521 (label_ref (match_operand 3 "" ""))
8524 "operands[1] = arm_gen_compare_reg (GET_CODE (operands[0]),
8525 operands[1], operands[2], NULL_RTX);
8526 operands[2] = const0_rtx;"
8530 ;; Patterns to match conditional branch insns.
8533 (define_insn "arm_cond_branch"
8535 (if_then_else (match_operator 1 "arm_comparison_operator"
8536 [(match_operand 2 "cc_register" "") (const_int 0)])
8537 (label_ref (match_operand 0 "" ""))
8541 if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
8543 arm_ccfsm_state += 2;
8546 return \"b%d1\\t%l0\";
8548 [(set_attr "conds" "use")
8549 (set_attr "type" "branch")
8550 (set (attr "length")
8552 (and (match_test "TARGET_THUMB2")
8553 (and (ge (minus (match_dup 0) (pc)) (const_int -250))
8554 (le (minus (match_dup 0) (pc)) (const_int 256))))
8559 (define_insn "*arm_cond_branch_reversed"
8561 (if_then_else (match_operator 1 "arm_comparison_operator"
8562 [(match_operand 2 "cc_register" "") (const_int 0)])
8564 (label_ref (match_operand 0 "" ""))))]
8567 if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
8569 arm_ccfsm_state += 2;
8572 return \"b%D1\\t%l0\";
8574 [(set_attr "conds" "use")
8575 (set_attr "type" "branch")
8576 (set (attr "length")
8578 (and (match_test "TARGET_THUMB2")
8579 (and (ge (minus (match_dup 0) (pc)) (const_int -250))
8580 (le (minus (match_dup 0) (pc)) (const_int 256))))
8589 (define_expand "cstore_cc"
8590 [(set (match_operand:SI 0 "s_register_operand" "")
8591 (match_operator:SI 1 "" [(match_operand 2 "" "")
8592 (match_operand 3 "" "")]))]
8594 "operands[2] = arm_gen_compare_reg (GET_CODE (operands[1]),
8595 operands[2], operands[3], NULL_RTX);
8596 operands[3] = const0_rtx;"
8599 (define_insn_and_split "*mov_scc"
8600 [(set (match_operand:SI 0 "s_register_operand" "=r")
8601 (match_operator:SI 1 "arm_comparison_operator"
8602 [(match_operand 2 "cc_register" "") (const_int 0)]))]
8604 "#" ; "mov%D1\\t%0, #0\;mov%d1\\t%0, #1"
8607 (if_then_else:SI (match_dup 1)
8611 [(set_attr "conds" "use")
8612 (set_attr "length" "8")
8613 (set_attr "type" "multiple")]
8616 (define_insn_and_split "*mov_negscc"
8617 [(set (match_operand:SI 0 "s_register_operand" "=r")
8618 (neg:SI (match_operator:SI 1 "arm_comparison_operator"
8619 [(match_operand 2 "cc_register" "") (const_int 0)])))]
8621 "#" ; "mov%D1\\t%0, #0\;mvn%d1\\t%0, #0"
8624 (if_then_else:SI (match_dup 1)
8628 operands[3] = GEN_INT (~0);
8630 [(set_attr "conds" "use")
8631 (set_attr "length" "8")
8632 (set_attr "type" "multiple")]
8635 (define_insn_and_split "*mov_notscc"
8636 [(set (match_operand:SI 0 "s_register_operand" "=r")
8637 (not:SI (match_operator:SI 1 "arm_comparison_operator"
8638 [(match_operand 2 "cc_register" "") (const_int 0)])))]
8640 "#" ; "mvn%D1\\t%0, #0\;mvn%d1\\t%0, #1"
8643 (if_then_else:SI (match_dup 1)
8647 operands[3] = GEN_INT (~1);
8648 operands[4] = GEN_INT (~0);
8650 [(set_attr "conds" "use")
8651 (set_attr "length" "8")
8652 (set_attr "type" "multiple")]
8655 (define_expand "cstoresi4"
8656 [(set (match_operand:SI 0 "s_register_operand" "")
8657 (match_operator:SI 1 "expandable_comparison_operator"
8658 [(match_operand:SI 2 "s_register_operand" "")
8659 (match_operand:SI 3 "reg_or_int_operand" "")]))]
8660 "TARGET_32BIT || TARGET_THUMB1"
8662 rtx op3, scratch, scratch2;
8666 if (!arm_add_operand (operands[3], SImode))
8667 operands[3] = force_reg (SImode, operands[3]);
8668 emit_insn (gen_cstore_cc (operands[0], operands[1],
8669 operands[2], operands[3]));
8673 if (operands[3] == const0_rtx)
8675 switch (GET_CODE (operands[1]))
8678 emit_insn (gen_cstoresi_eq0_thumb1 (operands[0], operands[2]));
8682 emit_insn (gen_cstoresi_ne0_thumb1 (operands[0], operands[2]));
8686 scratch = expand_binop (SImode, add_optab, operands[2], constm1_rtx,
8687 NULL_RTX, 0, OPTAB_WIDEN);
8688 scratch = expand_binop (SImode, ior_optab, operands[2], scratch,
8689 NULL_RTX, 0, OPTAB_WIDEN);
8690 expand_binop (SImode, lshr_optab, scratch, GEN_INT (31),
8691 operands[0], 1, OPTAB_WIDEN);
8695 scratch = expand_unop (SImode, one_cmpl_optab, operands[2],
8697 expand_binop (SImode, lshr_optab, scratch, GEN_INT (31),
8698 NULL_RTX, 1, OPTAB_WIDEN);
8702 scratch = expand_binop (SImode, ashr_optab, operands[2],
8703 GEN_INT (31), NULL_RTX, 0, OPTAB_WIDEN);
8704 scratch = expand_binop (SImode, sub_optab, scratch, operands[2],
8705 NULL_RTX, 0, OPTAB_WIDEN);
8706 expand_binop (SImode, lshr_optab, scratch, GEN_INT (31), operands[0],
8710 /* LT is handled by generic code. No need for unsigned with 0. */
8717 switch (GET_CODE (operands[1]))
8720 scratch = expand_binop (SImode, sub_optab, operands[2], operands[3],
8721 NULL_RTX, 0, OPTAB_WIDEN);
8722 emit_insn (gen_cstoresi_eq0_thumb1 (operands[0], scratch));
8726 scratch = expand_binop (SImode, sub_optab, operands[2], operands[3],
8727 NULL_RTX, 0, OPTAB_WIDEN);
8728 emit_insn (gen_cstoresi_ne0_thumb1 (operands[0], scratch));
8732 op3 = force_reg (SImode, operands[3]);
8734 scratch = expand_binop (SImode, lshr_optab, operands[2], GEN_INT (31),
8735 NULL_RTX, 1, OPTAB_WIDEN);
8736 scratch2 = expand_binop (SImode, ashr_optab, op3, GEN_INT (31),
8737 NULL_RTX, 0, OPTAB_WIDEN);
8738 emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch2,
8744 if (!thumb1_cmp_operand (op3, SImode))
8745 op3 = force_reg (SImode, op3);
8746 scratch = expand_binop (SImode, ashr_optab, operands[2], GEN_INT (31),
8747 NULL_RTX, 0, OPTAB_WIDEN);
8748 scratch2 = expand_binop (SImode, lshr_optab, op3, GEN_INT (31),
8749 NULL_RTX, 1, OPTAB_WIDEN);
8750 emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch2,
8755 op3 = force_reg (SImode, operands[3]);
8756 scratch = force_reg (SImode, const0_rtx);
8757 emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch,
8763 if (!thumb1_cmp_operand (op3, SImode))
8764 op3 = force_reg (SImode, op3);
8765 scratch = force_reg (SImode, const0_rtx);
8766 emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch,
8772 if (!thumb1_cmp_operand (op3, SImode))
8773 op3 = force_reg (SImode, op3);
8774 scratch = gen_reg_rtx (SImode);
8775 emit_insn (gen_cstoresi_ltu_thumb1 (operands[0], operands[2], op3));
8779 op3 = force_reg (SImode, operands[3]);
8780 scratch = gen_reg_rtx (SImode);
8781 emit_insn (gen_cstoresi_ltu_thumb1 (operands[0], op3, operands[2]));
8784 /* No good sequences for GT, LT. */
8791 (define_expand "cstoresf4"
8792 [(set (match_operand:SI 0 "s_register_operand" "")
8793 (match_operator:SI 1 "expandable_comparison_operator"
8794 [(match_operand:SF 2 "s_register_operand" "")
8795 (match_operand:SF 3 "arm_float_compare_operand" "")]))]
8796 "TARGET_32BIT && TARGET_HARD_FLOAT"
8797 "emit_insn (gen_cstore_cc (operands[0], operands[1],
8798 operands[2], operands[3])); DONE;"
8801 (define_expand "cstoredf4"
8802 [(set (match_operand:SI 0 "s_register_operand" "")
8803 (match_operator:SI 1 "expandable_comparison_operator"
8804 [(match_operand:DF 2 "s_register_operand" "")
8805 (match_operand:DF 3 "arm_float_compare_operand" "")]))]
8806 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
8807 "emit_insn (gen_cstore_cc (operands[0], operands[1],
8808 operands[2], operands[3])); DONE;"
8811 (define_expand "cstoredi4"
8812 [(set (match_operand:SI 0 "s_register_operand" "")
8813 (match_operator:SI 1 "expandable_comparison_operator"
8814 [(match_operand:DI 2 "s_register_operand" "")
8815 (match_operand:DI 3 "cmpdi_operand" "")]))]
8818 if (!arm_validize_comparison (&operands[1],
8822 emit_insn (gen_cstore_cc (operands[0], operands[1], operands[2],
8828 (define_expand "cstoresi_eq0_thumb1"
8830 [(set (match_operand:SI 0 "s_register_operand" "")
8831 (eq:SI (match_operand:SI 1 "s_register_operand" "")
8833 (clobber (match_dup:SI 2))])]
8835 "operands[2] = gen_reg_rtx (SImode);"
8838 (define_expand "cstoresi_ne0_thumb1"
8840 [(set (match_operand:SI 0 "s_register_operand" "")
8841 (ne:SI (match_operand:SI 1 "s_register_operand" "")
8843 (clobber (match_dup:SI 2))])]
8845 "operands[2] = gen_reg_rtx (SImode);"
8848 (define_insn "*cstoresi_eq0_thumb1_insn"
8849 [(set (match_operand:SI 0 "s_register_operand" "=&l,l")
8850 (eq:SI (match_operand:SI 1 "s_register_operand" "l,0")
8852 (clobber (match_operand:SI 2 "s_register_operand" "=X,l"))]
8855 neg\\t%0, %1\;adc\\t%0, %0, %1
8856 neg\\t%2, %1\;adc\\t%0, %1, %2"
8857 [(set_attr "length" "4")
8858 (set_attr "type" "multiple")]
8861 (define_insn "*cstoresi_ne0_thumb1_insn"
8862 [(set (match_operand:SI 0 "s_register_operand" "=l")
8863 (ne:SI (match_operand:SI 1 "s_register_operand" "0")
8865 (clobber (match_operand:SI 2 "s_register_operand" "=l"))]
8867 "sub\\t%2, %1, #1\;sbc\\t%0, %1, %2"
8868 [(set_attr "length" "4")]
8871 ;; Used as part of the expansion of thumb ltu and gtu sequences
8872 (define_insn "cstoresi_nltu_thumb1"
8873 [(set (match_operand:SI 0 "s_register_operand" "=l,l")
8874 (neg:SI (ltu:SI (match_operand:SI 1 "s_register_operand" "l,*h")
8875 (match_operand:SI 2 "thumb1_cmp_operand" "lI*h,*r"))))]
8877 "cmp\\t%1, %2\;sbc\\t%0, %0, %0"
8878 [(set_attr "length" "4")
8879 (set_attr "type" "multiple")]
8882 (define_insn_and_split "cstoresi_ltu_thumb1"
8883 [(set (match_operand:SI 0 "s_register_operand" "=l,l")
8884 (ltu:SI (match_operand:SI 1 "s_register_operand" "l,*h")
8885 (match_operand:SI 2 "thumb1_cmp_operand" "lI*h,*r")))]
8890 (neg:SI (ltu:SI (match_dup 1) (match_dup 2))))
8891 (set (match_dup 0) (neg:SI (match_dup 3)))]
8892 "operands[3] = gen_reg_rtx (SImode);"
8893 [(set_attr "length" "4")
8894 (set_attr "type" "multiple")]
8897 ;; Used as part of the expansion of thumb les sequence.
8898 (define_insn "thumb1_addsi3_addgeu"
8899 [(set (match_operand:SI 0 "s_register_operand" "=l")
8900 (plus:SI (plus:SI (match_operand:SI 1 "s_register_operand" "%0")
8901 (match_operand:SI 2 "s_register_operand" "l"))
8902 (geu:SI (match_operand:SI 3 "s_register_operand" "l")
8903 (match_operand:SI 4 "thumb1_cmp_operand" "lI"))))]
8905 "cmp\\t%3, %4\;adc\\t%0, %1, %2"
8906 [(set_attr "length" "4")
8907 (set_attr "type" "multiple")]
8911 ;; Conditional move insns
8913 (define_expand "movsicc"
8914 [(set (match_operand:SI 0 "s_register_operand" "")
8915 (if_then_else:SI (match_operand 1 "expandable_comparison_operator" "")
8916 (match_operand:SI 2 "arm_not_operand" "")
8917 (match_operand:SI 3 "arm_not_operand" "")))]
8924 if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0),
8925 &XEXP (operands[1], 1)))
8928 code = GET_CODE (operands[1]);
8929 ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
8930 XEXP (operands[1], 1), NULL_RTX);
8931 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
8935 (define_expand "movsfcc"
8936 [(set (match_operand:SF 0 "s_register_operand" "")
8937 (if_then_else:SF (match_operand 1 "arm_cond_move_operator" "")
8938 (match_operand:SF 2 "s_register_operand" "")
8939 (match_operand:SF 3 "s_register_operand" "")))]
8940 "TARGET_32BIT && TARGET_HARD_FLOAT"
8943 enum rtx_code code = GET_CODE (operands[1]);
8946 if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0),
8947 &XEXP (operands[1], 1)))
8950 code = GET_CODE (operands[1]);
8951 ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
8952 XEXP (operands[1], 1), NULL_RTX);
8953 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
8957 (define_expand "movdfcc"
8958 [(set (match_operand:DF 0 "s_register_operand" "")
8959 (if_then_else:DF (match_operand 1 "arm_cond_move_operator" "")
8960 (match_operand:DF 2 "s_register_operand" "")
8961 (match_operand:DF 3 "s_register_operand" "")))]
8962 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
8965 enum rtx_code code = GET_CODE (operands[1]);
8968 if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0),
8969 &XEXP (operands[1], 1)))
8971 code = GET_CODE (operands[1]);
8972 ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
8973 XEXP (operands[1], 1), NULL_RTX);
8974 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
8978 (define_insn "*cmov<mode>"
8979 [(set (match_operand:SDF 0 "s_register_operand" "=<F_constraint>")
8980 (if_then_else:SDF (match_operator 1 "arm_vsel_comparison_operator"
8981 [(match_operand 2 "cc_register" "") (const_int 0)])
8982 (match_operand:SDF 3 "s_register_operand"
8984 (match_operand:SDF 4 "s_register_operand"
8985 "<F_constraint>")))]
8986 "TARGET_HARD_FLOAT && TARGET_FPU_ARMV8 <vfp_double_cond>"
8989 enum arm_cond_code code = maybe_get_arm_condition_code (operands[1]);
8996 return \"vsel%d1.<V_if_elem>\\t%<V_reg>0, %<V_reg>3, %<V_reg>4\";
9001 return \"vsel%D1.<V_if_elem>\\t%<V_reg>0, %<V_reg>4, %<V_reg>3\";
9007 [(set_attr "conds" "use")
9008 (set_attr "type" "f_sel<vfp_type>")]
9011 (define_insn_and_split "*movsicc_insn"
9012 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r,r,r,r,r")
9014 (match_operator 3 "arm_comparison_operator"
9015 [(match_operand 4 "cc_register" "") (const_int 0)])
9016 (match_operand:SI 1 "arm_not_operand" "0,0,rI,K,rI,rI,K,K")
9017 (match_operand:SI 2 "arm_not_operand" "rI,K,0,0,rI,K,rI,K")))]
9028 ; alt4: mov%d3\\t%0, %1\;mov%D3\\t%0, %2
9029 ; alt5: mov%d3\\t%0, %1\;mvn%D3\\t%0, #%B2
9030 ; alt6: mvn%d3\\t%0, #%B1\;mov%D3\\t%0, %2
9031 ; alt7: mvn%d3\\t%0, #%B1\;mvn%D3\\t%0, #%B2"
9032 "&& reload_completed"
9035 enum rtx_code rev_code;
9036 enum machine_mode mode;
9039 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
9041 gen_rtx_SET (VOIDmode,
9045 rev_code = GET_CODE (operands[3]);
9046 mode = GET_MODE (operands[4]);
9047 if (mode == CCFPmode || mode == CCFPEmode)
9048 rev_code = reverse_condition_maybe_unordered (rev_code);
9050 rev_code = reverse_condition (rev_code);
9052 rev_cond = gen_rtx_fmt_ee (rev_code,
9056 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
9058 gen_rtx_SET (VOIDmode,
9063 [(set_attr "length" "4,4,4,4,8,8,8,8")
9064 (set_attr "conds" "use")
9065 (set_attr_alternative "type"
9066 [(if_then_else (match_operand 2 "const_int_operand" "")
9067 (const_string "mov_imm")
9068 (const_string "mov_reg"))
9069 (const_string "mvn_imm")
9070 (if_then_else (match_operand 1 "const_int_operand" "")
9071 (const_string "mov_imm")
9072 (const_string "mov_reg"))
9073 (const_string "mvn_imm")
9074 (const_string "mov_reg")
9075 (const_string "mov_reg")
9076 (const_string "mov_reg")
9077 (const_string "mov_reg")])]
9080 (define_insn "*movsfcc_soft_insn"
9081 [(set (match_operand:SF 0 "s_register_operand" "=r,r")
9082 (if_then_else:SF (match_operator 3 "arm_comparison_operator"
9083 [(match_operand 4 "cc_register" "") (const_int 0)])
9084 (match_operand:SF 1 "s_register_operand" "0,r")
9085 (match_operand:SF 2 "s_register_operand" "r,0")))]
9086 "TARGET_ARM && TARGET_SOFT_FLOAT"
9090 [(set_attr "conds" "use")
9091 (set_attr "type" "mov_reg")]
9095 ;; Jump and linkage insns
9097 (define_expand "jump"
9099 (label_ref (match_operand 0 "" "")))]
9104 (define_insn "*arm_jump"
9106 (label_ref (match_operand 0 "" "")))]
9110 if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
9112 arm_ccfsm_state += 2;
9115 return \"b%?\\t%l0\";
9118 [(set_attr "predicable" "yes")
9119 (set (attr "length")
9121 (and (match_test "TARGET_THUMB2")
9122 (and (ge (minus (match_dup 0) (pc)) (const_int -2044))
9123 (le (minus (match_dup 0) (pc)) (const_int 2048))))
9126 (set_attr "type" "branch")]
9129 (define_insn "*thumb_jump"
9131 (label_ref (match_operand 0 "" "")))]
9134 if (get_attr_length (insn) == 2)
9136 return \"bl\\t%l0\\t%@ far jump\";
9138 [(set (attr "far_jump")
9140 (eq_attr "length" "4")
9141 (const_string "yes")
9142 (const_string "no")))
9143 (set (attr "length")
9145 (and (ge (minus (match_dup 0) (pc)) (const_int -2044))
9146 (le (minus (match_dup 0) (pc)) (const_int 2048)))
9149 (set_attr "type" "branch")]
9152 (define_expand "call"
9153 [(parallel [(call (match_operand 0 "memory_operand" "")
9154 (match_operand 1 "general_operand" ""))
9155 (use (match_operand 2 "" ""))
9156 (clobber (reg:SI LR_REGNUM))])]
9162 /* In an untyped call, we can get NULL for operand 2. */
9163 if (operands[2] == NULL_RTX)
9164 operands[2] = const0_rtx;
9166 /* Decide if we should generate indirect calls by loading the
9167 32-bit address of the callee into a register before performing the
9169 callee = XEXP (operands[0], 0);
9170 if (GET_CODE (callee) == SYMBOL_REF
9171 ? arm_is_long_call_p (SYMBOL_REF_DECL (callee))
9173 XEXP (operands[0], 0) = force_reg (Pmode, callee);
9175 pat = gen_call_internal (operands[0], operands[1], operands[2]);
9176 arm_emit_call_insn (pat, XEXP (operands[0], 0));
9181 (define_expand "call_internal"
9182 [(parallel [(call (match_operand 0 "memory_operand" "")
9183 (match_operand 1 "general_operand" ""))
9184 (use (match_operand 2 "" ""))
9185 (clobber (reg:SI LR_REGNUM))])])
9187 (define_insn "*call_reg_armv5"
9188 [(call (mem:SI (match_operand:SI 0 "s_register_operand" "r"))
9189 (match_operand 1 "" ""))
9190 (use (match_operand 2 "" ""))
9191 (clobber (reg:SI LR_REGNUM))]
9192 "TARGET_ARM && arm_arch5 && !SIBLING_CALL_P (insn)"
9194 [(set_attr "type" "call")]
9197 (define_insn "*call_reg_arm"
9198 [(call (mem:SI (match_operand:SI 0 "s_register_operand" "r"))
9199 (match_operand 1 "" ""))
9200 (use (match_operand 2 "" ""))
9201 (clobber (reg:SI LR_REGNUM))]
9202 "TARGET_ARM && !arm_arch5 && !SIBLING_CALL_P (insn)"
9204 return output_call (operands);
9206 ;; length is worst case, normally it is only two
9207 [(set_attr "length" "12")
9208 (set_attr "type" "call")]
9212 ;; Note: not used for armv5+ because the sequence used (ldr pc, ...) is not
9213 ;; considered a function call by the branch predictor of some cores (PR40887).
9214 ;; Falls back to blx rN (*call_reg_armv5).
9216 (define_insn "*call_mem"
9217 [(call (mem:SI (match_operand:SI 0 "call_memory_operand" "m"))
9218 (match_operand 1 "" ""))
9219 (use (match_operand 2 "" ""))
9220 (clobber (reg:SI LR_REGNUM))]
9221 "TARGET_ARM && !arm_arch5 && !SIBLING_CALL_P (insn)"
9223 return output_call_mem (operands);
9225 [(set_attr "length" "12")
9226 (set_attr "type" "call")]
9229 (define_insn "*call_reg_thumb1_v5"
9230 [(call (mem:SI (match_operand:SI 0 "register_operand" "l*r"))
9231 (match_operand 1 "" ""))
9232 (use (match_operand 2 "" ""))
9233 (clobber (reg:SI LR_REGNUM))]
9234 "TARGET_THUMB1 && arm_arch5 && !SIBLING_CALL_P (insn)"
9236 [(set_attr "length" "2")
9237 (set_attr "type" "call")]
9240 (define_insn "*call_reg_thumb1"
9241 [(call (mem:SI (match_operand:SI 0 "register_operand" "l*r"))
9242 (match_operand 1 "" ""))
9243 (use (match_operand 2 "" ""))
9244 (clobber (reg:SI LR_REGNUM))]
9245 "TARGET_THUMB1 && !arm_arch5 && !SIBLING_CALL_P (insn)"
9248 if (!TARGET_CALLER_INTERWORKING)
9249 return thumb_call_via_reg (operands[0]);
9250 else if (operands[1] == const0_rtx)
9251 return \"bl\\t%__interwork_call_via_%0\";
9252 else if (frame_pointer_needed)
9253 return \"bl\\t%__interwork_r7_call_via_%0\";
9255 return \"bl\\t%__interwork_r11_call_via_%0\";
9257 [(set_attr "type" "call")]
9260 (define_expand "call_value"
9261 [(parallel [(set (match_operand 0 "" "")
9262 (call (match_operand 1 "memory_operand" "")
9263 (match_operand 2 "general_operand" "")))
9264 (use (match_operand 3 "" ""))
9265 (clobber (reg:SI LR_REGNUM))])]
9271 /* In an untyped call, we can get NULL for operand 2. */
9272 if (operands[3] == 0)
9273 operands[3] = const0_rtx;
9275 /* Decide if we should generate indirect calls by loading the
9276 32-bit address of the callee into a register before performing the
9278 callee = XEXP (operands[1], 0);
9279 if (GET_CODE (callee) == SYMBOL_REF
9280 ? arm_is_long_call_p (SYMBOL_REF_DECL (callee))
9282 XEXP (operands[1], 0) = force_reg (Pmode, callee);
9284 pat = gen_call_value_internal (operands[0], operands[1],
9285 operands[2], operands[3]);
9286 arm_emit_call_insn (pat, XEXP (operands[1], 0));
9291 (define_expand "call_value_internal"
9292 [(parallel [(set (match_operand 0 "" "")
9293 (call (match_operand 1 "memory_operand" "")
9294 (match_operand 2 "general_operand" "")))
9295 (use (match_operand 3 "" ""))
9296 (clobber (reg:SI LR_REGNUM))])])
9298 (define_insn "*call_value_reg_armv5"
9299 [(set (match_operand 0 "" "")
9300 (call (mem:SI (match_operand:SI 1 "s_register_operand" "r"))
9301 (match_operand 2 "" "")))
9302 (use (match_operand 3 "" ""))
9303 (clobber (reg:SI LR_REGNUM))]
9304 "TARGET_ARM && arm_arch5 && !SIBLING_CALL_P (insn)"
9306 [(set_attr "type" "call")]
9309 (define_insn "*call_value_reg_arm"
9310 [(set (match_operand 0 "" "")
9311 (call (mem:SI (match_operand:SI 1 "s_register_operand" "r"))
9312 (match_operand 2 "" "")))
9313 (use (match_operand 3 "" ""))
9314 (clobber (reg:SI LR_REGNUM))]
9315 "TARGET_ARM && !arm_arch5 && !SIBLING_CALL_P (insn)"
9317 return output_call (&operands[1]);
9319 [(set_attr "length" "12")
9320 (set_attr "type" "call")]
9323 ;; Note: see *call_mem
9325 (define_insn "*call_value_mem"
9326 [(set (match_operand 0 "" "")
9327 (call (mem:SI (match_operand:SI 1 "call_memory_operand" "m"))
9328 (match_operand 2 "" "")))
9329 (use (match_operand 3 "" ""))
9330 (clobber (reg:SI LR_REGNUM))]
9331 "TARGET_ARM && !arm_arch5 && (!CONSTANT_ADDRESS_P (XEXP (operands[1], 0)))
9332 && !SIBLING_CALL_P (insn)"
9334 return output_call_mem (&operands[1]);
9336 [(set_attr "length" "12")
9337 (set_attr "type" "call")]
9340 (define_insn "*call_value_reg_thumb1_v5"
9341 [(set (match_operand 0 "" "")
9342 (call (mem:SI (match_operand:SI 1 "register_operand" "l*r"))
9343 (match_operand 2 "" "")))
9344 (use (match_operand 3 "" ""))
9345 (clobber (reg:SI LR_REGNUM))]
9346 "TARGET_THUMB1 && arm_arch5"
9348 [(set_attr "length" "2")
9349 (set_attr "type" "call")]
9352 (define_insn "*call_value_reg_thumb1"
9353 [(set (match_operand 0 "" "")
9354 (call (mem:SI (match_operand:SI 1 "register_operand" "l*r"))
9355 (match_operand 2 "" "")))
9356 (use (match_operand 3 "" ""))
9357 (clobber (reg:SI LR_REGNUM))]
9358 "TARGET_THUMB1 && !arm_arch5"
9361 if (!TARGET_CALLER_INTERWORKING)
9362 return thumb_call_via_reg (operands[1]);
9363 else if (operands[2] == const0_rtx)
9364 return \"bl\\t%__interwork_call_via_%1\";
9365 else if (frame_pointer_needed)
9366 return \"bl\\t%__interwork_r7_call_via_%1\";
9368 return \"bl\\t%__interwork_r11_call_via_%1\";
9370 [(set_attr "type" "call")]
9373 ;; Allow calls to SYMBOL_REFs specially as they are not valid general addresses
9374 ;; The 'a' causes the operand to be treated as an address, i.e. no '#' output.
9376 (define_insn "*call_symbol"
9377 [(call (mem:SI (match_operand:SI 0 "" ""))
9378 (match_operand 1 "" ""))
9379 (use (match_operand 2 "" ""))
9380 (clobber (reg:SI LR_REGNUM))]
9382 && !SIBLING_CALL_P (insn)
9383 && (GET_CODE (operands[0]) == SYMBOL_REF)
9384 && !arm_is_long_call_p (SYMBOL_REF_DECL (operands[0]))"
9387 return NEED_PLT_RELOC ? \"bl%?\\t%a0(PLT)\" : \"bl%?\\t%a0\";
9389 [(set_attr "type" "call")]
9392 (define_insn "*call_value_symbol"
9393 [(set (match_operand 0 "" "")
9394 (call (mem:SI (match_operand:SI 1 "" ""))
9395 (match_operand:SI 2 "" "")))
9396 (use (match_operand 3 "" ""))
9397 (clobber (reg:SI LR_REGNUM))]
9399 && !SIBLING_CALL_P (insn)
9400 && (GET_CODE (operands[1]) == SYMBOL_REF)
9401 && !arm_is_long_call_p (SYMBOL_REF_DECL (operands[1]))"
9404 return NEED_PLT_RELOC ? \"bl%?\\t%a1(PLT)\" : \"bl%?\\t%a1\";
9406 [(set_attr "type" "call")]
9409 (define_insn "*call_insn"
9410 [(call (mem:SI (match_operand:SI 0 "" ""))
9411 (match_operand:SI 1 "" ""))
9412 (use (match_operand 2 "" ""))
9413 (clobber (reg:SI LR_REGNUM))]
9415 && GET_CODE (operands[0]) == SYMBOL_REF
9416 && !arm_is_long_call_p (SYMBOL_REF_DECL (operands[0]))"
9418 [(set_attr "length" "4")
9419 (set_attr "type" "call")]
9422 (define_insn "*call_value_insn"
9423 [(set (match_operand 0 "" "")
9424 (call (mem:SI (match_operand 1 "" ""))
9425 (match_operand 2 "" "")))
9426 (use (match_operand 3 "" ""))
9427 (clobber (reg:SI LR_REGNUM))]
9429 && GET_CODE (operands[1]) == SYMBOL_REF
9430 && !arm_is_long_call_p (SYMBOL_REF_DECL (operands[1]))"
9432 [(set_attr "length" "4")
9433 (set_attr "type" "call")]
9436 ;; We may also be able to do sibcalls for Thumb, but it's much harder...
9437 (define_expand "sibcall"
9438 [(parallel [(call (match_operand 0 "memory_operand" "")
9439 (match_operand 1 "general_operand" ""))
9441 (use (match_operand 2 "" ""))])]
9445 if (!REG_P (XEXP (operands[0], 0))
9446 && (GET_CODE (XEXP (operands[0], 0)) != SYMBOL_REF))
9447 XEXP (operands[0], 0) = force_reg (SImode, XEXP (operands[0], 0));
9449 if (operands[2] == NULL_RTX)
9450 operands[2] = const0_rtx;
9454 (define_expand "sibcall_value"
9455 [(parallel [(set (match_operand 0 "" "")
9456 (call (match_operand 1 "memory_operand" "")
9457 (match_operand 2 "general_operand" "")))
9459 (use (match_operand 3 "" ""))])]
9463 if (!REG_P (XEXP (operands[1], 0)) &&
9464 (GET_CODE (XEXP (operands[1],0)) != SYMBOL_REF))
9465 XEXP (operands[1], 0) = force_reg (SImode, XEXP (operands[1], 0));
9467 if (operands[3] == NULL_RTX)
9468 operands[3] = const0_rtx;
9472 (define_insn "*sibcall_insn"
9473 [(call (mem:SI (match_operand:SI 0 "call_insn_operand" "Cs, US"))
9474 (match_operand 1 "" ""))
9476 (use (match_operand 2 "" ""))]
9477 "TARGET_32BIT && SIBLING_CALL_P (insn)"
9479 if (which_alternative == 1)
9480 return NEED_PLT_RELOC ? \"b%?\\t%a0(PLT)\" : \"b%?\\t%a0\";
9483 if (arm_arch5 || arm_arch4t)
9484 return \"bx%?\\t%0\\t%@ indirect register sibling call\";
9486 return \"mov%?\\t%|pc, %0\\t%@ indirect register sibling call\";
9489 [(set_attr "type" "call")]
9492 (define_insn "*sibcall_value_insn"
9493 [(set (match_operand 0 "" "")
9494 (call (mem:SI (match_operand:SI 1 "call_insn_operand" "Cs,US"))
9495 (match_operand 2 "" "")))
9497 (use (match_operand 3 "" ""))]
9498 "TARGET_32BIT && SIBLING_CALL_P (insn)"
9500 if (which_alternative == 1)
9501 return NEED_PLT_RELOC ? \"b%?\\t%a1(PLT)\" : \"b%?\\t%a1\";
9504 if (arm_arch5 || arm_arch4t)
9505 return \"bx%?\\t%1\";
9507 return \"mov%?\\t%|pc, %1\\t@ indirect sibling call \";
9510 [(set_attr "type" "call")]
9513 (define_expand "<return_str>return"
9515 "(TARGET_ARM || (TARGET_THUMB2
9516 && ARM_FUNC_TYPE (arm_current_func_type ()) == ARM_FT_NORMAL
9517 && !IS_STACKALIGN (arm_current_func_type ())))
9518 <return_cond_false>"
9523 thumb2_expand_return (<return_simple_p>);
9530 ;; Often the return insn will be the same as loading from memory, so set attr
9531 (define_insn "*arm_return"
9533 "TARGET_ARM && USE_RETURN_INSN (FALSE)"
9536 if (arm_ccfsm_state == 2)
9538 arm_ccfsm_state += 2;
9541 return output_return_instruction (const_true_rtx, true, false, false);
9543 [(set_attr "type" "load1")
9544 (set_attr "length" "12")
9545 (set_attr "predicable" "yes")]
9548 (define_insn "*cond_<return_str>return"
9550 (if_then_else (match_operator 0 "arm_comparison_operator"
9551 [(match_operand 1 "cc_register" "") (const_int 0)])
9554 "TARGET_ARM <return_cond_true>"
9557 if (arm_ccfsm_state == 2)
9559 arm_ccfsm_state += 2;
9562 return output_return_instruction (operands[0], true, false,
9565 [(set_attr "conds" "use")
9566 (set_attr "length" "12")
9567 (set_attr "type" "load1")]
9570 (define_insn "*cond_<return_str>return_inverted"
9572 (if_then_else (match_operator 0 "arm_comparison_operator"
9573 [(match_operand 1 "cc_register" "") (const_int 0)])
9576 "TARGET_ARM <return_cond_true>"
9579 if (arm_ccfsm_state == 2)
9581 arm_ccfsm_state += 2;
9584 return output_return_instruction (operands[0], true, true,
9587 [(set_attr "conds" "use")
9588 (set_attr "length" "12")
9589 (set_attr "type" "load1")]
9592 (define_insn "*arm_simple_return"
9597 if (arm_ccfsm_state == 2)
9599 arm_ccfsm_state += 2;
9602 return output_return_instruction (const_true_rtx, true, false, true);
9604 [(set_attr "type" "branch")
9605 (set_attr "length" "4")
9606 (set_attr "predicable" "yes")]
9609 ;; Generate a sequence of instructions to determine if the processor is
9610 ;; in 26-bit or 32-bit mode, and return the appropriate return address
9613 (define_expand "return_addr_mask"
9615 (compare:CC_NOOV (unspec [(const_int 0)] UNSPEC_CHECK_ARCH)
9617 (set (match_operand:SI 0 "s_register_operand" "")
9618 (if_then_else:SI (eq (match_dup 1) (const_int 0))
9620 (const_int 67108860)))] ; 0x03fffffc
9623 operands[1] = gen_rtx_REG (CC_NOOVmode, CC_REGNUM);
9626 (define_insn "*check_arch2"
9627 [(set (match_operand:CC_NOOV 0 "cc_register" "")
9628 (compare:CC_NOOV (unspec [(const_int 0)] UNSPEC_CHECK_ARCH)
9631 "teq\\t%|r0, %|r0\;teq\\t%|pc, %|pc"
9632 [(set_attr "length" "8")
9633 (set_attr "conds" "set")
9634 (set_attr "type" "multiple")]
9637 ;; Call subroutine returning any type.
9639 (define_expand "untyped_call"
9640 [(parallel [(call (match_operand 0 "" "")
9642 (match_operand 1 "" "")
9643 (match_operand 2 "" "")])]
9648 rtx par = gen_rtx_PARALLEL (VOIDmode,
9649 rtvec_alloc (XVECLEN (operands[2], 0)));
9650 rtx addr = gen_reg_rtx (Pmode);
9654 emit_move_insn (addr, XEXP (operands[1], 0));
9655 mem = change_address (operands[1], BLKmode, addr);
9657 for (i = 0; i < XVECLEN (operands[2], 0); i++)
9659 rtx src = SET_SRC (XVECEXP (operands[2], 0, i));
9661 /* Default code only uses r0 as a return value, but we could
9662 be using anything up to 4 registers. */
9663 if (REGNO (src) == R0_REGNUM)
9664 src = gen_rtx_REG (TImode, R0_REGNUM);
9666 XVECEXP (par, 0, i) = gen_rtx_EXPR_LIST (VOIDmode, src,
9668 size += GET_MODE_SIZE (GET_MODE (src));
9671 emit_call_insn (GEN_CALL_VALUE (par, operands[0], const0_rtx, NULL,
9676 for (i = 0; i < XVECLEN (par, 0); i++)
9678 HOST_WIDE_INT offset = 0;
9679 rtx reg = XEXP (XVECEXP (par, 0, i), 0);
9682 emit_move_insn (addr, plus_constant (Pmode, addr, size));
9684 mem = change_address (mem, GET_MODE (reg), NULL);
9685 if (REGNO (reg) == R0_REGNUM)
9687 /* On thumb we have to use a write-back instruction. */
9688 emit_insn (arm_gen_store_multiple (arm_regs_in_sequence, 4, addr,
9689 TARGET_THUMB ? TRUE : FALSE, mem, &offset));
9690 size = TARGET_ARM ? 16 : 0;
9694 emit_move_insn (mem, reg);
9695 size = GET_MODE_SIZE (GET_MODE (reg));
9699 /* The optimizer does not know that the call sets the function value
9700 registers we stored in the result block. We avoid problems by
9701 claiming that all hard registers are used and clobbered at this
9703 emit_insn (gen_blockage ());
9709 (define_expand "untyped_return"
9710 [(match_operand:BLK 0 "memory_operand" "")
9711 (match_operand 1 "" "")]
9716 rtx addr = gen_reg_rtx (Pmode);
9720 emit_move_insn (addr, XEXP (operands[0], 0));
9721 mem = change_address (operands[0], BLKmode, addr);
9723 for (i = 0; i < XVECLEN (operands[1], 0); i++)
9725 HOST_WIDE_INT offset = 0;
9726 rtx reg = SET_DEST (XVECEXP (operands[1], 0, i));
9729 emit_move_insn (addr, plus_constant (Pmode, addr, size));
9731 mem = change_address (mem, GET_MODE (reg), NULL);
9732 if (REGNO (reg) == R0_REGNUM)
9734 /* On thumb we have to use a write-back instruction. */
9735 emit_insn (arm_gen_load_multiple (arm_regs_in_sequence, 4, addr,
9736 TARGET_THUMB ? TRUE : FALSE, mem, &offset));
9737 size = TARGET_ARM ? 16 : 0;
9741 emit_move_insn (reg, mem);
9742 size = GET_MODE_SIZE (GET_MODE (reg));
9746 /* Emit USE insns before the return. */
9747 for (i = 0; i < XVECLEN (operands[1], 0); i++)
9748 emit_use (SET_DEST (XVECEXP (operands[1], 0, i)));
9750 /* Construct the return. */
9751 expand_naked_return ();
9757 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
9758 ;; all of memory. This blocks insns from being moved across this point.
9760 (define_insn "blockage"
9761 [(unspec_volatile [(const_int 0)] VUNSPEC_BLOCKAGE)]
9764 [(set_attr "length" "0")
9765 (set_attr "type" "block")]
9768 (define_expand "casesi"
9769 [(match_operand:SI 0 "s_register_operand" "") ; index to jump on
9770 (match_operand:SI 1 "const_int_operand" "") ; lower bound
9771 (match_operand:SI 2 "const_int_operand" "") ; total range
9772 (match_operand:SI 3 "" "") ; table label
9773 (match_operand:SI 4 "" "")] ; Out of range label
9774 "TARGET_32BIT || optimize_size || flag_pic"
9777 enum insn_code code;
9778 if (operands[1] != const0_rtx)
9780 rtx reg = gen_reg_rtx (SImode);
9782 emit_insn (gen_addsi3 (reg, operands[0],
9783 gen_int_mode (-INTVAL (operands[1]),
9789 code = CODE_FOR_arm_casesi_internal;
9790 else if (TARGET_THUMB1)
9791 code = CODE_FOR_thumb1_casesi_internal_pic;
9793 code = CODE_FOR_thumb2_casesi_internal_pic;
9795 code = CODE_FOR_thumb2_casesi_internal;
9797 if (!insn_data[(int) code].operand[1].predicate(operands[2], SImode))
9798 operands[2] = force_reg (SImode, operands[2]);
9800 emit_jump_insn (GEN_FCN ((int) code) (operands[0], operands[2],
9801 operands[3], operands[4]));
9806 ;; The USE in this pattern is needed to tell flow analysis that this is
9807 ;; a CASESI insn. It has no other purpose.
9808 (define_insn "arm_casesi_internal"
9809 [(parallel [(set (pc)
9811 (leu (match_operand:SI 0 "s_register_operand" "r")
9812 (match_operand:SI 1 "arm_rhs_operand" "rI"))
9813 (mem:SI (plus:SI (mult:SI (match_dup 0) (const_int 4))
9814 (label_ref (match_operand 2 "" ""))))
9815 (label_ref (match_operand 3 "" ""))))
9816 (clobber (reg:CC CC_REGNUM))
9817 (use (label_ref (match_dup 2)))])]
9821 return \"cmp\\t%0, %1\;addls\\t%|pc, %|pc, %0, asl #2\;b\\t%l3\";
9822 return \"cmp\\t%0, %1\;ldrls\\t%|pc, [%|pc, %0, asl #2]\;b\\t%l3\";
9824 [(set_attr "conds" "clob")
9825 (set_attr "length" "12")
9826 (set_attr "type" "multiple")]
9829 (define_expand "thumb1_casesi_internal_pic"
9830 [(match_operand:SI 0 "s_register_operand" "")
9831 (match_operand:SI 1 "thumb1_cmp_operand" "")
9832 (match_operand 2 "" "")
9833 (match_operand 3 "" "")]
9837 rtx test = gen_rtx_GTU (VOIDmode, operands[0], operands[1]);
9838 emit_jump_insn (gen_cbranchsi4 (test, operands[0], operands[1],
9840 reg0 = gen_rtx_REG (SImode, 0);
9841 emit_move_insn (reg0, operands[0]);
9842 emit_jump_insn (gen_thumb1_casesi_dispatch (operands[2]/*, operands[3]*/));
9847 (define_insn "thumb1_casesi_dispatch"
9848 [(parallel [(set (pc) (unspec [(reg:SI 0)
9849 (label_ref (match_operand 0 "" ""))
9850 ;; (label_ref (match_operand 1 "" ""))
9852 UNSPEC_THUMB1_CASESI))
9853 (clobber (reg:SI IP_REGNUM))
9854 (clobber (reg:SI LR_REGNUM))])]
9856 "* return thumb1_output_casesi(operands);"
9857 [(set_attr "length" "4")
9858 (set_attr "type" "multiple")]
9861 (define_expand "indirect_jump"
9863 (match_operand:SI 0 "s_register_operand" ""))]
9866 /* Thumb-2 doesn't have mov pc, reg. Explicitly set the low bit of the
9867 address and use bx. */
9871 tmp = gen_reg_rtx (SImode);
9872 emit_insn (gen_iorsi3 (tmp, operands[0], GEN_INT(1)));
9878 ;; NB Never uses BX.
9879 (define_insn "*arm_indirect_jump"
9881 (match_operand:SI 0 "s_register_operand" "r"))]
9883 "mov%?\\t%|pc, %0\\t%@ indirect register jump"
9884 [(set_attr "predicable" "yes")
9885 (set_attr "type" "branch")]
9888 (define_insn "*load_indirect_jump"
9890 (match_operand:SI 0 "memory_operand" "m"))]
9892 "ldr%?\\t%|pc, %0\\t%@ indirect memory jump"
9893 [(set_attr "type" "load1")
9894 (set_attr "pool_range" "4096")
9895 (set_attr "neg_pool_range" "4084")
9896 (set_attr "predicable" "yes")]
9899 ;; NB Never uses BX.
9900 (define_insn "*thumb1_indirect_jump"
9902 (match_operand:SI 0 "register_operand" "l*r"))]
9905 [(set_attr "conds" "clob")
9906 (set_attr "length" "2")
9907 (set_attr "type" "branch")]
9917 if (TARGET_UNIFIED_ASM)
9920 return \"mov%?\\t%|r0, %|r0\\t%@ nop\";
9921 return \"mov\\tr8, r8\";
9923 [(set (attr "length")
9924 (if_then_else (eq_attr "is_thumb" "yes")
9927 (set_attr "type" "mov_reg")]
9931 [(trap_if (const_int 1) (const_int 0))]
9935 return \".inst\\t0xe7f000f0\";
9937 return \".inst\\t0xdeff\";
9939 [(set (attr "length")
9940 (if_then_else (eq_attr "is_thumb" "yes")
9943 (set_attr "type" "trap")
9944 (set_attr "conds" "unconditional")]
9948 ;; Patterns to allow combination of arithmetic, cond code and shifts
9950 (define_insn "*arith_shiftsi"
9951 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r")
9952 (match_operator:SI 1 "shiftable_operator"
9953 [(match_operator:SI 3 "shift_operator"
9954 [(match_operand:SI 4 "s_register_operand" "r,r,r,r")
9955 (match_operand:SI 5 "shift_amount_operand" "M,M,M,r")])
9956 (match_operand:SI 2 "s_register_operand" "rk,rk,r,rk")]))]
9958 "%i1%?\\t%0, %2, %4%S3"
9959 [(set_attr "predicable" "yes")
9960 (set_attr "shift" "4")
9961 (set_attr "arch" "a,t2,t2,a")
9962 ;; Thumb2 doesn't allow the stack pointer to be used for
9963 ;; operand1 for all operations other than add and sub. In this case
9964 ;; the minus operation is a candidate for an rsub and hence needs
9966 ;; We have to make sure to disable the fourth alternative if
9967 ;; the shift_operator is MULT, since otherwise the insn will
9968 ;; also match a multiply_accumulate pattern and validate_change
9969 ;; will allow a replacement of the constant with a register
9970 ;; despite the checks done in shift_operator.
9971 (set_attr_alternative "insn_enabled"
9972 [(const_string "yes")
9974 (match_operand:SI 1 "add_operator" "")
9975 (const_string "yes") (const_string "no"))
9976 (const_string "yes")
9978 (match_operand:SI 3 "mult_operator" "")
9979 (const_string "no") (const_string "yes"))])
9980 (set_attr "type" "alu_shift_imm,alu_shift_imm,alu_shift_imm,alu_shift_reg")])
9983 [(set (match_operand:SI 0 "s_register_operand" "")
9984 (match_operator:SI 1 "shiftable_operator"
9985 [(match_operator:SI 2 "shiftable_operator"
9986 [(match_operator:SI 3 "shift_operator"
9987 [(match_operand:SI 4 "s_register_operand" "")
9988 (match_operand:SI 5 "reg_or_int_operand" "")])
9989 (match_operand:SI 6 "s_register_operand" "")])
9990 (match_operand:SI 7 "arm_rhs_operand" "")]))
9991 (clobber (match_operand:SI 8 "s_register_operand" ""))]
9994 (match_op_dup 2 [(match_op_dup 3 [(match_dup 4) (match_dup 5)])
9997 (match_op_dup 1 [(match_dup 8) (match_dup 7)]))]
10000 (define_insn "*arith_shiftsi_compare0"
10001 [(set (reg:CC_NOOV CC_REGNUM)
10003 (match_operator:SI 1 "shiftable_operator"
10004 [(match_operator:SI 3 "shift_operator"
10005 [(match_operand:SI 4 "s_register_operand" "r,r")
10006 (match_operand:SI 5 "shift_amount_operand" "M,r")])
10007 (match_operand:SI 2 "s_register_operand" "r,r")])
10009 (set (match_operand:SI 0 "s_register_operand" "=r,r")
10010 (match_op_dup 1 [(match_op_dup 3 [(match_dup 4) (match_dup 5)])
10013 "%i1%.\\t%0, %2, %4%S3"
10014 [(set_attr "conds" "set")
10015 (set_attr "shift" "4")
10016 (set_attr "arch" "32,a")
10017 (set_attr "type" "alus_shift_imm,alus_shift_reg")])
10019 (define_insn "*arith_shiftsi_compare0_scratch"
10020 [(set (reg:CC_NOOV CC_REGNUM)
10022 (match_operator:SI 1 "shiftable_operator"
10023 [(match_operator:SI 3 "shift_operator"
10024 [(match_operand:SI 4 "s_register_operand" "r,r")
10025 (match_operand:SI 5 "shift_amount_operand" "M,r")])
10026 (match_operand:SI 2 "s_register_operand" "r,r")])
10028 (clobber (match_scratch:SI 0 "=r,r"))]
10030 "%i1%.\\t%0, %2, %4%S3"
10031 [(set_attr "conds" "set")
10032 (set_attr "shift" "4")
10033 (set_attr "arch" "32,a")
10034 (set_attr "type" "alus_shift_imm,alus_shift_reg")])
10036 (define_insn "*sub_shiftsi"
10037 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10038 (minus:SI (match_operand:SI 1 "s_register_operand" "r,r")
10039 (match_operator:SI 2 "shift_operator"
10040 [(match_operand:SI 3 "s_register_operand" "r,r")
10041 (match_operand:SI 4 "shift_amount_operand" "M,r")])))]
10043 "sub%?\\t%0, %1, %3%S2"
10044 [(set_attr "predicable" "yes")
10045 (set_attr "shift" "3")
10046 (set_attr "arch" "32,a")
10047 (set_attr "type" "alus_shift_imm,alus_shift_reg")])
10049 (define_insn "*sub_shiftsi_compare0"
10050 [(set (reg:CC_NOOV CC_REGNUM)
10052 (minus:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
10053 (match_operator:SI 2 "shift_operator"
10054 [(match_operand:SI 3 "s_register_operand" "r,r,r")
10055 (match_operand:SI 4 "shift_amount_operand" "M,r,M")]))
10057 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
10058 (minus:SI (match_dup 1)
10059 (match_op_dup 2 [(match_dup 3) (match_dup 4)])))]
10061 "sub%.\\t%0, %1, %3%S2"
10062 [(set_attr "conds" "set")
10063 (set_attr "shift" "3")
10064 (set_attr "arch" "32,a,a")
10065 (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")])
10067 (define_insn "*sub_shiftsi_compare0_scratch"
10068 [(set (reg:CC_NOOV CC_REGNUM)
10070 (minus:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
10071 (match_operator:SI 2 "shift_operator"
10072 [(match_operand:SI 3 "s_register_operand" "r,r,r")
10073 (match_operand:SI 4 "shift_amount_operand" "M,r,M")]))
10075 (clobber (match_scratch:SI 0 "=r,r,r"))]
10077 "sub%.\\t%0, %1, %3%S2"
10078 [(set_attr "conds" "set")
10079 (set_attr "shift" "3")
10080 (set_attr "arch" "32,a,a")
10081 (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")])
10084 (define_insn_and_split "*and_scc"
10085 [(set (match_operand:SI 0 "s_register_operand" "=r")
10086 (and:SI (match_operator:SI 1 "arm_comparison_operator"
10087 [(match_operand 2 "cc_register" "") (const_int 0)])
10088 (match_operand:SI 3 "s_register_operand" "r")))]
10090 "#" ; "mov%D1\\t%0, #0\;and%d1\\t%0, %3, #1"
10091 "&& reload_completed"
10092 [(cond_exec (match_dup 5) (set (match_dup 0) (const_int 0)))
10093 (cond_exec (match_dup 4) (set (match_dup 0)
10094 (and:SI (match_dup 3) (const_int 1))))]
10096 enum machine_mode mode = GET_MODE (operands[2]);
10097 enum rtx_code rc = GET_CODE (operands[1]);
10099 /* Note that operands[4] is the same as operands[1],
10100 but with VOIDmode as the result. */
10101 operands[4] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
10102 if (mode == CCFPmode || mode == CCFPEmode)
10103 rc = reverse_condition_maybe_unordered (rc);
10105 rc = reverse_condition (rc);
10106 operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
10108 [(set_attr "conds" "use")
10109 (set_attr "type" "multiple")
10110 (set_attr "length" "8")]
10113 (define_insn_and_split "*ior_scc"
10114 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10115 (ior:SI (match_operator:SI 1 "arm_comparison_operator"
10116 [(match_operand 2 "cc_register" "") (const_int 0)])
10117 (match_operand:SI 3 "s_register_operand" "0,?r")))]
10120 orr%d1\\t%0, %3, #1
10122 "&& reload_completed
10123 && REGNO (operands [0]) != REGNO (operands[3])"
10124 ;; && which_alternative == 1
10125 ; mov%D1\\t%0, %3\;orr%d1\\t%0, %3, #1
10126 [(cond_exec (match_dup 5) (set (match_dup 0) (match_dup 3)))
10127 (cond_exec (match_dup 4) (set (match_dup 0)
10128 (ior:SI (match_dup 3) (const_int 1))))]
10130 enum machine_mode mode = GET_MODE (operands[2]);
10131 enum rtx_code rc = GET_CODE (operands[1]);
10133 /* Note that operands[4] is the same as operands[1],
10134 but with VOIDmode as the result. */
10135 operands[4] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
10136 if (mode == CCFPmode || mode == CCFPEmode)
10137 rc = reverse_condition_maybe_unordered (rc);
10139 rc = reverse_condition (rc);
10140 operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
10142 [(set_attr "conds" "use")
10143 (set_attr "length" "4,8")
10144 (set_attr "type" "logic_imm,multiple")]
10147 ; A series of splitters for the compare_scc pattern below. Note that
10148 ; order is important.
10150 [(set (match_operand:SI 0 "s_register_operand" "")
10151 (lt:SI (match_operand:SI 1 "s_register_operand" "")
10153 (clobber (reg:CC CC_REGNUM))]
10154 "TARGET_32BIT && reload_completed"
10155 [(set (match_dup 0) (lshiftrt:SI (match_dup 1) (const_int 31)))])
10158 [(set (match_operand:SI 0 "s_register_operand" "")
10159 (ge:SI (match_operand:SI 1 "s_register_operand" "")
10161 (clobber (reg:CC CC_REGNUM))]
10162 "TARGET_32BIT && reload_completed"
10163 [(set (match_dup 0) (not:SI (match_dup 1)))
10164 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 31)))])
10167 [(set (match_operand:SI 0 "s_register_operand" "")
10168 (eq:SI (match_operand:SI 1 "s_register_operand" "")
10170 (clobber (reg:CC CC_REGNUM))]
10171 "arm_arch5 && TARGET_32BIT"
10172 [(set (match_dup 0) (clz:SI (match_dup 1)))
10173 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 5)))]
10177 [(set (match_operand:SI 0 "s_register_operand" "")
10178 (eq:SI (match_operand:SI 1 "s_register_operand" "")
10180 (clobber (reg:CC CC_REGNUM))]
10181 "TARGET_32BIT && reload_completed"
10183 [(set (reg:CC CC_REGNUM)
10184 (compare:CC (const_int 1) (match_dup 1)))
10186 (minus:SI (const_int 1) (match_dup 1)))])
10187 (cond_exec (ltu:CC (reg:CC CC_REGNUM) (const_int 0))
10188 (set (match_dup 0) (const_int 0)))])
10191 [(set (match_operand:SI 0 "s_register_operand" "")
10192 (ne:SI (match_operand:SI 1 "s_register_operand" "")
10193 (match_operand:SI 2 "const_int_operand" "")))
10194 (clobber (reg:CC CC_REGNUM))]
10195 "TARGET_32BIT && reload_completed"
10197 [(set (reg:CC CC_REGNUM)
10198 (compare:CC (match_dup 1) (match_dup 2)))
10199 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 3)))])
10200 (cond_exec (ne:CC (reg:CC CC_REGNUM) (const_int 0))
10201 (set (match_dup 0) (const_int 1)))]
10203 operands[3] = GEN_INT (-INTVAL (operands[2]));
10207 [(set (match_operand:SI 0 "s_register_operand" "")
10208 (ne:SI (match_operand:SI 1 "s_register_operand" "")
10209 (match_operand:SI 2 "arm_add_operand" "")))
10210 (clobber (reg:CC CC_REGNUM))]
10211 "TARGET_32BIT && reload_completed"
10213 [(set (reg:CC_NOOV CC_REGNUM)
10214 (compare:CC_NOOV (minus:SI (match_dup 1) (match_dup 2))
10216 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
10217 (cond_exec (ne:CC_NOOV (reg:CC_NOOV CC_REGNUM) (const_int 0))
10218 (set (match_dup 0) (const_int 1)))])
10220 (define_insn_and_split "*compare_scc"
10221 [(set (match_operand:SI 0 "s_register_operand" "=Ts,Ts")
10222 (match_operator:SI 1 "arm_comparison_operator"
10223 [(match_operand:SI 2 "s_register_operand" "r,r")
10224 (match_operand:SI 3 "arm_add_operand" "rI,L")]))
10225 (clobber (reg:CC CC_REGNUM))]
10228 "&& reload_completed"
10229 [(set (reg:CC CC_REGNUM) (compare:CC (match_dup 2) (match_dup 3)))
10230 (cond_exec (match_dup 4) (set (match_dup 0) (const_int 0)))
10231 (cond_exec (match_dup 5) (set (match_dup 0) (const_int 1)))]
10234 enum machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
10235 operands[2], operands[3]);
10236 enum rtx_code rc = GET_CODE (operands[1]);
10238 tmp1 = gen_rtx_REG (mode, CC_REGNUM);
10240 operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, tmp1, const0_rtx);
10241 if (mode == CCFPmode || mode == CCFPEmode)
10242 rc = reverse_condition_maybe_unordered (rc);
10244 rc = reverse_condition (rc);
10245 operands[4] = gen_rtx_fmt_ee (rc, VOIDmode, tmp1, const0_rtx);
10247 [(set_attr "type" "multiple")]
10250 ;; Attempt to improve the sequence generated by the compare_scc splitters
10251 ;; not to use conditional execution.
10253 ;; Rd = (eq (reg1) (const_int0)) // ARMv5
10257 [(set (reg:CC CC_REGNUM)
10258 (compare:CC (match_operand:SI 1 "register_operand" "")
10260 (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
10261 (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
10262 (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
10263 (set (match_dup 0) (const_int 1)))]
10264 "arm_arch5 && TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)"
10265 [(set (match_dup 0) (clz:SI (match_dup 1)))
10266 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 5)))]
10269 ;; Rd = (eq (reg1) (const_int0)) // !ARMv5
10271 ;; adc Rd, Rd, reg1
10273 [(set (reg:CC CC_REGNUM)
10274 (compare:CC (match_operand:SI 1 "register_operand" "")
10276 (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
10277 (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
10278 (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
10279 (set (match_dup 0) (const_int 1)))
10280 (match_scratch:SI 2 "r")]
10281 "TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)"
10283 [(set (reg:CC CC_REGNUM)
10284 (compare:CC (const_int 0) (match_dup 1)))
10285 (set (match_dup 2) (minus:SI (const_int 0) (match_dup 1)))])
10287 (plus:SI (plus:SI (match_dup 1) (match_dup 2))
10288 (geu:SI (reg:CC CC_REGNUM) (const_int 0))))]
10291 ;; Rd = (eq (reg1) (reg2/imm)) // ARMv5 and optimising for speed.
10292 ;; sub Rd, Reg1, reg2
10296 [(set (reg:CC CC_REGNUM)
10297 (compare:CC (match_operand:SI 1 "register_operand" "")
10298 (match_operand:SI 2 "arm_rhs_operand" "")))
10299 (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
10300 (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
10301 (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
10302 (set (match_dup 0) (const_int 1)))]
10303 "arm_arch5 && TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)
10304 && !(TARGET_THUMB2 && optimize_insn_for_size_p ())"
10305 [(set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))
10306 (set (match_dup 0) (clz:SI (match_dup 0)))
10307 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 5)))]
10311 ;; Rd = (eq (reg1) (reg2)) // ! ARMv5 or optimising for size.
10312 ;; sub T1, Reg1, reg2
10316 [(set (reg:CC CC_REGNUM)
10317 (compare:CC (match_operand:SI 1 "register_operand" "")
10318 (match_operand:SI 2 "arm_rhs_operand" "")))
10319 (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
10320 (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
10321 (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
10322 (set (match_dup 0) (const_int 1)))
10323 (match_scratch:SI 3 "r")]
10324 "TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)"
10325 [(set (match_dup 3) (match_dup 4))
10327 [(set (reg:CC CC_REGNUM)
10328 (compare:CC (const_int 0) (match_dup 3)))
10329 (set (match_dup 0) (minus:SI (const_int 0) (match_dup 3)))])
10331 (plus:SI (plus:SI (match_dup 0) (match_dup 3))
10332 (geu:SI (reg:CC CC_REGNUM) (const_int 0))))]
10334 if (CONST_INT_P (operands[2]))
10335 operands[4] = plus_constant (SImode, operands[1], -INTVAL (operands[2]));
10337 operands[4] = gen_rtx_MINUS (SImode, operands[1], operands[2]);
10340 (define_insn "*cond_move"
10341 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
10342 (if_then_else:SI (match_operator 3 "equality_operator"
10343 [(match_operator 4 "arm_comparison_operator"
10344 [(match_operand 5 "cc_register" "") (const_int 0)])
10346 (match_operand:SI 1 "arm_rhs_operand" "0,rI,?rI")
10347 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))]
10350 if (GET_CODE (operands[3]) == NE)
10352 if (which_alternative != 1)
10353 output_asm_insn (\"mov%D4\\t%0, %2\", operands);
10354 if (which_alternative != 0)
10355 output_asm_insn (\"mov%d4\\t%0, %1\", operands);
10358 if (which_alternative != 0)
10359 output_asm_insn (\"mov%D4\\t%0, %1\", operands);
10360 if (which_alternative != 1)
10361 output_asm_insn (\"mov%d4\\t%0, %2\", operands);
10364 [(set_attr "conds" "use")
10365 (set_attr "type" "mov_reg,mov_reg,multiple")
10366 (set_attr "length" "4,4,8")]
10369 (define_insn "*cond_arith"
10370 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10371 (match_operator:SI 5 "shiftable_operator"
10372 [(match_operator:SI 4 "arm_comparison_operator"
10373 [(match_operand:SI 2 "s_register_operand" "r,r")
10374 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
10375 (match_operand:SI 1 "s_register_operand" "0,?r")]))
10376 (clobber (reg:CC CC_REGNUM))]
10379 if (GET_CODE (operands[4]) == LT && operands[3] == const0_rtx)
10380 return \"%i5\\t%0, %1, %2, lsr #31\";
10382 output_asm_insn (\"cmp\\t%2, %3\", operands);
10383 if (GET_CODE (operands[5]) == AND)
10384 output_asm_insn (\"mov%D4\\t%0, #0\", operands);
10385 else if (GET_CODE (operands[5]) == MINUS)
10386 output_asm_insn (\"rsb%D4\\t%0, %1, #0\", operands);
10387 else if (which_alternative != 0)
10388 output_asm_insn (\"mov%D4\\t%0, %1\", operands);
10389 return \"%i5%d4\\t%0, %1, #1\";
10391 [(set_attr "conds" "clob")
10392 (set_attr "length" "12")
10393 (set_attr "type" "multiple")]
10396 (define_insn "*cond_sub"
10397 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10398 (minus:SI (match_operand:SI 1 "s_register_operand" "0,?r")
10399 (match_operator:SI 4 "arm_comparison_operator"
10400 [(match_operand:SI 2 "s_register_operand" "r,r")
10401 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))
10402 (clobber (reg:CC CC_REGNUM))]
10405 output_asm_insn (\"cmp\\t%2, %3\", operands);
10406 if (which_alternative != 0)
10407 output_asm_insn (\"mov%D4\\t%0, %1\", operands);
10408 return \"sub%d4\\t%0, %1, #1\";
10410 [(set_attr "conds" "clob")
10411 (set_attr "length" "8,12")
10412 (set_attr "type" "multiple")]
10415 (define_insn "*cmp_ite0"
10416 [(set (match_operand 6 "dominant_cc_register" "")
10419 (match_operator 4 "arm_comparison_operator"
10420 [(match_operand:SI 0 "s_register_operand"
10421 "l,l,l,r,r,r,r,r,r")
10422 (match_operand:SI 1 "arm_add_operand"
10423 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
10424 (match_operator:SI 5 "arm_comparison_operator"
10425 [(match_operand:SI 2 "s_register_operand"
10426 "l,r,r,l,l,r,r,r,r")
10427 (match_operand:SI 3 "arm_add_operand"
10428 "lPy,rI,L,lPy,lPy,rI,rI,L,L")])
10434 static const char * const cmp1[NUM_OF_COND_CMP][2] =
10436 {\"cmp%d5\\t%0, %1\",
10437 \"cmp%d4\\t%2, %3\"},
10438 {\"cmn%d5\\t%0, #%n1\",
10439 \"cmp%d4\\t%2, %3\"},
10440 {\"cmp%d5\\t%0, %1\",
10441 \"cmn%d4\\t%2, #%n3\"},
10442 {\"cmn%d5\\t%0, #%n1\",
10443 \"cmn%d4\\t%2, #%n3\"}
10445 static const char * const cmp2[NUM_OF_COND_CMP][2] =
10450 \"cmn\\t%0, #%n1\"},
10451 {\"cmn\\t%2, #%n3\",
10453 {\"cmn\\t%2, #%n3\",
10454 \"cmn\\t%0, #%n1\"}
10456 static const char * const ite[2] =
10461 static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
10462 CMP_CMP, CMN_CMP, CMP_CMP,
10463 CMN_CMP, CMP_CMN, CMN_CMN};
10465 comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4]));
10467 output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
10468 if (TARGET_THUMB2) {
10469 output_asm_insn (ite[swap], operands);
10471 output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
10474 [(set_attr "conds" "set")
10475 (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
10476 (set_attr "type" "multiple")
10477 (set_attr_alternative "length"
10483 (if_then_else (eq_attr "is_thumb" "no")
10486 (if_then_else (eq_attr "is_thumb" "no")
10489 (if_then_else (eq_attr "is_thumb" "no")
10492 (if_then_else (eq_attr "is_thumb" "no")
10497 (define_insn "*cmp_ite1"
10498 [(set (match_operand 6 "dominant_cc_register" "")
10501 (match_operator 4 "arm_comparison_operator"
10502 [(match_operand:SI 0 "s_register_operand"
10503 "l,l,l,r,r,r,r,r,r")
10504 (match_operand:SI 1 "arm_add_operand"
10505 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
10506 (match_operator:SI 5 "arm_comparison_operator"
10507 [(match_operand:SI 2 "s_register_operand"
10508 "l,r,r,l,l,r,r,r,r")
10509 (match_operand:SI 3 "arm_add_operand"
10510 "lPy,rI,L,lPy,lPy,rI,rI,L,L")])
10516 static const char * const cmp1[NUM_OF_COND_CMP][2] =
10520 {\"cmn\\t%0, #%n1\",
10523 \"cmn\\t%2, #%n3\"},
10524 {\"cmn\\t%0, #%n1\",
10525 \"cmn\\t%2, #%n3\"}
10527 static const char * const cmp2[NUM_OF_COND_CMP][2] =
10529 {\"cmp%d4\\t%2, %3\",
10530 \"cmp%D5\\t%0, %1\"},
10531 {\"cmp%d4\\t%2, %3\",
10532 \"cmn%D5\\t%0, #%n1\"},
10533 {\"cmn%d4\\t%2, #%n3\",
10534 \"cmp%D5\\t%0, %1\"},
10535 {\"cmn%d4\\t%2, #%n3\",
10536 \"cmn%D5\\t%0, #%n1\"}
10538 static const char * const ite[2] =
10543 static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
10544 CMP_CMP, CMN_CMP, CMP_CMP,
10545 CMN_CMP, CMP_CMN, CMN_CMN};
10547 comparison_dominates_p (GET_CODE (operands[5]),
10548 reverse_condition (GET_CODE (operands[4])));
10550 output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
10551 if (TARGET_THUMB2) {
10552 output_asm_insn (ite[swap], operands);
10554 output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
10557 [(set_attr "conds" "set")
10558 (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
10559 (set_attr_alternative "length"
10565 (if_then_else (eq_attr "is_thumb" "no")
10568 (if_then_else (eq_attr "is_thumb" "no")
10571 (if_then_else (eq_attr "is_thumb" "no")
10574 (if_then_else (eq_attr "is_thumb" "no")
10577 (set_attr "type" "multiple")]
10580 (define_insn "*cmp_and"
10581 [(set (match_operand 6 "dominant_cc_register" "")
10584 (match_operator 4 "arm_comparison_operator"
10585 [(match_operand:SI 0 "s_register_operand"
10586 "l,l,l,r,r,r,r,r,r")
10587 (match_operand:SI 1 "arm_add_operand"
10588 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
10589 (match_operator:SI 5 "arm_comparison_operator"
10590 [(match_operand:SI 2 "s_register_operand"
10591 "l,r,r,l,l,r,r,r,r")
10592 (match_operand:SI 3 "arm_add_operand"
10593 "lPy,rI,L,lPy,lPy,rI,rI,L,L")]))
10598 static const char *const cmp1[NUM_OF_COND_CMP][2] =
10600 {\"cmp%d5\\t%0, %1\",
10601 \"cmp%d4\\t%2, %3\"},
10602 {\"cmn%d5\\t%0, #%n1\",
10603 \"cmp%d4\\t%2, %3\"},
10604 {\"cmp%d5\\t%0, %1\",
10605 \"cmn%d4\\t%2, #%n3\"},
10606 {\"cmn%d5\\t%0, #%n1\",
10607 \"cmn%d4\\t%2, #%n3\"}
10609 static const char *const cmp2[NUM_OF_COND_CMP][2] =
10614 \"cmn\\t%0, #%n1\"},
10615 {\"cmn\\t%2, #%n3\",
10617 {\"cmn\\t%2, #%n3\",
10618 \"cmn\\t%0, #%n1\"}
10620 static const char *const ite[2] =
10625 static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
10626 CMP_CMP, CMN_CMP, CMP_CMP,
10627 CMN_CMP, CMP_CMN, CMN_CMN};
10629 comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4]));
10631 output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
10632 if (TARGET_THUMB2) {
10633 output_asm_insn (ite[swap], operands);
10635 output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
10638 [(set_attr "conds" "set")
10639 (set_attr "predicable" "no")
10640 (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
10641 (set_attr_alternative "length"
10647 (if_then_else (eq_attr "is_thumb" "no")
10650 (if_then_else (eq_attr "is_thumb" "no")
10653 (if_then_else (eq_attr "is_thumb" "no")
10656 (if_then_else (eq_attr "is_thumb" "no")
10659 (set_attr "type" "multiple")]
10662 (define_insn "*cmp_ior"
10663 [(set (match_operand 6 "dominant_cc_register" "")
10666 (match_operator 4 "arm_comparison_operator"
10667 [(match_operand:SI 0 "s_register_operand"
10668 "l,l,l,r,r,r,r,r,r")
10669 (match_operand:SI 1 "arm_add_operand"
10670 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
10671 (match_operator:SI 5 "arm_comparison_operator"
10672 [(match_operand:SI 2 "s_register_operand"
10673 "l,r,r,l,l,r,r,r,r")
10674 (match_operand:SI 3 "arm_add_operand"
10675 "lPy,rI,L,lPy,lPy,rI,rI,L,L")]))
10680 static const char *const cmp1[NUM_OF_COND_CMP][2] =
10684 {\"cmn\\t%0, #%n1\",
10687 \"cmn\\t%2, #%n3\"},
10688 {\"cmn\\t%0, #%n1\",
10689 \"cmn\\t%2, #%n3\"}
10691 static const char *const cmp2[NUM_OF_COND_CMP][2] =
10693 {\"cmp%D4\\t%2, %3\",
10694 \"cmp%D5\\t%0, %1\"},
10695 {\"cmp%D4\\t%2, %3\",
10696 \"cmn%D5\\t%0, #%n1\"},
10697 {\"cmn%D4\\t%2, #%n3\",
10698 \"cmp%D5\\t%0, %1\"},
10699 {\"cmn%D4\\t%2, #%n3\",
10700 \"cmn%D5\\t%0, #%n1\"}
10702 static const char *const ite[2] =
10707 static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
10708 CMP_CMP, CMN_CMP, CMP_CMP,
10709 CMN_CMP, CMP_CMN, CMN_CMN};
10711 comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4]));
10713 output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
10714 if (TARGET_THUMB2) {
10715 output_asm_insn (ite[swap], operands);
10717 output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
10721 [(set_attr "conds" "set")
10722 (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
10723 (set_attr_alternative "length"
10729 (if_then_else (eq_attr "is_thumb" "no")
10732 (if_then_else (eq_attr "is_thumb" "no")
10735 (if_then_else (eq_attr "is_thumb" "no")
10738 (if_then_else (eq_attr "is_thumb" "no")
10741 (set_attr "type" "multiple")]
10744 (define_insn_and_split "*ior_scc_scc"
10745 [(set (match_operand:SI 0 "s_register_operand" "=Ts")
10746 (ior:SI (match_operator:SI 3 "arm_comparison_operator"
10747 [(match_operand:SI 1 "s_register_operand" "r")
10748 (match_operand:SI 2 "arm_add_operand" "rIL")])
10749 (match_operator:SI 6 "arm_comparison_operator"
10750 [(match_operand:SI 4 "s_register_operand" "r")
10751 (match_operand:SI 5 "arm_add_operand" "rIL")])))
10752 (clobber (reg:CC CC_REGNUM))]
10754 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_OR_Y)
10757 "TARGET_32BIT && reload_completed"
10758 [(set (match_dup 7)
10761 (match_op_dup 3 [(match_dup 1) (match_dup 2)])
10762 (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
10764 (set (match_dup 0) (ne:SI (match_dup 7) (const_int 0)))]
10766 = gen_rtx_REG (arm_select_dominance_cc_mode (operands[3], operands[6],
10769 [(set_attr "conds" "clob")
10770 (set_attr "length" "16")
10771 (set_attr "type" "multiple")]
10774 ; If the above pattern is followed by a CMP insn, then the compare is
10775 ; redundant, since we can rework the conditional instruction that follows.
10776 (define_insn_and_split "*ior_scc_scc_cmp"
10777 [(set (match_operand 0 "dominant_cc_register" "")
10778 (compare (ior:SI (match_operator:SI 3 "arm_comparison_operator"
10779 [(match_operand:SI 1 "s_register_operand" "r")
10780 (match_operand:SI 2 "arm_add_operand" "rIL")])
10781 (match_operator:SI 6 "arm_comparison_operator"
10782 [(match_operand:SI 4 "s_register_operand" "r")
10783 (match_operand:SI 5 "arm_add_operand" "rIL")]))
10785 (set (match_operand:SI 7 "s_register_operand" "=Ts")
10786 (ior:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)])
10787 (match_op_dup 6 [(match_dup 4) (match_dup 5)])))]
10790 "TARGET_32BIT && reload_completed"
10791 [(set (match_dup 0)
10794 (match_op_dup 3 [(match_dup 1) (match_dup 2)])
10795 (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
10797 (set (match_dup 7) (ne:SI (match_dup 0) (const_int 0)))]
10799 [(set_attr "conds" "set")
10800 (set_attr "length" "16")
10801 (set_attr "type" "multiple")]
10804 (define_insn_and_split "*and_scc_scc"
10805 [(set (match_operand:SI 0 "s_register_operand" "=Ts")
10806 (and:SI (match_operator:SI 3 "arm_comparison_operator"
10807 [(match_operand:SI 1 "s_register_operand" "r")
10808 (match_operand:SI 2 "arm_add_operand" "rIL")])
10809 (match_operator:SI 6 "arm_comparison_operator"
10810 [(match_operand:SI 4 "s_register_operand" "r")
10811 (match_operand:SI 5 "arm_add_operand" "rIL")])))
10812 (clobber (reg:CC CC_REGNUM))]
10814 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y)
10817 "TARGET_32BIT && reload_completed
10818 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y)
10820 [(set (match_dup 7)
10823 (match_op_dup 3 [(match_dup 1) (match_dup 2)])
10824 (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
10826 (set (match_dup 0) (ne:SI (match_dup 7) (const_int 0)))]
10828 = gen_rtx_REG (arm_select_dominance_cc_mode (operands[3], operands[6],
10831 [(set_attr "conds" "clob")
10832 (set_attr "length" "16")
10833 (set_attr "type" "multiple")]
10836 ; If the above pattern is followed by a CMP insn, then the compare is
10837 ; redundant, since we can rework the conditional instruction that follows.
10838 (define_insn_and_split "*and_scc_scc_cmp"
10839 [(set (match_operand 0 "dominant_cc_register" "")
10840 (compare (and:SI (match_operator:SI 3 "arm_comparison_operator"
10841 [(match_operand:SI 1 "s_register_operand" "r")
10842 (match_operand:SI 2 "arm_add_operand" "rIL")])
10843 (match_operator:SI 6 "arm_comparison_operator"
10844 [(match_operand:SI 4 "s_register_operand" "r")
10845 (match_operand:SI 5 "arm_add_operand" "rIL")]))
10847 (set (match_operand:SI 7 "s_register_operand" "=Ts")
10848 (and:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)])
10849 (match_op_dup 6 [(match_dup 4) (match_dup 5)])))]
10852 "TARGET_32BIT && reload_completed"
10853 [(set (match_dup 0)
10856 (match_op_dup 3 [(match_dup 1) (match_dup 2)])
10857 (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
10859 (set (match_dup 7) (ne:SI (match_dup 0) (const_int 0)))]
10861 [(set_attr "conds" "set")
10862 (set_attr "length" "16")
10863 (set_attr "type" "multiple")]
10866 ;; If there is no dominance in the comparison, then we can still save an
10867 ;; instruction in the AND case, since we can know that the second compare
10868 ;; need only zero the value if false (if true, then the value is already
10870 (define_insn_and_split "*and_scc_scc_nodom"
10871 [(set (match_operand:SI 0 "s_register_operand" "=&Ts,&Ts,&Ts")
10872 (and:SI (match_operator:SI 3 "arm_comparison_operator"
10873 [(match_operand:SI 1 "s_register_operand" "r,r,0")
10874 (match_operand:SI 2 "arm_add_operand" "rIL,0,rIL")])
10875 (match_operator:SI 6 "arm_comparison_operator"
10876 [(match_operand:SI 4 "s_register_operand" "r,r,r")
10877 (match_operand:SI 5 "arm_add_operand" "rIL,rIL,rIL")])))
10878 (clobber (reg:CC CC_REGNUM))]
10880 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y)
10883 "TARGET_32BIT && reload_completed"
10884 [(parallel [(set (match_dup 0)
10885 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
10886 (clobber (reg:CC CC_REGNUM))])
10887 (set (match_dup 7) (match_op_dup 8 [(match_dup 4) (match_dup 5)]))
10889 (if_then_else:SI (match_op_dup 6 [(match_dup 7) (const_int 0)])
10892 "operands[7] = gen_rtx_REG (SELECT_CC_MODE (GET_CODE (operands[6]),
10893 operands[4], operands[5]),
10895 operands[8] = gen_rtx_COMPARE (GET_MODE (operands[7]), operands[4],
10897 [(set_attr "conds" "clob")
10898 (set_attr "length" "20")
10899 (set_attr "type" "multiple")]
10903 [(set (reg:CC_NOOV CC_REGNUM)
10904 (compare:CC_NOOV (ior:SI
10905 (and:SI (match_operand:SI 0 "s_register_operand" "")
10907 (match_operator:SI 1 "arm_comparison_operator"
10908 [(match_operand:SI 2 "s_register_operand" "")
10909 (match_operand:SI 3 "arm_add_operand" "")]))
10911 (clobber (match_operand:SI 4 "s_register_operand" ""))]
10913 [(set (match_dup 4)
10914 (ior:SI (match_op_dup 1 [(match_dup 2) (match_dup 3)])
10916 (set (reg:CC_NOOV CC_REGNUM)
10917 (compare:CC_NOOV (and:SI (match_dup 4) (const_int 1))
10922 [(set (reg:CC_NOOV CC_REGNUM)
10923 (compare:CC_NOOV (ior:SI
10924 (match_operator:SI 1 "arm_comparison_operator"
10925 [(match_operand:SI 2 "s_register_operand" "")
10926 (match_operand:SI 3 "arm_add_operand" "")])
10927 (and:SI (match_operand:SI 0 "s_register_operand" "")
10930 (clobber (match_operand:SI 4 "s_register_operand" ""))]
10932 [(set (match_dup 4)
10933 (ior:SI (match_op_dup 1 [(match_dup 2) (match_dup 3)])
10935 (set (reg:CC_NOOV CC_REGNUM)
10936 (compare:CC_NOOV (and:SI (match_dup 4) (const_int 1))
10939 ;; ??? The conditional patterns above need checking for Thumb-2 usefulness
10941 (define_insn_and_split "*negscc"
10942 [(set (match_operand:SI 0 "s_register_operand" "=r")
10943 (neg:SI (match_operator 3 "arm_comparison_operator"
10944 [(match_operand:SI 1 "s_register_operand" "r")
10945 (match_operand:SI 2 "arm_rhs_operand" "rI")])))
10946 (clobber (reg:CC CC_REGNUM))]
10949 "&& reload_completed"
10952 rtx cc_reg = gen_rtx_REG (CCmode, CC_REGNUM);
10954 if (GET_CODE (operands[3]) == LT && operands[2] == const0_rtx)
10956 /* Emit mov\\t%0, %1, asr #31 */
10957 emit_insn (gen_rtx_SET (VOIDmode,
10959 gen_rtx_ASHIFTRT (SImode,
10964 else if (GET_CODE (operands[3]) == NE)
10966 /* Emit subs\\t%0, %1, %2\;mvnne\\t%0, #0 */
10967 if (CONST_INT_P (operands[2]))
10968 emit_insn (gen_cmpsi2_addneg (operands[0], operands[1], operands[2],
10969 GEN_INT (- INTVAL (operands[2]))));
10971 emit_insn (gen_subsi3_compare (operands[0], operands[1], operands[2]));
10973 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
10974 gen_rtx_NE (SImode,
10977 gen_rtx_SET (SImode,
10984 /* Emit: cmp\\t%1, %2\;mov%D3\\t%0, #0\;mvn%d3\\t%0, #0 */
10985 emit_insn (gen_rtx_SET (VOIDmode,
10987 gen_rtx_COMPARE (CCmode, operands[1], operands[2])));
10988 enum rtx_code rc = GET_CODE (operands[3]);
10990 rc = reverse_condition (rc);
10991 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
10992 gen_rtx_fmt_ee (rc,
10996 gen_rtx_SET (VOIDmode, operands[0], const0_rtx)));
10997 rc = GET_CODE (operands[3]);
10998 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
10999 gen_rtx_fmt_ee (rc,
11003 gen_rtx_SET (VOIDmode,
11010 [(set_attr "conds" "clob")
11011 (set_attr "length" "12")
11012 (set_attr "type" "multiple")]
11015 (define_insn_and_split "movcond_addsi"
11016 [(set (match_operand:SI 0 "s_register_operand" "=r,l,r")
11018 (match_operator 5 "comparison_operator"
11019 [(plus:SI (match_operand:SI 3 "s_register_operand" "r,r,r")
11020 (match_operand:SI 4 "arm_add_operand" "rIL,rIL,rIL"))
11022 (match_operand:SI 1 "arm_rhs_operand" "rI,rPy,r")
11023 (match_operand:SI 2 "arm_rhs_operand" "rI,rPy,r")))
11024 (clobber (reg:CC CC_REGNUM))]
11027 "&& reload_completed"
11028 [(set (reg:CC_NOOV CC_REGNUM)
11030 (plus:SI (match_dup 3)
11033 (set (match_dup 0) (match_dup 1))
11034 (cond_exec (match_dup 6)
11035 (set (match_dup 0) (match_dup 2)))]
11038 enum machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[5]),
11039 operands[3], operands[4]);
11040 enum rtx_code rc = GET_CODE (operands[5]);
11042 operands[6] = gen_rtx_REG (mode, CC_REGNUM);
11043 gcc_assert (!(mode == CCFPmode || mode == CCFPEmode));
11044 rc = reverse_condition (rc);
11046 operands[6] = gen_rtx_fmt_ee (rc, VOIDmode, operands[6], const0_rtx);
11049 [(set_attr "conds" "clob")
11050 (set_attr "enabled_for_depr_it" "no,yes,yes")
11051 (set_attr "type" "multiple")]
11054 (define_insn "movcond"
11055 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
11057 (match_operator 5 "arm_comparison_operator"
11058 [(match_operand:SI 3 "s_register_operand" "r,r,r")
11059 (match_operand:SI 4 "arm_add_operand" "rIL,rIL,rIL")])
11060 (match_operand:SI 1 "arm_rhs_operand" "0,rI,?rI")
11061 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
11062 (clobber (reg:CC CC_REGNUM))]
11065 if (GET_CODE (operands[5]) == LT
11066 && (operands[4] == const0_rtx))
11068 if (which_alternative != 1 && REG_P (operands[1]))
11070 if (operands[2] == const0_rtx)
11071 return \"and\\t%0, %1, %3, asr #31\";
11072 return \"ands\\t%0, %1, %3, asr #32\;movcc\\t%0, %2\";
11074 else if (which_alternative != 0 && REG_P (operands[2]))
11076 if (operands[1] == const0_rtx)
11077 return \"bic\\t%0, %2, %3, asr #31\";
11078 return \"bics\\t%0, %2, %3, asr #32\;movcs\\t%0, %1\";
11080 /* The only case that falls through to here is when both ops 1 & 2
11084 if (GET_CODE (operands[5]) == GE
11085 && (operands[4] == const0_rtx))
11087 if (which_alternative != 1 && REG_P (operands[1]))
11089 if (operands[2] == const0_rtx)
11090 return \"bic\\t%0, %1, %3, asr #31\";
11091 return \"bics\\t%0, %1, %3, asr #32\;movcs\\t%0, %2\";
11093 else if (which_alternative != 0 && REG_P (operands[2]))
11095 if (operands[1] == const0_rtx)
11096 return \"and\\t%0, %2, %3, asr #31\";
11097 return \"ands\\t%0, %2, %3, asr #32\;movcc\\t%0, %1\";
11099 /* The only case that falls through to here is when both ops 1 & 2
11102 if (CONST_INT_P (operands[4])
11103 && !const_ok_for_arm (INTVAL (operands[4])))
11104 output_asm_insn (\"cmn\\t%3, #%n4\", operands);
11106 output_asm_insn (\"cmp\\t%3, %4\", operands);
11107 if (which_alternative != 0)
11108 output_asm_insn (\"mov%d5\\t%0, %1\", operands);
11109 if (which_alternative != 1)
11110 output_asm_insn (\"mov%D5\\t%0, %2\", operands);
11113 [(set_attr "conds" "clob")
11114 (set_attr "length" "8,8,12")
11115 (set_attr "type" "multiple")]
11118 ;; ??? The patterns below need checking for Thumb-2 usefulness.
11120 (define_insn "*ifcompare_plus_move"
11121 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
11122 (if_then_else:SI (match_operator 6 "arm_comparison_operator"
11123 [(match_operand:SI 4 "s_register_operand" "r,r")
11124 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
11126 (match_operand:SI 2 "s_register_operand" "r,r")
11127 (match_operand:SI 3 "arm_add_operand" "rIL,rIL"))
11128 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))
11129 (clobber (reg:CC CC_REGNUM))]
11132 [(set_attr "conds" "clob")
11133 (set_attr "length" "8,12")
11134 (set_attr "type" "multiple")]
11137 (define_insn "*if_plus_move"
11138 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r")
11140 (match_operator 4 "arm_comparison_operator"
11141 [(match_operand 5 "cc_register" "") (const_int 0)])
11143 (match_operand:SI 2 "s_register_operand" "r,r,r,r")
11144 (match_operand:SI 3 "arm_add_operand" "rI,L,rI,L"))
11145 (match_operand:SI 1 "arm_rhs_operand" "0,0,?rI,?rI")))]
11148 add%d4\\t%0, %2, %3
11149 sub%d4\\t%0, %2, #%n3
11150 add%d4\\t%0, %2, %3\;mov%D4\\t%0, %1
11151 sub%d4\\t%0, %2, #%n3\;mov%D4\\t%0, %1"
11152 [(set_attr "conds" "use")
11153 (set_attr "length" "4,4,8,8")
11154 (set_attr_alternative "type"
11155 [(if_then_else (match_operand 3 "const_int_operand" "")
11156 (const_string "alu_imm" )
11157 (const_string "alu_reg"))
11158 (const_string "alu_imm")
11159 (const_string "alu_reg")
11160 (const_string "alu_reg")])]
11163 (define_insn "*ifcompare_move_plus"
11164 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
11165 (if_then_else:SI (match_operator 6 "arm_comparison_operator"
11166 [(match_operand:SI 4 "s_register_operand" "r,r")
11167 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
11168 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
11170 (match_operand:SI 2 "s_register_operand" "r,r")
11171 (match_operand:SI 3 "arm_add_operand" "rIL,rIL"))))
11172 (clobber (reg:CC CC_REGNUM))]
11175 [(set_attr "conds" "clob")
11176 (set_attr "length" "8,12")
11177 (set_attr "type" "multiple")]
11180 (define_insn "*if_move_plus"
11181 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r")
11183 (match_operator 4 "arm_comparison_operator"
11184 [(match_operand 5 "cc_register" "") (const_int 0)])
11185 (match_operand:SI 1 "arm_rhs_operand" "0,0,?rI,?rI")
11187 (match_operand:SI 2 "s_register_operand" "r,r,r,r")
11188 (match_operand:SI 3 "arm_add_operand" "rI,L,rI,L"))))]
11191 add%D4\\t%0, %2, %3
11192 sub%D4\\t%0, %2, #%n3
11193 add%D4\\t%0, %2, %3\;mov%d4\\t%0, %1
11194 sub%D4\\t%0, %2, #%n3\;mov%d4\\t%0, %1"
11195 [(set_attr "conds" "use")
11196 (set_attr "length" "4,4,8,8")
11197 (set_attr "type" "alu_reg,alu_imm,multiple,multiple")]
11200 (define_insn "*ifcompare_arith_arith"
11201 [(set (match_operand:SI 0 "s_register_operand" "=r")
11202 (if_then_else:SI (match_operator 9 "arm_comparison_operator"
11203 [(match_operand:SI 5 "s_register_operand" "r")
11204 (match_operand:SI 6 "arm_add_operand" "rIL")])
11205 (match_operator:SI 8 "shiftable_operator"
11206 [(match_operand:SI 1 "s_register_operand" "r")
11207 (match_operand:SI 2 "arm_rhs_operand" "rI")])
11208 (match_operator:SI 7 "shiftable_operator"
11209 [(match_operand:SI 3 "s_register_operand" "r")
11210 (match_operand:SI 4 "arm_rhs_operand" "rI")])))
11211 (clobber (reg:CC CC_REGNUM))]
11214 [(set_attr "conds" "clob")
11215 (set_attr "length" "12")
11216 (set_attr "type" "multiple")]
11219 (define_insn "*if_arith_arith"
11220 [(set (match_operand:SI 0 "s_register_operand" "=r")
11221 (if_then_else:SI (match_operator 5 "arm_comparison_operator"
11222 [(match_operand 8 "cc_register" "") (const_int 0)])
11223 (match_operator:SI 6 "shiftable_operator"
11224 [(match_operand:SI 1 "s_register_operand" "r")
11225 (match_operand:SI 2 "arm_rhs_operand" "rI")])
11226 (match_operator:SI 7 "shiftable_operator"
11227 [(match_operand:SI 3 "s_register_operand" "r")
11228 (match_operand:SI 4 "arm_rhs_operand" "rI")])))]
11230 "%I6%d5\\t%0, %1, %2\;%I7%D5\\t%0, %3, %4"
11231 [(set_attr "conds" "use")
11232 (set_attr "length" "8")
11233 (set_attr "type" "multiple")]
11236 (define_insn "*ifcompare_arith_move"
11237 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
11238 (if_then_else:SI (match_operator 6 "arm_comparison_operator"
11239 [(match_operand:SI 2 "s_register_operand" "r,r")
11240 (match_operand:SI 3 "arm_add_operand" "rIL,rIL")])
11241 (match_operator:SI 7 "shiftable_operator"
11242 [(match_operand:SI 4 "s_register_operand" "r,r")
11243 (match_operand:SI 5 "arm_rhs_operand" "rI,rI")])
11244 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))
11245 (clobber (reg:CC CC_REGNUM))]
11248 /* If we have an operation where (op x 0) is the identity operation and
11249 the conditional operator is LT or GE and we are comparing against zero and
11250 everything is in registers then we can do this in two instructions. */
11251 if (operands[3] == const0_rtx
11252 && GET_CODE (operands[7]) != AND
11253 && REG_P (operands[5])
11254 && REG_P (operands[1])
11255 && REGNO (operands[1]) == REGNO (operands[4])
11256 && REGNO (operands[4]) != REGNO (operands[0]))
11258 if (GET_CODE (operands[6]) == LT)
11259 return \"and\\t%0, %5, %2, asr #31\;%I7\\t%0, %4, %0\";
11260 else if (GET_CODE (operands[6]) == GE)
11261 return \"bic\\t%0, %5, %2, asr #31\;%I7\\t%0, %4, %0\";
11263 if (CONST_INT_P (operands[3])
11264 && !const_ok_for_arm (INTVAL (operands[3])))
11265 output_asm_insn (\"cmn\\t%2, #%n3\", operands);
11267 output_asm_insn (\"cmp\\t%2, %3\", operands);
11268 output_asm_insn (\"%I7%d6\\t%0, %4, %5\", operands);
11269 if (which_alternative != 0)
11270 return \"mov%D6\\t%0, %1\";
11273 [(set_attr "conds" "clob")
11274 (set_attr "length" "8,12")
11275 (set_attr "type" "multiple")]
11278 (define_insn "*if_arith_move"
11279 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
11280 (if_then_else:SI (match_operator 4 "arm_comparison_operator"
11281 [(match_operand 6 "cc_register" "") (const_int 0)])
11282 (match_operator:SI 5 "shiftable_operator"
11283 [(match_operand:SI 2 "s_register_operand" "r,r")
11284 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
11285 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))]
11288 %I5%d4\\t%0, %2, %3
11289 %I5%d4\\t%0, %2, %3\;mov%D4\\t%0, %1"
11290 [(set_attr "conds" "use")
11291 (set_attr "length" "4,8")
11292 (set_attr "type" "alu_shift_reg,multiple")]
11295 (define_insn "*ifcompare_move_arith"
11296 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
11297 (if_then_else:SI (match_operator 6 "arm_comparison_operator"
11298 [(match_operand:SI 4 "s_register_operand" "r,r")
11299 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
11300 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
11301 (match_operator:SI 7 "shiftable_operator"
11302 [(match_operand:SI 2 "s_register_operand" "r,r")
11303 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))
11304 (clobber (reg:CC CC_REGNUM))]
11307 /* If we have an operation where (op x 0) is the identity operation and
11308 the conditional operator is LT or GE and we are comparing against zero and
11309 everything is in registers then we can do this in two instructions */
11310 if (operands[5] == const0_rtx
11311 && GET_CODE (operands[7]) != AND
11312 && REG_P (operands[3])
11313 && REG_P (operands[1])
11314 && REGNO (operands[1]) == REGNO (operands[2])
11315 && REGNO (operands[2]) != REGNO (operands[0]))
11317 if (GET_CODE (operands[6]) == GE)
11318 return \"and\\t%0, %3, %4, asr #31\;%I7\\t%0, %2, %0\";
11319 else if (GET_CODE (operands[6]) == LT)
11320 return \"bic\\t%0, %3, %4, asr #31\;%I7\\t%0, %2, %0\";
11323 if (CONST_INT_P (operands[5])
11324 && !const_ok_for_arm (INTVAL (operands[5])))
11325 output_asm_insn (\"cmn\\t%4, #%n5\", operands);
11327 output_asm_insn (\"cmp\\t%4, %5\", operands);
11329 if (which_alternative != 0)
11330 output_asm_insn (\"mov%d6\\t%0, %1\", operands);
11331 return \"%I7%D6\\t%0, %2, %3\";
11333 [(set_attr "conds" "clob")
11334 (set_attr "length" "8,12")
11335 (set_attr "type" "multiple")]
11338 (define_insn "*if_move_arith"
11339 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
11341 (match_operator 4 "arm_comparison_operator"
11342 [(match_operand 6 "cc_register" "") (const_int 0)])
11343 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
11344 (match_operator:SI 5 "shiftable_operator"
11345 [(match_operand:SI 2 "s_register_operand" "r,r")
11346 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))]
11349 %I5%D4\\t%0, %2, %3
11350 %I5%D4\\t%0, %2, %3\;mov%d4\\t%0, %1"
11351 [(set_attr "conds" "use")
11352 (set_attr "length" "4,8")
11353 (set_attr "type" "alu_shift_reg,multiple")]
11356 (define_insn "*ifcompare_move_not"
11357 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
11359 (match_operator 5 "arm_comparison_operator"
11360 [(match_operand:SI 3 "s_register_operand" "r,r")
11361 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
11362 (match_operand:SI 1 "arm_not_operand" "0,?rIK")
11364 (match_operand:SI 2 "s_register_operand" "r,r"))))
11365 (clobber (reg:CC CC_REGNUM))]
11368 [(set_attr "conds" "clob")
11369 (set_attr "length" "8,12")
11370 (set_attr "type" "multiple")]
11373 (define_insn "*if_move_not"
11374 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
11376 (match_operator 4 "arm_comparison_operator"
11377 [(match_operand 3 "cc_register" "") (const_int 0)])
11378 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")
11379 (not:SI (match_operand:SI 2 "s_register_operand" "r,r,r"))))]
11383 mov%d4\\t%0, %1\;mvn%D4\\t%0, %2
11384 mvn%d4\\t%0, #%B1\;mvn%D4\\t%0, %2"
11385 [(set_attr "conds" "use")
11386 (set_attr "type" "mvn_reg")
11387 (set_attr "length" "4,8,8")
11388 (set_attr "type" "mvn_reg,multiple,multiple")]
11391 (define_insn "*ifcompare_not_move"
11392 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
11394 (match_operator 5 "arm_comparison_operator"
11395 [(match_operand:SI 3 "s_register_operand" "r,r")
11396 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
11398 (match_operand:SI 2 "s_register_operand" "r,r"))
11399 (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
11400 (clobber (reg:CC CC_REGNUM))]
11403 [(set_attr "conds" "clob")
11404 (set_attr "length" "8,12")
11405 (set_attr "type" "multiple")]
11408 (define_insn "*if_not_move"
11409 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
11411 (match_operator 4 "arm_comparison_operator"
11412 [(match_operand 3 "cc_register" "") (const_int 0)])
11413 (not:SI (match_operand:SI 2 "s_register_operand" "r,r,r"))
11414 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")))]
11418 mov%D4\\t%0, %1\;mvn%d4\\t%0, %2
11419 mvn%D4\\t%0, #%B1\;mvn%d4\\t%0, %2"
11420 [(set_attr "conds" "use")
11421 (set_attr "type" "mvn_reg,multiple,multiple")
11422 (set_attr "length" "4,8,8")]
11425 (define_insn "*ifcompare_shift_move"
11426 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
11428 (match_operator 6 "arm_comparison_operator"
11429 [(match_operand:SI 4 "s_register_operand" "r,r")
11430 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
11431 (match_operator:SI 7 "shift_operator"
11432 [(match_operand:SI 2 "s_register_operand" "r,r")
11433 (match_operand:SI 3 "arm_rhs_operand" "rM,rM")])
11434 (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
11435 (clobber (reg:CC CC_REGNUM))]
11438 [(set_attr "conds" "clob")
11439 (set_attr "length" "8,12")
11440 (set_attr "type" "multiple")]
11443 (define_insn "*if_shift_move"
11444 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
11446 (match_operator 5 "arm_comparison_operator"
11447 [(match_operand 6 "cc_register" "") (const_int 0)])
11448 (match_operator:SI 4 "shift_operator"
11449 [(match_operand:SI 2 "s_register_operand" "r,r,r")
11450 (match_operand:SI 3 "arm_rhs_operand" "rM,rM,rM")])
11451 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")))]
11455 mov%D5\\t%0, %1\;mov%d5\\t%0, %2%S4
11456 mvn%D5\\t%0, #%B1\;mov%d5\\t%0, %2%S4"
11457 [(set_attr "conds" "use")
11458 (set_attr "shift" "2")
11459 (set_attr "length" "4,8,8")
11460 (set_attr "type" "mov_shift_reg,multiple,multiple")]
11463 (define_insn "*ifcompare_move_shift"
11464 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
11466 (match_operator 6 "arm_comparison_operator"
11467 [(match_operand:SI 4 "s_register_operand" "r,r")
11468 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
11469 (match_operand:SI 1 "arm_not_operand" "0,?rIK")
11470 (match_operator:SI 7 "shift_operator"
11471 [(match_operand:SI 2 "s_register_operand" "r,r")
11472 (match_operand:SI 3 "arm_rhs_operand" "rM,rM")])))
11473 (clobber (reg:CC CC_REGNUM))]
11476 [(set_attr "conds" "clob")
11477 (set_attr "length" "8,12")
11478 (set_attr "type" "multiple")]
11481 (define_insn "*if_move_shift"
11482 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
11484 (match_operator 5 "arm_comparison_operator"
11485 [(match_operand 6 "cc_register" "") (const_int 0)])
11486 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")
11487 (match_operator:SI 4 "shift_operator"
11488 [(match_operand:SI 2 "s_register_operand" "r,r,r")
11489 (match_operand:SI 3 "arm_rhs_operand" "rM,rM,rM")])))]
11493 mov%d5\\t%0, %1\;mov%D5\\t%0, %2%S4
11494 mvn%d5\\t%0, #%B1\;mov%D5\\t%0, %2%S4"
11495 [(set_attr "conds" "use")
11496 (set_attr "shift" "2")
11497 (set_attr "length" "4,8,8")
11498 (set_attr "type" "mov_shift_reg,multiple,multiple")]
11501 (define_insn "*ifcompare_shift_shift"
11502 [(set (match_operand:SI 0 "s_register_operand" "=r")
11504 (match_operator 7 "arm_comparison_operator"
11505 [(match_operand:SI 5 "s_register_operand" "r")
11506 (match_operand:SI 6 "arm_add_operand" "rIL")])
11507 (match_operator:SI 8 "shift_operator"
11508 [(match_operand:SI 1 "s_register_operand" "r")
11509 (match_operand:SI 2 "arm_rhs_operand" "rM")])
11510 (match_operator:SI 9 "shift_operator"
11511 [(match_operand:SI 3 "s_register_operand" "r")
11512 (match_operand:SI 4 "arm_rhs_operand" "rM")])))
11513 (clobber (reg:CC CC_REGNUM))]
11516 [(set_attr "conds" "clob")
11517 (set_attr "length" "12")
11518 (set_attr "type" "multiple")]
11521 (define_insn "*if_shift_shift"
11522 [(set (match_operand:SI 0 "s_register_operand" "=r")
11524 (match_operator 5 "arm_comparison_operator"
11525 [(match_operand 8 "cc_register" "") (const_int 0)])
11526 (match_operator:SI 6 "shift_operator"
11527 [(match_operand:SI 1 "s_register_operand" "r")
11528 (match_operand:SI 2 "arm_rhs_operand" "rM")])
11529 (match_operator:SI 7 "shift_operator"
11530 [(match_operand:SI 3 "s_register_operand" "r")
11531 (match_operand:SI 4 "arm_rhs_operand" "rM")])))]
11533 "mov%d5\\t%0, %1%S6\;mov%D5\\t%0, %3%S7"
11534 [(set_attr "conds" "use")
11535 (set_attr "shift" "1")
11536 (set_attr "length" "8")
11537 (set (attr "type") (if_then_else
11538 (and (match_operand 2 "const_int_operand" "")
11539 (match_operand 4 "const_int_operand" ""))
11540 (const_string "mov_shift")
11541 (const_string "mov_shift_reg")))]
11544 (define_insn "*ifcompare_not_arith"
11545 [(set (match_operand:SI 0 "s_register_operand" "=r")
11547 (match_operator 6 "arm_comparison_operator"
11548 [(match_operand:SI 4 "s_register_operand" "r")
11549 (match_operand:SI 5 "arm_add_operand" "rIL")])
11550 (not:SI (match_operand:SI 1 "s_register_operand" "r"))
11551 (match_operator:SI 7 "shiftable_operator"
11552 [(match_operand:SI 2 "s_register_operand" "r")
11553 (match_operand:SI 3 "arm_rhs_operand" "rI")])))
11554 (clobber (reg:CC CC_REGNUM))]
11557 [(set_attr "conds" "clob")
11558 (set_attr "length" "12")
11559 (set_attr "type" "multiple")]
11562 (define_insn "*if_not_arith"
11563 [(set (match_operand:SI 0 "s_register_operand" "=r")
11565 (match_operator 5 "arm_comparison_operator"
11566 [(match_operand 4 "cc_register" "") (const_int 0)])
11567 (not:SI (match_operand:SI 1 "s_register_operand" "r"))
11568 (match_operator:SI 6 "shiftable_operator"
11569 [(match_operand:SI 2 "s_register_operand" "r")
11570 (match_operand:SI 3 "arm_rhs_operand" "rI")])))]
11572 "mvn%d5\\t%0, %1\;%I6%D5\\t%0, %2, %3"
11573 [(set_attr "conds" "use")
11574 (set_attr "type" "mvn_reg")
11575 (set_attr "length" "8")]
11578 (define_insn "*ifcompare_arith_not"
11579 [(set (match_operand:SI 0 "s_register_operand" "=r")
11581 (match_operator 6 "arm_comparison_operator"
11582 [(match_operand:SI 4 "s_register_operand" "r")
11583 (match_operand:SI 5 "arm_add_operand" "rIL")])
11584 (match_operator:SI 7 "shiftable_operator"
11585 [(match_operand:SI 2 "s_register_operand" "r")
11586 (match_operand:SI 3 "arm_rhs_operand" "rI")])
11587 (not:SI (match_operand:SI 1 "s_register_operand" "r"))))
11588 (clobber (reg:CC CC_REGNUM))]
11591 [(set_attr "conds" "clob")
11592 (set_attr "length" "12")
11593 (set_attr "type" "multiple")]
11596 (define_insn "*if_arith_not"
11597 [(set (match_operand:SI 0 "s_register_operand" "=r")
11599 (match_operator 5 "arm_comparison_operator"
11600 [(match_operand 4 "cc_register" "") (const_int 0)])
11601 (match_operator:SI 6 "shiftable_operator"
11602 [(match_operand:SI 2 "s_register_operand" "r")
11603 (match_operand:SI 3 "arm_rhs_operand" "rI")])
11604 (not:SI (match_operand:SI 1 "s_register_operand" "r"))))]
11606 "mvn%D5\\t%0, %1\;%I6%d5\\t%0, %2, %3"
11607 [(set_attr "conds" "use")
11608 (set_attr "type" "multiple")
11609 (set_attr "length" "8")]
11612 (define_insn "*ifcompare_neg_move"
11613 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
11615 (match_operator 5 "arm_comparison_operator"
11616 [(match_operand:SI 3 "s_register_operand" "r,r")
11617 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
11618 (neg:SI (match_operand:SI 2 "s_register_operand" "r,r"))
11619 (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
11620 (clobber (reg:CC CC_REGNUM))]
11623 [(set_attr "conds" "clob")
11624 (set_attr "length" "8,12")
11625 (set_attr "type" "multiple")]
11628 (define_insn "*if_neg_move"
11629 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
11631 (match_operator 4 "arm_comparison_operator"
11632 [(match_operand 3 "cc_register" "") (const_int 0)])
11633 (neg:SI (match_operand:SI 2 "s_register_operand" "r,r,r"))
11634 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")))]
11637 rsb%d4\\t%0, %2, #0
11638 mov%D4\\t%0, %1\;rsb%d4\\t%0, %2, #0
11639 mvn%D4\\t%0, #%B1\;rsb%d4\\t%0, %2, #0"
11640 [(set_attr "conds" "use")
11641 (set_attr "length" "4,8,8")
11642 (set_attr "type" "logic_shift_imm,multiple,multiple")]
11645 (define_insn "*ifcompare_move_neg"
11646 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
11648 (match_operator 5 "arm_comparison_operator"
11649 [(match_operand:SI 3 "s_register_operand" "r,r")
11650 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
11651 (match_operand:SI 1 "arm_not_operand" "0,?rIK")
11652 (neg:SI (match_operand:SI 2 "s_register_operand" "r,r"))))
11653 (clobber (reg:CC CC_REGNUM))]
11656 [(set_attr "conds" "clob")
11657 (set_attr "length" "8,12")
11658 (set_attr "type" "multiple")]
11661 (define_insn "*if_move_neg"
11662 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
11664 (match_operator 4 "arm_comparison_operator"
11665 [(match_operand 3 "cc_register" "") (const_int 0)])
11666 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")
11667 (neg:SI (match_operand:SI 2 "s_register_operand" "r,r,r"))))]
11670 rsb%D4\\t%0, %2, #0
11671 mov%d4\\t%0, %1\;rsb%D4\\t%0, %2, #0
11672 mvn%d4\\t%0, #%B1\;rsb%D4\\t%0, %2, #0"
11673 [(set_attr "conds" "use")
11674 (set_attr "length" "4,8,8")
11675 (set_attr "type" "logic_shift_imm,multiple,multiple")]
11678 (define_insn "*arith_adjacentmem"
11679 [(set (match_operand:SI 0 "s_register_operand" "=r")
11680 (match_operator:SI 1 "shiftable_operator"
11681 [(match_operand:SI 2 "memory_operand" "m")
11682 (match_operand:SI 3 "memory_operand" "m")]))
11683 (clobber (match_scratch:SI 4 "=r"))]
11684 "TARGET_ARM && adjacent_mem_locations (operands[2], operands[3])"
11690 HOST_WIDE_INT val1 = 0, val2 = 0;
11692 if (REGNO (operands[0]) > REGNO (operands[4]))
11694 ldm[1] = operands[4];
11695 ldm[2] = operands[0];
11699 ldm[1] = operands[0];
11700 ldm[2] = operands[4];
11703 base_reg = XEXP (operands[2], 0);
11705 if (!REG_P (base_reg))
11707 val1 = INTVAL (XEXP (base_reg, 1));
11708 base_reg = XEXP (base_reg, 0);
11711 if (!REG_P (XEXP (operands[3], 0)))
11712 val2 = INTVAL (XEXP (XEXP (operands[3], 0), 1));
11714 arith[0] = operands[0];
11715 arith[3] = operands[1];
11729 if (val1 !=0 && val2 != 0)
11733 if (val1 == 4 || val2 == 4)
11734 /* Other val must be 8, since we know they are adjacent and neither
11736 output_asm_insn (\"ldm%(ib%)\\t%0, {%1, %2}\", ldm);
11737 else if (const_ok_for_arm (val1) || const_ok_for_arm (-val1))
11739 ldm[0] = ops[0] = operands[4];
11741 ops[2] = GEN_INT (val1);
11742 output_add_immediate (ops);
11744 output_asm_insn (\"ldm%(ia%)\\t%0, {%1, %2}\", ldm);
11746 output_asm_insn (\"ldm%(da%)\\t%0, {%1, %2}\", ldm);
11750 /* Offset is out of range for a single add, so use two ldr. */
11753 ops[2] = GEN_INT (val1);
11754 output_asm_insn (\"ldr%?\\t%0, [%1, %2]\", ops);
11756 ops[2] = GEN_INT (val2);
11757 output_asm_insn (\"ldr%?\\t%0, [%1, %2]\", ops);
11760 else if (val1 != 0)
11763 output_asm_insn (\"ldm%(da%)\\t%0, {%1, %2}\", ldm);
11765 output_asm_insn (\"ldm%(ia%)\\t%0, {%1, %2}\", ldm);
11770 output_asm_insn (\"ldm%(ia%)\\t%0, {%1, %2}\", ldm);
11772 output_asm_insn (\"ldm%(da%)\\t%0, {%1, %2}\", ldm);
11774 output_asm_insn (\"%I3%?\\t%0, %1, %2\", arith);
11777 [(set_attr "length" "12")
11778 (set_attr "predicable" "yes")
11779 (set_attr "type" "load1")]
11782 ; This pattern is never tried by combine, so do it as a peephole
11785 [(set (match_operand:SI 0 "arm_general_register_operand" "")
11786 (match_operand:SI 1 "arm_general_register_operand" ""))
11787 (set (reg:CC CC_REGNUM)
11788 (compare:CC (match_dup 1) (const_int 0)))]
11790 [(parallel [(set (reg:CC CC_REGNUM) (compare:CC (match_dup 1) (const_int 0)))
11791 (set (match_dup 0) (match_dup 1))])]
11796 [(set (match_operand:SI 0 "s_register_operand" "")
11797 (and:SI (ge:SI (match_operand:SI 1 "s_register_operand" "")
11799 (neg:SI (match_operator:SI 2 "arm_comparison_operator"
11800 [(match_operand:SI 3 "s_register_operand" "")
11801 (match_operand:SI 4 "arm_rhs_operand" "")]))))
11802 (clobber (match_operand:SI 5 "s_register_operand" ""))]
11804 [(set (match_dup 5) (not:SI (ashiftrt:SI (match_dup 1) (const_int 31))))
11805 (set (match_dup 0) (and:SI (match_op_dup 2 [(match_dup 3) (match_dup 4)])
11810 ;; This split can be used because CC_Z mode implies that the following
11811 ;; branch will be an equality, or an unsigned inequality, so the sign
11812 ;; extension is not needed.
11815 [(set (reg:CC_Z CC_REGNUM)
11817 (ashift:SI (subreg:SI (match_operand:QI 0 "memory_operand" "") 0)
11819 (match_operand 1 "const_int_operand" "")))
11820 (clobber (match_scratch:SI 2 ""))]
11822 && (((unsigned HOST_WIDE_INT) INTVAL (operands[1]))
11823 == (((unsigned HOST_WIDE_INT) INTVAL (operands[1])) >> 24) << 24)"
11824 [(set (match_dup 2) (zero_extend:SI (match_dup 0)))
11825 (set (reg:CC CC_REGNUM) (compare:CC (match_dup 2) (match_dup 1)))]
11827 operands[1] = GEN_INT (((unsigned long) INTVAL (operands[1])) >> 24);
11830 ;; ??? Check the patterns above for Thumb-2 usefulness
11832 (define_expand "prologue"
11833 [(clobber (const_int 0))]
11836 arm_expand_prologue ();
11838 thumb1_expand_prologue ();
11843 (define_expand "epilogue"
11844 [(clobber (const_int 0))]
11847 if (crtl->calls_eh_return)
11848 emit_insn (gen_force_register_use (gen_rtx_REG (Pmode, 2)));
11851 thumb1_expand_epilogue ();
11852 emit_jump_insn (gen_rtx_UNSPEC_VOLATILE (VOIDmode,
11853 gen_rtvec (1, ret_rtx), VUNSPEC_EPILOGUE));
11855 else if (HAVE_return)
11857 /* HAVE_return is testing for USE_RETURN_INSN (FALSE). Hence,
11858 no need for explicit testing again. */
11859 emit_jump_insn (gen_return ());
11861 else if (TARGET_32BIT)
11863 arm_expand_epilogue (true);
11869 (define_insn "prologue_thumb1_interwork"
11870 [(unspec_volatile [(const_int 0)] VUNSPEC_THUMB1_INTERWORK)]
11872 "* return thumb1_output_interwork ();"
11873 [(set_attr "length" "8")
11874 (set_attr "type" "multiple")]
11877 ;; Note - although unspec_volatile's USE all hard registers,
11878 ;; USEs are ignored after relaod has completed. Thus we need
11879 ;; to add an unspec of the link register to ensure that flow
11880 ;; does not think that it is unused by the sibcall branch that
11881 ;; will replace the standard function epilogue.
11882 (define_expand "sibcall_epilogue"
11883 [(parallel [(unspec:SI [(reg:SI LR_REGNUM)] UNSPEC_REGISTER_USE)
11884 (unspec_volatile [(return)] VUNSPEC_EPILOGUE)])]
11887 arm_expand_epilogue (false);
11892 (define_insn "*epilogue_insns"
11893 [(unspec_volatile [(return)] VUNSPEC_EPILOGUE)]
11896 return thumb1_unexpanded_epilogue ();
11898 ; Length is absolute worst case
11899 [(set_attr "length" "44")
11900 (set_attr "type" "block")
11901 ;; We don't clobber the conditions, but the potential length of this
11902 ;; operation is sufficient to make conditionalizing the sequence
11903 ;; unlikely to be profitable.
11904 (set_attr "conds" "clob")]
11907 (define_expand "eh_epilogue"
11908 [(use (match_operand:SI 0 "register_operand" ""))
11909 (use (match_operand:SI 1 "register_operand" ""))
11910 (use (match_operand:SI 2 "register_operand" ""))]
11914 cfun->machine->eh_epilogue_sp_ofs = operands[1];
11915 if (!REG_P (operands[2]) || REGNO (operands[2]) != 2)
11917 rtx ra = gen_rtx_REG (Pmode, 2);
11919 emit_move_insn (ra, operands[2]);
11922 /* This is a hack -- we may have crystalized the function type too
11924 cfun->machine->func_type = 0;
11928 ;; This split is only used during output to reduce the number of patterns
11929 ;; that need assembler instructions adding to them. We allowed the setting
11930 ;; of the conditions to be implicit during rtl generation so that
11931 ;; the conditional compare patterns would work. However this conflicts to
11932 ;; some extent with the conditional data operations, so we have to split them
11935 ;; ??? Need to audit these splitters for Thumb-2. Why isn't normal
11936 ;; conditional execution sufficient?
11939 [(set (match_operand:SI 0 "s_register_operand" "")
11940 (if_then_else:SI (match_operator 1 "arm_comparison_operator"
11941 [(match_operand 2 "" "") (match_operand 3 "" "")])
11943 (match_operand 4 "" "")))
11944 (clobber (reg:CC CC_REGNUM))]
11945 "TARGET_ARM && reload_completed"
11946 [(set (match_dup 5) (match_dup 6))
11947 (cond_exec (match_dup 7)
11948 (set (match_dup 0) (match_dup 4)))]
11951 enum machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
11952 operands[2], operands[3]);
11953 enum rtx_code rc = GET_CODE (operands[1]);
11955 operands[5] = gen_rtx_REG (mode, CC_REGNUM);
11956 operands[6] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
11957 if (mode == CCFPmode || mode == CCFPEmode)
11958 rc = reverse_condition_maybe_unordered (rc);
11960 rc = reverse_condition (rc);
11962 operands[7] = gen_rtx_fmt_ee (rc, VOIDmode, operands[5], const0_rtx);
11967 [(set (match_operand:SI 0 "s_register_operand" "")
11968 (if_then_else:SI (match_operator 1 "arm_comparison_operator"
11969 [(match_operand 2 "" "") (match_operand 3 "" "")])
11970 (match_operand 4 "" "")
11972 (clobber (reg:CC CC_REGNUM))]
11973 "TARGET_ARM && reload_completed"
11974 [(set (match_dup 5) (match_dup 6))
11975 (cond_exec (match_op_dup 1 [(match_dup 5) (const_int 0)])
11976 (set (match_dup 0) (match_dup 4)))]
11979 enum machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
11980 operands[2], operands[3]);
11982 operands[5] = gen_rtx_REG (mode, CC_REGNUM);
11983 operands[6] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
11988 [(set (match_operand:SI 0 "s_register_operand" "")
11989 (if_then_else:SI (match_operator 1 "arm_comparison_operator"
11990 [(match_operand 2 "" "") (match_operand 3 "" "")])
11991 (match_operand 4 "" "")
11992 (match_operand 5 "" "")))
11993 (clobber (reg:CC CC_REGNUM))]
11994 "TARGET_ARM && reload_completed"
11995 [(set (match_dup 6) (match_dup 7))
11996 (cond_exec (match_op_dup 1 [(match_dup 6) (const_int 0)])
11997 (set (match_dup 0) (match_dup 4)))
11998 (cond_exec (match_dup 8)
11999 (set (match_dup 0) (match_dup 5)))]
12002 enum machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
12003 operands[2], operands[3]);
12004 enum rtx_code rc = GET_CODE (operands[1]);
12006 operands[6] = gen_rtx_REG (mode, CC_REGNUM);
12007 operands[7] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
12008 if (mode == CCFPmode || mode == CCFPEmode)
12009 rc = reverse_condition_maybe_unordered (rc);
12011 rc = reverse_condition (rc);
12013 operands[8] = gen_rtx_fmt_ee (rc, VOIDmode, operands[6], const0_rtx);
12018 [(set (match_operand:SI 0 "s_register_operand" "")
12019 (if_then_else:SI (match_operator 1 "arm_comparison_operator"
12020 [(match_operand:SI 2 "s_register_operand" "")
12021 (match_operand:SI 3 "arm_add_operand" "")])
12022 (match_operand:SI 4 "arm_rhs_operand" "")
12024 (match_operand:SI 5 "s_register_operand" ""))))
12025 (clobber (reg:CC CC_REGNUM))]
12026 "TARGET_ARM && reload_completed"
12027 [(set (match_dup 6) (match_dup 7))
12028 (cond_exec (match_op_dup 1 [(match_dup 6) (const_int 0)])
12029 (set (match_dup 0) (match_dup 4)))
12030 (cond_exec (match_dup 8)
12031 (set (match_dup 0) (not:SI (match_dup 5))))]
12034 enum machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
12035 operands[2], operands[3]);
12036 enum rtx_code rc = GET_CODE (operands[1]);
12038 operands[6] = gen_rtx_REG (mode, CC_REGNUM);
12039 operands[7] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
12040 if (mode == CCFPmode || mode == CCFPEmode)
12041 rc = reverse_condition_maybe_unordered (rc);
12043 rc = reverse_condition (rc);
12045 operands[8] = gen_rtx_fmt_ee (rc, VOIDmode, operands[6], const0_rtx);
12049 (define_insn "*cond_move_not"
12050 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
12051 (if_then_else:SI (match_operator 4 "arm_comparison_operator"
12052 [(match_operand 3 "cc_register" "") (const_int 0)])
12053 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
12055 (match_operand:SI 2 "s_register_operand" "r,r"))))]
12059 mov%d4\\t%0, %1\;mvn%D4\\t%0, %2"
12060 [(set_attr "conds" "use")
12061 (set_attr "type" "mvn_reg,multiple")
12062 (set_attr "length" "4,8")]
12065 ;; The next two patterns occur when an AND operation is followed by a
12066 ;; scc insn sequence
12068 (define_insn "*sign_extract_onebit"
12069 [(set (match_operand:SI 0 "s_register_operand" "=r")
12070 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
12072 (match_operand:SI 2 "const_int_operand" "n")))
12073 (clobber (reg:CC CC_REGNUM))]
12076 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
12077 output_asm_insn (\"ands\\t%0, %1, %2\", operands);
12078 return \"mvnne\\t%0, #0\";
12080 [(set_attr "conds" "clob")
12081 (set_attr "length" "8")
12082 (set_attr "type" "multiple")]
12085 (define_insn "*not_signextract_onebit"
12086 [(set (match_operand:SI 0 "s_register_operand" "=r")
12088 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
12090 (match_operand:SI 2 "const_int_operand" "n"))))
12091 (clobber (reg:CC CC_REGNUM))]
12094 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
12095 output_asm_insn (\"tst\\t%1, %2\", operands);
12096 output_asm_insn (\"mvneq\\t%0, #0\", operands);
12097 return \"movne\\t%0, #0\";
12099 [(set_attr "conds" "clob")
12100 (set_attr "length" "12")
12101 (set_attr "type" "multiple")]
12103 ;; ??? The above patterns need auditing for Thumb-2
12105 ;; Push multiple registers to the stack. Registers are in parallel (use ...)
12106 ;; expressions. For simplicity, the first register is also in the unspec
12108 ;; To avoid the usage of GNU extension, the length attribute is computed
12109 ;; in a C function arm_attr_length_push_multi.
12110 (define_insn "*push_multi"
12111 [(match_parallel 2 "multi_register_push"
12112 [(set (match_operand:BLK 0 "push_mult_memory_operand" "")
12113 (unspec:BLK [(match_operand:SI 1 "s_register_operand" "")]
12114 UNSPEC_PUSH_MULT))])]
12118 int num_saves = XVECLEN (operands[2], 0);
12120 /* For the StrongARM at least it is faster to
12121 use STR to store only a single register.
12122 In Thumb mode always use push, and the assembler will pick
12123 something appropriate. */
12124 if (num_saves == 1 && TARGET_ARM)
12125 output_asm_insn (\"str%?\\t%1, [%m0, #-4]!\", operands);
12132 strcpy (pattern, \"stm%(fd%)\\t%m0!, {%1\");
12133 else if (TARGET_THUMB2)
12134 strcpy (pattern, \"push%?\\t{%1\");
12136 strcpy (pattern, \"push\\t{%1\");
12138 for (i = 1; i < num_saves; i++)
12140 strcat (pattern, \", %|\");
12142 reg_names[REGNO (XEXP (XVECEXP (operands[2], 0, i), 0))]);
12145 strcat (pattern, \"}\");
12146 output_asm_insn (pattern, operands);
12151 [(set_attr "type" "store4")
12152 (set (attr "length")
12153 (symbol_ref "arm_attr_length_push_multi (operands[2], operands[1])"))]
12156 (define_insn "stack_tie"
12157 [(set (mem:BLK (scratch))
12158 (unspec:BLK [(match_operand:SI 0 "s_register_operand" "rk")
12159 (match_operand:SI 1 "s_register_operand" "rk")]
12163 [(set_attr "length" "0")
12164 (set_attr "type" "block")]
12167 ;; Pop (as used in epilogue RTL)
12169 (define_insn "*load_multiple_with_writeback"
12170 [(match_parallel 0 "load_multiple_operation"
12171 [(set (match_operand:SI 1 "s_register_operand" "+rk")
12172 (plus:SI (match_dup 1)
12173 (match_operand:SI 2 "const_int_operand" "I")))
12174 (set (match_operand:SI 3 "s_register_operand" "=rk")
12175 (mem:SI (match_dup 1)))
12177 "TARGET_32BIT && (reload_in_progress || reload_completed)"
12180 arm_output_multireg_pop (operands, /*return_pc=*/false,
12181 /*cond=*/const_true_rtx,
12187 [(set_attr "type" "load4")
12188 (set_attr "predicable" "yes")]
12191 ;; Pop with return (as used in epilogue RTL)
12193 ;; This instruction is generated when the registers are popped at the end of
12194 ;; epilogue. Here, instead of popping the value into LR and then generating
12195 ;; jump to LR, value is popped into PC directly. Hence, the pattern is combined
12197 (define_insn "*pop_multiple_with_writeback_and_return"
12198 [(match_parallel 0 "pop_multiple_return"
12200 (set (match_operand:SI 1 "s_register_operand" "+rk")
12201 (plus:SI (match_dup 1)
12202 (match_operand:SI 2 "const_int_operand" "I")))
12203 (set (match_operand:SI 3 "s_register_operand" "=rk")
12204 (mem:SI (match_dup 1)))
12206 "TARGET_32BIT && (reload_in_progress || reload_completed)"
12209 arm_output_multireg_pop (operands, /*return_pc=*/true,
12210 /*cond=*/const_true_rtx,
12216 [(set_attr "type" "load4")
12217 (set_attr "predicable" "yes")]
12220 (define_insn "*pop_multiple_with_return"
12221 [(match_parallel 0 "pop_multiple_return"
12223 (set (match_operand:SI 2 "s_register_operand" "=rk")
12224 (mem:SI (match_operand:SI 1 "s_register_operand" "rk")))
12226 "TARGET_32BIT && (reload_in_progress || reload_completed)"
12229 arm_output_multireg_pop (operands, /*return_pc=*/true,
12230 /*cond=*/const_true_rtx,
12236 [(set_attr "type" "load4")
12237 (set_attr "predicable" "yes")]
12240 ;; Load into PC and return
12241 (define_insn "*ldr_with_return"
12243 (set (reg:SI PC_REGNUM)
12244 (mem:SI (post_inc:SI (match_operand:SI 0 "s_register_operand" "+rk"))))]
12245 "TARGET_32BIT && (reload_in_progress || reload_completed)"
12246 "ldr%?\t%|pc, [%0], #4"
12247 [(set_attr "type" "load1")
12248 (set_attr "predicable" "yes")]
12250 ;; Pop for floating point registers (as used in epilogue RTL)
12251 (define_insn "*vfp_pop_multiple_with_writeback"
12252 [(match_parallel 0 "pop_multiple_fp"
12253 [(set (match_operand:SI 1 "s_register_operand" "+rk")
12254 (plus:SI (match_dup 1)
12255 (match_operand:SI 2 "const_int_operand" "I")))
12256 (set (match_operand:DF 3 "arm_hard_register_operand" "")
12257 (mem:DF (match_dup 1)))])]
12258 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
12261 int num_regs = XVECLEN (operands[0], 0);
12264 strcpy (pattern, \"fldmfdd\\t\");
12265 strcat (pattern, reg_names[REGNO (SET_DEST (XVECEXP (operands[0], 0, 0)))]);
12266 strcat (pattern, \"!, {\");
12267 op_list[0] = XEXP (XVECEXP (operands[0], 0, 1), 0);
12268 strcat (pattern, \"%P0\");
12269 if ((num_regs - 1) > 1)
12271 strcat (pattern, \"-%P1\");
12272 op_list [1] = XEXP (XVECEXP (operands[0], 0, num_regs - 1), 0);
12275 strcat (pattern, \"}\");
12276 output_asm_insn (pattern, op_list);
12280 [(set_attr "type" "load4")
12281 (set_attr "conds" "unconditional")
12282 (set_attr "predicable" "no")]
12285 ;; Special patterns for dealing with the constant pool
12287 (define_insn "align_4"
12288 [(unspec_volatile [(const_int 0)] VUNSPEC_ALIGN)]
12291 assemble_align (32);
12294 [(set_attr "type" "no_insn")]
12297 (define_insn "align_8"
12298 [(unspec_volatile [(const_int 0)] VUNSPEC_ALIGN8)]
12301 assemble_align (64);
12304 [(set_attr "type" "no_insn")]
12307 (define_insn "consttable_end"
12308 [(unspec_volatile [(const_int 0)] VUNSPEC_POOL_END)]
12311 making_const_table = FALSE;
12314 [(set_attr "type" "no_insn")]
12317 (define_insn "consttable_1"
12318 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_1)]
12321 making_const_table = TRUE;
12322 assemble_integer (operands[0], 1, BITS_PER_WORD, 1);
12323 assemble_zeros (3);
12326 [(set_attr "length" "4")
12327 (set_attr "type" "no_insn")]
12330 (define_insn "consttable_2"
12331 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_2)]
12334 making_const_table = TRUE;
12335 gcc_assert (GET_MODE_CLASS (GET_MODE (operands[0])) != MODE_FLOAT);
12336 assemble_integer (operands[0], 2, BITS_PER_WORD, 1);
12337 assemble_zeros (2);
12340 [(set_attr "length" "4")
12341 (set_attr "type" "no_insn")]
12344 (define_insn "consttable_4"
12345 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_4)]
12349 rtx x = operands[0];
12350 making_const_table = TRUE;
12351 switch (GET_MODE_CLASS (GET_MODE (x)))
12354 if (GET_MODE (x) == HFmode)
12355 arm_emit_fp16_const (x);
12359 REAL_VALUE_FROM_CONST_DOUBLE (r, x);
12360 assemble_real (r, GET_MODE (x), BITS_PER_WORD);
12364 /* XXX: Sometimes gcc does something really dumb and ends up with
12365 a HIGH in a constant pool entry, usually because it's trying to
12366 load into a VFP register. We know this will always be used in
12367 combination with a LO_SUM which ignores the high bits, so just
12368 strip off the HIGH. */
12369 if (GET_CODE (x) == HIGH)
12371 assemble_integer (x, 4, BITS_PER_WORD, 1);
12372 mark_symbol_refs_as_used (x);
12377 [(set_attr "length" "4")
12378 (set_attr "type" "no_insn")]
12381 (define_insn "consttable_8"
12382 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_8)]
12386 making_const_table = TRUE;
12387 switch (GET_MODE_CLASS (GET_MODE (operands[0])))
12392 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[0]);
12393 assemble_real (r, GET_MODE (operands[0]), BITS_PER_WORD);
12397 assemble_integer (operands[0], 8, BITS_PER_WORD, 1);
12402 [(set_attr "length" "8")
12403 (set_attr "type" "no_insn")]
12406 (define_insn "consttable_16"
12407 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_16)]
12411 making_const_table = TRUE;
12412 switch (GET_MODE_CLASS (GET_MODE (operands[0])))
12417 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[0]);
12418 assemble_real (r, GET_MODE (operands[0]), BITS_PER_WORD);
12422 assemble_integer (operands[0], 16, BITS_PER_WORD, 1);
12427 [(set_attr "length" "16")
12428 (set_attr "type" "no_insn")]
12431 ;; Miscellaneous Thumb patterns
12433 (define_expand "tablejump"
12434 [(parallel [(set (pc) (match_operand:SI 0 "register_operand" ""))
12435 (use (label_ref (match_operand 1 "" "")))])]
12440 /* Hopefully, CSE will eliminate this copy. */
12441 rtx reg1 = copy_addr_to_reg (gen_rtx_LABEL_REF (Pmode, operands[1]));
12442 rtx reg2 = gen_reg_rtx (SImode);
12444 emit_insn (gen_addsi3 (reg2, operands[0], reg1));
12445 operands[0] = reg2;
12450 ;; NB never uses BX.
12451 (define_insn "*thumb1_tablejump"
12452 [(set (pc) (match_operand:SI 0 "register_operand" "l*r"))
12453 (use (label_ref (match_operand 1 "" "")))]
12456 [(set_attr "length" "2")
12457 (set_attr "type" "no_insn")]
12460 ;; V5 Instructions,
12462 (define_insn "clzsi2"
12463 [(set (match_operand:SI 0 "s_register_operand" "=r")
12464 (clz:SI (match_operand:SI 1 "s_register_operand" "r")))]
12465 "TARGET_32BIT && arm_arch5"
12467 [(set_attr "predicable" "yes")
12468 (set_attr "type" "clz")])
12470 (define_insn "rbitsi2"
12471 [(set (match_operand:SI 0 "s_register_operand" "=r")
12472 (unspec:SI [(match_operand:SI 1 "s_register_operand" "r")] UNSPEC_RBIT))]
12473 "TARGET_32BIT && arm_arch_thumb2"
12475 [(set_attr "predicable" "yes")
12476 (set_attr "type" "clz")])
12478 (define_expand "ctzsi2"
12479 [(set (match_operand:SI 0 "s_register_operand" "")
12480 (ctz:SI (match_operand:SI 1 "s_register_operand" "")))]
12481 "TARGET_32BIT && arm_arch_thumb2"
12484 rtx tmp = gen_reg_rtx (SImode);
12485 emit_insn (gen_rbitsi2 (tmp, operands[1]));
12486 emit_insn (gen_clzsi2 (operands[0], tmp));
12492 ;; V5E instructions.
12494 (define_insn "prefetch"
12495 [(prefetch (match_operand:SI 0 "address_operand" "p")
12496 (match_operand:SI 1 "" "")
12497 (match_operand:SI 2 "" ""))]
12498 "TARGET_32BIT && arm_arch5e"
12500 [(set_attr "type" "load1")]
12503 ;; General predication pattern
12506 [(match_operator 0 "arm_comparison_operator"
12507 [(match_operand 1 "cc_register" "")
12511 [(set_attr "predicated" "yes")]
12514 (define_insn "force_register_use"
12515 [(unspec:SI [(match_operand:SI 0 "register_operand" "")] UNSPEC_REGISTER_USE)]
12518 [(set_attr "length" "0")
12519 (set_attr "type" "no_insn")]
12523 ;; Patterns for exception handling
12525 (define_expand "eh_return"
12526 [(use (match_operand 0 "general_operand" ""))]
12531 emit_insn (gen_arm_eh_return (operands[0]));
12533 emit_insn (gen_thumb_eh_return (operands[0]));
12538 ;; We can't expand this before we know where the link register is stored.
12539 (define_insn_and_split "arm_eh_return"
12540 [(unspec_volatile [(match_operand:SI 0 "s_register_operand" "r")]
12542 (clobber (match_scratch:SI 1 "=&r"))]
12545 "&& reload_completed"
12549 arm_set_return_address (operands[0], operands[1]);
12554 (define_insn_and_split "thumb_eh_return"
12555 [(unspec_volatile [(match_operand:SI 0 "s_register_operand" "l")]
12557 (clobber (match_scratch:SI 1 "=&l"))]
12560 "&& reload_completed"
12564 thumb_set_return_address (operands[0], operands[1]);
12567 [(set_attr "type" "mov_reg")]
12573 (define_insn "load_tp_hard"
12574 [(set (match_operand:SI 0 "register_operand" "=r")
12575 (unspec:SI [(const_int 0)] UNSPEC_TLS))]
12577 "mrc%?\\tp15, 0, %0, c13, c0, 3\\t@ load_tp_hard"
12578 [(set_attr "predicable" "yes")
12579 (set_attr "type" "mrs")]
12582 ;; Doesn't clobber R1-R3. Must use r0 for the first operand.
12583 (define_insn "load_tp_soft"
12584 [(set (reg:SI 0) (unspec:SI [(const_int 0)] UNSPEC_TLS))
12585 (clobber (reg:SI LR_REGNUM))
12586 (clobber (reg:SI IP_REGNUM))
12587 (clobber (reg:CC CC_REGNUM))]
12589 "bl\\t__aeabi_read_tp\\t@ load_tp_soft"
12590 [(set_attr "conds" "clob")
12591 (set_attr "type" "branch")]
12594 ;; tls descriptor call
12595 (define_insn "tlscall"
12596 [(set (reg:SI R0_REGNUM)
12597 (unspec:SI [(reg:SI R0_REGNUM)
12598 (match_operand:SI 0 "" "X")
12599 (match_operand 1 "" "")] UNSPEC_TLS))
12600 (clobber (reg:SI R1_REGNUM))
12601 (clobber (reg:SI LR_REGNUM))
12602 (clobber (reg:SI CC_REGNUM))]
12605 targetm.asm_out.internal_label (asm_out_file, "LPIC",
12606 INTVAL (operands[1]));
12607 return "bl\\t%c0(tlscall)";
12609 [(set_attr "conds" "clob")
12610 (set_attr "length" "4")
12611 (set_attr "type" "branch")]
12614 ;; For thread pointer builtin
12615 (define_expand "get_thread_pointersi"
12616 [(match_operand:SI 0 "s_register_operand" "=r")]
12620 arm_load_tp (operands[0]);
12626 ;; We only care about the lower 16 bits of the constant
12627 ;; being inserted into the upper 16 bits of the register.
12628 (define_insn "*arm_movtas_ze"
12629 [(set (zero_extract:SI (match_operand:SI 0 "s_register_operand" "+r")
12632 (match_operand:SI 1 "const_int_operand" ""))]
12635 [(set_attr "predicable" "yes")
12636 (set_attr "predicable_short_it" "no")
12637 (set_attr "length" "4")
12638 (set_attr "type" "mov_imm")]
12641 (define_insn "*arm_rev"
12642 [(set (match_operand:SI 0 "s_register_operand" "=l,l,r")
12643 (bswap:SI (match_operand:SI 1 "s_register_operand" "l,l,r")))]
12649 [(set_attr "arch" "t1,t2,32")
12650 (set_attr "length" "2,2,4")
12651 (set_attr "type" "rev")]
12654 (define_expand "arm_legacy_rev"
12655 [(set (match_operand:SI 2 "s_register_operand" "")
12656 (xor:SI (rotatert:SI (match_operand:SI 1 "s_register_operand" "")
12660 (lshiftrt:SI (match_dup 2)
12662 (set (match_operand:SI 3 "s_register_operand" "")
12663 (rotatert:SI (match_dup 1)
12666 (and:SI (match_dup 2)
12667 (const_int -65281)))
12668 (set (match_operand:SI 0 "s_register_operand" "")
12669 (xor:SI (match_dup 3)
12675 ;; Reuse temporaries to keep register pressure down.
12676 (define_expand "thumb_legacy_rev"
12677 [(set (match_operand:SI 2 "s_register_operand" "")
12678 (ashift:SI (match_operand:SI 1 "s_register_operand" "")
12680 (set (match_operand:SI 3 "s_register_operand" "")
12681 (lshiftrt:SI (match_dup 1)
12684 (ior:SI (match_dup 3)
12686 (set (match_operand:SI 4 "s_register_operand" "")
12688 (set (match_operand:SI 5 "s_register_operand" "")
12689 (rotatert:SI (match_dup 1)
12692 (ashift:SI (match_dup 5)
12695 (lshiftrt:SI (match_dup 5)
12698 (ior:SI (match_dup 5)
12701 (rotatert:SI (match_dup 5)
12703 (set (match_operand:SI 0 "s_register_operand" "")
12704 (ior:SI (match_dup 5)
12710 (define_expand "bswapsi2"
12711 [(set (match_operand:SI 0 "s_register_operand" "=r")
12712 (bswap:SI (match_operand:SI 1 "s_register_operand" "r")))]
12713 "TARGET_EITHER && (arm_arch6 || !optimize_size)"
12717 rtx op2 = gen_reg_rtx (SImode);
12718 rtx op3 = gen_reg_rtx (SImode);
12722 rtx op4 = gen_reg_rtx (SImode);
12723 rtx op5 = gen_reg_rtx (SImode);
12725 emit_insn (gen_thumb_legacy_rev (operands[0], operands[1],
12726 op2, op3, op4, op5));
12730 emit_insn (gen_arm_legacy_rev (operands[0], operands[1],
12739 ;; bswap16 patterns: use revsh and rev16 instructions for the signed
12740 ;; and unsigned variants, respectively. For rev16, expose
12741 ;; byte-swapping in the lower 16 bits only.
12742 (define_insn "*arm_revsh"
12743 [(set (match_operand:SI 0 "s_register_operand" "=l,l,r")
12744 (sign_extend:SI (bswap:HI (match_operand:HI 1 "s_register_operand" "l,l,r"))))]
12750 [(set_attr "arch" "t1,t2,32")
12751 (set_attr "length" "2,2,4")
12752 (set_attr "type" "rev")]
12755 (define_insn "*arm_rev16"
12756 [(set (match_operand:HI 0 "s_register_operand" "=l,l,r")
12757 (bswap:HI (match_operand:HI 1 "s_register_operand" "l,l,r")))]
12763 [(set_attr "arch" "t1,t2,32")
12764 (set_attr "length" "2,2,4")
12765 (set_attr "type" "rev")]
12768 (define_expand "bswaphi2"
12769 [(set (match_operand:HI 0 "s_register_operand" "=r")
12770 (bswap:HI (match_operand:HI 1 "s_register_operand" "r")))]
12775 ;; Patterns for LDRD/STRD in Thumb2 mode
12777 (define_insn "*thumb2_ldrd"
12778 [(set (match_operand:SI 0 "s_register_operand" "=r")
12779 (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "rk")
12780 (match_operand:SI 2 "ldrd_strd_offset_operand" "Do"))))
12781 (set (match_operand:SI 3 "s_register_operand" "=r")
12782 (mem:SI (plus:SI (match_dup 1)
12783 (match_operand:SI 4 "const_int_operand" ""))))]
12784 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
12785 && current_tune->prefer_ldrd_strd
12786 && ((INTVAL (operands[2]) + 4) == INTVAL (operands[4]))
12787 && (operands_ok_ldrd_strd (operands[0], operands[3],
12788 operands[1], INTVAL (operands[2]),
12790 "ldrd%?\t%0, %3, [%1, %2]"
12791 [(set_attr "type" "load2")
12792 (set_attr "predicable" "yes")
12793 (set_attr "predicable_short_it" "no")])
12795 (define_insn "*thumb2_ldrd_base"
12796 [(set (match_operand:SI 0 "s_register_operand" "=r")
12797 (mem:SI (match_operand:SI 1 "s_register_operand" "rk")))
12798 (set (match_operand:SI 2 "s_register_operand" "=r")
12799 (mem:SI (plus:SI (match_dup 1)
12801 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
12802 && current_tune->prefer_ldrd_strd
12803 && (operands_ok_ldrd_strd (operands[0], operands[2],
12804 operands[1], 0, false, true))"
12805 "ldrd%?\t%0, %2, [%1]"
12806 [(set_attr "type" "load2")
12807 (set_attr "predicable" "yes")
12808 (set_attr "predicable_short_it" "no")])
12810 (define_insn "*thumb2_ldrd_base_neg"
12811 [(set (match_operand:SI 0 "s_register_operand" "=r")
12812 (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "rk")
12814 (set (match_operand:SI 2 "s_register_operand" "=r")
12815 (mem:SI (match_dup 1)))]
12816 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
12817 && current_tune->prefer_ldrd_strd
12818 && (operands_ok_ldrd_strd (operands[0], operands[2],
12819 operands[1], -4, false, true))"
12820 "ldrd%?\t%0, %2, [%1, #-4]"
12821 [(set_attr "type" "load2")
12822 (set_attr "predicable" "yes")
12823 (set_attr "predicable_short_it" "no")])
12825 (define_insn "*thumb2_strd"
12826 [(set (mem:SI (plus:SI (match_operand:SI 0 "s_register_operand" "rk")
12827 (match_operand:SI 1 "ldrd_strd_offset_operand" "Do")))
12828 (match_operand:SI 2 "s_register_operand" "r"))
12829 (set (mem:SI (plus:SI (match_dup 0)
12830 (match_operand:SI 3 "const_int_operand" "")))
12831 (match_operand:SI 4 "s_register_operand" "r"))]
12832 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
12833 && current_tune->prefer_ldrd_strd
12834 && ((INTVAL (operands[1]) + 4) == INTVAL (operands[3]))
12835 && (operands_ok_ldrd_strd (operands[2], operands[4],
12836 operands[0], INTVAL (operands[1]),
12838 "strd%?\t%2, %4, [%0, %1]"
12839 [(set_attr "type" "store2")
12840 (set_attr "predicable" "yes")
12841 (set_attr "predicable_short_it" "no")])
12843 (define_insn "*thumb2_strd_base"
12844 [(set (mem:SI (match_operand:SI 0 "s_register_operand" "rk"))
12845 (match_operand:SI 1 "s_register_operand" "r"))
12846 (set (mem:SI (plus:SI (match_dup 0)
12848 (match_operand:SI 2 "s_register_operand" "r"))]
12849 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
12850 && current_tune->prefer_ldrd_strd
12851 && (operands_ok_ldrd_strd (operands[1], operands[2],
12852 operands[0], 0, false, false))"
12853 "strd%?\t%1, %2, [%0]"
12854 [(set_attr "type" "store2")
12855 (set_attr "predicable" "yes")
12856 (set_attr "predicable_short_it" "no")])
12858 (define_insn "*thumb2_strd_base_neg"
12859 [(set (mem:SI (plus:SI (match_operand:SI 0 "s_register_operand" "rk")
12861 (match_operand:SI 1 "s_register_operand" "r"))
12862 (set (mem:SI (match_dup 0))
12863 (match_operand:SI 2 "s_register_operand" "r"))]
12864 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
12865 && current_tune->prefer_ldrd_strd
12866 && (operands_ok_ldrd_strd (operands[1], operands[2],
12867 operands[0], -4, false, false))"
12868 "strd%?\t%1, %2, [%0, #-4]"
12869 [(set_attr "type" "store2")
12870 (set_attr "predicable" "yes")
12871 (set_attr "predicable_short_it" "no")])
12874 ;; Load the load/store double peephole optimizations.
12875 (include "ldrdstrd.md")
12877 ;; Load the load/store multiple patterns
12878 (include "ldmstm.md")
12880 ;; Patterns in ldmstm.md don't cover more than 4 registers. This pattern covers
12881 ;; large lists without explicit writeback generated for APCS_FRAME epilogue.
12882 (define_insn "*load_multiple"
12883 [(match_parallel 0 "load_multiple_operation"
12884 [(set (match_operand:SI 2 "s_register_operand" "=rk")
12885 (mem:SI (match_operand:SI 1 "s_register_operand" "rk")))
12890 arm_output_multireg_pop (operands, /*return_pc=*/false,
12891 /*cond=*/const_true_rtx,
12897 [(set_attr "predicable" "yes")]
12900 ;; Vector bits common to IWMMXT and Neon
12901 (include "vec-common.md")
12902 ;; Load the Intel Wireless Multimedia Extension patterns
12903 (include "iwmmxt.md")
12904 ;; Load the VFP co-processor patterns
12906 ;; Thumb-2 patterns
12907 (include "thumb2.md")
12909 (include "neon.md")
12910 ;; Synchronization Primitives
12911 (include "sync.md")
12912 ;; Fixed-point patterns
12913 (include "arm-fixed.md")