1 ;;- Machine description for ARM for GNU compiler
2 ;; Copyright (C) 1991-2014 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_d_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, crypto_aes,\
359 crypto_sha1_xor, crypto_sha1_fast, crypto_sha1_slow, crypto_sha256_fast,\
362 (const_string "no")))
364 ; condition codes: this one is used by final_prescan_insn to speed up
365 ; conditionalizing instructions. It saves having to scan the rtl to see if
366 ; it uses or alters the condition codes.
368 ; USE means that the condition codes are used by the insn in the process of
369 ; outputting code, this means (at present) that we can't use the insn in
372 ; SET means that the purpose of the insn is to set the condition codes in a
373 ; well defined manner.
375 ; CLOB means that the condition codes are altered in an undefined manner, if
376 ; they are altered at all
378 ; UNCONDITIONAL means the instruction can not be conditionally executed and
379 ; that the instruction does not use or alter the condition codes.
381 ; NOCOND means that the instruction does not use or alter the condition
382 ; codes but can be converted into a conditionally exectuted instruction.
384 (define_attr "conds" "use,set,clob,unconditional,nocond"
386 (ior (eq_attr "is_thumb1" "yes")
387 (eq_attr "type" "call"))
388 (const_string "clob")
389 (if_then_else (eq_attr "is_neon_type" "no")
390 (const_string "nocond")
391 (const_string "unconditional"))))
393 ; Predicable means that the insn can be conditionally executed based on
394 ; an automatically added predicate (additional patterns are generated by
395 ; gen...). We default to 'no' because no Thumb patterns match this rule
396 ; and not all ARM patterns do.
397 (define_attr "predicable" "no,yes" (const_string "no"))
399 ; Only model the write buffer for ARM6 and ARM7. Earlier processors don't
400 ; have one. Later ones, such as StrongARM, have write-back caches, so don't
401 ; suffer blockages enough to warrant modelling this (and it can adversely
402 ; affect the schedule).
403 (define_attr "model_wbuf" "no,yes" (const (symbol_ref "arm_tune_wbuf")))
405 ; WRITE_CONFLICT implies that a read following an unrelated write is likely
406 ; to stall the processor. Used with model_wbuf above.
407 (define_attr "write_conflict" "no,yes"
408 (if_then_else (eq_attr "type"
411 (const_string "no")))
413 ; Classify the insns into those that take one cycle and those that take more
414 ; than one on the main cpu execution unit.
415 (define_attr "core_cycles" "single,multi"
416 (if_then_else (eq_attr "type"
417 "adc_imm, adc_reg, adcs_imm, adcs_reg, adr, alu_ext, alu_imm, alu_reg,\
418 alu_shift_imm, alu_shift_reg, alus_ext, alus_imm, alus_reg,\
419 alus_shift_imm, alus_shift_reg, bfm, csel, rev, logic_imm, logic_reg,\
420 logic_shift_imm, logic_shift_reg, logics_imm, logics_reg,\
421 logics_shift_imm, logics_shift_reg, extend, shift_imm, float, fcsel,\
422 wmmx_wor, wmmx_wxor, wmmx_wand, wmmx_wandn, wmmx_wmov, wmmx_tmcrr,\
423 wmmx_tmrrc, wmmx_wldr, wmmx_wstr, wmmx_tmcr, wmmx_tmrc, wmmx_wadd,\
424 wmmx_wsub, wmmx_wmul, wmmx_wmac, wmmx_wavg2, wmmx_tinsr, wmmx_textrm,\
425 wmmx_wshufh, wmmx_wcmpeq, wmmx_wcmpgt, wmmx_wmax, wmmx_wmin, wmmx_wpack,\
426 wmmx_wunpckih, wmmx_wunpckil, wmmx_wunpckeh, wmmx_wunpckel, wmmx_wror,\
427 wmmx_wsra, wmmx_wsrl, wmmx_wsll, wmmx_wmadd, wmmx_tmia, wmmx_tmiaph,\
428 wmmx_tmiaxy, wmmx_tbcst, wmmx_tmovmsk, wmmx_wacc, wmmx_waligni,\
429 wmmx_walignr, wmmx_tandc, wmmx_textrc, wmmx_torc, wmmx_torvsc, wmmx_wsad,\
430 wmmx_wabs, wmmx_wabsdiff, wmmx_waddsubhx, wmmx_wsubaddhx, wmmx_wavg4,\
431 wmmx_wmulw, wmmx_wqmulm, wmmx_wqmulwm, wmmx_waddbhus, wmmx_wqmiaxy,\
432 wmmx_wmiaxy, wmmx_wmiawxy, wmmx_wmerge")
433 (const_string "single")
434 (const_string "multi")))
436 ;; FAR_JUMP is "yes" if a BL instruction is used to generate a branch to a
437 ;; distant label. Only applicable to Thumb code.
438 (define_attr "far_jump" "yes,no" (const_string "no"))
441 ;; The number of machine instructions this pattern expands to.
442 ;; Used for Thumb-2 conditional execution.
443 (define_attr "ce_count" "" (const_int 1))
445 ;;---------------------------------------------------------------------------
448 (include "unspecs.md")
450 ;;---------------------------------------------------------------------------
453 (include "iterators.md")
455 ;;---------------------------------------------------------------------------
458 (include "predicates.md")
459 (include "constraints.md")
461 ;;---------------------------------------------------------------------------
462 ;; Pipeline descriptions
464 (define_attr "tune_cortexr4" "yes,no"
466 (eq_attr "tune" "cortexr4,cortexr4f,cortexr5")
468 (const_string "no"))))
470 ;; True if the generic scheduling description should be used.
472 (define_attr "generic_sched" "yes,no"
474 (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")
475 (eq_attr "tune_cortexr4" "yes"))
477 (const_string "yes"))))
479 (define_attr "generic_vfp" "yes,no"
481 (and (eq_attr "fpu" "vfp")
482 (eq_attr "tune" "!arm1020e,arm1022e,cortexa5,cortexa7,cortexa8,cortexa9,cortexa53,cortexm4,marvell_pj4")
483 (eq_attr "tune_cortexr4" "no"))
485 (const_string "no"))))
487 (include "marvell-f-iwmmxt.md")
488 (include "arm-generic.md")
489 (include "arm926ejs.md")
490 (include "arm1020e.md")
491 (include "arm1026ejs.md")
492 (include "arm1136jfs.md")
494 (include "fa606te.md")
495 (include "fa626te.md")
496 (include "fmp626.md")
497 (include "fa726te.md")
498 (include "cortex-a5.md")
499 (include "cortex-a7.md")
500 (include "cortex-a8.md")
501 (include "cortex-a9.md")
502 (include "cortex-a15.md")
503 (include "cortex-a53.md")
504 (include "cortex-r4.md")
505 (include "cortex-r4f.md")
506 (include "cortex-m4.md")
507 (include "cortex-m4-fpu.md")
509 (include "marvell-pj4.md")
512 ;;---------------------------------------------------------------------------
517 ;; Note: For DImode insns, there is normally no reason why operands should
518 ;; not be in the same register, what we don't want is for something being
519 ;; written to partially overlap something that is an input.
521 (define_expand "adddi3"
523 [(set (match_operand:DI 0 "s_register_operand" "")
524 (plus:DI (match_operand:DI 1 "s_register_operand" "")
525 (match_operand:DI 2 "arm_adddi_operand" "")))
526 (clobber (reg:CC CC_REGNUM))])]
531 if (!REG_P (operands[1]))
532 operands[1] = force_reg (DImode, operands[1]);
533 if (!REG_P (operands[2]))
534 operands[2] = force_reg (DImode, operands[2]);
539 (define_insn "*thumb1_adddi3"
540 [(set (match_operand:DI 0 "register_operand" "=l")
541 (plus:DI (match_operand:DI 1 "register_operand" "%0")
542 (match_operand:DI 2 "register_operand" "l")))
543 (clobber (reg:CC CC_REGNUM))
546 "add\\t%Q0, %Q0, %Q2\;adc\\t%R0, %R0, %R2"
547 [(set_attr "length" "4")
548 (set_attr "type" "multiple")]
551 (define_insn_and_split "*arm_adddi3"
552 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r,&r,&r,&r")
553 (plus:DI (match_operand:DI 1 "s_register_operand" "%0, 0, r, 0, r")
554 (match_operand:DI 2 "arm_adddi_operand" "r, 0, r, Dd, Dd")))
555 (clobber (reg:CC CC_REGNUM))]
556 "TARGET_32BIT && !TARGET_NEON"
558 "TARGET_32BIT && reload_completed
559 && ! (TARGET_NEON && IS_VFP_REGNUM (REGNO (operands[0])))"
560 [(parallel [(set (reg:CC_C CC_REGNUM)
561 (compare:CC_C (plus:SI (match_dup 1) (match_dup 2))
563 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
564 (set (match_dup 3) (plus:SI (plus:SI (match_dup 4) (match_dup 5))
565 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
568 operands[3] = gen_highpart (SImode, operands[0]);
569 operands[0] = gen_lowpart (SImode, operands[0]);
570 operands[4] = gen_highpart (SImode, operands[1]);
571 operands[1] = gen_lowpart (SImode, operands[1]);
572 operands[5] = gen_highpart_mode (SImode, DImode, operands[2]);
573 operands[2] = gen_lowpart (SImode, operands[2]);
575 [(set_attr "conds" "clob")
576 (set_attr "length" "8")
577 (set_attr "type" "multiple")]
580 (define_insn_and_split "*adddi_sesidi_di"
581 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
582 (plus:DI (sign_extend:DI
583 (match_operand:SI 2 "s_register_operand" "r,r"))
584 (match_operand:DI 1 "s_register_operand" "0,r")))
585 (clobber (reg:CC CC_REGNUM))]
588 "TARGET_32BIT && reload_completed"
589 [(parallel [(set (reg:CC_C CC_REGNUM)
590 (compare:CC_C (plus:SI (match_dup 1) (match_dup 2))
592 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
593 (set (match_dup 3) (plus:SI (plus:SI (ashiftrt:SI (match_dup 2)
596 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
599 operands[3] = gen_highpart (SImode, operands[0]);
600 operands[0] = gen_lowpart (SImode, operands[0]);
601 operands[4] = gen_highpart (SImode, operands[1]);
602 operands[1] = gen_lowpart (SImode, operands[1]);
603 operands[2] = gen_lowpart (SImode, operands[2]);
605 [(set_attr "conds" "clob")
606 (set_attr "length" "8")
607 (set_attr "type" "multiple")]
610 (define_insn_and_split "*adddi_zesidi_di"
611 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
612 (plus:DI (zero_extend:DI
613 (match_operand:SI 2 "s_register_operand" "r,r"))
614 (match_operand:DI 1 "s_register_operand" "0,r")))
615 (clobber (reg:CC CC_REGNUM))]
618 "TARGET_32BIT && reload_completed"
619 [(parallel [(set (reg:CC_C CC_REGNUM)
620 (compare:CC_C (plus:SI (match_dup 1) (match_dup 2))
622 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
623 (set (match_dup 3) (plus:SI (plus:SI (match_dup 4) (const_int 0))
624 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
627 operands[3] = gen_highpart (SImode, operands[0]);
628 operands[0] = gen_lowpart (SImode, operands[0]);
629 operands[4] = gen_highpart (SImode, operands[1]);
630 operands[1] = gen_lowpart (SImode, operands[1]);
631 operands[2] = gen_lowpart (SImode, operands[2]);
633 [(set_attr "conds" "clob")
634 (set_attr "length" "8")
635 (set_attr "type" "multiple")]
638 (define_expand "addsi3"
639 [(set (match_operand:SI 0 "s_register_operand" "")
640 (plus:SI (match_operand:SI 1 "s_register_operand" "")
641 (match_operand:SI 2 "reg_or_int_operand" "")))]
644 if (TARGET_32BIT && CONST_INT_P (operands[2]))
646 arm_split_constant (PLUS, SImode, NULL_RTX,
647 INTVAL (operands[2]), operands[0], operands[1],
648 optimize && can_create_pseudo_p ());
654 ; If there is a scratch available, this will be faster than synthesizing the
657 [(match_scratch:SI 3 "r")
658 (set (match_operand:SI 0 "arm_general_register_operand" "")
659 (plus:SI (match_operand:SI 1 "arm_general_register_operand" "")
660 (match_operand:SI 2 "const_int_operand" "")))]
662 !(const_ok_for_arm (INTVAL (operands[2]))
663 || const_ok_for_arm (-INTVAL (operands[2])))
664 && const_ok_for_arm (~INTVAL (operands[2]))"
665 [(set (match_dup 3) (match_dup 2))
666 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 3)))]
670 ;; The r/r/k alternative is required when reloading the address
671 ;; (plus (reg rN) (reg sp)) into (reg rN). In this case reload will
672 ;; put the duplicated register first, and not try the commutative version.
673 (define_insn_and_split "*arm_addsi3"
674 [(set (match_operand:SI 0 "s_register_operand" "=rk,l,l ,l ,r ,k ,r,r ,k ,r ,k,k,r ,k ,r")
675 (plus:SI (match_operand:SI 1 "s_register_operand" "%0 ,l,0 ,l ,rk,k ,r,rk,k ,rk,k,r,rk,k ,rk")
676 (match_operand:SI 2 "reg_or_int_operand" "rk ,l,Py,Pd,rI,rI,k,Pj,Pj,L ,L,L,PJ,PJ,?n")))]
691 subw%?\\t%0, %1, #%n2
692 subw%?\\t%0, %1, #%n2
695 && CONST_INT_P (operands[2])
696 && !const_ok_for_op (INTVAL (operands[2]), PLUS)
697 && (reload_completed || !arm_eliminable_register (operands[1]))"
698 [(clobber (const_int 0))]
700 arm_split_constant (PLUS, SImode, curr_insn,
701 INTVAL (operands[2]), operands[0],
705 [(set_attr "length" "2,4,4,4,4,4,4,4,4,4,4,4,4,4,16")
706 (set_attr "predicable" "yes")
707 (set_attr "predicable_short_it" "yes,yes,yes,yes,no,no,no,no,no,no,no,no,no,no,no")
708 (set_attr "arch" "t2,t2,t2,t2,*,*,*,t2,t2,*,*,a,t2,t2,*")
709 (set (attr "type") (if_then_else (match_operand 2 "const_int_operand" "")
710 (const_string "alu_imm")
711 (const_string "alu_reg")))
715 (define_insn_and_split "*thumb1_addsi3"
716 [(set (match_operand:SI 0 "register_operand" "=l,l,l,*rk,*hk,l,k,l,l,l")
717 (plus:SI (match_operand:SI 1 "register_operand" "%0,0,l,*0,*0,k,k,0,l,k")
718 (match_operand:SI 2 "nonmemory_operand" "I,J,lL,*hk,*rk,M,O,Pa,Pb,Pc")))]
721 static const char * const asms[] =
723 \"add\\t%0, %0, %2\",
724 \"sub\\t%0, %0, #%n2\",
725 \"add\\t%0, %1, %2\",
726 \"add\\t%0, %0, %2\",
727 \"add\\t%0, %0, %2\",
728 \"add\\t%0, %1, %2\",
729 \"add\\t%0, %1, %2\",
734 if ((which_alternative == 2 || which_alternative == 6)
735 && CONST_INT_P (operands[2])
736 && INTVAL (operands[2]) < 0)
737 return \"sub\\t%0, %1, #%n2\";
738 return asms[which_alternative];
740 "&& reload_completed && CONST_INT_P (operands[2])
741 && ((operands[1] != stack_pointer_rtx
742 && (INTVAL (operands[2]) > 255 || INTVAL (operands[2]) < -255))
743 || (operands[1] == stack_pointer_rtx
744 && INTVAL (operands[2]) > 1020))"
745 [(set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))
746 (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 3)))]
748 HOST_WIDE_INT offset = INTVAL (operands[2]);
749 if (operands[1] == stack_pointer_rtx)
755 else if (offset < -255)
758 operands[3] = GEN_INT (offset);
759 operands[2] = GEN_INT (INTVAL (operands[2]) - offset);
761 [(set_attr "length" "2,2,2,2,2,2,2,4,4,4")
762 (set_attr "type" "alus_imm,alus_imm,alus_reg,alus_reg,alus_reg,
763 alus_reg,alus_reg,multiple,multiple,multiple")]
766 ;; Reloading and elimination of the frame pointer can
767 ;; sometimes cause this optimization to be missed.
769 [(set (match_operand:SI 0 "arm_general_register_operand" "")
770 (match_operand:SI 1 "const_int_operand" ""))
772 (plus:SI (match_dup 0) (reg:SI SP_REGNUM)))]
774 && (unsigned HOST_WIDE_INT) (INTVAL (operands[1])) < 1024
775 && (INTVAL (operands[1]) & 3) == 0"
776 [(set (match_dup 0) (plus:SI (reg:SI SP_REGNUM) (match_dup 1)))]
780 (define_insn "addsi3_compare0"
781 [(set (reg:CC_NOOV CC_REGNUM)
783 (plus:SI (match_operand:SI 1 "s_register_operand" "r, r,r")
784 (match_operand:SI 2 "arm_add_operand" "I,L,r"))
786 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
787 (plus:SI (match_dup 1) (match_dup 2)))]
793 [(set_attr "conds" "set")
794 (set_attr "type" "alus_imm,alus_imm,alus_reg")]
797 (define_insn "*addsi3_compare0_scratch"
798 [(set (reg:CC_NOOV CC_REGNUM)
800 (plus:SI (match_operand:SI 0 "s_register_operand" "r, r, r")
801 (match_operand:SI 1 "arm_add_operand" "I,L, r"))
808 [(set_attr "conds" "set")
809 (set_attr "predicable" "yes")
810 (set_attr "type" "alus_imm,alus_imm,alus_reg")]
813 (define_insn "*compare_negsi_si"
814 [(set (reg:CC_Z CC_REGNUM)
816 (neg:SI (match_operand:SI 0 "s_register_operand" "l,r"))
817 (match_operand:SI 1 "s_register_operand" "l,r")))]
820 [(set_attr "conds" "set")
821 (set_attr "predicable" "yes")
822 (set_attr "arch" "t2,*")
823 (set_attr "length" "2,4")
824 (set_attr "predicable_short_it" "yes,no")
825 (set_attr "type" "alus_reg")]
828 ;; This is the canonicalization of addsi3_compare0_for_combiner when the
829 ;; addend is a constant.
830 (define_insn "cmpsi2_addneg"
831 [(set (reg:CC CC_REGNUM)
833 (match_operand:SI 1 "s_register_operand" "r,r")
834 (match_operand:SI 2 "arm_addimm_operand" "L,I")))
835 (set (match_operand:SI 0 "s_register_operand" "=r,r")
836 (plus:SI (match_dup 1)
837 (match_operand:SI 3 "arm_addimm_operand" "I,L")))]
838 "TARGET_32BIT && INTVAL (operands[2]) == -INTVAL (operands[3])"
841 sub%.\\t%0, %1, #%n3"
842 [(set_attr "conds" "set")
843 (set_attr "type" "alus_reg")]
846 ;; Convert the sequence
848 ;; cmn rd, #1 (equivalent to cmp rd, #-1)
852 ;; bcs dest ((unsigned)rn >= 1)
853 ;; similarly for the beq variant using bcc.
854 ;; This is a common looping idiom (while (n--))
856 [(set (match_operand:SI 0 "arm_general_register_operand" "")
857 (plus:SI (match_operand:SI 1 "arm_general_register_operand" "")
859 (set (match_operand 2 "cc_register" "")
860 (compare (match_dup 0) (const_int -1)))
862 (if_then_else (match_operator 3 "equality_operator"
863 [(match_dup 2) (const_int 0)])
864 (match_operand 4 "" "")
865 (match_operand 5 "" "")))]
866 "TARGET_32BIT && peep2_reg_dead_p (3, operands[2])"
870 (match_dup 1) (const_int 1)))
871 (set (match_dup 0) (plus:SI (match_dup 1) (const_int -1)))])
873 (if_then_else (match_op_dup 3 [(match_dup 2) (const_int 0)])
876 "operands[2] = gen_rtx_REG (CCmode, CC_REGNUM);
877 operands[3] = gen_rtx_fmt_ee ((GET_CODE (operands[3]) == NE
880 operands[2], const0_rtx);"
883 ;; The next four insns work because they compare the result with one of
884 ;; the operands, and we know that the use of the condition code is
885 ;; either GEU or LTU, so we can use the carry flag from the addition
886 ;; instead of doing the compare a second time.
887 (define_insn "*addsi3_compare_op1"
888 [(set (reg:CC_C CC_REGNUM)
890 (plus:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
891 (match_operand:SI 2 "arm_add_operand" "I,L,r"))
893 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
894 (plus:SI (match_dup 1) (match_dup 2)))]
900 [(set_attr "conds" "set")
901 (set_attr "type" "alus_imm,alus_imm,alus_reg")]
904 (define_insn "*addsi3_compare_op2"
905 [(set (reg:CC_C CC_REGNUM)
907 (plus:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
908 (match_operand:SI 2 "arm_add_operand" "I,L,r"))
910 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
911 (plus:SI (match_dup 1) (match_dup 2)))]
916 sub%.\\t%0, %1, #%n2"
917 [(set_attr "conds" "set")
918 (set_attr "type" "alus_imm,alus_imm,alus_reg")]
921 (define_insn "*compare_addsi2_op0"
922 [(set (reg:CC_C CC_REGNUM)
924 (plus:SI (match_operand:SI 0 "s_register_operand" "l,l,r,r,r")
925 (match_operand:SI 1 "arm_add_operand" "Pv,l,I,L,r"))
934 [(set_attr "conds" "set")
935 (set_attr "predicable" "yes")
936 (set_attr "arch" "t2,t2,*,*,*")
937 (set_attr "predicable_short_it" "yes,yes,no,no,no")
938 (set_attr "length" "2,2,4,4,4")
939 (set_attr "type" "alus_imm,alus_reg,alus_imm,alus_imm,alus_reg")]
942 (define_insn "*compare_addsi2_op1"
943 [(set (reg:CC_C CC_REGNUM)
945 (plus:SI (match_operand:SI 0 "s_register_operand" "l,l,r,r,r")
946 (match_operand:SI 1 "arm_add_operand" "Pv,l,I,L,r"))
955 [(set_attr "conds" "set")
956 (set_attr "predicable" "yes")
957 (set_attr "arch" "t2,t2,*,*,*")
958 (set_attr "predicable_short_it" "yes,yes,no,no,no")
959 (set_attr "length" "2,2,4,4,4")
960 (set_attr "type" "alus_imm,alus_reg,alus_imm,alus_imm,alus_reg")]
963 (define_insn "*addsi3_carryin_<optab>"
964 [(set (match_operand:SI 0 "s_register_operand" "=l,r,r")
965 (plus:SI (plus:SI (match_operand:SI 1 "s_register_operand" "%l,r,r")
966 (match_operand:SI 2 "arm_not_operand" "0,rI,K"))
967 (LTUGEU:SI (reg:<cnb> CC_REGNUM) (const_int 0))))]
972 sbc%?\\t%0, %1, #%B2"
973 [(set_attr "conds" "use")
974 (set_attr "predicable" "yes")
975 (set_attr "arch" "t2,*,*")
976 (set_attr "length" "4")
977 (set_attr "predicable_short_it" "yes,no,no")
978 (set_attr "type" "adc_reg,adc_reg,adc_imm")]
981 (define_insn "*addsi3_carryin_alt2_<optab>"
982 [(set (match_operand:SI 0 "s_register_operand" "=l,r,r")
983 (plus:SI (plus:SI (LTUGEU:SI (reg:<cnb> CC_REGNUM) (const_int 0))
984 (match_operand:SI 1 "s_register_operand" "%l,r,r"))
985 (match_operand:SI 2 "arm_rhs_operand" "l,rI,K")))]
990 sbc%?\\t%0, %1, #%B2"
991 [(set_attr "conds" "use")
992 (set_attr "predicable" "yes")
993 (set_attr "arch" "t2,*,*")
994 (set_attr "length" "4")
995 (set_attr "predicable_short_it" "yes,no,no")
996 (set_attr "type" "adc_reg,adc_reg,adc_imm")]
999 (define_insn "*addsi3_carryin_shift_<optab>"
1000 [(set (match_operand:SI 0 "s_register_operand" "=r")
1002 (match_operator:SI 2 "shift_operator"
1003 [(match_operand:SI 3 "s_register_operand" "r")
1004 (match_operand:SI 4 "reg_or_int_operand" "rM")])
1005 (match_operand:SI 1 "s_register_operand" "r"))
1006 (LTUGEU:SI (reg:<cnb> CC_REGNUM) (const_int 0))))]
1008 "adc%?\\t%0, %1, %3%S2"
1009 [(set_attr "conds" "use")
1010 (set_attr "predicable" "yes")
1011 (set_attr "predicable_short_it" "no")
1012 (set (attr "type") (if_then_else (match_operand 4 "const_int_operand" "")
1013 (const_string "alu_shift_imm")
1014 (const_string "alu_shift_reg")))]
1017 (define_insn "*addsi3_carryin_clobercc_<optab>"
1018 [(set (match_operand:SI 0 "s_register_operand" "=r")
1019 (plus:SI (plus:SI (match_operand:SI 1 "s_register_operand" "%r")
1020 (match_operand:SI 2 "arm_rhs_operand" "rI"))
1021 (LTUGEU:SI (reg:<cnb> CC_REGNUM) (const_int 0))))
1022 (clobber (reg:CC CC_REGNUM))]
1024 "adc%.\\t%0, %1, %2"
1025 [(set_attr "conds" "set")
1026 (set_attr "type" "adcs_reg")]
1029 (define_insn "*subsi3_carryin"
1030 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
1031 (minus:SI (minus:SI (match_operand:SI 1 "reg_or_int_operand" "r,I")
1032 (match_operand:SI 2 "s_register_operand" "r,r"))
1033 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1038 [(set_attr "conds" "use")
1039 (set_attr "arch" "*,a")
1040 (set_attr "predicable" "yes")
1041 (set_attr "predicable_short_it" "no")
1042 (set_attr "type" "adc_reg,adc_imm")]
1045 (define_insn "*subsi3_carryin_const"
1046 [(set (match_operand:SI 0 "s_register_operand" "=r")
1047 (minus:SI (plus:SI (match_operand:SI 1 "reg_or_int_operand" "r")
1048 (match_operand:SI 2 "arm_not_operand" "K"))
1049 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1051 "sbc\\t%0, %1, #%B2"
1052 [(set_attr "conds" "use")
1053 (set_attr "type" "adc_imm")]
1056 (define_insn "*subsi3_carryin_compare"
1057 [(set (reg:CC CC_REGNUM)
1058 (compare:CC (match_operand:SI 1 "s_register_operand" "r")
1059 (match_operand:SI 2 "s_register_operand" "r")))
1060 (set (match_operand:SI 0 "s_register_operand" "=r")
1061 (minus:SI (minus:SI (match_dup 1)
1063 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1066 [(set_attr "conds" "set")
1067 (set_attr "type" "adcs_reg")]
1070 (define_insn "*subsi3_carryin_compare_const"
1071 [(set (reg:CC CC_REGNUM)
1072 (compare:CC (match_operand:SI 1 "reg_or_int_operand" "r")
1073 (match_operand:SI 2 "arm_not_operand" "K")))
1074 (set (match_operand:SI 0 "s_register_operand" "=r")
1075 (minus:SI (plus:SI (match_dup 1)
1077 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1079 "sbcs\\t%0, %1, #%B2"
1080 [(set_attr "conds" "set")
1081 (set_attr "type" "adcs_imm")]
1084 (define_insn "*subsi3_carryin_shift"
1085 [(set (match_operand:SI 0 "s_register_operand" "=r")
1087 (match_operand:SI 1 "s_register_operand" "r")
1088 (match_operator:SI 2 "shift_operator"
1089 [(match_operand:SI 3 "s_register_operand" "r")
1090 (match_operand:SI 4 "reg_or_int_operand" "rM")]))
1091 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1093 "sbc%?\\t%0, %1, %3%S2"
1094 [(set_attr "conds" "use")
1095 (set_attr "predicable" "yes")
1096 (set (attr "type") (if_then_else (match_operand 4 "const_int_operand" "")
1097 (const_string "alu_shift_imm")
1098 (const_string "alu_shift_reg")))]
1101 (define_insn "*rsbsi3_carryin_shift"
1102 [(set (match_operand:SI 0 "s_register_operand" "=r")
1104 (match_operator:SI 2 "shift_operator"
1105 [(match_operand:SI 3 "s_register_operand" "r")
1106 (match_operand:SI 4 "reg_or_int_operand" "rM")])
1107 (match_operand:SI 1 "s_register_operand" "r"))
1108 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1110 "rsc%?\\t%0, %1, %3%S2"
1111 [(set_attr "conds" "use")
1112 (set_attr "predicable" "yes")
1113 (set (attr "type") (if_then_else (match_operand 4 "const_int_operand" "")
1114 (const_string "alu_shift_imm")
1115 (const_string "alu_shift_reg")))]
1118 ; transform ((x << y) - 1) to ~(~(x-1) << y) Where X is a constant.
1120 [(set (match_operand:SI 0 "s_register_operand" "")
1121 (plus:SI (ashift:SI (match_operand:SI 1 "const_int_operand" "")
1122 (match_operand:SI 2 "s_register_operand" ""))
1124 (clobber (match_operand:SI 3 "s_register_operand" ""))]
1126 [(set (match_dup 3) (match_dup 1))
1127 (set (match_dup 0) (not:SI (ashift:SI (match_dup 3) (match_dup 2))))]
1129 operands[1] = GEN_INT (~(INTVAL (operands[1]) - 1));
1132 (define_expand "addsf3"
1133 [(set (match_operand:SF 0 "s_register_operand" "")
1134 (plus:SF (match_operand:SF 1 "s_register_operand" "")
1135 (match_operand:SF 2 "s_register_operand" "")))]
1136 "TARGET_32BIT && TARGET_HARD_FLOAT"
1140 (define_expand "adddf3"
1141 [(set (match_operand:DF 0 "s_register_operand" "")
1142 (plus:DF (match_operand:DF 1 "s_register_operand" "")
1143 (match_operand:DF 2 "s_register_operand" "")))]
1144 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
1148 (define_expand "subdi3"
1150 [(set (match_operand:DI 0 "s_register_operand" "")
1151 (minus:DI (match_operand:DI 1 "s_register_operand" "")
1152 (match_operand:DI 2 "s_register_operand" "")))
1153 (clobber (reg:CC CC_REGNUM))])]
1158 if (!REG_P (operands[1]))
1159 operands[1] = force_reg (DImode, operands[1]);
1160 if (!REG_P (operands[2]))
1161 operands[2] = force_reg (DImode, operands[2]);
1166 (define_insn_and_split "*arm_subdi3"
1167 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r,&r")
1168 (minus:DI (match_operand:DI 1 "s_register_operand" "0,r,0")
1169 (match_operand:DI 2 "s_register_operand" "r,0,0")))
1170 (clobber (reg:CC CC_REGNUM))]
1171 "TARGET_32BIT && !TARGET_NEON"
1172 "#" ; "subs\\t%Q0, %Q1, %Q2\;sbc\\t%R0, %R1, %R2"
1173 "&& reload_completed"
1174 [(parallel [(set (reg:CC CC_REGNUM)
1175 (compare:CC (match_dup 1) (match_dup 2)))
1176 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
1177 (set (match_dup 3) (minus:SI (minus:SI (match_dup 4) (match_dup 5))
1178 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1180 operands[3] = gen_highpart (SImode, operands[0]);
1181 operands[0] = gen_lowpart (SImode, operands[0]);
1182 operands[4] = gen_highpart (SImode, operands[1]);
1183 operands[1] = gen_lowpart (SImode, operands[1]);
1184 operands[5] = gen_highpart (SImode, operands[2]);
1185 operands[2] = gen_lowpart (SImode, operands[2]);
1187 [(set_attr "conds" "clob")
1188 (set_attr "length" "8")
1189 (set_attr "type" "multiple")]
1192 (define_insn "*thumb_subdi3"
1193 [(set (match_operand:DI 0 "register_operand" "=l")
1194 (minus:DI (match_operand:DI 1 "register_operand" "0")
1195 (match_operand:DI 2 "register_operand" "l")))
1196 (clobber (reg:CC CC_REGNUM))]
1198 "sub\\t%Q0, %Q0, %Q2\;sbc\\t%R0, %R0, %R2"
1199 [(set_attr "length" "4")
1200 (set_attr "type" "multiple")]
1203 (define_insn_and_split "*subdi_di_zesidi"
1204 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1205 (minus:DI (match_operand:DI 1 "s_register_operand" "0,r")
1207 (match_operand:SI 2 "s_register_operand" "r,r"))))
1208 (clobber (reg:CC CC_REGNUM))]
1210 "#" ; "subs\\t%Q0, %Q1, %2\;sbc\\t%R0, %R1, #0"
1211 "&& reload_completed"
1212 [(parallel [(set (reg:CC CC_REGNUM)
1213 (compare:CC (match_dup 1) (match_dup 2)))
1214 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
1215 (set (match_dup 3) (minus:SI (plus:SI (match_dup 4) (match_dup 5))
1216 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1218 operands[3] = gen_highpart (SImode, operands[0]);
1219 operands[0] = gen_lowpart (SImode, operands[0]);
1220 operands[4] = gen_highpart (SImode, operands[1]);
1221 operands[1] = gen_lowpart (SImode, operands[1]);
1222 operands[5] = GEN_INT (~0);
1224 [(set_attr "conds" "clob")
1225 (set_attr "length" "8")
1226 (set_attr "type" "multiple")]
1229 (define_insn_and_split "*subdi_di_sesidi"
1230 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1231 (minus:DI (match_operand:DI 1 "s_register_operand" "0,r")
1233 (match_operand:SI 2 "s_register_operand" "r,r"))))
1234 (clobber (reg:CC CC_REGNUM))]
1236 "#" ; "subs\\t%Q0, %Q1, %2\;sbc\\t%R0, %R1, %2, asr #31"
1237 "&& reload_completed"
1238 [(parallel [(set (reg:CC CC_REGNUM)
1239 (compare:CC (match_dup 1) (match_dup 2)))
1240 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
1241 (set (match_dup 3) (minus:SI (minus:SI (match_dup 4)
1242 (ashiftrt:SI (match_dup 2)
1244 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1246 operands[3] = gen_highpart (SImode, operands[0]);
1247 operands[0] = gen_lowpart (SImode, operands[0]);
1248 operands[4] = gen_highpart (SImode, operands[1]);
1249 operands[1] = gen_lowpart (SImode, operands[1]);
1251 [(set_attr "conds" "clob")
1252 (set_attr "length" "8")
1253 (set_attr "type" "multiple")]
1256 (define_insn_and_split "*subdi_zesidi_di"
1257 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1258 (minus:DI (zero_extend:DI
1259 (match_operand:SI 2 "s_register_operand" "r,r"))
1260 (match_operand:DI 1 "s_register_operand" "0,r")))
1261 (clobber (reg:CC CC_REGNUM))]
1263 "#" ; "rsbs\\t%Q0, %Q1, %2\;rsc\\t%R0, %R1, #0"
1265 ; "subs\\t%Q0, %2, %Q1\;rsc\\t%R0, %R1, #0"
1266 "&& reload_completed"
1267 [(parallel [(set (reg:CC CC_REGNUM)
1268 (compare:CC (match_dup 2) (match_dup 1)))
1269 (set (match_dup 0) (minus:SI (match_dup 2) (match_dup 1)))])
1270 (set (match_dup 3) (minus:SI (minus:SI (const_int 0) (match_dup 4))
1271 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1273 operands[3] = gen_highpart (SImode, operands[0]);
1274 operands[0] = gen_lowpart (SImode, operands[0]);
1275 operands[4] = gen_highpart (SImode, operands[1]);
1276 operands[1] = gen_lowpart (SImode, operands[1]);
1278 [(set_attr "conds" "clob")
1279 (set_attr "length" "8")
1280 (set_attr "type" "multiple")]
1283 (define_insn_and_split "*subdi_sesidi_di"
1284 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1285 (minus:DI (sign_extend:DI
1286 (match_operand:SI 2 "s_register_operand" "r,r"))
1287 (match_operand:DI 1 "s_register_operand" "0,r")))
1288 (clobber (reg:CC CC_REGNUM))]
1290 "#" ; "rsbs\\t%Q0, %Q1, %2\;rsc\\t%R0, %R1, %2, asr #31"
1292 ; "subs\\t%Q0, %2, %Q1\;rsc\\t%R0, %R1, %2, asr #31"
1293 "&& reload_completed"
1294 [(parallel [(set (reg:CC CC_REGNUM)
1295 (compare:CC (match_dup 2) (match_dup 1)))
1296 (set (match_dup 0) (minus:SI (match_dup 2) (match_dup 1)))])
1297 (set (match_dup 3) (minus:SI (minus:SI
1298 (ashiftrt:SI (match_dup 2)
1301 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1303 operands[3] = gen_highpart (SImode, operands[0]);
1304 operands[0] = gen_lowpart (SImode, operands[0]);
1305 operands[4] = gen_highpart (SImode, operands[1]);
1306 operands[1] = gen_lowpart (SImode, operands[1]);
1308 [(set_attr "conds" "clob")
1309 (set_attr "length" "8")
1310 (set_attr "type" "multiple")]
1313 (define_insn_and_split "*subdi_zesidi_zesidi"
1314 [(set (match_operand:DI 0 "s_register_operand" "=r")
1315 (minus:DI (zero_extend:DI
1316 (match_operand:SI 1 "s_register_operand" "r"))
1318 (match_operand:SI 2 "s_register_operand" "r"))))
1319 (clobber (reg:CC CC_REGNUM))]
1321 "#" ; "subs\\t%Q0, %1, %2\;sbc\\t%R0, %1, %1"
1322 "&& reload_completed"
1323 [(parallel [(set (reg:CC CC_REGNUM)
1324 (compare:CC (match_dup 1) (match_dup 2)))
1325 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
1326 (set (match_dup 3) (minus:SI (minus:SI (match_dup 1) (match_dup 1))
1327 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1329 operands[3] = gen_highpart (SImode, operands[0]);
1330 operands[0] = gen_lowpart (SImode, operands[0]);
1332 [(set_attr "conds" "clob")
1333 (set_attr "length" "8")
1334 (set_attr "type" "multiple")]
1337 (define_expand "subsi3"
1338 [(set (match_operand:SI 0 "s_register_operand" "")
1339 (minus:SI (match_operand:SI 1 "reg_or_int_operand" "")
1340 (match_operand:SI 2 "s_register_operand" "")))]
1343 if (CONST_INT_P (operands[1]))
1347 arm_split_constant (MINUS, SImode, NULL_RTX,
1348 INTVAL (operands[1]), operands[0],
1349 operands[2], optimize && can_create_pseudo_p ());
1352 else /* TARGET_THUMB1 */
1353 operands[1] = force_reg (SImode, operands[1]);
1358 (define_insn "thumb1_subsi3_insn"
1359 [(set (match_operand:SI 0 "register_operand" "=l")
1360 (minus:SI (match_operand:SI 1 "register_operand" "l")
1361 (match_operand:SI 2 "reg_or_int_operand" "lPd")))]
1364 [(set_attr "length" "2")
1365 (set_attr "conds" "set")
1366 (set_attr "type" "alus_reg")]
1369 ; ??? Check Thumb-2 split length
1370 (define_insn_and_split "*arm_subsi3_insn"
1371 [(set (match_operand:SI 0 "s_register_operand" "=l,l ,l ,l ,r ,r,r,rk,r")
1372 (minus:SI (match_operand:SI 1 "reg_or_int_operand" "l ,0 ,l ,Pz,rI,r,r,k ,?n")
1373 (match_operand:SI 2 "reg_or_int_operand" "l ,Py,Pd,l ,r ,I,r,r ,r")))]
1385 "&& (CONST_INT_P (operands[1])
1386 && !const_ok_for_arm (INTVAL (operands[1])))"
1387 [(clobber (const_int 0))]
1389 arm_split_constant (MINUS, SImode, curr_insn,
1390 INTVAL (operands[1]), operands[0], operands[2], 0);
1393 [(set_attr "length" "4,4,4,4,4,4,4,4,16")
1394 (set_attr "arch" "t2,t2,t2,t2,*,*,*,*,*")
1395 (set_attr "predicable" "yes")
1396 (set_attr "predicable_short_it" "yes,yes,yes,yes,no,no,no,no,no")
1397 (set_attr "type" "alu_reg,alu_reg,alu_reg,alu_reg,alu_imm,alu_imm,alu_reg,alu_reg,multiple")]
1401 [(match_scratch:SI 3 "r")
1402 (set (match_operand:SI 0 "arm_general_register_operand" "")
1403 (minus:SI (match_operand:SI 1 "const_int_operand" "")
1404 (match_operand:SI 2 "arm_general_register_operand" "")))]
1406 && !const_ok_for_arm (INTVAL (operands[1]))
1407 && const_ok_for_arm (~INTVAL (operands[1]))"
1408 [(set (match_dup 3) (match_dup 1))
1409 (set (match_dup 0) (minus:SI (match_dup 3) (match_dup 2)))]
1413 (define_insn "*subsi3_compare0"
1414 [(set (reg:CC_NOOV CC_REGNUM)
1416 (minus:SI (match_operand:SI 1 "arm_rhs_operand" "r,r,I")
1417 (match_operand:SI 2 "arm_rhs_operand" "I,r,r"))
1419 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
1420 (minus:SI (match_dup 1) (match_dup 2)))]
1426 [(set_attr "conds" "set")
1427 (set_attr "type" "alus_imm,alus_reg,alus_reg")]
1430 (define_insn "subsi3_compare"
1431 [(set (reg:CC CC_REGNUM)
1432 (compare:CC (match_operand:SI 1 "arm_rhs_operand" "r,r,I")
1433 (match_operand:SI 2 "arm_rhs_operand" "I,r,r")))
1434 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
1435 (minus:SI (match_dup 1) (match_dup 2)))]
1441 [(set_attr "conds" "set")
1442 (set_attr "type" "alus_imm,alus_reg,alus_reg")]
1445 (define_expand "subsf3"
1446 [(set (match_operand:SF 0 "s_register_operand" "")
1447 (minus:SF (match_operand:SF 1 "s_register_operand" "")
1448 (match_operand:SF 2 "s_register_operand" "")))]
1449 "TARGET_32BIT && TARGET_HARD_FLOAT"
1453 (define_expand "subdf3"
1454 [(set (match_operand:DF 0 "s_register_operand" "")
1455 (minus:DF (match_operand:DF 1 "s_register_operand" "")
1456 (match_operand:DF 2 "s_register_operand" "")))]
1457 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
1462 ;; Multiplication insns
1464 (define_expand "mulhi3"
1465 [(set (match_operand:HI 0 "s_register_operand" "")
1466 (mult:HI (match_operand:HI 1 "s_register_operand" "")
1467 (match_operand:HI 2 "s_register_operand" "")))]
1468 "TARGET_DSP_MULTIPLY"
1471 rtx result = gen_reg_rtx (SImode);
1472 emit_insn (gen_mulhisi3 (result, operands[1], operands[2]));
1473 emit_move_insn (operands[0], gen_lowpart (HImode, result));
1478 (define_expand "mulsi3"
1479 [(set (match_operand:SI 0 "s_register_operand" "")
1480 (mult:SI (match_operand:SI 2 "s_register_operand" "")
1481 (match_operand:SI 1 "s_register_operand" "")))]
1486 ;; Use `&' and then `0' to prevent the operands 0 and 1 being the same
1487 (define_insn "*arm_mulsi3"
1488 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r")
1489 (mult:SI (match_operand:SI 2 "s_register_operand" "r,r")
1490 (match_operand:SI 1 "s_register_operand" "%0,r")))]
1491 "TARGET_32BIT && !arm_arch6"
1492 "mul%?\\t%0, %2, %1"
1493 [(set_attr "type" "mul")
1494 (set_attr "predicable" "yes")]
1497 (define_insn "*arm_mulsi3_v6"
1498 [(set (match_operand:SI 0 "s_register_operand" "=l,l,r")
1499 (mult:SI (match_operand:SI 1 "s_register_operand" "0,l,r")
1500 (match_operand:SI 2 "s_register_operand" "l,0,r")))]
1501 "TARGET_32BIT && arm_arch6"
1502 "mul%?\\t%0, %1, %2"
1503 [(set_attr "type" "mul")
1504 (set_attr "predicable" "yes")
1505 (set_attr "arch" "t2,t2,*")
1506 (set_attr "length" "4")
1507 (set_attr "predicable_short_it" "yes,yes,no")]
1510 ; Unfortunately with the Thumb the '&'/'0' trick can fails when operands
1511 ; 1 and 2; are the same, because reload will make operand 0 match
1512 ; operand 1 without realizing that this conflicts with operand 2. We fix
1513 ; this by adding another alternative to match this case, and then `reload'
1514 ; it ourselves. This alternative must come first.
1515 (define_insn "*thumb_mulsi3"
1516 [(set (match_operand:SI 0 "register_operand" "=&l,&l,&l")
1517 (mult:SI (match_operand:SI 1 "register_operand" "%l,*h,0")
1518 (match_operand:SI 2 "register_operand" "l,l,l")))]
1519 "TARGET_THUMB1 && !arm_arch6"
1521 if (which_alternative < 2)
1522 return \"mov\\t%0, %1\;mul\\t%0, %2\";
1524 return \"mul\\t%0, %2\";
1526 [(set_attr "length" "4,4,2")
1527 (set_attr "type" "muls")]
1530 (define_insn "*thumb_mulsi3_v6"
1531 [(set (match_operand:SI 0 "register_operand" "=l,l,l")
1532 (mult:SI (match_operand:SI 1 "register_operand" "0,l,0")
1533 (match_operand:SI 2 "register_operand" "l,0,0")))]
1534 "TARGET_THUMB1 && arm_arch6"
1539 [(set_attr "length" "2")
1540 (set_attr "type" "muls")]
1543 (define_insn "*mulsi3_compare0"
1544 [(set (reg:CC_NOOV CC_REGNUM)
1545 (compare:CC_NOOV (mult:SI
1546 (match_operand:SI 2 "s_register_operand" "r,r")
1547 (match_operand:SI 1 "s_register_operand" "%0,r"))
1549 (set (match_operand:SI 0 "s_register_operand" "=&r,&r")
1550 (mult:SI (match_dup 2) (match_dup 1)))]
1551 "TARGET_ARM && !arm_arch6"
1552 "mul%.\\t%0, %2, %1"
1553 [(set_attr "conds" "set")
1554 (set_attr "type" "muls")]
1557 (define_insn "*mulsi3_compare0_v6"
1558 [(set (reg:CC_NOOV CC_REGNUM)
1559 (compare:CC_NOOV (mult:SI
1560 (match_operand:SI 2 "s_register_operand" "r")
1561 (match_operand:SI 1 "s_register_operand" "r"))
1563 (set (match_operand:SI 0 "s_register_operand" "=r")
1564 (mult:SI (match_dup 2) (match_dup 1)))]
1565 "TARGET_ARM && arm_arch6 && optimize_size"
1566 "mul%.\\t%0, %2, %1"
1567 [(set_attr "conds" "set")
1568 (set_attr "type" "muls")]
1571 (define_insn "*mulsi_compare0_scratch"
1572 [(set (reg:CC_NOOV CC_REGNUM)
1573 (compare:CC_NOOV (mult:SI
1574 (match_operand:SI 2 "s_register_operand" "r,r")
1575 (match_operand:SI 1 "s_register_operand" "%0,r"))
1577 (clobber (match_scratch:SI 0 "=&r,&r"))]
1578 "TARGET_ARM && !arm_arch6"
1579 "mul%.\\t%0, %2, %1"
1580 [(set_attr "conds" "set")
1581 (set_attr "type" "muls")]
1584 (define_insn "*mulsi_compare0_scratch_v6"
1585 [(set (reg:CC_NOOV CC_REGNUM)
1586 (compare:CC_NOOV (mult:SI
1587 (match_operand:SI 2 "s_register_operand" "r")
1588 (match_operand:SI 1 "s_register_operand" "r"))
1590 (clobber (match_scratch:SI 0 "=r"))]
1591 "TARGET_ARM && arm_arch6 && optimize_size"
1592 "mul%.\\t%0, %2, %1"
1593 [(set_attr "conds" "set")
1594 (set_attr "type" "muls")]
1597 ;; Unnamed templates to match MLA instruction.
1599 (define_insn "*mulsi3addsi"
1600 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r,&r")
1602 (mult:SI (match_operand:SI 2 "s_register_operand" "r,r,r,r")
1603 (match_operand:SI 1 "s_register_operand" "%0,r,0,r"))
1604 (match_operand:SI 3 "s_register_operand" "r,r,0,0")))]
1605 "TARGET_32BIT && !arm_arch6"
1606 "mla%?\\t%0, %2, %1, %3"
1607 [(set_attr "type" "mla")
1608 (set_attr "predicable" "yes")]
1611 (define_insn "*mulsi3addsi_v6"
1612 [(set (match_operand:SI 0 "s_register_operand" "=r")
1614 (mult:SI (match_operand:SI 2 "s_register_operand" "r")
1615 (match_operand:SI 1 "s_register_operand" "r"))
1616 (match_operand:SI 3 "s_register_operand" "r")))]
1617 "TARGET_32BIT && arm_arch6"
1618 "mla%?\\t%0, %2, %1, %3"
1619 [(set_attr "type" "mla")
1620 (set_attr "predicable" "yes")
1621 (set_attr "predicable_short_it" "no")]
1624 (define_insn "*mulsi3addsi_compare0"
1625 [(set (reg:CC_NOOV CC_REGNUM)
1628 (match_operand:SI 2 "s_register_operand" "r,r,r,r")
1629 (match_operand:SI 1 "s_register_operand" "%0,r,0,r"))
1630 (match_operand:SI 3 "s_register_operand" "r,r,0,0"))
1632 (set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r,&r")
1633 (plus:SI (mult:SI (match_dup 2) (match_dup 1))
1635 "TARGET_ARM && arm_arch6"
1636 "mla%.\\t%0, %2, %1, %3"
1637 [(set_attr "conds" "set")
1638 (set_attr "type" "mlas")]
1641 (define_insn "*mulsi3addsi_compare0_v6"
1642 [(set (reg:CC_NOOV CC_REGNUM)
1645 (match_operand:SI 2 "s_register_operand" "r")
1646 (match_operand:SI 1 "s_register_operand" "r"))
1647 (match_operand:SI 3 "s_register_operand" "r"))
1649 (set (match_operand:SI 0 "s_register_operand" "=r")
1650 (plus:SI (mult:SI (match_dup 2) (match_dup 1))
1652 "TARGET_ARM && arm_arch6 && optimize_size"
1653 "mla%.\\t%0, %2, %1, %3"
1654 [(set_attr "conds" "set")
1655 (set_attr "type" "mlas")]
1658 (define_insn "*mulsi3addsi_compare0_scratch"
1659 [(set (reg:CC_NOOV CC_REGNUM)
1662 (match_operand:SI 2 "s_register_operand" "r,r,r,r")
1663 (match_operand:SI 1 "s_register_operand" "%0,r,0,r"))
1664 (match_operand:SI 3 "s_register_operand" "?r,r,0,0"))
1666 (clobber (match_scratch:SI 0 "=&r,&r,&r,&r"))]
1667 "TARGET_ARM && !arm_arch6"
1668 "mla%.\\t%0, %2, %1, %3"
1669 [(set_attr "conds" "set")
1670 (set_attr "type" "mlas")]
1673 (define_insn "*mulsi3addsi_compare0_scratch_v6"
1674 [(set (reg:CC_NOOV CC_REGNUM)
1677 (match_operand:SI 2 "s_register_operand" "r")
1678 (match_operand:SI 1 "s_register_operand" "r"))
1679 (match_operand:SI 3 "s_register_operand" "r"))
1681 (clobber (match_scratch:SI 0 "=r"))]
1682 "TARGET_ARM && arm_arch6 && optimize_size"
1683 "mla%.\\t%0, %2, %1, %3"
1684 [(set_attr "conds" "set")
1685 (set_attr "type" "mlas")]
1688 (define_insn "*mulsi3subsi"
1689 [(set (match_operand:SI 0 "s_register_operand" "=r")
1691 (match_operand:SI 3 "s_register_operand" "r")
1692 (mult:SI (match_operand:SI 2 "s_register_operand" "r")
1693 (match_operand:SI 1 "s_register_operand" "r"))))]
1694 "TARGET_32BIT && arm_arch_thumb2"
1695 "mls%?\\t%0, %2, %1, %3"
1696 [(set_attr "type" "mla")
1697 (set_attr "predicable" "yes")
1698 (set_attr "predicable_short_it" "no")]
1701 (define_expand "maddsidi4"
1702 [(set (match_operand:DI 0 "s_register_operand" "")
1705 (sign_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1706 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "")))
1707 (match_operand:DI 3 "s_register_operand" "")))]
1708 "TARGET_32BIT && arm_arch3m"
1711 (define_insn "*mulsidi3adddi"
1712 [(set (match_operand:DI 0 "s_register_operand" "=&r")
1715 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "%r"))
1716 (sign_extend:DI (match_operand:SI 3 "s_register_operand" "r")))
1717 (match_operand:DI 1 "s_register_operand" "0")))]
1718 "TARGET_32BIT && arm_arch3m && !arm_arch6"
1719 "smlal%?\\t%Q0, %R0, %3, %2"
1720 [(set_attr "type" "smlal")
1721 (set_attr "predicable" "yes")]
1724 (define_insn "*mulsidi3adddi_v6"
1725 [(set (match_operand:DI 0 "s_register_operand" "=r")
1728 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r"))
1729 (sign_extend:DI (match_operand:SI 3 "s_register_operand" "r")))
1730 (match_operand:DI 1 "s_register_operand" "0")))]
1731 "TARGET_32BIT && arm_arch6"
1732 "smlal%?\\t%Q0, %R0, %3, %2"
1733 [(set_attr "type" "smlal")
1734 (set_attr "predicable" "yes")
1735 (set_attr "predicable_short_it" "no")]
1738 ;; 32x32->64 widening multiply.
1739 ;; As with mulsi3, the only difference between the v3-5 and v6+
1740 ;; versions of these patterns is the requirement that the output not
1741 ;; overlap the inputs, but that still means we have to have a named
1742 ;; expander and two different starred insns.
1744 (define_expand "mulsidi3"
1745 [(set (match_operand:DI 0 "s_register_operand" "")
1747 (sign_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1748 (sign_extend:DI (match_operand:SI 2 "s_register_operand" ""))))]
1749 "TARGET_32BIT && arm_arch3m"
1753 (define_insn "*mulsidi3_nov6"
1754 [(set (match_operand:DI 0 "s_register_operand" "=&r")
1756 (sign_extend:DI (match_operand:SI 1 "s_register_operand" "%r"))
1757 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))]
1758 "TARGET_32BIT && arm_arch3m && !arm_arch6"
1759 "smull%?\\t%Q0, %R0, %1, %2"
1760 [(set_attr "type" "smull")
1761 (set_attr "predicable" "yes")]
1764 (define_insn "*mulsidi3_v6"
1765 [(set (match_operand:DI 0 "s_register_operand" "=r")
1767 (sign_extend:DI (match_operand:SI 1 "s_register_operand" "r"))
1768 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))]
1769 "TARGET_32BIT && arm_arch6"
1770 "smull%?\\t%Q0, %R0, %1, %2"
1771 [(set_attr "type" "smull")
1772 (set_attr "predicable" "yes")
1773 (set_attr "predicable_short_it" "no")]
1776 (define_expand "umulsidi3"
1777 [(set (match_operand:DI 0 "s_register_operand" "")
1779 (zero_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1780 (zero_extend:DI (match_operand:SI 2 "s_register_operand" ""))))]
1781 "TARGET_32BIT && arm_arch3m"
1785 (define_insn "*umulsidi3_nov6"
1786 [(set (match_operand:DI 0 "s_register_operand" "=&r")
1788 (zero_extend:DI (match_operand:SI 1 "s_register_operand" "%r"))
1789 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))]
1790 "TARGET_32BIT && arm_arch3m && !arm_arch6"
1791 "umull%?\\t%Q0, %R0, %1, %2"
1792 [(set_attr "type" "umull")
1793 (set_attr "predicable" "yes")]
1796 (define_insn "*umulsidi3_v6"
1797 [(set (match_operand:DI 0 "s_register_operand" "=r")
1799 (zero_extend:DI (match_operand:SI 1 "s_register_operand" "r"))
1800 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))]
1801 "TARGET_32BIT && arm_arch6"
1802 "umull%?\\t%Q0, %R0, %1, %2"
1803 [(set_attr "type" "umull")
1804 (set_attr "predicable" "yes")
1805 (set_attr "predicable_short_it" "no")]
1808 (define_expand "umaddsidi4"
1809 [(set (match_operand:DI 0 "s_register_operand" "")
1812 (zero_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1813 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "")))
1814 (match_operand:DI 3 "s_register_operand" "")))]
1815 "TARGET_32BIT && arm_arch3m"
1818 (define_insn "*umulsidi3adddi"
1819 [(set (match_operand:DI 0 "s_register_operand" "=&r")
1822 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "%r"))
1823 (zero_extend:DI (match_operand:SI 3 "s_register_operand" "r")))
1824 (match_operand:DI 1 "s_register_operand" "0")))]
1825 "TARGET_32BIT && arm_arch3m && !arm_arch6"
1826 "umlal%?\\t%Q0, %R0, %3, %2"
1827 [(set_attr "type" "umlal")
1828 (set_attr "predicable" "yes")]
1831 (define_insn "*umulsidi3adddi_v6"
1832 [(set (match_operand:DI 0 "s_register_operand" "=r")
1835 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r"))
1836 (zero_extend:DI (match_operand:SI 3 "s_register_operand" "r")))
1837 (match_operand:DI 1 "s_register_operand" "0")))]
1838 "TARGET_32BIT && arm_arch6"
1839 "umlal%?\\t%Q0, %R0, %3, %2"
1840 [(set_attr "type" "umlal")
1841 (set_attr "predicable" "yes")
1842 (set_attr "predicable_short_it" "no")]
1845 (define_expand "smulsi3_highpart"
1847 [(set (match_operand:SI 0 "s_register_operand" "")
1851 (sign_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1852 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "")))
1854 (clobber (match_scratch:SI 3 ""))])]
1855 "TARGET_32BIT && arm_arch3m"
1859 (define_insn "*smulsi3_highpart_nov6"
1860 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r")
1864 (sign_extend:DI (match_operand:SI 1 "s_register_operand" "%0,r"))
1865 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r,r")))
1867 (clobber (match_scratch:SI 3 "=&r,&r"))]
1868 "TARGET_32BIT && arm_arch3m && !arm_arch6"
1869 "smull%?\\t%3, %0, %2, %1"
1870 [(set_attr "type" "smull")
1871 (set_attr "predicable" "yes")]
1874 (define_insn "*smulsi3_highpart_v6"
1875 [(set (match_operand:SI 0 "s_register_operand" "=r")
1879 (sign_extend:DI (match_operand:SI 1 "s_register_operand" "r"))
1880 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r")))
1882 (clobber (match_scratch:SI 3 "=r"))]
1883 "TARGET_32BIT && arm_arch6"
1884 "smull%?\\t%3, %0, %2, %1"
1885 [(set_attr "type" "smull")
1886 (set_attr "predicable" "yes")
1887 (set_attr "predicable_short_it" "no")]
1890 (define_expand "umulsi3_highpart"
1892 [(set (match_operand:SI 0 "s_register_operand" "")
1896 (zero_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1897 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "")))
1899 (clobber (match_scratch:SI 3 ""))])]
1900 "TARGET_32BIT && arm_arch3m"
1904 (define_insn "*umulsi3_highpart_nov6"
1905 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r")
1909 (zero_extend:DI (match_operand:SI 1 "s_register_operand" "%0,r"))
1910 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r,r")))
1912 (clobber (match_scratch:SI 3 "=&r,&r"))]
1913 "TARGET_32BIT && arm_arch3m && !arm_arch6"
1914 "umull%?\\t%3, %0, %2, %1"
1915 [(set_attr "type" "umull")
1916 (set_attr "predicable" "yes")]
1919 (define_insn "*umulsi3_highpart_v6"
1920 [(set (match_operand:SI 0 "s_register_operand" "=r")
1924 (zero_extend:DI (match_operand:SI 1 "s_register_operand" "r"))
1925 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r")))
1927 (clobber (match_scratch:SI 3 "=r"))]
1928 "TARGET_32BIT && arm_arch6"
1929 "umull%?\\t%3, %0, %2, %1"
1930 [(set_attr "type" "umull")
1931 (set_attr "predicable" "yes")
1932 (set_attr "predicable_short_it" "no")]
1935 (define_insn "mulhisi3"
1936 [(set (match_operand:SI 0 "s_register_operand" "=r")
1937 (mult:SI (sign_extend:SI
1938 (match_operand:HI 1 "s_register_operand" "%r"))
1940 (match_operand:HI 2 "s_register_operand" "r"))))]
1941 "TARGET_DSP_MULTIPLY"
1942 "smulbb%?\\t%0, %1, %2"
1943 [(set_attr "type" "smulxy")
1944 (set_attr "predicable" "yes")]
1947 (define_insn "*mulhisi3tb"
1948 [(set (match_operand:SI 0 "s_register_operand" "=r")
1949 (mult:SI (ashiftrt:SI
1950 (match_operand:SI 1 "s_register_operand" "r")
1953 (match_operand:HI 2 "s_register_operand" "r"))))]
1954 "TARGET_DSP_MULTIPLY"
1955 "smultb%?\\t%0, %1, %2"
1956 [(set_attr "type" "smulxy")
1957 (set_attr "predicable" "yes")
1958 (set_attr "predicable_short_it" "no")]
1961 (define_insn "*mulhisi3bt"
1962 [(set (match_operand:SI 0 "s_register_operand" "=r")
1963 (mult:SI (sign_extend:SI
1964 (match_operand:HI 1 "s_register_operand" "r"))
1966 (match_operand:SI 2 "s_register_operand" "r")
1968 "TARGET_DSP_MULTIPLY"
1969 "smulbt%?\\t%0, %1, %2"
1970 [(set_attr "type" "smulxy")
1971 (set_attr "predicable" "yes")
1972 (set_attr "predicable_short_it" "no")]
1975 (define_insn "*mulhisi3tt"
1976 [(set (match_operand:SI 0 "s_register_operand" "=r")
1977 (mult:SI (ashiftrt:SI
1978 (match_operand:SI 1 "s_register_operand" "r")
1981 (match_operand:SI 2 "s_register_operand" "r")
1983 "TARGET_DSP_MULTIPLY"
1984 "smultt%?\\t%0, %1, %2"
1985 [(set_attr "type" "smulxy")
1986 (set_attr "predicable" "yes")
1987 (set_attr "predicable_short_it" "no")]
1990 (define_insn "maddhisi4"
1991 [(set (match_operand:SI 0 "s_register_operand" "=r")
1992 (plus:SI (mult:SI (sign_extend:SI
1993 (match_operand:HI 1 "s_register_operand" "r"))
1995 (match_operand:HI 2 "s_register_operand" "r")))
1996 (match_operand:SI 3 "s_register_operand" "r")))]
1997 "TARGET_DSP_MULTIPLY"
1998 "smlabb%?\\t%0, %1, %2, %3"
1999 [(set_attr "type" "smlaxy")
2000 (set_attr "predicable" "yes")
2001 (set_attr "predicable_short_it" "no")]
2004 ;; Note: there is no maddhisi4ibt because this one is canonical form
2005 (define_insn "*maddhisi4tb"
2006 [(set (match_operand:SI 0 "s_register_operand" "=r")
2007 (plus:SI (mult:SI (ashiftrt:SI
2008 (match_operand:SI 1 "s_register_operand" "r")
2011 (match_operand:HI 2 "s_register_operand" "r")))
2012 (match_operand:SI 3 "s_register_operand" "r")))]
2013 "TARGET_DSP_MULTIPLY"
2014 "smlatb%?\\t%0, %1, %2, %3"
2015 [(set_attr "type" "smlaxy")
2016 (set_attr "predicable" "yes")
2017 (set_attr "predicable_short_it" "no")]
2020 (define_insn "*maddhisi4tt"
2021 [(set (match_operand:SI 0 "s_register_operand" "=r")
2022 (plus:SI (mult:SI (ashiftrt:SI
2023 (match_operand:SI 1 "s_register_operand" "r")
2026 (match_operand:SI 2 "s_register_operand" "r")
2028 (match_operand:SI 3 "s_register_operand" "r")))]
2029 "TARGET_DSP_MULTIPLY"
2030 "smlatt%?\\t%0, %1, %2, %3"
2031 [(set_attr "type" "smlaxy")
2032 (set_attr "predicable" "yes")
2033 (set_attr "predicable_short_it" "no")]
2036 (define_insn "maddhidi4"
2037 [(set (match_operand:DI 0 "s_register_operand" "=r")
2039 (mult:DI (sign_extend:DI
2040 (match_operand:HI 1 "s_register_operand" "r"))
2042 (match_operand:HI 2 "s_register_operand" "r")))
2043 (match_operand:DI 3 "s_register_operand" "0")))]
2044 "TARGET_DSP_MULTIPLY"
2045 "smlalbb%?\\t%Q0, %R0, %1, %2"
2046 [(set_attr "type" "smlalxy")
2047 (set_attr "predicable" "yes")
2048 (set_attr "predicable_short_it" "no")])
2050 ;; Note: there is no maddhidi4ibt because this one is canonical form
2051 (define_insn "*maddhidi4tb"
2052 [(set (match_operand:DI 0 "s_register_operand" "=r")
2054 (mult:DI (sign_extend:DI
2056 (match_operand:SI 1 "s_register_operand" "r")
2059 (match_operand:HI 2 "s_register_operand" "r")))
2060 (match_operand:DI 3 "s_register_operand" "0")))]
2061 "TARGET_DSP_MULTIPLY"
2062 "smlaltb%?\\t%Q0, %R0, %1, %2"
2063 [(set_attr "type" "smlalxy")
2064 (set_attr "predicable" "yes")
2065 (set_attr "predicable_short_it" "no")])
2067 (define_insn "*maddhidi4tt"
2068 [(set (match_operand:DI 0 "s_register_operand" "=r")
2070 (mult:DI (sign_extend:DI
2072 (match_operand:SI 1 "s_register_operand" "r")
2076 (match_operand:SI 2 "s_register_operand" "r")
2078 (match_operand:DI 3 "s_register_operand" "0")))]
2079 "TARGET_DSP_MULTIPLY"
2080 "smlaltt%?\\t%Q0, %R0, %1, %2"
2081 [(set_attr "type" "smlalxy")
2082 (set_attr "predicable" "yes")
2083 (set_attr "predicable_short_it" "no")])
2085 (define_expand "mulsf3"
2086 [(set (match_operand:SF 0 "s_register_operand" "")
2087 (mult:SF (match_operand:SF 1 "s_register_operand" "")
2088 (match_operand:SF 2 "s_register_operand" "")))]
2089 "TARGET_32BIT && TARGET_HARD_FLOAT"
2093 (define_expand "muldf3"
2094 [(set (match_operand:DF 0 "s_register_operand" "")
2095 (mult:DF (match_operand:DF 1 "s_register_operand" "")
2096 (match_operand:DF 2 "s_register_operand" "")))]
2097 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
2103 (define_expand "divsf3"
2104 [(set (match_operand:SF 0 "s_register_operand" "")
2105 (div:SF (match_operand:SF 1 "s_register_operand" "")
2106 (match_operand:SF 2 "s_register_operand" "")))]
2107 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
2110 (define_expand "divdf3"
2111 [(set (match_operand:DF 0 "s_register_operand" "")
2112 (div:DF (match_operand:DF 1 "s_register_operand" "")
2113 (match_operand:DF 2 "s_register_operand" "")))]
2114 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
2117 ;; Boolean and,ior,xor insns
2119 ;; Split up double word logical operations
2121 ;; Split up simple DImode logical operations. Simply perform the logical
2122 ;; operation on the upper and lower halves of the registers.
2124 [(set (match_operand:DI 0 "s_register_operand" "")
2125 (match_operator:DI 6 "logical_binary_operator"
2126 [(match_operand:DI 1 "s_register_operand" "")
2127 (match_operand:DI 2 "s_register_operand" "")]))]
2128 "TARGET_32BIT && reload_completed
2129 && ! (TARGET_NEON && IS_VFP_REGNUM (REGNO (operands[0])))
2130 && ! IS_IWMMXT_REGNUM (REGNO (operands[0]))"
2131 [(set (match_dup 0) (match_op_dup:SI 6 [(match_dup 1) (match_dup 2)]))
2132 (set (match_dup 3) (match_op_dup:SI 6 [(match_dup 4) (match_dup 5)]))]
2135 operands[3] = gen_highpart (SImode, operands[0]);
2136 operands[0] = gen_lowpart (SImode, operands[0]);
2137 operands[4] = gen_highpart (SImode, operands[1]);
2138 operands[1] = gen_lowpart (SImode, operands[1]);
2139 operands[5] = gen_highpart (SImode, operands[2]);
2140 operands[2] = gen_lowpart (SImode, operands[2]);
2145 [(set (match_operand:DI 0 "s_register_operand" "")
2146 (match_operator:DI 6 "logical_binary_operator"
2147 [(sign_extend:DI (match_operand:SI 2 "s_register_operand" ""))
2148 (match_operand:DI 1 "s_register_operand" "")]))]
2149 "TARGET_32BIT && reload_completed"
2150 [(set (match_dup 0) (match_op_dup:SI 6 [(match_dup 1) (match_dup 2)]))
2151 (set (match_dup 3) (match_op_dup:SI 6
2152 [(ashiftrt:SI (match_dup 2) (const_int 31))
2156 operands[3] = gen_highpart (SImode, operands[0]);
2157 operands[0] = gen_lowpart (SImode, operands[0]);
2158 operands[4] = gen_highpart (SImode, operands[1]);
2159 operands[1] = gen_lowpart (SImode, operands[1]);
2160 operands[5] = gen_highpart (SImode, operands[2]);
2161 operands[2] = gen_lowpart (SImode, operands[2]);
2165 ;; The zero extend of operand 2 means we can just copy the high part of
2166 ;; operand1 into operand0.
2168 [(set (match_operand:DI 0 "s_register_operand" "")
2170 (zero_extend:DI (match_operand:SI 2 "s_register_operand" ""))
2171 (match_operand:DI 1 "s_register_operand" "")))]
2172 "TARGET_32BIT && operands[0] != operands[1] && reload_completed"
2173 [(set (match_dup 0) (ior:SI (match_dup 1) (match_dup 2)))
2174 (set (match_dup 3) (match_dup 4))]
2177 operands[4] = gen_highpart (SImode, operands[1]);
2178 operands[3] = gen_highpart (SImode, operands[0]);
2179 operands[0] = gen_lowpart (SImode, operands[0]);
2180 operands[1] = gen_lowpart (SImode, operands[1]);
2184 ;; The zero extend of operand 2 means we can just copy the high part of
2185 ;; operand1 into operand0.
2187 [(set (match_operand:DI 0 "s_register_operand" "")
2189 (zero_extend:DI (match_operand:SI 2 "s_register_operand" ""))
2190 (match_operand:DI 1 "s_register_operand" "")))]
2191 "TARGET_32BIT && operands[0] != operands[1] && reload_completed"
2192 [(set (match_dup 0) (xor:SI (match_dup 1) (match_dup 2)))
2193 (set (match_dup 3) (match_dup 4))]
2196 operands[4] = gen_highpart (SImode, operands[1]);
2197 operands[3] = gen_highpart (SImode, operands[0]);
2198 operands[0] = gen_lowpart (SImode, operands[0]);
2199 operands[1] = gen_lowpart (SImode, operands[1]);
2203 (define_expand "anddi3"
2204 [(set (match_operand:DI 0 "s_register_operand" "")
2205 (and:DI (match_operand:DI 1 "s_register_operand" "")
2206 (match_operand:DI 2 "neon_inv_logic_op2" "")))]
2211 (define_insn_and_split "*anddi3_insn"
2212 [(set (match_operand:DI 0 "s_register_operand" "=w,w ,&r,&r,&r,&r,?w,?w")
2213 (and:DI (match_operand:DI 1 "s_register_operand" "%w,0 ,0 ,r ,0 ,r ,w ,0")
2214 (match_operand:DI 2 "arm_anddi_operand_neon" "w ,DL,r ,r ,De,De,w ,DL")))]
2215 "TARGET_32BIT && !TARGET_IWMMXT"
2217 switch (which_alternative)
2219 case 0: /* fall through */
2220 case 6: return "vand\t%P0, %P1, %P2";
2221 case 1: /* fall through */
2222 case 7: return neon_output_logic_immediate ("vand", &operands[2],
2223 DImode, 1, VALID_NEON_QREG_MODE (DImode));
2227 case 5: /* fall through */
2229 default: gcc_unreachable ();
2232 "TARGET_32BIT && !TARGET_IWMMXT && reload_completed
2233 && !(IS_VFP_REGNUM (REGNO (operands[0])))"
2234 [(set (match_dup 3) (match_dup 4))
2235 (set (match_dup 5) (match_dup 6))]
2238 operands[3] = gen_lowpart (SImode, operands[0]);
2239 operands[5] = gen_highpart (SImode, operands[0]);
2241 operands[4] = simplify_gen_binary (AND, SImode,
2242 gen_lowpart (SImode, operands[1]),
2243 gen_lowpart (SImode, operands[2]));
2244 operands[6] = simplify_gen_binary (AND, SImode,
2245 gen_highpart (SImode, operands[1]),
2246 gen_highpart_mode (SImode, DImode, operands[2]));
2249 [(set_attr "type" "neon_logic,neon_logic,multiple,multiple,\
2250 multiple,multiple,neon_logic,neon_logic")
2251 (set_attr "arch" "neon_for_64bits,neon_for_64bits,*,*,*,*,
2252 avoid_neon_for_64bits,avoid_neon_for_64bits")
2253 (set_attr "length" "*,*,8,8,8,8,*,*")
2257 (define_insn_and_split "*anddi_zesidi_di"
2258 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2259 (and:DI (zero_extend:DI
2260 (match_operand:SI 2 "s_register_operand" "r,r"))
2261 (match_operand:DI 1 "s_register_operand" "0,r")))]
2264 "TARGET_32BIT && reload_completed"
2265 ; The zero extend of operand 2 clears the high word of the output
2267 [(set (match_dup 0) (and:SI (match_dup 1) (match_dup 2)))
2268 (set (match_dup 3) (const_int 0))]
2271 operands[3] = gen_highpart (SImode, operands[0]);
2272 operands[0] = gen_lowpart (SImode, operands[0]);
2273 operands[1] = gen_lowpart (SImode, operands[1]);
2275 [(set_attr "length" "8")
2276 (set_attr "type" "multiple")]
2279 (define_insn "*anddi_sesdi_di"
2280 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2281 (and:DI (sign_extend:DI
2282 (match_operand:SI 2 "s_register_operand" "r,r"))
2283 (match_operand:DI 1 "s_register_operand" "0,r")))]
2286 [(set_attr "length" "8")
2287 (set_attr "type" "multiple")]
2290 (define_expand "andsi3"
2291 [(set (match_operand:SI 0 "s_register_operand" "")
2292 (and:SI (match_operand:SI 1 "s_register_operand" "")
2293 (match_operand:SI 2 "reg_or_int_operand" "")))]
2298 if (CONST_INT_P (operands[2]))
2300 if (INTVAL (operands[2]) == 255 && arm_arch6)
2302 operands[1] = convert_to_mode (QImode, operands[1], 1);
2303 emit_insn (gen_thumb2_zero_extendqisi2_v6 (operands[0],
2307 arm_split_constant (AND, SImode, NULL_RTX,
2308 INTVAL (operands[2]), operands[0],
2310 optimize && can_create_pseudo_p ());
2315 else /* TARGET_THUMB1 */
2317 if (!CONST_INT_P (operands[2]))
2319 rtx tmp = force_reg (SImode, operands[2]);
2320 if (rtx_equal_p (operands[0], operands[1]))
2324 operands[2] = operands[1];
2332 if (((unsigned HOST_WIDE_INT) ~INTVAL (operands[2])) < 256)
2334 operands[2] = force_reg (SImode,
2335 GEN_INT (~INTVAL (operands[2])));
2337 emit_insn (gen_thumb1_bicsi3 (operands[0], operands[2], operands[1]));
2342 for (i = 9; i <= 31; i++)
2344 if ((((HOST_WIDE_INT) 1) << i) - 1 == INTVAL (operands[2]))
2346 emit_insn (gen_extzv (operands[0], operands[1], GEN_INT (i),
2350 else if ((((HOST_WIDE_INT) 1) << i) - 1
2351 == ~INTVAL (operands[2]))
2353 rtx shift = GEN_INT (i);
2354 rtx reg = gen_reg_rtx (SImode);
2356 emit_insn (gen_lshrsi3 (reg, operands[1], shift));
2357 emit_insn (gen_ashlsi3 (operands[0], reg, shift));
2363 operands[2] = force_reg (SImode, operands[2]);
2369 ; ??? Check split length for Thumb-2
2370 (define_insn_and_split "*arm_andsi3_insn"
2371 [(set (match_operand:SI 0 "s_register_operand" "=r,l,r,r,r")
2372 (and:SI (match_operand:SI 1 "s_register_operand" "%r,0,r,r,r")
2373 (match_operand:SI 2 "reg_or_int_operand" "I,l,K,r,?n")))]
2378 bic%?\\t%0, %1, #%B2
2382 && CONST_INT_P (operands[2])
2383 && !(const_ok_for_arm (INTVAL (operands[2]))
2384 || const_ok_for_arm (~INTVAL (operands[2])))"
2385 [(clobber (const_int 0))]
2387 arm_split_constant (AND, SImode, curr_insn,
2388 INTVAL (operands[2]), operands[0], operands[1], 0);
2391 [(set_attr "length" "4,4,4,4,16")
2392 (set_attr "predicable" "yes")
2393 (set_attr "predicable_short_it" "no,yes,no,no,no")
2394 (set_attr "type" "logic_imm,logic_imm,logic_reg,logic_reg,logic_imm")]
2397 (define_insn "*thumb1_andsi3_insn"
2398 [(set (match_operand:SI 0 "register_operand" "=l")
2399 (and:SI (match_operand:SI 1 "register_operand" "%0")
2400 (match_operand:SI 2 "register_operand" "l")))]
2403 [(set_attr "length" "2")
2404 (set_attr "type" "logic_imm")
2405 (set_attr "conds" "set")])
2407 (define_insn "*andsi3_compare0"
2408 [(set (reg:CC_NOOV CC_REGNUM)
2410 (and:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
2411 (match_operand:SI 2 "arm_not_operand" "I,K,r"))
2413 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
2414 (and:SI (match_dup 1) (match_dup 2)))]
2418 bic%.\\t%0, %1, #%B2
2420 [(set_attr "conds" "set")
2421 (set_attr "type" "logics_imm,logics_imm,logics_reg")]
2424 (define_insn "*andsi3_compare0_scratch"
2425 [(set (reg:CC_NOOV CC_REGNUM)
2427 (and:SI (match_operand:SI 0 "s_register_operand" "r,r,r")
2428 (match_operand:SI 1 "arm_not_operand" "I,K,r"))
2430 (clobber (match_scratch:SI 2 "=X,r,X"))]
2434 bic%.\\t%2, %0, #%B1
2436 [(set_attr "conds" "set")
2437 (set_attr "type" "logics_imm,logics_imm,logics_reg")]
2440 (define_insn "*zeroextractsi_compare0_scratch"
2441 [(set (reg:CC_NOOV CC_REGNUM)
2442 (compare:CC_NOOV (zero_extract:SI
2443 (match_operand:SI 0 "s_register_operand" "r")
2444 (match_operand 1 "const_int_operand" "n")
2445 (match_operand 2 "const_int_operand" "n"))
2448 && (INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) < 32
2449 && INTVAL (operands[1]) > 0
2450 && INTVAL (operands[1]) + (INTVAL (operands[2]) & 1) <= 8
2451 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32)"
2453 operands[1] = GEN_INT (((1 << INTVAL (operands[1])) - 1)
2454 << INTVAL (operands[2]));
2455 output_asm_insn (\"tst%?\\t%0, %1\", operands);
2458 [(set_attr "conds" "set")
2459 (set_attr "predicable" "yes")
2460 (set_attr "predicable_short_it" "no")
2461 (set_attr "type" "logics_imm")]
2464 (define_insn_and_split "*ne_zeroextractsi"
2465 [(set (match_operand:SI 0 "s_register_operand" "=r")
2466 (ne:SI (zero_extract:SI
2467 (match_operand:SI 1 "s_register_operand" "r")
2468 (match_operand:SI 2 "const_int_operand" "n")
2469 (match_operand:SI 3 "const_int_operand" "n"))
2471 (clobber (reg:CC CC_REGNUM))]
2473 && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
2474 && INTVAL (operands[2]) > 0
2475 && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
2476 && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)"
2479 && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
2480 && INTVAL (operands[2]) > 0
2481 && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
2482 && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)"
2483 [(parallel [(set (reg:CC_NOOV CC_REGNUM)
2484 (compare:CC_NOOV (and:SI (match_dup 1) (match_dup 2))
2486 (set (match_dup 0) (and:SI (match_dup 1) (match_dup 2)))])
2488 (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
2489 (match_dup 0) (const_int 1)))]
2491 operands[2] = GEN_INT (((1 << INTVAL (operands[2])) - 1)
2492 << INTVAL (operands[3]));
2494 [(set_attr "conds" "clob")
2495 (set (attr "length")
2496 (if_then_else (eq_attr "is_thumb" "yes")
2499 (set_attr "type" "multiple")]
2502 (define_insn_and_split "*ne_zeroextractsi_shifted"
2503 [(set (match_operand:SI 0 "s_register_operand" "=r")
2504 (ne:SI (zero_extract:SI
2505 (match_operand:SI 1 "s_register_operand" "r")
2506 (match_operand:SI 2 "const_int_operand" "n")
2509 (clobber (reg:CC CC_REGNUM))]
2513 [(parallel [(set (reg:CC_NOOV CC_REGNUM)
2514 (compare:CC_NOOV (ashift:SI (match_dup 1) (match_dup 2))
2516 (set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 2)))])
2518 (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
2519 (match_dup 0) (const_int 1)))]
2521 operands[2] = GEN_INT (32 - INTVAL (operands[2]));
2523 [(set_attr "conds" "clob")
2524 (set_attr "length" "8")
2525 (set_attr "type" "multiple")]
2528 (define_insn_and_split "*ite_ne_zeroextractsi"
2529 [(set (match_operand:SI 0 "s_register_operand" "=r")
2530 (if_then_else:SI (ne (zero_extract:SI
2531 (match_operand:SI 1 "s_register_operand" "r")
2532 (match_operand:SI 2 "const_int_operand" "n")
2533 (match_operand:SI 3 "const_int_operand" "n"))
2535 (match_operand:SI 4 "arm_not_operand" "rIK")
2537 (clobber (reg:CC CC_REGNUM))]
2539 && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
2540 && INTVAL (operands[2]) > 0
2541 && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
2542 && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)
2543 && !reg_overlap_mentioned_p (operands[0], operands[4])"
2546 && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
2547 && INTVAL (operands[2]) > 0
2548 && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
2549 && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)
2550 && !reg_overlap_mentioned_p (operands[0], operands[4])"
2551 [(parallel [(set (reg:CC_NOOV CC_REGNUM)
2552 (compare:CC_NOOV (and:SI (match_dup 1) (match_dup 2))
2554 (set (match_dup 0) (and:SI (match_dup 1) (match_dup 2)))])
2556 (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
2557 (match_dup 0) (match_dup 4)))]
2559 operands[2] = GEN_INT (((1 << INTVAL (operands[2])) - 1)
2560 << INTVAL (operands[3]));
2562 [(set_attr "conds" "clob")
2563 (set_attr "length" "8")
2564 (set_attr "type" "multiple")]
2567 (define_insn_and_split "*ite_ne_zeroextractsi_shifted"
2568 [(set (match_operand:SI 0 "s_register_operand" "=r")
2569 (if_then_else:SI (ne (zero_extract:SI
2570 (match_operand:SI 1 "s_register_operand" "r")
2571 (match_operand:SI 2 "const_int_operand" "n")
2574 (match_operand:SI 3 "arm_not_operand" "rIK")
2576 (clobber (reg:CC CC_REGNUM))]
2577 "TARGET_ARM && !reg_overlap_mentioned_p (operands[0], operands[3])"
2579 "TARGET_ARM && !reg_overlap_mentioned_p (operands[0], operands[3])"
2580 [(parallel [(set (reg:CC_NOOV CC_REGNUM)
2581 (compare:CC_NOOV (ashift:SI (match_dup 1) (match_dup 2))
2583 (set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 2)))])
2585 (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
2586 (match_dup 0) (match_dup 3)))]
2588 operands[2] = GEN_INT (32 - INTVAL (operands[2]));
2590 [(set_attr "conds" "clob")
2591 (set_attr "length" "8")
2592 (set_attr "type" "multiple")]
2596 [(set (match_operand:SI 0 "s_register_operand" "")
2597 (zero_extract:SI (match_operand:SI 1 "s_register_operand" "")
2598 (match_operand:SI 2 "const_int_operand" "")
2599 (match_operand:SI 3 "const_int_operand" "")))
2600 (clobber (match_operand:SI 4 "s_register_operand" ""))]
2602 [(set (match_dup 4) (ashift:SI (match_dup 1) (match_dup 2)))
2603 (set (match_dup 0) (lshiftrt:SI (match_dup 4) (match_dup 3)))]
2605 HOST_WIDE_INT temp = INTVAL (operands[2]);
2607 operands[2] = GEN_INT (32 - temp - INTVAL (operands[3]));
2608 operands[3] = GEN_INT (32 - temp);
2612 ;; ??? Use Thumb-2 has bitfield insert/extract instructions.
2614 [(set (match_operand:SI 0 "s_register_operand" "")
2615 (match_operator:SI 1 "shiftable_operator"
2616 [(zero_extract:SI (match_operand:SI 2 "s_register_operand" "")
2617 (match_operand:SI 3 "const_int_operand" "")
2618 (match_operand:SI 4 "const_int_operand" ""))
2619 (match_operand:SI 5 "s_register_operand" "")]))
2620 (clobber (match_operand:SI 6 "s_register_operand" ""))]
2622 [(set (match_dup 6) (ashift:SI (match_dup 2) (match_dup 3)))
2625 [(lshiftrt:SI (match_dup 6) (match_dup 4))
2628 HOST_WIDE_INT temp = INTVAL (operands[3]);
2630 operands[3] = GEN_INT (32 - temp - INTVAL (operands[4]));
2631 operands[4] = GEN_INT (32 - temp);
2636 [(set (match_operand:SI 0 "s_register_operand" "")
2637 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "")
2638 (match_operand:SI 2 "const_int_operand" "")
2639 (match_operand:SI 3 "const_int_operand" "")))]
2641 [(set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 2)))
2642 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (match_dup 3)))]
2644 HOST_WIDE_INT temp = INTVAL (operands[2]);
2646 operands[2] = GEN_INT (32 - temp - INTVAL (operands[3]));
2647 operands[3] = GEN_INT (32 - temp);
2652 [(set (match_operand:SI 0 "s_register_operand" "")
2653 (match_operator:SI 1 "shiftable_operator"
2654 [(sign_extract:SI (match_operand:SI 2 "s_register_operand" "")
2655 (match_operand:SI 3 "const_int_operand" "")
2656 (match_operand:SI 4 "const_int_operand" ""))
2657 (match_operand:SI 5 "s_register_operand" "")]))
2658 (clobber (match_operand:SI 6 "s_register_operand" ""))]
2660 [(set (match_dup 6) (ashift:SI (match_dup 2) (match_dup 3)))
2663 [(ashiftrt:SI (match_dup 6) (match_dup 4))
2666 HOST_WIDE_INT temp = INTVAL (operands[3]);
2668 operands[3] = GEN_INT (32 - temp - INTVAL (operands[4]));
2669 operands[4] = GEN_INT (32 - temp);
2673 ;;; ??? This pattern is bogus. If operand3 has bits outside the range
2674 ;;; represented by the bitfield, then this will produce incorrect results.
2675 ;;; Somewhere, the value needs to be truncated. On targets like the m68k,
2676 ;;; which have a real bit-field insert instruction, the truncation happens
2677 ;;; in the bit-field insert instruction itself. Since arm does not have a
2678 ;;; bit-field insert instruction, we would have to emit code here to truncate
2679 ;;; the value before we insert. This loses some of the advantage of having
2680 ;;; this insv pattern, so this pattern needs to be reevalutated.
2682 (define_expand "insv"
2683 [(set (zero_extract (match_operand 0 "nonimmediate_operand" "")
2684 (match_operand 1 "general_operand" "")
2685 (match_operand 2 "general_operand" ""))
2686 (match_operand 3 "reg_or_int_operand" ""))]
2687 "TARGET_ARM || arm_arch_thumb2"
2690 int start_bit = INTVAL (operands[2]);
2691 int width = INTVAL (operands[1]);
2692 HOST_WIDE_INT mask = (((HOST_WIDE_INT)1) << width) - 1;
2693 rtx target, subtarget;
2695 if (arm_arch_thumb2)
2697 if (unaligned_access && MEM_P (operands[0])
2698 && s_register_operand (operands[3], GET_MODE (operands[3]))
2699 && (width == 16 || width == 32) && (start_bit % BITS_PER_UNIT) == 0)
2703 if (BYTES_BIG_ENDIAN)
2704 start_bit = GET_MODE_BITSIZE (GET_MODE (operands[3])) - width
2709 base_addr = adjust_address (operands[0], SImode,
2710 start_bit / BITS_PER_UNIT);
2711 emit_insn (gen_unaligned_storesi (base_addr, operands[3]));
2715 rtx tmp = gen_reg_rtx (HImode);
2717 base_addr = adjust_address (operands[0], HImode,
2718 start_bit / BITS_PER_UNIT);
2719 emit_move_insn (tmp, gen_lowpart (HImode, operands[3]));
2720 emit_insn (gen_unaligned_storehi (base_addr, tmp));
2724 else if (s_register_operand (operands[0], GET_MODE (operands[0])))
2726 bool use_bfi = TRUE;
2728 if (CONST_INT_P (operands[3]))
2730 HOST_WIDE_INT val = INTVAL (operands[3]) & mask;
2734 emit_insn (gen_insv_zero (operands[0], operands[1],
2739 /* See if the set can be done with a single orr instruction. */
2740 if (val == mask && const_ok_for_arm (val << start_bit))
2746 if (!REG_P (operands[3]))
2747 operands[3] = force_reg (SImode, operands[3]);
2749 emit_insn (gen_insv_t2 (operands[0], operands[1], operands[2],
2758 if (!s_register_operand (operands[0], GET_MODE (operands[0])))
2761 target = copy_rtx (operands[0]);
2762 /* Avoid using a subreg as a subtarget, and avoid writing a paradoxical
2763 subreg as the final target. */
2764 if (GET_CODE (target) == SUBREG)
2766 subtarget = gen_reg_rtx (SImode);
2767 if (GET_MODE_SIZE (GET_MODE (SUBREG_REG (target)))
2768 < GET_MODE_SIZE (SImode))
2769 target = SUBREG_REG (target);
2774 if (CONST_INT_P (operands[3]))
2776 /* Since we are inserting a known constant, we may be able to
2777 reduce the number of bits that we have to clear so that
2778 the mask becomes simple. */
2779 /* ??? This code does not check to see if the new mask is actually
2780 simpler. It may not be. */
2781 rtx op1 = gen_reg_rtx (SImode);
2782 /* ??? Truncate operand3 to fit in the bitfield. See comment before
2783 start of this pattern. */
2784 HOST_WIDE_INT op3_value = mask & INTVAL (operands[3]);
2785 HOST_WIDE_INT mask2 = ((mask & ~op3_value) << start_bit);
2787 emit_insn (gen_andsi3 (op1, operands[0],
2788 gen_int_mode (~mask2, SImode)));
2789 emit_insn (gen_iorsi3 (subtarget, op1,
2790 gen_int_mode (op3_value << start_bit, SImode)));
2792 else if (start_bit == 0
2793 && !(const_ok_for_arm (mask)
2794 || const_ok_for_arm (~mask)))
2796 /* A Trick, since we are setting the bottom bits in the word,
2797 we can shift operand[3] up, operand[0] down, OR them together
2798 and rotate the result back again. This takes 3 insns, and
2799 the third might be mergeable into another op. */
2800 /* The shift up copes with the possibility that operand[3] is
2801 wider than the bitfield. */
2802 rtx op0 = gen_reg_rtx (SImode);
2803 rtx op1 = gen_reg_rtx (SImode);
2805 emit_insn (gen_ashlsi3 (op0, operands[3], GEN_INT (32 - width)));
2806 emit_insn (gen_lshrsi3 (op1, operands[0], operands[1]));
2807 emit_insn (gen_iorsi3 (op1, op1, op0));
2808 emit_insn (gen_rotlsi3 (subtarget, op1, operands[1]));
2810 else if ((width + start_bit == 32)
2811 && !(const_ok_for_arm (mask)
2812 || const_ok_for_arm (~mask)))
2814 /* Similar trick, but slightly less efficient. */
2816 rtx op0 = gen_reg_rtx (SImode);
2817 rtx op1 = gen_reg_rtx (SImode);
2819 emit_insn (gen_ashlsi3 (op0, operands[3], GEN_INT (32 - width)));
2820 emit_insn (gen_ashlsi3 (op1, operands[0], operands[1]));
2821 emit_insn (gen_lshrsi3 (op1, op1, operands[1]));
2822 emit_insn (gen_iorsi3 (subtarget, op1, op0));
2826 rtx op0 = gen_int_mode (mask, SImode);
2827 rtx op1 = gen_reg_rtx (SImode);
2828 rtx op2 = gen_reg_rtx (SImode);
2830 if (!(const_ok_for_arm (mask) || const_ok_for_arm (~mask)))
2832 rtx tmp = gen_reg_rtx (SImode);
2834 emit_insn (gen_movsi (tmp, op0));
2838 /* Mask out any bits in operand[3] that are not needed. */
2839 emit_insn (gen_andsi3 (op1, operands[3], op0));
2841 if (CONST_INT_P (op0)
2842 && (const_ok_for_arm (mask << start_bit)
2843 || const_ok_for_arm (~(mask << start_bit))))
2845 op0 = gen_int_mode (~(mask << start_bit), SImode);
2846 emit_insn (gen_andsi3 (op2, operands[0], op0));
2850 if (CONST_INT_P (op0))
2852 rtx tmp = gen_reg_rtx (SImode);
2854 emit_insn (gen_movsi (tmp, op0));
2859 emit_insn (gen_ashlsi3 (op0, op0, operands[2]));
2861 emit_insn (gen_andsi_notsi_si (op2, operands[0], op0));
2865 emit_insn (gen_ashlsi3 (op1, op1, operands[2]));
2867 emit_insn (gen_iorsi3 (subtarget, op1, op2));
2870 if (subtarget != target)
2872 /* If TARGET is still a SUBREG, then it must be wider than a word,
2873 so we must be careful only to set the subword we were asked to. */
2874 if (GET_CODE (target) == SUBREG)
2875 emit_move_insn (target, subtarget);
2877 emit_move_insn (target, gen_lowpart (GET_MODE (target), subtarget));
2884 (define_insn "insv_zero"
2885 [(set (zero_extract:SI (match_operand:SI 0 "s_register_operand" "+r")
2886 (match_operand:SI 1 "const_int_operand" "M")
2887 (match_operand:SI 2 "const_int_operand" "M"))
2891 [(set_attr "length" "4")
2892 (set_attr "predicable" "yes")
2893 (set_attr "predicable_short_it" "no")
2894 (set_attr "type" "bfm")]
2897 (define_insn "insv_t2"
2898 [(set (zero_extract:SI (match_operand:SI 0 "s_register_operand" "+r")
2899 (match_operand:SI 1 "const_int_operand" "M")
2900 (match_operand:SI 2 "const_int_operand" "M"))
2901 (match_operand:SI 3 "s_register_operand" "r"))]
2903 "bfi%?\t%0, %3, %2, %1"
2904 [(set_attr "length" "4")
2905 (set_attr "predicable" "yes")
2906 (set_attr "predicable_short_it" "no")
2907 (set_attr "type" "bfm")]
2910 ; constants for op 2 will never be given to these patterns.
2911 (define_insn_and_split "*anddi_notdi_di"
2912 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2913 (and:DI (not:DI (match_operand:DI 1 "s_register_operand" "0,r"))
2914 (match_operand:DI 2 "s_register_operand" "r,0")))]
2917 "TARGET_32BIT && reload_completed
2918 && ! (TARGET_NEON && IS_VFP_REGNUM (REGNO (operands[0])))
2919 && ! IS_IWMMXT_REGNUM (REGNO (operands[0]))"
2920 [(set (match_dup 0) (and:SI (not:SI (match_dup 1)) (match_dup 2)))
2921 (set (match_dup 3) (and:SI (not:SI (match_dup 4)) (match_dup 5)))]
2924 operands[3] = gen_highpart (SImode, operands[0]);
2925 operands[0] = gen_lowpart (SImode, operands[0]);
2926 operands[4] = gen_highpart (SImode, operands[1]);
2927 operands[1] = gen_lowpart (SImode, operands[1]);
2928 operands[5] = gen_highpart (SImode, operands[2]);
2929 operands[2] = gen_lowpart (SImode, operands[2]);
2931 [(set_attr "length" "8")
2932 (set_attr "predicable" "yes")
2933 (set_attr "type" "multiple")]
2936 (define_insn_and_split "*anddi_notzesidi_di"
2937 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2938 (and:DI (not:DI (zero_extend:DI
2939 (match_operand:SI 2 "s_register_operand" "r,r")))
2940 (match_operand:DI 1 "s_register_operand" "0,?r")))]
2943 bic%?\\t%Q0, %Q1, %2
2945 ; (not (zero_extend ...)) allows us to just copy the high word from
2946 ; operand1 to operand0.
2949 && operands[0] != operands[1]"
2950 [(set (match_dup 0) (and:SI (not:SI (match_dup 2)) (match_dup 1)))
2951 (set (match_dup 3) (match_dup 4))]
2954 operands[3] = gen_highpart (SImode, operands[0]);
2955 operands[0] = gen_lowpart (SImode, operands[0]);
2956 operands[4] = gen_highpart (SImode, operands[1]);
2957 operands[1] = gen_lowpart (SImode, operands[1]);
2959 [(set_attr "length" "4,8")
2960 (set_attr "predicable" "yes")
2961 (set_attr "predicable_short_it" "no")
2962 (set_attr "type" "multiple")]
2965 (define_insn_and_split "*anddi_notsesidi_di"
2966 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2967 (and:DI (not:DI (sign_extend:DI
2968 (match_operand:SI 2 "s_register_operand" "r,r")))
2969 (match_operand:DI 1 "s_register_operand" "0,r")))]
2972 "TARGET_32BIT && reload_completed"
2973 [(set (match_dup 0) (and:SI (not:SI (match_dup 2)) (match_dup 1)))
2974 (set (match_dup 3) (and:SI (not:SI
2975 (ashiftrt:SI (match_dup 2) (const_int 31)))
2979 operands[3] = gen_highpart (SImode, operands[0]);
2980 operands[0] = gen_lowpart (SImode, operands[0]);
2981 operands[4] = gen_highpart (SImode, operands[1]);
2982 operands[1] = gen_lowpart (SImode, operands[1]);
2984 [(set_attr "length" "8")
2985 (set_attr "predicable" "yes")
2986 (set_attr "predicable_short_it" "no")
2987 (set_attr "type" "multiple")]
2990 (define_insn "andsi_notsi_si"
2991 [(set (match_operand:SI 0 "s_register_operand" "=r")
2992 (and:SI (not:SI (match_operand:SI 2 "s_register_operand" "r"))
2993 (match_operand:SI 1 "s_register_operand" "r")))]
2995 "bic%?\\t%0, %1, %2"
2996 [(set_attr "predicable" "yes")
2997 (set_attr "predicable_short_it" "no")
2998 (set_attr "type" "logic_reg")]
3001 (define_insn "thumb1_bicsi3"
3002 [(set (match_operand:SI 0 "register_operand" "=l")
3003 (and:SI (not:SI (match_operand:SI 1 "register_operand" "l"))
3004 (match_operand:SI 2 "register_operand" "0")))]
3007 [(set_attr "length" "2")
3008 (set_attr "conds" "set")
3009 (set_attr "type" "logics_reg")]
3012 (define_insn "andsi_not_shiftsi_si"
3013 [(set (match_operand:SI 0 "s_register_operand" "=r")
3014 (and:SI (not:SI (match_operator:SI 4 "shift_operator"
3015 [(match_operand:SI 2 "s_register_operand" "r")
3016 (match_operand:SI 3 "arm_rhs_operand" "rM")]))
3017 (match_operand:SI 1 "s_register_operand" "r")))]
3019 "bic%?\\t%0, %1, %2%S4"
3020 [(set_attr "predicable" "yes")
3021 (set_attr "shift" "2")
3022 (set (attr "type") (if_then_else (match_operand 3 "const_int_operand" "")
3023 (const_string "logic_shift_imm")
3024 (const_string "logic_shift_reg")))]
3027 (define_insn "*andsi_notsi_si_compare0"
3028 [(set (reg:CC_NOOV CC_REGNUM)
3030 (and:SI (not:SI (match_operand:SI 2 "s_register_operand" "r"))
3031 (match_operand:SI 1 "s_register_operand" "r"))
3033 (set (match_operand:SI 0 "s_register_operand" "=r")
3034 (and:SI (not:SI (match_dup 2)) (match_dup 1)))]
3036 "bic%.\\t%0, %1, %2"
3037 [(set_attr "conds" "set")
3038 (set_attr "type" "logics_shift_reg")]
3041 (define_insn "*andsi_notsi_si_compare0_scratch"
3042 [(set (reg:CC_NOOV CC_REGNUM)
3044 (and:SI (not:SI (match_operand:SI 2 "s_register_operand" "r"))
3045 (match_operand:SI 1 "s_register_operand" "r"))
3047 (clobber (match_scratch:SI 0 "=r"))]
3049 "bic%.\\t%0, %1, %2"
3050 [(set_attr "conds" "set")
3051 (set_attr "type" "logics_shift_reg")]
3054 (define_expand "iordi3"
3055 [(set (match_operand:DI 0 "s_register_operand" "")
3056 (ior:DI (match_operand:DI 1 "s_register_operand" "")
3057 (match_operand:DI 2 "neon_logic_op2" "")))]
3062 (define_insn_and_split "*iordi3_insn"
3063 [(set (match_operand:DI 0 "s_register_operand" "=w,w ,&r,&r,&r,&r,?w,?w")
3064 (ior:DI (match_operand:DI 1 "s_register_operand" "%w,0 ,0 ,r ,0 ,r ,w ,0")
3065 (match_operand:DI 2 "arm_iordi_operand_neon" "w ,Dl,r ,r ,Df,Df,w ,Dl")))]
3066 "TARGET_32BIT && !TARGET_IWMMXT"
3068 switch (which_alternative)
3070 case 0: /* fall through */
3071 case 6: return "vorr\t%P0, %P1, %P2";
3072 case 1: /* fall through */
3073 case 7: return neon_output_logic_immediate ("vorr", &operands[2],
3074 DImode, 0, VALID_NEON_QREG_MODE (DImode));
3080 default: gcc_unreachable ();
3083 "TARGET_32BIT && !TARGET_IWMMXT && reload_completed
3084 && !(IS_VFP_REGNUM (REGNO (operands[0])))"
3085 [(set (match_dup 3) (match_dup 4))
3086 (set (match_dup 5) (match_dup 6))]
3089 operands[3] = gen_lowpart (SImode, operands[0]);
3090 operands[5] = gen_highpart (SImode, operands[0]);
3092 operands[4] = simplify_gen_binary (IOR, SImode,
3093 gen_lowpart (SImode, operands[1]),
3094 gen_lowpart (SImode, operands[2]));
3095 operands[6] = simplify_gen_binary (IOR, SImode,
3096 gen_highpart (SImode, operands[1]),
3097 gen_highpart_mode (SImode, DImode, operands[2]));
3100 [(set_attr "type" "neon_logic,neon_logic,multiple,multiple,multiple,\
3101 multiple,neon_logic,neon_logic")
3102 (set_attr "length" "*,*,8,8,8,8,*,*")
3103 (set_attr "arch" "neon_for_64bits,neon_for_64bits,*,*,*,*,avoid_neon_for_64bits,avoid_neon_for_64bits")]
3106 (define_insn "*iordi_zesidi_di"
3107 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
3108 (ior:DI (zero_extend:DI
3109 (match_operand:SI 2 "s_register_operand" "r,r"))
3110 (match_operand:DI 1 "s_register_operand" "0,?r")))]
3113 orr%?\\t%Q0, %Q1, %2
3115 [(set_attr "length" "4,8")
3116 (set_attr "predicable" "yes")
3117 (set_attr "predicable_short_it" "no")
3118 (set_attr "type" "logic_reg,multiple")]
3121 (define_insn "*iordi_sesidi_di"
3122 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
3123 (ior:DI (sign_extend:DI
3124 (match_operand:SI 2 "s_register_operand" "r,r"))
3125 (match_operand:DI 1 "s_register_operand" "0,r")))]
3128 [(set_attr "length" "8")
3129 (set_attr "predicable" "yes")
3130 (set_attr "type" "multiple")]
3133 (define_expand "iorsi3"
3134 [(set (match_operand:SI 0 "s_register_operand" "")
3135 (ior:SI (match_operand:SI 1 "s_register_operand" "")
3136 (match_operand:SI 2 "reg_or_int_operand" "")))]
3139 if (CONST_INT_P (operands[2]))
3143 arm_split_constant (IOR, SImode, NULL_RTX,
3144 INTVAL (operands[2]), operands[0], operands[1],
3145 optimize && can_create_pseudo_p ());
3148 else /* TARGET_THUMB1 */
3150 rtx tmp = force_reg (SImode, operands[2]);
3151 if (rtx_equal_p (operands[0], operands[1]))
3155 operands[2] = operands[1];
3163 (define_insn_and_split "*iorsi3_insn"
3164 [(set (match_operand:SI 0 "s_register_operand" "=r,l,r,r,r")
3165 (ior:SI (match_operand:SI 1 "s_register_operand" "%r,0,r,r,r")
3166 (match_operand:SI 2 "reg_or_int_operand" "I,l,K,r,?n")))]
3171 orn%?\\t%0, %1, #%B2
3175 && CONST_INT_P (operands[2])
3176 && !(const_ok_for_arm (INTVAL (operands[2]))
3177 || (TARGET_THUMB2 && const_ok_for_arm (~INTVAL (operands[2]))))"
3178 [(clobber (const_int 0))]
3180 arm_split_constant (IOR, SImode, curr_insn,
3181 INTVAL (operands[2]), operands[0], operands[1], 0);
3184 [(set_attr "length" "4,4,4,4,16")
3185 (set_attr "arch" "32,t2,t2,32,32")
3186 (set_attr "predicable" "yes")
3187 (set_attr "predicable_short_it" "no,yes,no,no,no")
3188 (set_attr "type" "logic_imm,logic_reg,logic_imm,logic_reg,logic_reg")]
3191 (define_insn "*thumb1_iorsi3_insn"
3192 [(set (match_operand:SI 0 "register_operand" "=l")
3193 (ior:SI (match_operand:SI 1 "register_operand" "%0")
3194 (match_operand:SI 2 "register_operand" "l")))]
3197 [(set_attr "length" "2")
3198 (set_attr "conds" "set")
3199 (set_attr "type" "logics_reg")])
3202 [(match_scratch:SI 3 "r")
3203 (set (match_operand:SI 0 "arm_general_register_operand" "")
3204 (ior:SI (match_operand:SI 1 "arm_general_register_operand" "")
3205 (match_operand:SI 2 "const_int_operand" "")))]
3207 && !const_ok_for_arm (INTVAL (operands[2]))
3208 && const_ok_for_arm (~INTVAL (operands[2]))"
3209 [(set (match_dup 3) (match_dup 2))
3210 (set (match_dup 0) (ior:SI (match_dup 1) (match_dup 3)))]
3214 (define_insn "*iorsi3_compare0"
3215 [(set (reg:CC_NOOV CC_REGNUM)
3216 (compare:CC_NOOV (ior:SI (match_operand:SI 1 "s_register_operand" "%r,r")
3217 (match_operand:SI 2 "arm_rhs_operand" "I,r"))
3219 (set (match_operand:SI 0 "s_register_operand" "=r,r")
3220 (ior:SI (match_dup 1) (match_dup 2)))]
3222 "orr%.\\t%0, %1, %2"
3223 [(set_attr "conds" "set")
3224 (set_attr "type" "logics_imm,logics_reg")]
3227 (define_insn "*iorsi3_compare0_scratch"
3228 [(set (reg:CC_NOOV CC_REGNUM)
3229 (compare:CC_NOOV (ior:SI (match_operand:SI 1 "s_register_operand" "%r,r")
3230 (match_operand:SI 2 "arm_rhs_operand" "I,r"))
3232 (clobber (match_scratch:SI 0 "=r,r"))]
3234 "orr%.\\t%0, %1, %2"
3235 [(set_attr "conds" "set")
3236 (set_attr "type" "logics_imm,logics_reg")]
3239 (define_expand "xordi3"
3240 [(set (match_operand:DI 0 "s_register_operand" "")
3241 (xor:DI (match_operand:DI 1 "s_register_operand" "")
3242 (match_operand:DI 2 "arm_xordi_operand" "")))]
3247 (define_insn_and_split "*xordi3_insn"
3248 [(set (match_operand:DI 0 "s_register_operand" "=w,&r,&r,&r,&r,?w")
3249 (xor:DI (match_operand:DI 1 "s_register_operand" "w ,%0,r ,0 ,r ,w")
3250 (match_operand:DI 2 "arm_xordi_operand" "w ,r ,r ,Dg,Dg,w")))]
3251 "TARGET_32BIT && !TARGET_IWMMXT"
3253 switch (which_alternative)
3258 case 4: /* fall through */
3260 case 0: /* fall through */
3261 case 5: return "veor\t%P0, %P1, %P2";
3262 default: gcc_unreachable ();
3265 "TARGET_32BIT && !TARGET_IWMMXT && reload_completed
3266 && !(IS_VFP_REGNUM (REGNO (operands[0])))"
3267 [(set (match_dup 3) (match_dup 4))
3268 (set (match_dup 5) (match_dup 6))]
3271 operands[3] = gen_lowpart (SImode, operands[0]);
3272 operands[5] = gen_highpart (SImode, operands[0]);
3274 operands[4] = simplify_gen_binary (XOR, SImode,
3275 gen_lowpart (SImode, operands[1]),
3276 gen_lowpart (SImode, operands[2]));
3277 operands[6] = simplify_gen_binary (XOR, SImode,
3278 gen_highpart (SImode, operands[1]),
3279 gen_highpart_mode (SImode, DImode, operands[2]));
3282 [(set_attr "length" "*,8,8,8,8,*")
3283 (set_attr "type" "neon_logic,multiple,multiple,multiple,multiple,neon_logic")
3284 (set_attr "arch" "neon_for_64bits,*,*,*,*,avoid_neon_for_64bits")]
3287 (define_insn "*xordi_zesidi_di"
3288 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
3289 (xor:DI (zero_extend:DI
3290 (match_operand:SI 2 "s_register_operand" "r,r"))
3291 (match_operand:DI 1 "s_register_operand" "0,?r")))]
3294 eor%?\\t%Q0, %Q1, %2
3296 [(set_attr "length" "4,8")
3297 (set_attr "predicable" "yes")
3298 (set_attr "predicable_short_it" "no")
3299 (set_attr "type" "logic_reg")]
3302 (define_insn "*xordi_sesidi_di"
3303 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
3304 (xor:DI (sign_extend:DI
3305 (match_operand:SI 2 "s_register_operand" "r,r"))
3306 (match_operand:DI 1 "s_register_operand" "0,r")))]
3309 [(set_attr "length" "8")
3310 (set_attr "predicable" "yes")
3311 (set_attr "type" "multiple")]
3314 (define_expand "xorsi3"
3315 [(set (match_operand:SI 0 "s_register_operand" "")
3316 (xor:SI (match_operand:SI 1 "s_register_operand" "")
3317 (match_operand:SI 2 "reg_or_int_operand" "")))]
3319 "if (CONST_INT_P (operands[2]))
3323 arm_split_constant (XOR, SImode, NULL_RTX,
3324 INTVAL (operands[2]), operands[0], operands[1],
3325 optimize && can_create_pseudo_p ());
3328 else /* TARGET_THUMB1 */
3330 rtx tmp = force_reg (SImode, operands[2]);
3331 if (rtx_equal_p (operands[0], operands[1]))
3335 operands[2] = operands[1];
3342 (define_insn_and_split "*arm_xorsi3"
3343 [(set (match_operand:SI 0 "s_register_operand" "=r,l,r,r")
3344 (xor:SI (match_operand:SI 1 "s_register_operand" "%r,0,r,r")
3345 (match_operand:SI 2 "reg_or_int_operand" "I,l,r,?n")))]
3353 && CONST_INT_P (operands[2])
3354 && !const_ok_for_arm (INTVAL (operands[2]))"
3355 [(clobber (const_int 0))]
3357 arm_split_constant (XOR, SImode, curr_insn,
3358 INTVAL (operands[2]), operands[0], operands[1], 0);
3361 [(set_attr "length" "4,4,4,16")
3362 (set_attr "predicable" "yes")
3363 (set_attr "predicable_short_it" "no,yes,no,no")
3364 (set_attr "type" "logic_imm,logic_reg,logic_reg,multiple")]
3367 (define_insn "*thumb1_xorsi3_insn"
3368 [(set (match_operand:SI 0 "register_operand" "=l")
3369 (xor:SI (match_operand:SI 1 "register_operand" "%0")
3370 (match_operand:SI 2 "register_operand" "l")))]
3373 [(set_attr "length" "2")
3374 (set_attr "conds" "set")
3375 (set_attr "type" "logics_reg")]
3378 (define_insn "*xorsi3_compare0"
3379 [(set (reg:CC_NOOV CC_REGNUM)
3380 (compare:CC_NOOV (xor:SI (match_operand:SI 1 "s_register_operand" "r,r")
3381 (match_operand:SI 2 "arm_rhs_operand" "I,r"))
3383 (set (match_operand:SI 0 "s_register_operand" "=r,r")
3384 (xor:SI (match_dup 1) (match_dup 2)))]
3386 "eor%.\\t%0, %1, %2"
3387 [(set_attr "conds" "set")
3388 (set_attr "type" "logics_imm,logics_reg")]
3391 (define_insn "*xorsi3_compare0_scratch"
3392 [(set (reg:CC_NOOV CC_REGNUM)
3393 (compare:CC_NOOV (xor:SI (match_operand:SI 0 "s_register_operand" "r,r")
3394 (match_operand:SI 1 "arm_rhs_operand" "I,r"))
3398 [(set_attr "conds" "set")
3399 (set_attr "type" "logics_imm,logics_reg")]
3402 ; By splitting (IOR (AND (NOT A) (NOT B)) C) as D = AND (IOR A B) (NOT C),
3403 ; (NOT D) we can sometimes merge the final NOT into one of the following
3407 [(set (match_operand:SI 0 "s_register_operand" "")
3408 (ior:SI (and:SI (not:SI (match_operand:SI 1 "s_register_operand" ""))
3409 (not:SI (match_operand:SI 2 "arm_rhs_operand" "")))
3410 (match_operand:SI 3 "arm_rhs_operand" "")))
3411 (clobber (match_operand:SI 4 "s_register_operand" ""))]
3413 [(set (match_dup 4) (and:SI (ior:SI (match_dup 1) (match_dup 2))
3414 (not:SI (match_dup 3))))
3415 (set (match_dup 0) (not:SI (match_dup 4)))]
3419 (define_insn_and_split "*andsi_iorsi3_notsi"
3420 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r")
3421 (and:SI (ior:SI (match_operand:SI 1 "s_register_operand" "%0,r,r")
3422 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI"))
3423 (not:SI (match_operand:SI 3 "arm_rhs_operand" "rI,rI,rI"))))]
3425 "#" ; "orr%?\\t%0, %1, %2\;bic%?\\t%0, %0, %3"
3426 "&& reload_completed"
3427 [(set (match_dup 0) (ior:SI (match_dup 1) (match_dup 2)))
3428 (set (match_dup 0) (and:SI (not:SI (match_dup 3)) (match_dup 0)))]
3430 [(set_attr "length" "8")
3431 (set_attr "ce_count" "2")
3432 (set_attr "predicable" "yes")
3433 (set_attr "predicable_short_it" "no")
3434 (set_attr "type" "multiple")]
3437 ; ??? Are these four splitters still beneficial when the Thumb-2 bitfield
3438 ; insns are available?
3440 [(set (match_operand:SI 0 "s_register_operand" "")
3441 (match_operator:SI 1 "logical_binary_operator"
3442 [(zero_extract:SI (match_operand:SI 2 "s_register_operand" "")
3443 (match_operand:SI 3 "const_int_operand" "")
3444 (match_operand:SI 4 "const_int_operand" ""))
3445 (match_operator:SI 9 "logical_binary_operator"
3446 [(lshiftrt:SI (match_operand:SI 5 "s_register_operand" "")
3447 (match_operand:SI 6 "const_int_operand" ""))
3448 (match_operand:SI 7 "s_register_operand" "")])]))
3449 (clobber (match_operand:SI 8 "s_register_operand" ""))]
3451 && GET_CODE (operands[1]) == GET_CODE (operands[9])
3452 && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
3455 [(ashift:SI (match_dup 2) (match_dup 4))
3459 [(lshiftrt:SI (match_dup 8) (match_dup 6))
3462 operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
3466 [(set (match_operand:SI 0 "s_register_operand" "")
3467 (match_operator:SI 1 "logical_binary_operator"
3468 [(match_operator:SI 9 "logical_binary_operator"
3469 [(lshiftrt:SI (match_operand:SI 5 "s_register_operand" "")
3470 (match_operand:SI 6 "const_int_operand" ""))
3471 (match_operand:SI 7 "s_register_operand" "")])
3472 (zero_extract:SI (match_operand:SI 2 "s_register_operand" "")
3473 (match_operand:SI 3 "const_int_operand" "")
3474 (match_operand:SI 4 "const_int_operand" ""))]))
3475 (clobber (match_operand:SI 8 "s_register_operand" ""))]
3477 && GET_CODE (operands[1]) == GET_CODE (operands[9])
3478 && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
3481 [(ashift:SI (match_dup 2) (match_dup 4))
3485 [(lshiftrt:SI (match_dup 8) (match_dup 6))
3488 operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
3492 [(set (match_operand:SI 0 "s_register_operand" "")
3493 (match_operator:SI 1 "logical_binary_operator"
3494 [(sign_extract:SI (match_operand:SI 2 "s_register_operand" "")
3495 (match_operand:SI 3 "const_int_operand" "")
3496 (match_operand:SI 4 "const_int_operand" ""))
3497 (match_operator:SI 9 "logical_binary_operator"
3498 [(ashiftrt:SI (match_operand:SI 5 "s_register_operand" "")
3499 (match_operand:SI 6 "const_int_operand" ""))
3500 (match_operand:SI 7 "s_register_operand" "")])]))
3501 (clobber (match_operand:SI 8 "s_register_operand" ""))]
3503 && GET_CODE (operands[1]) == GET_CODE (operands[9])
3504 && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
3507 [(ashift:SI (match_dup 2) (match_dup 4))
3511 [(ashiftrt:SI (match_dup 8) (match_dup 6))
3514 operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
3518 [(set (match_operand:SI 0 "s_register_operand" "")
3519 (match_operator:SI 1 "logical_binary_operator"
3520 [(match_operator:SI 9 "logical_binary_operator"
3521 [(ashiftrt:SI (match_operand:SI 5 "s_register_operand" "")
3522 (match_operand:SI 6 "const_int_operand" ""))
3523 (match_operand:SI 7 "s_register_operand" "")])
3524 (sign_extract:SI (match_operand:SI 2 "s_register_operand" "")
3525 (match_operand:SI 3 "const_int_operand" "")
3526 (match_operand:SI 4 "const_int_operand" ""))]))
3527 (clobber (match_operand:SI 8 "s_register_operand" ""))]
3529 && GET_CODE (operands[1]) == GET_CODE (operands[9])
3530 && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
3533 [(ashift:SI (match_dup 2) (match_dup 4))
3537 [(ashiftrt:SI (match_dup 8) (match_dup 6))
3540 operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
3544 ;; Minimum and maximum insns
3546 (define_expand "smaxsi3"
3548 (set (match_operand:SI 0 "s_register_operand" "")
3549 (smax:SI (match_operand:SI 1 "s_register_operand" "")
3550 (match_operand:SI 2 "arm_rhs_operand" "")))
3551 (clobber (reg:CC CC_REGNUM))])]
3554 if (operands[2] == const0_rtx || operands[2] == constm1_rtx)
3556 /* No need for a clobber of the condition code register here. */
3557 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
3558 gen_rtx_SMAX (SImode, operands[1],
3564 (define_insn "*smax_0"
3565 [(set (match_operand:SI 0 "s_register_operand" "=r")
3566 (smax:SI (match_operand:SI 1 "s_register_operand" "r")
3569 "bic%?\\t%0, %1, %1, asr #31"
3570 [(set_attr "predicable" "yes")
3571 (set_attr "predicable_short_it" "no")
3572 (set_attr "type" "logic_shift_reg")]
3575 (define_insn "*smax_m1"
3576 [(set (match_operand:SI 0 "s_register_operand" "=r")
3577 (smax:SI (match_operand:SI 1 "s_register_operand" "r")
3580 "orr%?\\t%0, %1, %1, asr #31"
3581 [(set_attr "predicable" "yes")
3582 (set_attr "predicable_short_it" "no")
3583 (set_attr "type" "logic_shift_reg")]
3586 (define_insn_and_split "*arm_smax_insn"
3587 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
3588 (smax:SI (match_operand:SI 1 "s_register_operand" "%0,?r")
3589 (match_operand:SI 2 "arm_rhs_operand" "rI,rI")))
3590 (clobber (reg:CC CC_REGNUM))]
3593 ; cmp\\t%1, %2\;movlt\\t%0, %2
3594 ; cmp\\t%1, %2\;movge\\t%0, %1\;movlt\\t%0, %2"
3596 [(set (reg:CC CC_REGNUM)
3597 (compare:CC (match_dup 1) (match_dup 2)))
3599 (if_then_else:SI (ge:SI (reg:CC CC_REGNUM) (const_int 0))
3603 [(set_attr "conds" "clob")
3604 (set_attr "length" "8,12")
3605 (set_attr "type" "multiple")]
3608 (define_expand "sminsi3"
3610 (set (match_operand:SI 0 "s_register_operand" "")
3611 (smin:SI (match_operand:SI 1 "s_register_operand" "")
3612 (match_operand:SI 2 "arm_rhs_operand" "")))
3613 (clobber (reg:CC CC_REGNUM))])]
3616 if (operands[2] == const0_rtx)
3618 /* No need for a clobber of the condition code register here. */
3619 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
3620 gen_rtx_SMIN (SImode, operands[1],
3626 (define_insn "*smin_0"
3627 [(set (match_operand:SI 0 "s_register_operand" "=r")
3628 (smin:SI (match_operand:SI 1 "s_register_operand" "r")
3631 "and%?\\t%0, %1, %1, asr #31"
3632 [(set_attr "predicable" "yes")
3633 (set_attr "predicable_short_it" "no")
3634 (set_attr "type" "logic_shift_reg")]
3637 (define_insn_and_split "*arm_smin_insn"
3638 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
3639 (smin:SI (match_operand:SI 1 "s_register_operand" "%0,?r")
3640 (match_operand:SI 2 "arm_rhs_operand" "rI,rI")))
3641 (clobber (reg:CC CC_REGNUM))]
3644 ; cmp\\t%1, %2\;movge\\t%0, %2
3645 ; cmp\\t%1, %2\;movlt\\t%0, %1\;movge\\t%0, %2"
3647 [(set (reg:CC CC_REGNUM)
3648 (compare:CC (match_dup 1) (match_dup 2)))
3650 (if_then_else:SI (lt:SI (reg:CC CC_REGNUM) (const_int 0))
3654 [(set_attr "conds" "clob")
3655 (set_attr "length" "8,12")
3656 (set_attr "type" "multiple,multiple")]
3659 (define_expand "umaxsi3"
3661 (set (match_operand:SI 0 "s_register_operand" "")
3662 (umax:SI (match_operand:SI 1 "s_register_operand" "")
3663 (match_operand:SI 2 "arm_rhs_operand" "")))
3664 (clobber (reg:CC CC_REGNUM))])]
3669 (define_insn_and_split "*arm_umaxsi3"
3670 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
3671 (umax:SI (match_operand:SI 1 "s_register_operand" "0,r,?r")
3672 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
3673 (clobber (reg:CC CC_REGNUM))]
3676 ; cmp\\t%1, %2\;movcc\\t%0, %2
3677 ; cmp\\t%1, %2\;movcs\\t%0, %1
3678 ; cmp\\t%1, %2\;movcs\\t%0, %1\;movcc\\t%0, %2"
3680 [(set (reg:CC CC_REGNUM)
3681 (compare:CC (match_dup 1) (match_dup 2)))
3683 (if_then_else:SI (geu:SI (reg:CC CC_REGNUM) (const_int 0))
3687 [(set_attr "conds" "clob")
3688 (set_attr "length" "8,8,12")
3689 (set_attr "type" "store1")]
3692 (define_expand "uminsi3"
3694 (set (match_operand:SI 0 "s_register_operand" "")
3695 (umin:SI (match_operand:SI 1 "s_register_operand" "")
3696 (match_operand:SI 2 "arm_rhs_operand" "")))
3697 (clobber (reg:CC CC_REGNUM))])]
3702 (define_insn_and_split "*arm_uminsi3"
3703 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
3704 (umin:SI (match_operand:SI 1 "s_register_operand" "0,r,?r")
3705 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
3706 (clobber (reg:CC CC_REGNUM))]
3709 ; cmp\\t%1, %2\;movcs\\t%0, %2
3710 ; cmp\\t%1, %2\;movcc\\t%0, %1
3711 ; cmp\\t%1, %2\;movcc\\t%0, %1\;movcs\\t%0, %2"
3713 [(set (reg:CC CC_REGNUM)
3714 (compare:CC (match_dup 1) (match_dup 2)))
3716 (if_then_else:SI (ltu:SI (reg:CC CC_REGNUM) (const_int 0))
3720 [(set_attr "conds" "clob")
3721 (set_attr "length" "8,8,12")
3722 (set_attr "type" "store1")]
3725 (define_insn "*store_minmaxsi"
3726 [(set (match_operand:SI 0 "memory_operand" "=m")
3727 (match_operator:SI 3 "minmax_operator"
3728 [(match_operand:SI 1 "s_register_operand" "r")
3729 (match_operand:SI 2 "s_register_operand" "r")]))
3730 (clobber (reg:CC CC_REGNUM))]
3731 "TARGET_32BIT && optimize_function_for_size_p (cfun)"
3733 operands[3] = gen_rtx_fmt_ee (minmax_code (operands[3]), SImode,
3734 operands[1], operands[2]);
3735 output_asm_insn (\"cmp\\t%1, %2\", operands);
3737 output_asm_insn (\"ite\t%d3\", operands);
3738 output_asm_insn (\"str%d3\\t%1, %0\", operands);
3739 output_asm_insn (\"str%D3\\t%2, %0\", operands);
3742 [(set_attr "conds" "clob")
3743 (set (attr "length")
3744 (if_then_else (eq_attr "is_thumb" "yes")
3747 (set_attr "type" "store1")]
3750 ; Reject the frame pointer in operand[1], since reloading this after
3751 ; it has been eliminated can cause carnage.
3752 (define_insn "*minmax_arithsi"
3753 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
3754 (match_operator:SI 4 "shiftable_operator"
3755 [(match_operator:SI 5 "minmax_operator"
3756 [(match_operand:SI 2 "s_register_operand" "r,r")
3757 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
3758 (match_operand:SI 1 "s_register_operand" "0,?r")]))
3759 (clobber (reg:CC CC_REGNUM))]
3760 "TARGET_32BIT && !arm_eliminable_register (operands[1]) && !arm_restrict_it"
3763 enum rtx_code code = GET_CODE (operands[4]);
3766 if (which_alternative != 0 || operands[3] != const0_rtx
3767 || (code != PLUS && code != IOR && code != XOR))
3772 operands[5] = gen_rtx_fmt_ee (minmax_code (operands[5]), SImode,
3773 operands[2], operands[3]);
3774 output_asm_insn (\"cmp\\t%2, %3\", operands);
3778 output_asm_insn (\"ite\\t%d5\", operands);
3780 output_asm_insn (\"it\\t%d5\", operands);
3782 output_asm_insn (\"%i4%d5\\t%0, %1, %2\", operands);
3784 output_asm_insn (\"%i4%D5\\t%0, %1, %3\", operands);
3787 [(set_attr "conds" "clob")
3788 (set (attr "length")
3789 (if_then_else (eq_attr "is_thumb" "yes")
3792 (set_attr "type" "multiple")]
3795 ; Reject the frame pointer in operand[1], since reloading this after
3796 ; it has been eliminated can cause carnage.
3797 (define_insn_and_split "*minmax_arithsi_non_canon"
3798 [(set (match_operand:SI 0 "s_register_operand" "=Ts,Ts")
3800 (match_operand:SI 1 "s_register_operand" "0,?Ts")
3801 (match_operator:SI 4 "minmax_operator"
3802 [(match_operand:SI 2 "s_register_operand" "Ts,Ts")
3803 (match_operand:SI 3 "arm_rhs_operand" "TsI,TsI")])))
3804 (clobber (reg:CC CC_REGNUM))]
3805 "TARGET_32BIT && !arm_eliminable_register (operands[1])
3806 && !(arm_restrict_it && CONST_INT_P (operands[3]))"
3808 "TARGET_32BIT && !arm_eliminable_register (operands[1]) && reload_completed"
3809 [(set (reg:CC CC_REGNUM)
3810 (compare:CC (match_dup 2) (match_dup 3)))
3812 (cond_exec (match_op_dup 4 [(reg:CC CC_REGNUM) (const_int 0)])
3814 (minus:SI (match_dup 1)
3816 (cond_exec (match_op_dup 5 [(reg:CC CC_REGNUM) (const_int 0)])
3820 enum machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
3821 operands[2], operands[3]);
3822 enum rtx_code rc = minmax_code (operands[4]);
3823 operands[4] = gen_rtx_fmt_ee (rc, VOIDmode,
3824 operands[2], operands[3]);
3826 if (mode == CCFPmode || mode == CCFPEmode)
3827 rc = reverse_condition_maybe_unordered (rc);
3829 rc = reverse_condition (rc);
3830 operands[5] = gen_rtx_fmt_ee (rc, SImode, operands[2], operands[3]);
3831 if (CONST_INT_P (operands[3]))
3832 operands[6] = plus_constant (SImode, operands[1], -INTVAL (operands[3]));
3834 operands[6] = gen_rtx_MINUS (SImode, operands[1], operands[3]);
3836 [(set_attr "conds" "clob")
3837 (set (attr "length")
3838 (if_then_else (eq_attr "is_thumb" "yes")
3841 (set_attr "type" "multiple")]
3844 (define_code_iterator SAT [smin smax])
3845 (define_code_iterator SATrev [smin smax])
3846 (define_code_attr SATlo [(smin "1") (smax "2")])
3847 (define_code_attr SAThi [(smin "2") (smax "1")])
3849 (define_insn "*satsi_<SAT:code>"
3850 [(set (match_operand:SI 0 "s_register_operand" "=r")
3851 (SAT:SI (SATrev:SI (match_operand:SI 3 "s_register_operand" "r")
3852 (match_operand:SI 1 "const_int_operand" "i"))
3853 (match_operand:SI 2 "const_int_operand" "i")))]
3854 "TARGET_32BIT && arm_arch6 && <SAT:CODE> != <SATrev:CODE>
3855 && arm_sat_operator_match (operands[<SAT:SATlo>], operands[<SAT:SAThi>], NULL, NULL)"
3859 if (!arm_sat_operator_match (operands[<SAT:SATlo>], operands[<SAT:SAThi>],
3860 &mask, &signed_sat))
3863 operands[1] = GEN_INT (mask);
3865 return "ssat%?\t%0, %1, %3";
3867 return "usat%?\t%0, %1, %3";
3869 [(set_attr "predicable" "yes")
3870 (set_attr "predicable_short_it" "no")
3871 (set_attr "type" "alus_imm")]
3874 (define_insn "*satsi_<SAT:code>_shift"
3875 [(set (match_operand:SI 0 "s_register_operand" "=r")
3876 (SAT:SI (SATrev:SI (match_operator:SI 3 "sat_shift_operator"
3877 [(match_operand:SI 4 "s_register_operand" "r")
3878 (match_operand:SI 5 "const_int_operand" "i")])
3879 (match_operand:SI 1 "const_int_operand" "i"))
3880 (match_operand:SI 2 "const_int_operand" "i")))]
3881 "TARGET_32BIT && arm_arch6 && <SAT:CODE> != <SATrev:CODE>
3882 && arm_sat_operator_match (operands[<SAT:SATlo>], operands[<SAT:SAThi>], NULL, NULL)"
3886 if (!arm_sat_operator_match (operands[<SAT:SATlo>], operands[<SAT:SAThi>],
3887 &mask, &signed_sat))
3890 operands[1] = GEN_INT (mask);
3892 return "ssat%?\t%0, %1, %4%S3";
3894 return "usat%?\t%0, %1, %4%S3";
3896 [(set_attr "predicable" "yes")
3897 (set_attr "predicable_short_it" "no")
3898 (set_attr "shift" "3")
3899 (set_attr "type" "logic_shift_reg")])
3901 ;; Shift and rotation insns
3903 (define_expand "ashldi3"
3904 [(set (match_operand:DI 0 "s_register_operand" "")
3905 (ashift:DI (match_operand:DI 1 "s_register_operand" "")
3906 (match_operand:SI 2 "general_operand" "")))]
3911 /* Delay the decision whether to use NEON or core-regs until
3912 register allocation. */
3913 emit_insn (gen_ashldi3_neon (operands[0], operands[1], operands[2]));
3918 /* Only the NEON case can handle in-memory shift counts. */
3919 if (!reg_or_int_operand (operands[2], SImode))
3920 operands[2] = force_reg (SImode, operands[2]);
3923 if (!CONST_INT_P (operands[2]) && TARGET_REALLY_IWMMXT)
3924 ; /* No special preparation statements; expand pattern as above. */
3927 rtx scratch1, scratch2;
3929 if (CONST_INT_P (operands[2])
3930 && (HOST_WIDE_INT) INTVAL (operands[2]) == 1)
3932 emit_insn (gen_arm_ashldi3_1bit (operands[0], operands[1]));
3936 /* Ideally we should use iwmmxt here if we could know that operands[1]
3937 ends up already living in an iwmmxt register. Otherwise it's
3938 cheaper to have the alternate code being generated than moving
3939 values to iwmmxt regs and back. */
3941 /* If we're optimizing for size, we prefer the libgcc calls. */
3942 if (optimize_function_for_size_p (cfun))
3945 /* Expand operation using core-registers.
3946 'FAIL' would achieve the same thing, but this is a bit smarter. */
3947 scratch1 = gen_reg_rtx (SImode);
3948 scratch2 = gen_reg_rtx (SImode);
3949 arm_emit_coreregs_64bit_shift (ASHIFT, operands[0], operands[1],
3950 operands[2], scratch1, scratch2);
3956 (define_insn "arm_ashldi3_1bit"
3957 [(set (match_operand:DI 0 "s_register_operand" "=r,&r")
3958 (ashift:DI (match_operand:DI 1 "s_register_operand" "0,r")
3960 (clobber (reg:CC CC_REGNUM))]
3962 "movs\\t%Q0, %Q1, asl #1\;adc\\t%R0, %R1, %R1"
3963 [(set_attr "conds" "clob")
3964 (set_attr "length" "8")
3965 (set_attr "type" "multiple")]
3968 (define_expand "ashlsi3"
3969 [(set (match_operand:SI 0 "s_register_operand" "")
3970 (ashift:SI (match_operand:SI 1 "s_register_operand" "")
3971 (match_operand:SI 2 "arm_rhs_operand" "")))]
3974 if (CONST_INT_P (operands[2])
3975 && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) > 31)
3977 emit_insn (gen_movsi (operands[0], const0_rtx));
3983 (define_insn "*thumb1_ashlsi3"
3984 [(set (match_operand:SI 0 "register_operand" "=l,l")
3985 (ashift:SI (match_operand:SI 1 "register_operand" "l,0")
3986 (match_operand:SI 2 "nonmemory_operand" "N,l")))]
3989 [(set_attr "length" "2")
3990 (set_attr "type" "shift_imm,shift_reg")
3991 (set_attr "conds" "set")])
3993 (define_expand "ashrdi3"
3994 [(set (match_operand:DI 0 "s_register_operand" "")
3995 (ashiftrt:DI (match_operand:DI 1 "s_register_operand" "")
3996 (match_operand:SI 2 "reg_or_int_operand" "")))]
4001 /* Delay the decision whether to use NEON or core-regs until
4002 register allocation. */
4003 emit_insn (gen_ashrdi3_neon (operands[0], operands[1], operands[2]));
4007 if (!CONST_INT_P (operands[2]) && TARGET_REALLY_IWMMXT)
4008 ; /* No special preparation statements; expand pattern as above. */
4011 rtx scratch1, scratch2;
4013 if (CONST_INT_P (operands[2])
4014 && (HOST_WIDE_INT) INTVAL (operands[2]) == 1)
4016 emit_insn (gen_arm_ashrdi3_1bit (operands[0], operands[1]));
4020 /* Ideally we should use iwmmxt here if we could know that operands[1]
4021 ends up already living in an iwmmxt register. Otherwise it's
4022 cheaper to have the alternate code being generated than moving
4023 values to iwmmxt regs and back. */
4025 /* If we're optimizing for size, we prefer the libgcc calls. */
4026 if (optimize_function_for_size_p (cfun))
4029 /* Expand operation using core-registers.
4030 'FAIL' would achieve the same thing, but this is a bit smarter. */
4031 scratch1 = gen_reg_rtx (SImode);
4032 scratch2 = gen_reg_rtx (SImode);
4033 arm_emit_coreregs_64bit_shift (ASHIFTRT, operands[0], operands[1],
4034 operands[2], scratch1, scratch2);
4040 (define_insn "arm_ashrdi3_1bit"
4041 [(set (match_operand:DI 0 "s_register_operand" "=r,&r")
4042 (ashiftrt:DI (match_operand:DI 1 "s_register_operand" "0,r")
4044 (clobber (reg:CC CC_REGNUM))]
4046 "movs\\t%R0, %R1, asr #1\;mov\\t%Q0, %Q1, rrx"
4047 [(set_attr "conds" "clob")
4048 (set_attr "length" "8")
4049 (set_attr "type" "multiple")]
4052 (define_expand "ashrsi3"
4053 [(set (match_operand:SI 0 "s_register_operand" "")
4054 (ashiftrt:SI (match_operand:SI 1 "s_register_operand" "")
4055 (match_operand:SI 2 "arm_rhs_operand" "")))]
4058 if (CONST_INT_P (operands[2])
4059 && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) > 31)
4060 operands[2] = GEN_INT (31);
4064 (define_insn "*thumb1_ashrsi3"
4065 [(set (match_operand:SI 0 "register_operand" "=l,l")
4066 (ashiftrt:SI (match_operand:SI 1 "register_operand" "l,0")
4067 (match_operand:SI 2 "nonmemory_operand" "N,l")))]
4070 [(set_attr "length" "2")
4071 (set_attr "type" "shift_imm,shift_reg")
4072 (set_attr "conds" "set")])
4074 (define_expand "lshrdi3"
4075 [(set (match_operand:DI 0 "s_register_operand" "")
4076 (lshiftrt:DI (match_operand:DI 1 "s_register_operand" "")
4077 (match_operand:SI 2 "reg_or_int_operand" "")))]
4082 /* Delay the decision whether to use NEON or core-regs until
4083 register allocation. */
4084 emit_insn (gen_lshrdi3_neon (operands[0], operands[1], operands[2]));
4088 if (!CONST_INT_P (operands[2]) && TARGET_REALLY_IWMMXT)
4089 ; /* No special preparation statements; expand pattern as above. */
4092 rtx scratch1, scratch2;
4094 if (CONST_INT_P (operands[2])
4095 && (HOST_WIDE_INT) INTVAL (operands[2]) == 1)
4097 emit_insn (gen_arm_lshrdi3_1bit (operands[0], operands[1]));
4101 /* Ideally we should use iwmmxt here if we could know that operands[1]
4102 ends up already living in an iwmmxt register. Otherwise it's
4103 cheaper to have the alternate code being generated than moving
4104 values to iwmmxt regs and back. */
4106 /* If we're optimizing for size, we prefer the libgcc calls. */
4107 if (optimize_function_for_size_p (cfun))
4110 /* Expand operation using core-registers.
4111 'FAIL' would achieve the same thing, but this is a bit smarter. */
4112 scratch1 = gen_reg_rtx (SImode);
4113 scratch2 = gen_reg_rtx (SImode);
4114 arm_emit_coreregs_64bit_shift (LSHIFTRT, operands[0], operands[1],
4115 operands[2], scratch1, scratch2);
4121 (define_insn "arm_lshrdi3_1bit"
4122 [(set (match_operand:DI 0 "s_register_operand" "=r,&r")
4123 (lshiftrt:DI (match_operand:DI 1 "s_register_operand" "0,r")
4125 (clobber (reg:CC CC_REGNUM))]
4127 "movs\\t%R0, %R1, lsr #1\;mov\\t%Q0, %Q1, rrx"
4128 [(set_attr "conds" "clob")
4129 (set_attr "length" "8")
4130 (set_attr "type" "multiple")]
4133 (define_expand "lshrsi3"
4134 [(set (match_operand:SI 0 "s_register_operand" "")
4135 (lshiftrt:SI (match_operand:SI 1 "s_register_operand" "")
4136 (match_operand:SI 2 "arm_rhs_operand" "")))]
4139 if (CONST_INT_P (operands[2])
4140 && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) > 31)
4142 emit_insn (gen_movsi (operands[0], const0_rtx));
4148 (define_insn "*thumb1_lshrsi3"
4149 [(set (match_operand:SI 0 "register_operand" "=l,l")
4150 (lshiftrt:SI (match_operand:SI 1 "register_operand" "l,0")
4151 (match_operand:SI 2 "nonmemory_operand" "N,l")))]
4154 [(set_attr "length" "2")
4155 (set_attr "type" "shift_imm,shift_reg")
4156 (set_attr "conds" "set")])
4158 (define_expand "rotlsi3"
4159 [(set (match_operand:SI 0 "s_register_operand" "")
4160 (rotatert:SI (match_operand:SI 1 "s_register_operand" "")
4161 (match_operand:SI 2 "reg_or_int_operand" "")))]
4164 if (CONST_INT_P (operands[2]))
4165 operands[2] = GEN_INT ((32 - INTVAL (operands[2])) % 32);
4168 rtx reg = gen_reg_rtx (SImode);
4169 emit_insn (gen_subsi3 (reg, GEN_INT (32), operands[2]));
4175 (define_expand "rotrsi3"
4176 [(set (match_operand:SI 0 "s_register_operand" "")
4177 (rotatert:SI (match_operand:SI 1 "s_register_operand" "")
4178 (match_operand:SI 2 "arm_rhs_operand" "")))]
4183 if (CONST_INT_P (operands[2])
4184 && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) > 31)
4185 operands[2] = GEN_INT (INTVAL (operands[2]) % 32);
4187 else /* TARGET_THUMB1 */
4189 if (CONST_INT_P (operands [2]))
4190 operands [2] = force_reg (SImode, operands[2]);
4195 (define_insn "*thumb1_rotrsi3"
4196 [(set (match_operand:SI 0 "register_operand" "=l")
4197 (rotatert:SI (match_operand:SI 1 "register_operand" "0")
4198 (match_operand:SI 2 "register_operand" "l")))]
4201 [(set_attr "type" "shift_reg")
4202 (set_attr "length" "2")]
4205 (define_insn "*arm_shiftsi3"
4206 [(set (match_operand:SI 0 "s_register_operand" "=l,l,r,r")
4207 (match_operator:SI 3 "shift_operator"
4208 [(match_operand:SI 1 "s_register_operand" "0,l,r,r")
4209 (match_operand:SI 2 "reg_or_int_operand" "l,M,M,r")]))]
4211 "* return arm_output_shift(operands, 0);"
4212 [(set_attr "predicable" "yes")
4213 (set_attr "arch" "t2,t2,*,*")
4214 (set_attr "predicable_short_it" "yes,yes,no,no")
4215 (set_attr "length" "4")
4216 (set_attr "shift" "1")
4217 (set_attr "type" "alu_shift_reg,alu_shift_imm,alu_shift_imm,alu_shift_reg")]
4220 (define_insn "*shiftsi3_compare0"
4221 [(set (reg:CC_NOOV CC_REGNUM)
4222 (compare:CC_NOOV (match_operator:SI 3 "shift_operator"
4223 [(match_operand:SI 1 "s_register_operand" "r,r")
4224 (match_operand:SI 2 "arm_rhs_operand" "M,r")])
4226 (set (match_operand:SI 0 "s_register_operand" "=r,r")
4227 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))]
4229 "* return arm_output_shift(operands, 1);"
4230 [(set_attr "conds" "set")
4231 (set_attr "shift" "1")
4232 (set_attr "type" "alus_shift_imm,alus_shift_reg")]
4235 (define_insn "*shiftsi3_compare0_scratch"
4236 [(set (reg:CC_NOOV CC_REGNUM)
4237 (compare:CC_NOOV (match_operator:SI 3 "shift_operator"
4238 [(match_operand:SI 1 "s_register_operand" "r,r")
4239 (match_operand:SI 2 "arm_rhs_operand" "M,r")])
4241 (clobber (match_scratch:SI 0 "=r,r"))]
4243 "* return arm_output_shift(operands, 1);"
4244 [(set_attr "conds" "set")
4245 (set_attr "shift" "1")
4246 (set_attr "type" "shift_imm,shift_reg")]
4249 (define_insn "*not_shiftsi"
4250 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4251 (not:SI (match_operator:SI 3 "shift_operator"
4252 [(match_operand:SI 1 "s_register_operand" "r,r")
4253 (match_operand:SI 2 "shift_amount_operand" "M,rM")])))]
4256 [(set_attr "predicable" "yes")
4257 (set_attr "predicable_short_it" "no")
4258 (set_attr "shift" "1")
4259 (set_attr "arch" "32,a")
4260 (set_attr "type" "mvn_shift,mvn_shift_reg")])
4262 (define_insn "*not_shiftsi_compare0"
4263 [(set (reg:CC_NOOV CC_REGNUM)
4265 (not:SI (match_operator:SI 3 "shift_operator"
4266 [(match_operand:SI 1 "s_register_operand" "r,r")
4267 (match_operand:SI 2 "shift_amount_operand" "M,rM")]))
4269 (set (match_operand:SI 0 "s_register_operand" "=r,r")
4270 (not:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)])))]
4273 [(set_attr "conds" "set")
4274 (set_attr "shift" "1")
4275 (set_attr "arch" "32,a")
4276 (set_attr "type" "mvn_shift,mvn_shift_reg")])
4278 (define_insn "*not_shiftsi_compare0_scratch"
4279 [(set (reg:CC_NOOV CC_REGNUM)
4281 (not:SI (match_operator:SI 3 "shift_operator"
4282 [(match_operand:SI 1 "s_register_operand" "r,r")
4283 (match_operand:SI 2 "shift_amount_operand" "M,rM")]))
4285 (clobber (match_scratch:SI 0 "=r,r"))]
4288 [(set_attr "conds" "set")
4289 (set_attr "shift" "1")
4290 (set_attr "arch" "32,a")
4291 (set_attr "type" "mvn_shift,mvn_shift_reg")])
4293 ;; We don't really have extzv, but defining this using shifts helps
4294 ;; to reduce register pressure later on.
4296 (define_expand "extzv"
4297 [(set (match_operand 0 "s_register_operand" "")
4298 (zero_extract (match_operand 1 "nonimmediate_operand" "")
4299 (match_operand 2 "const_int_operand" "")
4300 (match_operand 3 "const_int_operand" "")))]
4301 "TARGET_THUMB1 || arm_arch_thumb2"
4304 HOST_WIDE_INT lshift = 32 - INTVAL (operands[2]) - INTVAL (operands[3]);
4305 HOST_WIDE_INT rshift = 32 - INTVAL (operands[2]);
4307 if (arm_arch_thumb2)
4309 HOST_WIDE_INT width = INTVAL (operands[2]);
4310 HOST_WIDE_INT bitpos = INTVAL (operands[3]);
4312 if (unaligned_access && MEM_P (operands[1])
4313 && (width == 16 || width == 32) && (bitpos % BITS_PER_UNIT) == 0)
4317 if (BYTES_BIG_ENDIAN)
4318 bitpos = GET_MODE_BITSIZE (GET_MODE (operands[0])) - width
4323 base_addr = adjust_address (operands[1], SImode,
4324 bitpos / BITS_PER_UNIT);
4325 emit_insn (gen_unaligned_loadsi (operands[0], base_addr));
4329 rtx dest = operands[0];
4330 rtx tmp = gen_reg_rtx (SImode);
4332 /* We may get a paradoxical subreg here. Strip it off. */
4333 if (GET_CODE (dest) == SUBREG
4334 && GET_MODE (dest) == SImode
4335 && GET_MODE (SUBREG_REG (dest)) == HImode)
4336 dest = SUBREG_REG (dest);
4338 if (GET_MODE_BITSIZE (GET_MODE (dest)) != width)
4341 base_addr = adjust_address (operands[1], HImode,
4342 bitpos / BITS_PER_UNIT);
4343 emit_insn (gen_unaligned_loadhiu (tmp, base_addr));
4344 emit_move_insn (gen_lowpart (SImode, dest), tmp);
4348 else if (s_register_operand (operands[1], GET_MODE (operands[1])))
4350 emit_insn (gen_extzv_t2 (operands[0], operands[1], operands[2],
4358 if (!s_register_operand (operands[1], GET_MODE (operands[1])))
4361 operands[3] = GEN_INT (rshift);
4365 emit_insn (gen_lshrsi3 (operands[0], operands[1], operands[3]));
4369 emit_insn (gen_extzv_t1 (operands[0], operands[1], GEN_INT (lshift),
4370 operands[3], gen_reg_rtx (SImode)));
4375 ;; Helper for extzv, for the Thumb-1 register-shifts case.
4377 (define_expand "extzv_t1"
4378 [(set (match_operand:SI 4 "s_register_operand" "")
4379 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
4380 (match_operand:SI 2 "const_int_operand" "")))
4381 (set (match_operand:SI 0 "s_register_operand" "")
4382 (lshiftrt:SI (match_dup 4)
4383 (match_operand:SI 3 "const_int_operand" "")))]
4387 (define_expand "extv"
4388 [(set (match_operand 0 "s_register_operand" "")
4389 (sign_extract (match_operand 1 "nonimmediate_operand" "")
4390 (match_operand 2 "const_int_operand" "")
4391 (match_operand 3 "const_int_operand" "")))]
4394 HOST_WIDE_INT width = INTVAL (operands[2]);
4395 HOST_WIDE_INT bitpos = INTVAL (operands[3]);
4397 if (unaligned_access && MEM_P (operands[1]) && (width == 16 || width == 32)
4398 && (bitpos % BITS_PER_UNIT) == 0)
4402 if (BYTES_BIG_ENDIAN)
4403 bitpos = GET_MODE_BITSIZE (GET_MODE (operands[0])) - width - bitpos;
4407 base_addr = adjust_address (operands[1], SImode,
4408 bitpos / BITS_PER_UNIT);
4409 emit_insn (gen_unaligned_loadsi (operands[0], base_addr));
4413 rtx dest = operands[0];
4414 rtx tmp = gen_reg_rtx (SImode);
4416 /* We may get a paradoxical subreg here. Strip it off. */
4417 if (GET_CODE (dest) == SUBREG
4418 && GET_MODE (dest) == SImode
4419 && GET_MODE (SUBREG_REG (dest)) == HImode)
4420 dest = SUBREG_REG (dest);
4422 if (GET_MODE_BITSIZE (GET_MODE (dest)) != width)
4425 base_addr = adjust_address (operands[1], HImode,
4426 bitpos / BITS_PER_UNIT);
4427 emit_insn (gen_unaligned_loadhis (tmp, base_addr));
4428 emit_move_insn (gen_lowpart (SImode, dest), tmp);
4433 else if (!s_register_operand (operands[1], GET_MODE (operands[1])))
4435 else if (GET_MODE (operands[0]) == SImode
4436 && GET_MODE (operands[1]) == SImode)
4438 emit_insn (gen_extv_regsi (operands[0], operands[1], operands[2],
4446 ; Helper to expand register forms of extv with the proper modes.
4448 (define_expand "extv_regsi"
4449 [(set (match_operand:SI 0 "s_register_operand" "")
4450 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "")
4451 (match_operand 2 "const_int_operand" "")
4452 (match_operand 3 "const_int_operand" "")))]
4457 ; ARMv6+ unaligned load/store instructions (used for packed structure accesses).
4459 (define_insn "unaligned_loadsi"
4460 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
4461 (unspec:SI [(match_operand:SI 1 "memory_operand" "Uw,m")]
4462 UNSPEC_UNALIGNED_LOAD))]
4463 "unaligned_access && TARGET_32BIT"
4464 "ldr%?\t%0, %1\t@ unaligned"
4465 [(set_attr "arch" "t2,any")
4466 (set_attr "length" "2,4")
4467 (set_attr "predicable" "yes")
4468 (set_attr "predicable_short_it" "yes,no")
4469 (set_attr "type" "load1")])
4471 (define_insn "unaligned_loadhis"
4472 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
4474 (unspec:HI [(match_operand:HI 1 "memory_operand" "Uw,m")]
4475 UNSPEC_UNALIGNED_LOAD)))]
4476 "unaligned_access && TARGET_32BIT"
4477 "ldr%(sh%)\t%0, %1\t@ unaligned"
4478 [(set_attr "arch" "t2,any")
4479 (set_attr "length" "2,4")
4480 (set_attr "predicable" "yes")
4481 (set_attr "predicable_short_it" "yes,no")
4482 (set_attr "type" "load_byte")])
4484 (define_insn "unaligned_loadhiu"
4485 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
4487 (unspec:HI [(match_operand:HI 1 "memory_operand" "Uw,m")]
4488 UNSPEC_UNALIGNED_LOAD)))]
4489 "unaligned_access && TARGET_32BIT"
4490 "ldr%(h%)\t%0, %1\t@ unaligned"
4491 [(set_attr "arch" "t2,any")
4492 (set_attr "length" "2,4")
4493 (set_attr "predicable" "yes")
4494 (set_attr "predicable_short_it" "yes,no")
4495 (set_attr "type" "load_byte")])
4497 (define_insn "unaligned_storesi"
4498 [(set (match_operand:SI 0 "memory_operand" "=Uw,m")
4499 (unspec:SI [(match_operand:SI 1 "s_register_operand" "l,r")]
4500 UNSPEC_UNALIGNED_STORE))]
4501 "unaligned_access && TARGET_32BIT"
4502 "str%?\t%1, %0\t@ unaligned"
4503 [(set_attr "arch" "t2,any")
4504 (set_attr "length" "2,4")
4505 (set_attr "predicable" "yes")
4506 (set_attr "predicable_short_it" "yes,no")
4507 (set_attr "type" "store1")])
4509 (define_insn "unaligned_storehi"
4510 [(set (match_operand:HI 0 "memory_operand" "=Uw,m")
4511 (unspec:HI [(match_operand:HI 1 "s_register_operand" "l,r")]
4512 UNSPEC_UNALIGNED_STORE))]
4513 "unaligned_access && TARGET_32BIT"
4514 "str%(h%)\t%1, %0\t@ unaligned"
4515 [(set_attr "arch" "t2,any")
4516 (set_attr "length" "2,4")
4517 (set_attr "predicable" "yes")
4518 (set_attr "predicable_short_it" "yes,no")
4519 (set_attr "type" "store1")])
4521 ;; Unaligned double-word load and store.
4522 ;; Split after reload into two unaligned single-word accesses.
4523 ;; It prevents lower_subreg from splitting some other aligned
4524 ;; double-word accesses too early. Used for internal memcpy.
4526 (define_insn_and_split "unaligned_loaddi"
4527 [(set (match_operand:DI 0 "s_register_operand" "=l,r")
4528 (unspec:DI [(match_operand:DI 1 "memory_operand" "o,o")]
4529 UNSPEC_UNALIGNED_LOAD))]
4530 "unaligned_access && TARGET_32BIT"
4532 "&& reload_completed"
4533 [(set (match_dup 0) (unspec:SI [(match_dup 1)] UNSPEC_UNALIGNED_LOAD))
4534 (set (match_dup 2) (unspec:SI [(match_dup 3)] UNSPEC_UNALIGNED_LOAD))]
4536 operands[2] = gen_highpart (SImode, operands[0]);
4537 operands[0] = gen_lowpart (SImode, operands[0]);
4538 operands[3] = gen_highpart (SImode, operands[1]);
4539 operands[1] = gen_lowpart (SImode, operands[1]);
4541 /* If the first destination register overlaps with the base address,
4542 swap the order in which the loads are emitted. */
4543 if (reg_overlap_mentioned_p (operands[0], operands[1]))
4545 rtx tmp = operands[1];
4546 operands[1] = operands[3];
4549 operands[0] = operands[2];
4553 [(set_attr "arch" "t2,any")
4554 (set_attr "length" "4,8")
4555 (set_attr "predicable" "yes")
4556 (set_attr "type" "load2")])
4558 (define_insn_and_split "unaligned_storedi"
4559 [(set (match_operand:DI 0 "memory_operand" "=o,o")
4560 (unspec:DI [(match_operand:DI 1 "s_register_operand" "l,r")]
4561 UNSPEC_UNALIGNED_STORE))]
4562 "unaligned_access && TARGET_32BIT"
4564 "&& reload_completed"
4565 [(set (match_dup 0) (unspec:SI [(match_dup 1)] UNSPEC_UNALIGNED_STORE))
4566 (set (match_dup 2) (unspec:SI [(match_dup 3)] UNSPEC_UNALIGNED_STORE))]
4568 operands[2] = gen_highpart (SImode, operands[0]);
4569 operands[0] = gen_lowpart (SImode, operands[0]);
4570 operands[3] = gen_highpart (SImode, operands[1]);
4571 operands[1] = gen_lowpart (SImode, operands[1]);
4573 [(set_attr "arch" "t2,any")
4574 (set_attr "length" "4,8")
4575 (set_attr "predicable" "yes")
4576 (set_attr "type" "store2")])
4579 (define_insn "*extv_reg"
4580 [(set (match_operand:SI 0 "s_register_operand" "=r")
4581 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
4582 (match_operand:SI 2 "const_int_operand" "M")
4583 (match_operand:SI 3 "const_int_operand" "M")))]
4585 "sbfx%?\t%0, %1, %3, %2"
4586 [(set_attr "length" "4")
4587 (set_attr "predicable" "yes")
4588 (set_attr "predicable_short_it" "no")
4589 (set_attr "type" "bfm")]
4592 (define_insn "extzv_t2"
4593 [(set (match_operand:SI 0 "s_register_operand" "=r")
4594 (zero_extract:SI (match_operand:SI 1 "s_register_operand" "r")
4595 (match_operand:SI 2 "const_int_operand" "M")
4596 (match_operand:SI 3 "const_int_operand" "M")))]
4598 "ubfx%?\t%0, %1, %3, %2"
4599 [(set_attr "length" "4")
4600 (set_attr "predicable" "yes")
4601 (set_attr "predicable_short_it" "no")
4602 (set_attr "type" "bfm")]
4606 ;; Division instructions
4607 (define_insn "divsi3"
4608 [(set (match_operand:SI 0 "s_register_operand" "=r")
4609 (div:SI (match_operand:SI 1 "s_register_operand" "r")
4610 (match_operand:SI 2 "s_register_operand" "r")))]
4612 "sdiv%?\t%0, %1, %2"
4613 [(set_attr "predicable" "yes")
4614 (set_attr "predicable_short_it" "no")
4615 (set_attr "type" "sdiv")]
4618 (define_insn "udivsi3"
4619 [(set (match_operand:SI 0 "s_register_operand" "=r")
4620 (udiv:SI (match_operand:SI 1 "s_register_operand" "r")
4621 (match_operand:SI 2 "s_register_operand" "r")))]
4623 "udiv%?\t%0, %1, %2"
4624 [(set_attr "predicable" "yes")
4625 (set_attr "predicable_short_it" "no")
4626 (set_attr "type" "udiv")]
4630 ;; Unary arithmetic insns
4632 (define_expand "negdi2"
4634 [(set (match_operand:DI 0 "s_register_operand" "")
4635 (neg:DI (match_operand:DI 1 "s_register_operand" "")))
4636 (clobber (reg:CC CC_REGNUM))])]
4641 emit_insn (gen_negdi2_neon (operands[0], operands[1]));
4647 ;; The constraints here are to prevent a *partial* overlap (where %Q0 == %R1).
4648 ;; The first alternative allows the common case of a *full* overlap.
4649 (define_insn_and_split "*arm_negdi2"
4650 [(set (match_operand:DI 0 "s_register_operand" "=r,&r")
4651 (neg:DI (match_operand:DI 1 "s_register_operand" "0,r")))
4652 (clobber (reg:CC CC_REGNUM))]
4654 "#" ; "rsbs\\t%Q0, %Q1, #0\;rsc\\t%R0, %R1, #0"
4655 "&& reload_completed"
4656 [(parallel [(set (reg:CC CC_REGNUM)
4657 (compare:CC (const_int 0) (match_dup 1)))
4658 (set (match_dup 0) (minus:SI (const_int 0) (match_dup 1)))])
4659 (set (match_dup 2) (minus:SI (minus:SI (const_int 0) (match_dup 3))
4660 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
4662 operands[2] = gen_highpart (SImode, operands[0]);
4663 operands[0] = gen_lowpart (SImode, operands[0]);
4664 operands[3] = gen_highpart (SImode, operands[1]);
4665 operands[1] = gen_lowpart (SImode, operands[1]);
4667 [(set_attr "conds" "clob")
4668 (set_attr "length" "8")
4669 (set_attr "type" "multiple")]
4672 (define_insn "*thumb1_negdi2"
4673 [(set (match_operand:DI 0 "register_operand" "=&l")
4674 (neg:DI (match_operand:DI 1 "register_operand" "l")))
4675 (clobber (reg:CC CC_REGNUM))]
4677 "mov\\t%R0, #0\;neg\\t%Q0, %Q1\;sbc\\t%R0, %R1"
4678 [(set_attr "length" "6")
4679 (set_attr "type" "multiple")]
4682 (define_expand "negsi2"
4683 [(set (match_operand:SI 0 "s_register_operand" "")
4684 (neg:SI (match_operand:SI 1 "s_register_operand" "")))]
4689 (define_insn "*arm_negsi2"
4690 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
4691 (neg:SI (match_operand:SI 1 "s_register_operand" "l,r")))]
4693 "rsb%?\\t%0, %1, #0"
4694 [(set_attr "predicable" "yes")
4695 (set_attr "predicable_short_it" "yes,no")
4696 (set_attr "arch" "t2,*")
4697 (set_attr "length" "4")
4698 (set_attr "type" "alu_reg")]
4701 (define_insn "*thumb1_negsi2"
4702 [(set (match_operand:SI 0 "register_operand" "=l")
4703 (neg:SI (match_operand:SI 1 "register_operand" "l")))]
4706 [(set_attr "length" "2")
4707 (set_attr "type" "alu_imm")]
4710 (define_expand "negsf2"
4711 [(set (match_operand:SF 0 "s_register_operand" "")
4712 (neg:SF (match_operand:SF 1 "s_register_operand" "")))]
4713 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
4717 (define_expand "negdf2"
4718 [(set (match_operand:DF 0 "s_register_operand" "")
4719 (neg:DF (match_operand:DF 1 "s_register_operand" "")))]
4720 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
4723 (define_insn_and_split "*zextendsidi_negsi"
4724 [(set (match_operand:DI 0 "s_register_operand" "=r")
4725 (zero_extend:DI (neg:SI (match_operand:SI 1 "s_register_operand" "r"))))]
4730 (neg:SI (match_dup 1)))
4734 operands[2] = gen_lowpart (SImode, operands[0]);
4735 operands[3] = gen_highpart (SImode, operands[0]);
4737 [(set_attr "length" "8")
4738 (set_attr "type" "multiple")]
4741 ;; Negate an extended 32-bit value.
4742 (define_insn_and_split "*negdi_extendsidi"
4743 [(set (match_operand:DI 0 "s_register_operand" "=l,r")
4744 (neg:DI (sign_extend:DI
4745 (match_operand:SI 1 "s_register_operand" "l,r"))))
4746 (clobber (reg:CC CC_REGNUM))]
4749 "&& reload_completed"
4752 rtx low = gen_lowpart (SImode, operands[0]);
4753 rtx high = gen_highpart (SImode, operands[0]);
4755 if (reg_overlap_mentioned_p (low, operands[1]))
4757 /* Input overlaps the low word of the output. Use:
4760 rsc Rhi, Rhi, #0 (thumb2: sbc Rhi, Rhi, Rhi, lsl #1). */
4761 rtx cc_reg = gen_rtx_REG (CC_Cmode, CC_REGNUM);
4763 emit_insn (gen_rtx_SET (VOIDmode, high,
4764 gen_rtx_ASHIFTRT (SImode, operands[1],
4767 emit_insn (gen_subsi3_compare (low, const0_rtx, operands[1]));
4769 emit_insn (gen_rtx_SET (VOIDmode, high,
4770 gen_rtx_MINUS (SImode,
4771 gen_rtx_MINUS (SImode,
4774 gen_rtx_LTU (SImode,
4779 rtx two_x = gen_rtx_ASHIFT (SImode, high, GEN_INT (1));
4780 emit_insn (gen_rtx_SET (VOIDmode, high,
4781 gen_rtx_MINUS (SImode,
4782 gen_rtx_MINUS (SImode,
4785 gen_rtx_LTU (SImode,
4792 /* No overlap, or overlap on high word. Use:
4796 Flags not needed for this sequence. */
4797 emit_insn (gen_rtx_SET (VOIDmode, low,
4798 gen_rtx_NEG (SImode, operands[1])));
4799 emit_insn (gen_rtx_SET (VOIDmode, high,
4800 gen_rtx_AND (SImode,
4801 gen_rtx_NOT (SImode, operands[1]),
4803 emit_insn (gen_rtx_SET (VOIDmode, high,
4804 gen_rtx_ASHIFTRT (SImode, high,
4809 [(set_attr "length" "12")
4810 (set_attr "arch" "t2,*")
4811 (set_attr "type" "multiple")]
4814 (define_insn_and_split "*negdi_zero_extendsidi"
4815 [(set (match_operand:DI 0 "s_register_operand" "=r,&r")
4816 (neg:DI (zero_extend:DI (match_operand:SI 1 "s_register_operand" "0,r"))))
4817 (clobber (reg:CC CC_REGNUM))]
4819 "#" ; "rsbs\\t%Q0, %1, #0\;sbc\\t%R0,%R0,%R0"
4820 ;; Don't care what register is input to sbc,
4821 ;; since we just just need to propagate the carry.
4822 "&& reload_completed"
4823 [(parallel [(set (reg:CC CC_REGNUM)
4824 (compare:CC (const_int 0) (match_dup 1)))
4825 (set (match_dup 0) (minus:SI (const_int 0) (match_dup 1)))])
4826 (set (match_dup 2) (minus:SI (minus:SI (match_dup 2) (match_dup 2))
4827 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
4829 operands[2] = gen_highpart (SImode, operands[0]);
4830 operands[0] = gen_lowpart (SImode, operands[0]);
4832 [(set_attr "conds" "clob")
4833 (set_attr "length" "8")
4834 (set_attr "type" "multiple")] ;; length in thumb is 4
4837 ;; abssi2 doesn't really clobber the condition codes if a different register
4838 ;; is being set. To keep things simple, assume during rtl manipulations that
4839 ;; it does, but tell the final scan operator the truth. Similarly for
4842 (define_expand "abssi2"
4844 [(set (match_operand:SI 0 "s_register_operand" "")
4845 (abs:SI (match_operand:SI 1 "s_register_operand" "")))
4846 (clobber (match_dup 2))])]
4850 operands[2] = gen_rtx_SCRATCH (SImode);
4852 operands[2] = gen_rtx_REG (CCmode, CC_REGNUM);
4855 (define_insn_and_split "*arm_abssi2"
4856 [(set (match_operand:SI 0 "s_register_operand" "=r,&r")
4857 (abs:SI (match_operand:SI 1 "s_register_operand" "0,r")))
4858 (clobber (reg:CC CC_REGNUM))]
4861 "&& reload_completed"
4864 /* if (which_alternative == 0) */
4865 if (REGNO(operands[0]) == REGNO(operands[1]))
4867 /* Emit the pattern:
4868 cmp\\t%0, #0\;rsblt\\t%0, %0, #0
4869 [(set (reg:CC CC_REGNUM)
4870 (compare:CC (match_dup 0) (const_int 0)))
4871 (cond_exec (lt:CC (reg:CC CC_REGNUM) (const_int 0))
4872 (set (match_dup 0) (minus:SI (const_int 0) (match_dup 1))))]
4874 emit_insn (gen_rtx_SET (VOIDmode,
4875 gen_rtx_REG (CCmode, CC_REGNUM),
4876 gen_rtx_COMPARE (CCmode, operands[0], const0_rtx)));
4877 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
4878 (gen_rtx_LT (SImode,
4879 gen_rtx_REG (CCmode, CC_REGNUM),
4881 (gen_rtx_SET (VOIDmode,
4883 (gen_rtx_MINUS (SImode,
4890 /* Emit the pattern:
4891 alt1: eor%?\\t%0, %1, %1, asr #31\;sub%?\\t%0, %0, %1, asr #31
4893 (xor:SI (match_dup 1)
4894 (ashiftrt:SI (match_dup 1) (const_int 31))))
4896 (minus:SI (match_dup 0)
4897 (ashiftrt:SI (match_dup 1) (const_int 31))))]
4899 emit_insn (gen_rtx_SET (VOIDmode,
4901 gen_rtx_XOR (SImode,
4902 gen_rtx_ASHIFTRT (SImode,
4906 emit_insn (gen_rtx_SET (VOIDmode,
4908 gen_rtx_MINUS (SImode,
4910 gen_rtx_ASHIFTRT (SImode,
4916 [(set_attr "conds" "clob,*")
4917 (set_attr "shift" "1")
4918 (set_attr "predicable" "no, yes")
4919 (set_attr "length" "8")
4920 (set_attr "type" "multiple")]
4923 (define_insn_and_split "*thumb1_abssi2"
4924 [(set (match_operand:SI 0 "s_register_operand" "=l")
4925 (abs:SI (match_operand:SI 1 "s_register_operand" "l")))
4926 (clobber (match_scratch:SI 2 "=&l"))]
4929 "TARGET_THUMB1 && reload_completed"
4930 [(set (match_dup 2) (ashiftrt:SI (match_dup 1) (const_int 31)))
4931 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))
4932 (set (match_dup 0) (xor:SI (match_dup 0) (match_dup 2)))]
4934 [(set_attr "length" "6")
4935 (set_attr "type" "multiple")]
4938 (define_insn_and_split "*arm_neg_abssi2"
4939 [(set (match_operand:SI 0 "s_register_operand" "=r,&r")
4940 (neg:SI (abs:SI (match_operand:SI 1 "s_register_operand" "0,r"))))
4941 (clobber (reg:CC CC_REGNUM))]
4944 "&& reload_completed"
4947 /* if (which_alternative == 0) */
4948 if (REGNO (operands[0]) == REGNO (operands[1]))
4950 /* Emit the pattern:
4951 cmp\\t%0, #0\;rsbgt\\t%0, %0, #0
4953 emit_insn (gen_rtx_SET (VOIDmode,
4954 gen_rtx_REG (CCmode, CC_REGNUM),
4955 gen_rtx_COMPARE (CCmode, operands[0], const0_rtx)));
4956 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
4958 gen_rtx_REG (CCmode, CC_REGNUM),
4960 gen_rtx_SET (VOIDmode,
4962 (gen_rtx_MINUS (SImode,
4968 /* Emit the pattern:
4969 eor%?\\t%0, %1, %1, asr #31\;rsb%?\\t%0, %0, %1, asr #31
4971 emit_insn (gen_rtx_SET (VOIDmode,
4973 gen_rtx_XOR (SImode,
4974 gen_rtx_ASHIFTRT (SImode,
4978 emit_insn (gen_rtx_SET (VOIDmode,
4980 gen_rtx_MINUS (SImode,
4981 gen_rtx_ASHIFTRT (SImode,
4988 [(set_attr "conds" "clob,*")
4989 (set_attr "shift" "1")
4990 (set_attr "predicable" "no, yes")
4991 (set_attr "length" "8")
4992 (set_attr "type" "multiple")]
4995 (define_insn_and_split "*thumb1_neg_abssi2"
4996 [(set (match_operand:SI 0 "s_register_operand" "=l")
4997 (neg:SI (abs:SI (match_operand:SI 1 "s_register_operand" "l"))))
4998 (clobber (match_scratch:SI 2 "=&l"))]
5001 "TARGET_THUMB1 && reload_completed"
5002 [(set (match_dup 2) (ashiftrt:SI (match_dup 1) (const_int 31)))
5003 (set (match_dup 0) (minus:SI (match_dup 2) (match_dup 1)))
5004 (set (match_dup 0) (xor:SI (match_dup 0) (match_dup 2)))]
5006 [(set_attr "length" "6")
5007 (set_attr "type" "multiple")]
5010 (define_expand "abssf2"
5011 [(set (match_operand:SF 0 "s_register_operand" "")
5012 (abs:SF (match_operand:SF 1 "s_register_operand" "")))]
5013 "TARGET_32BIT && TARGET_HARD_FLOAT"
5016 (define_expand "absdf2"
5017 [(set (match_operand:DF 0 "s_register_operand" "")
5018 (abs:DF (match_operand:DF 1 "s_register_operand" "")))]
5019 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
5022 (define_expand "sqrtsf2"
5023 [(set (match_operand:SF 0 "s_register_operand" "")
5024 (sqrt:SF (match_operand:SF 1 "s_register_operand" "")))]
5025 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
5028 (define_expand "sqrtdf2"
5029 [(set (match_operand:DF 0 "s_register_operand" "")
5030 (sqrt:DF (match_operand:DF 1 "s_register_operand" "")))]
5031 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
5034 (define_insn_and_split "one_cmpldi2"
5035 [(set (match_operand:DI 0 "s_register_operand" "=w,&r,&r,?w")
5036 (not:DI (match_operand:DI 1 "s_register_operand" " w, 0, r, w")))]
5043 "TARGET_32BIT && reload_completed
5044 && arm_general_register_operand (operands[0], DImode)"
5045 [(set (match_dup 0) (not:SI (match_dup 1)))
5046 (set (match_dup 2) (not:SI (match_dup 3)))]
5049 operands[2] = gen_highpart (SImode, operands[0]);
5050 operands[0] = gen_lowpart (SImode, operands[0]);
5051 operands[3] = gen_highpart (SImode, operands[1]);
5052 operands[1] = gen_lowpart (SImode, operands[1]);
5054 [(set_attr "length" "*,8,8,*")
5055 (set_attr "predicable" "no,yes,yes,no")
5056 (set_attr "type" "neon_move,multiple,multiple,neon_move")
5057 (set_attr "arch" "neon_for_64bits,*,*,avoid_neon_for_64bits")]
5060 (define_expand "one_cmplsi2"
5061 [(set (match_operand:SI 0 "s_register_operand" "")
5062 (not:SI (match_operand:SI 1 "s_register_operand" "")))]
5067 (define_insn "*arm_one_cmplsi2"
5068 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
5069 (not:SI (match_operand:SI 1 "s_register_operand" "l,r")))]
5072 [(set_attr "predicable" "yes")
5073 (set_attr "predicable_short_it" "yes,no")
5074 (set_attr "arch" "t2,*")
5075 (set_attr "length" "4")
5076 (set_attr "type" "mvn_reg")]
5079 (define_insn "*thumb1_one_cmplsi2"
5080 [(set (match_operand:SI 0 "register_operand" "=l")
5081 (not:SI (match_operand:SI 1 "register_operand" "l")))]
5084 [(set_attr "length" "2")
5085 (set_attr "type" "mvn_reg")]
5088 (define_insn "*notsi_compare0"
5089 [(set (reg:CC_NOOV CC_REGNUM)
5090 (compare:CC_NOOV (not:SI (match_operand:SI 1 "s_register_operand" "r"))
5092 (set (match_operand:SI 0 "s_register_operand" "=r")
5093 (not:SI (match_dup 1)))]
5096 [(set_attr "conds" "set")
5097 (set_attr "type" "mvn_reg")]
5100 (define_insn "*notsi_compare0_scratch"
5101 [(set (reg:CC_NOOV CC_REGNUM)
5102 (compare:CC_NOOV (not:SI (match_operand:SI 1 "s_register_operand" "r"))
5104 (clobber (match_scratch:SI 0 "=r"))]
5107 [(set_attr "conds" "set")
5108 (set_attr "type" "mvn_reg")]
5111 ;; Fixed <--> Floating conversion insns
5113 (define_expand "floatsihf2"
5114 [(set (match_operand:HF 0 "general_operand" "")
5115 (float:HF (match_operand:SI 1 "general_operand" "")))]
5119 rtx op1 = gen_reg_rtx (SFmode);
5120 expand_float (op1, operands[1], 0);
5121 op1 = convert_to_mode (HFmode, op1, 0);
5122 emit_move_insn (operands[0], op1);
5127 (define_expand "floatdihf2"
5128 [(set (match_operand:HF 0 "general_operand" "")
5129 (float:HF (match_operand:DI 1 "general_operand" "")))]
5133 rtx op1 = gen_reg_rtx (SFmode);
5134 expand_float (op1, operands[1], 0);
5135 op1 = convert_to_mode (HFmode, op1, 0);
5136 emit_move_insn (operands[0], op1);
5141 (define_expand "floatsisf2"
5142 [(set (match_operand:SF 0 "s_register_operand" "")
5143 (float:SF (match_operand:SI 1 "s_register_operand" "")))]
5144 "TARGET_32BIT && TARGET_HARD_FLOAT"
5148 (define_expand "floatsidf2"
5149 [(set (match_operand:DF 0 "s_register_operand" "")
5150 (float:DF (match_operand:SI 1 "s_register_operand" "")))]
5151 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
5155 (define_expand "fix_trunchfsi2"
5156 [(set (match_operand:SI 0 "general_operand" "")
5157 (fix:SI (fix:HF (match_operand:HF 1 "general_operand" ""))))]
5161 rtx op1 = convert_to_mode (SFmode, operands[1], 0);
5162 expand_fix (operands[0], op1, 0);
5167 (define_expand "fix_trunchfdi2"
5168 [(set (match_operand:DI 0 "general_operand" "")
5169 (fix:DI (fix:HF (match_operand:HF 1 "general_operand" ""))))]
5173 rtx op1 = convert_to_mode (SFmode, operands[1], 0);
5174 expand_fix (operands[0], op1, 0);
5179 (define_expand "fix_truncsfsi2"
5180 [(set (match_operand:SI 0 "s_register_operand" "")
5181 (fix:SI (fix:SF (match_operand:SF 1 "s_register_operand" ""))))]
5182 "TARGET_32BIT && TARGET_HARD_FLOAT"
5186 (define_expand "fix_truncdfsi2"
5187 [(set (match_operand:SI 0 "s_register_operand" "")
5188 (fix:SI (fix:DF (match_operand:DF 1 "s_register_operand" ""))))]
5189 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
5195 (define_expand "truncdfsf2"
5196 [(set (match_operand:SF 0 "s_register_operand" "")
5198 (match_operand:DF 1 "s_register_operand" "")))]
5199 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
5203 /* DFmode -> HFmode conversions have to go through SFmode. */
5204 (define_expand "truncdfhf2"
5205 [(set (match_operand:HF 0 "general_operand" "")
5207 (match_operand:DF 1 "general_operand" "")))]
5212 op1 = convert_to_mode (SFmode, operands[1], 0);
5213 op1 = convert_to_mode (HFmode, op1, 0);
5214 emit_move_insn (operands[0], op1);
5219 ;; Zero and sign extension instructions.
5221 (define_insn "zero_extend<mode>di2"
5222 [(set (match_operand:DI 0 "s_register_operand" "=w,r,?r,w")
5223 (zero_extend:DI (match_operand:QHSI 1 "<qhs_zextenddi_op>"
5224 "<qhs_zextenddi_cstr>")))]
5225 "TARGET_32BIT <qhs_zextenddi_cond>"
5227 [(set_attr "length" "8,4,8,8")
5228 (set_attr "arch" "neon_for_64bits,*,*,avoid_neon_for_64bits")
5229 (set_attr "ce_count" "2")
5230 (set_attr "predicable" "yes")
5231 (set_attr "type" "multiple,mov_reg,multiple,multiple")]
5234 (define_insn "extend<mode>di2"
5235 [(set (match_operand:DI 0 "s_register_operand" "=w,r,?r,?r,w")
5236 (sign_extend:DI (match_operand:QHSI 1 "<qhs_extenddi_op>"
5237 "<qhs_extenddi_cstr>")))]
5238 "TARGET_32BIT <qhs_sextenddi_cond>"
5240 [(set_attr "length" "8,4,8,8,8")
5241 (set_attr "ce_count" "2")
5242 (set_attr "shift" "1")
5243 (set_attr "predicable" "yes")
5244 (set_attr "arch" "neon_for_64bits,*,a,t,avoid_neon_for_64bits")
5245 (set_attr "type" "multiple,mov_reg,multiple,multiple,multiple")]
5248 ;; Splits for all extensions to DImode
5250 [(set (match_operand:DI 0 "s_register_operand" "")
5251 (zero_extend:DI (match_operand 1 "nonimmediate_operand" "")))]
5252 "TARGET_32BIT && reload_completed && !IS_VFP_REGNUM (REGNO (operands[0]))"
5253 [(set (match_dup 0) (match_dup 1))]
5255 rtx lo_part = gen_lowpart (SImode, operands[0]);
5256 enum machine_mode src_mode = GET_MODE (operands[1]);
5258 if (REG_P (operands[0])
5259 && !reg_overlap_mentioned_p (operands[0], operands[1]))
5260 emit_clobber (operands[0]);
5261 if (!REG_P (lo_part) || src_mode != SImode
5262 || !rtx_equal_p (lo_part, operands[1]))
5264 if (src_mode == SImode)
5265 emit_move_insn (lo_part, operands[1]);
5267 emit_insn (gen_rtx_SET (VOIDmode, lo_part,
5268 gen_rtx_ZERO_EXTEND (SImode, operands[1])));
5269 operands[1] = lo_part;
5271 operands[0] = gen_highpart (SImode, operands[0]);
5272 operands[1] = const0_rtx;
5276 [(set (match_operand:DI 0 "s_register_operand" "")
5277 (sign_extend:DI (match_operand 1 "nonimmediate_operand" "")))]
5278 "TARGET_32BIT && reload_completed && !IS_VFP_REGNUM (REGNO (operands[0]))"
5279 [(set (match_dup 0) (ashiftrt:SI (match_dup 1) (const_int 31)))]
5281 rtx lo_part = gen_lowpart (SImode, operands[0]);
5282 enum machine_mode src_mode = GET_MODE (operands[1]);
5284 if (REG_P (operands[0])
5285 && !reg_overlap_mentioned_p (operands[0], operands[1]))
5286 emit_clobber (operands[0]);
5288 if (!REG_P (lo_part) || src_mode != SImode
5289 || !rtx_equal_p (lo_part, operands[1]))
5291 if (src_mode == SImode)
5292 emit_move_insn (lo_part, operands[1]);
5294 emit_insn (gen_rtx_SET (VOIDmode, lo_part,
5295 gen_rtx_SIGN_EXTEND (SImode, operands[1])));
5296 operands[1] = lo_part;
5298 operands[0] = gen_highpart (SImode, operands[0]);
5301 (define_expand "zero_extendhisi2"
5302 [(set (match_operand:SI 0 "s_register_operand" "")
5303 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
5306 if (TARGET_ARM && !arm_arch4 && MEM_P (operands[1]))
5308 emit_insn (gen_movhi_bytes (operands[0], operands[1]));
5311 if (!arm_arch6 && !MEM_P (operands[1]))
5313 rtx t = gen_lowpart (SImode, operands[1]);
5314 rtx tmp = gen_reg_rtx (SImode);
5315 emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (16)));
5316 emit_insn (gen_lshrsi3 (operands[0], tmp, GEN_INT (16)));
5322 [(set (match_operand:SI 0 "s_register_operand" "")
5323 (zero_extend:SI (match_operand:HI 1 "s_register_operand" "")))]
5324 "!TARGET_THUMB2 && !arm_arch6"
5325 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
5326 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 16)))]
5328 operands[2] = gen_lowpart (SImode, operands[1]);
5331 (define_insn "*thumb1_zero_extendhisi2"
5332 [(set (match_operand:SI 0 "register_operand" "=l,l")
5333 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "l,m")))]
5338 if (which_alternative == 0 && arm_arch6)
5339 return "uxth\t%0, %1";
5340 if (which_alternative == 0)
5343 mem = XEXP (operands[1], 0);
5345 if (GET_CODE (mem) == CONST)
5346 mem = XEXP (mem, 0);
5348 if (GET_CODE (mem) == PLUS)
5350 rtx a = XEXP (mem, 0);
5352 /* This can happen due to bugs in reload. */
5353 if (REG_P (a) && REGNO (a) == SP_REGNUM)
5356 ops[0] = operands[0];
5359 output_asm_insn ("mov\t%0, %1", ops);
5361 XEXP (mem, 0) = operands[0];
5365 return "ldrh\t%0, %1";
5367 [(set_attr_alternative "length"
5368 [(if_then_else (eq_attr "is_arch6" "yes")
5369 (const_int 2) (const_int 4))
5371 (set_attr "type" "extend,load_byte")]
5374 (define_insn "*arm_zero_extendhisi2"
5375 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5376 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
5377 "TARGET_ARM && arm_arch4 && !arm_arch6"
5381 [(set_attr "type" "alu_shift_reg,load_byte")
5382 (set_attr "predicable" "yes")]
5385 (define_insn "*arm_zero_extendhisi2_v6"
5386 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5387 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
5388 "TARGET_ARM && arm_arch6"
5392 [(set_attr "predicable" "yes")
5393 (set_attr "type" "extend,load_byte")]
5396 (define_insn "*arm_zero_extendhisi2addsi"
5397 [(set (match_operand:SI 0 "s_register_operand" "=r")
5398 (plus:SI (zero_extend:SI (match_operand:HI 1 "s_register_operand" "r"))
5399 (match_operand:SI 2 "s_register_operand" "r")))]
5401 "uxtah%?\\t%0, %2, %1"
5402 [(set_attr "type" "alu_shift_reg")
5403 (set_attr "predicable" "yes")
5404 (set_attr "predicable_short_it" "no")]
5407 (define_expand "zero_extendqisi2"
5408 [(set (match_operand:SI 0 "s_register_operand" "")
5409 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))]
5412 if (TARGET_ARM && !arm_arch6 && !MEM_P (operands[1]))
5414 emit_insn (gen_andsi3 (operands[0],
5415 gen_lowpart (SImode, operands[1]),
5419 if (!arm_arch6 && !MEM_P (operands[1]))
5421 rtx t = gen_lowpart (SImode, operands[1]);
5422 rtx tmp = gen_reg_rtx (SImode);
5423 emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (24)));
5424 emit_insn (gen_lshrsi3 (operands[0], tmp, GEN_INT (24)));
5430 [(set (match_operand:SI 0 "s_register_operand" "")
5431 (zero_extend:SI (match_operand:QI 1 "s_register_operand" "")))]
5433 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 24)))
5434 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 24)))]
5436 operands[2] = simplify_gen_subreg (SImode, operands[1], QImode, 0);
5439 emit_insn (gen_andsi3 (operands[0], operands[2], GEN_INT (255)));
5444 (define_insn "*thumb1_zero_extendqisi2"
5445 [(set (match_operand:SI 0 "register_operand" "=l,l")
5446 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "l,m")))]
5447 "TARGET_THUMB1 && !arm_arch6"
5451 [(set_attr "length" "4,2")
5452 (set_attr "type" "alu_shift_reg,load_byte")
5453 (set_attr "pool_range" "*,32")]
5456 (define_insn "*thumb1_zero_extendqisi2_v6"
5457 [(set (match_operand:SI 0 "register_operand" "=l,l")
5458 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "l,m")))]
5459 "TARGET_THUMB1 && arm_arch6"
5463 [(set_attr "length" "2")
5464 (set_attr "type" "extend,load_byte")]
5467 (define_insn "*arm_zero_extendqisi2"
5468 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5469 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
5470 "TARGET_ARM && !arm_arch6"
5473 ldr%(b%)\\t%0, %1\\t%@ zero_extendqisi2"
5474 [(set_attr "length" "8,4")
5475 (set_attr "type" "alu_shift_reg,load_byte")
5476 (set_attr "predicable" "yes")]
5479 (define_insn "*arm_zero_extendqisi2_v6"
5480 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5481 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
5482 "TARGET_ARM && arm_arch6"
5485 ldr%(b%)\\t%0, %1\\t%@ zero_extendqisi2"
5486 [(set_attr "type" "extend,load_byte")
5487 (set_attr "predicable" "yes")]
5490 (define_insn "*arm_zero_extendqisi2addsi"
5491 [(set (match_operand:SI 0 "s_register_operand" "=r")
5492 (plus:SI (zero_extend:SI (match_operand:QI 1 "s_register_operand" "r"))
5493 (match_operand:SI 2 "s_register_operand" "r")))]
5495 "uxtab%?\\t%0, %2, %1"
5496 [(set_attr "predicable" "yes")
5497 (set_attr "predicable_short_it" "no")
5498 (set_attr "type" "alu_shift_reg")]
5502 [(set (match_operand:SI 0 "s_register_operand" "")
5503 (zero_extend:SI (subreg:QI (match_operand:SI 1 "" "") 0)))
5504 (clobber (match_operand:SI 2 "s_register_operand" ""))]
5505 "TARGET_32BIT && (!MEM_P (operands[1])) && ! BYTES_BIG_ENDIAN"
5506 [(set (match_dup 2) (match_dup 1))
5507 (set (match_dup 0) (and:SI (match_dup 2) (const_int 255)))]
5512 [(set (match_operand:SI 0 "s_register_operand" "")
5513 (zero_extend:SI (subreg:QI (match_operand:SI 1 "" "") 3)))
5514 (clobber (match_operand:SI 2 "s_register_operand" ""))]
5515 "TARGET_32BIT && (!MEM_P (operands[1])) && BYTES_BIG_ENDIAN"
5516 [(set (match_dup 2) (match_dup 1))
5517 (set (match_dup 0) (and:SI (match_dup 2) (const_int 255)))]
5523 [(set (match_operand:SI 0 "s_register_operand" "")
5524 (ior_xor:SI (and:SI (ashift:SI
5525 (match_operand:SI 1 "s_register_operand" "")
5526 (match_operand:SI 2 "const_int_operand" ""))
5527 (match_operand:SI 3 "const_int_operand" ""))
5529 (match_operator 5 "subreg_lowpart_operator"
5530 [(match_operand:SI 4 "s_register_operand" "")]))))]
5532 && ((unsigned HOST_WIDE_INT) INTVAL (operands[3])
5533 == (GET_MODE_MASK (GET_MODE (operands[5]))
5534 & (GET_MODE_MASK (GET_MODE (operands[5]))
5535 << (INTVAL (operands[2])))))"
5536 [(set (match_dup 0) (ior_xor:SI (ashift:SI (match_dup 1) (match_dup 2))
5538 (set (match_dup 0) (zero_extend:SI (match_dup 5)))]
5539 "operands[5] = gen_lowpart (GET_MODE (operands[5]), operands[0]);"
5542 (define_insn "*compareqi_eq0"
5543 [(set (reg:CC_Z CC_REGNUM)
5544 (compare:CC_Z (match_operand:QI 0 "s_register_operand" "r")
5548 [(set_attr "conds" "set")
5549 (set_attr "predicable" "yes")
5550 (set_attr "predicable_short_it" "no")
5551 (set_attr "type" "logic_imm")]
5554 (define_expand "extendhisi2"
5555 [(set (match_operand:SI 0 "s_register_operand" "")
5556 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
5561 emit_insn (gen_thumb1_extendhisi2 (operands[0], operands[1]));
5564 if (MEM_P (operands[1]) && TARGET_ARM && !arm_arch4)
5566 emit_insn (gen_extendhisi2_mem (operands[0], operands[1]));
5570 if (!arm_arch6 && !MEM_P (operands[1]))
5572 rtx t = gen_lowpart (SImode, operands[1]);
5573 rtx tmp = gen_reg_rtx (SImode);
5574 emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (16)));
5575 emit_insn (gen_ashrsi3 (operands[0], tmp, GEN_INT (16)));
5582 [(set (match_operand:SI 0 "register_operand" "")
5583 (sign_extend:SI (match_operand:HI 1 "register_operand" "")))
5584 (clobber (match_scratch:SI 2 ""))])]
5586 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
5587 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 16)))]
5589 operands[2] = simplify_gen_subreg (SImode, operands[1], HImode, 0);
5592 ;; We used to have an early-clobber on the scratch register here.
5593 ;; However, there's a bug somewhere in reload which means that this
5594 ;; can be partially ignored during spill allocation if the memory
5595 ;; address also needs reloading; this causes us to die later on when
5596 ;; we try to verify the operands. Fortunately, we don't really need
5597 ;; the early-clobber: we can always use operand 0 if operand 2
5598 ;; overlaps the address.
5599 (define_insn "thumb1_extendhisi2"
5600 [(set (match_operand:SI 0 "register_operand" "=l,l")
5601 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "l,m")))
5602 (clobber (match_scratch:SI 2 "=X,l"))]
5609 if (which_alternative == 0 && !arm_arch6)
5611 if (which_alternative == 0)
5612 return \"sxth\\t%0, %1\";
5614 mem = XEXP (operands[1], 0);
5616 /* This code used to try to use 'V', and fix the address only if it was
5617 offsettable, but this fails for e.g. REG+48 because 48 is outside the
5618 range of QImode offsets, and offsettable_address_p does a QImode
5621 if (GET_CODE (mem) == CONST)
5622 mem = XEXP (mem, 0);
5624 if (GET_CODE (mem) == LABEL_REF)
5625 return \"ldr\\t%0, %1\";
5627 if (GET_CODE (mem) == PLUS)
5629 rtx a = XEXP (mem, 0);
5630 rtx b = XEXP (mem, 1);
5632 if (GET_CODE (a) == LABEL_REF
5634 return \"ldr\\t%0, %1\";
5637 return \"ldrsh\\t%0, %1\";
5645 ops[2] = const0_rtx;
5648 gcc_assert (REG_P (ops[1]));
5650 ops[0] = operands[0];
5651 if (reg_mentioned_p (operands[2], ops[1]))
5654 ops[3] = operands[2];
5655 output_asm_insn (\"mov\\t%3, %2\;ldrsh\\t%0, [%1, %3]\", ops);
5658 [(set_attr_alternative "length"
5659 [(if_then_else (eq_attr "is_arch6" "yes")
5660 (const_int 2) (const_int 4))
5662 (set_attr "type" "extend,load_byte")
5663 (set_attr "pool_range" "*,1018")]
5666 ;; This pattern will only be used when ldsh is not available
5667 (define_expand "extendhisi2_mem"
5668 [(set (match_dup 2) (zero_extend:SI (match_operand:HI 1 "" "")))
5670 (zero_extend:SI (match_dup 7)))
5671 (set (match_dup 6) (ashift:SI (match_dup 4) (const_int 24)))
5672 (set (match_operand:SI 0 "" "")
5673 (ior:SI (ashiftrt:SI (match_dup 6) (const_int 16)) (match_dup 5)))]
5678 rtx addr = copy_to_mode_reg (SImode, XEXP (operands[1], 0));
5680 mem1 = change_address (operands[1], QImode, addr);
5681 mem2 = change_address (operands[1], QImode,
5682 plus_constant (Pmode, addr, 1));
5683 operands[0] = gen_lowpart (SImode, operands[0]);
5685 operands[2] = gen_reg_rtx (SImode);
5686 operands[3] = gen_reg_rtx (SImode);
5687 operands[6] = gen_reg_rtx (SImode);
5690 if (BYTES_BIG_ENDIAN)
5692 operands[4] = operands[2];
5693 operands[5] = operands[3];
5697 operands[4] = operands[3];
5698 operands[5] = operands[2];
5704 [(set (match_operand:SI 0 "register_operand" "")
5705 (sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
5707 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
5708 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 16)))]
5710 operands[2] = simplify_gen_subreg (SImode, operands[1], HImode, 0);
5713 (define_insn "*arm_extendhisi2"
5714 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5715 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
5716 "TARGET_ARM && arm_arch4 && !arm_arch6"
5720 [(set_attr "length" "8,4")
5721 (set_attr "type" "alu_shift_reg,load_byte")
5722 (set_attr "predicable" "yes")
5723 (set_attr "pool_range" "*,256")
5724 (set_attr "neg_pool_range" "*,244")]
5727 ;; ??? Check Thumb-2 pool range
5728 (define_insn "*arm_extendhisi2_v6"
5729 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5730 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
5731 "TARGET_32BIT && arm_arch6"
5735 [(set_attr "type" "extend,load_byte")
5736 (set_attr "predicable" "yes")
5737 (set_attr "predicable_short_it" "no")
5738 (set_attr "pool_range" "*,256")
5739 (set_attr "neg_pool_range" "*,244")]
5742 (define_insn "*arm_extendhisi2addsi"
5743 [(set (match_operand:SI 0 "s_register_operand" "=r")
5744 (plus:SI (sign_extend:SI (match_operand:HI 1 "s_register_operand" "r"))
5745 (match_operand:SI 2 "s_register_operand" "r")))]
5747 "sxtah%?\\t%0, %2, %1"
5748 [(set_attr "type" "alu_shift_reg")]
5751 (define_expand "extendqihi2"
5753 (ashift:SI (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "")
5755 (set (match_operand:HI 0 "s_register_operand" "")
5756 (ashiftrt:SI (match_dup 2)
5761 if (arm_arch4 && MEM_P (operands[1]))
5763 emit_insn (gen_rtx_SET (VOIDmode,
5765 gen_rtx_SIGN_EXTEND (HImode, operands[1])));
5768 if (!s_register_operand (operands[1], QImode))
5769 operands[1] = copy_to_mode_reg (QImode, operands[1]);
5770 operands[0] = gen_lowpart (SImode, operands[0]);
5771 operands[1] = gen_lowpart (SImode, operands[1]);
5772 operands[2] = gen_reg_rtx (SImode);
5776 (define_insn "*arm_extendqihi_insn"
5777 [(set (match_operand:HI 0 "s_register_operand" "=r")
5778 (sign_extend:HI (match_operand:QI 1 "arm_extendqisi_mem_op" "Uq")))]
5779 "TARGET_ARM && arm_arch4"
5780 "ldr%(sb%)\\t%0, %1"
5781 [(set_attr "type" "load_byte")
5782 (set_attr "predicable" "yes")
5783 (set_attr "pool_range" "256")
5784 (set_attr "neg_pool_range" "244")]
5787 (define_expand "extendqisi2"
5788 [(set (match_operand:SI 0 "s_register_operand" "")
5789 (sign_extend:SI (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "")))]
5792 if (!arm_arch4 && MEM_P (operands[1]))
5793 operands[1] = copy_to_mode_reg (QImode, operands[1]);
5795 if (!arm_arch6 && !MEM_P (operands[1]))
5797 rtx t = gen_lowpart (SImode, operands[1]);
5798 rtx tmp = gen_reg_rtx (SImode);
5799 emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (24)));
5800 emit_insn (gen_ashrsi3 (operands[0], tmp, GEN_INT (24)));
5806 [(set (match_operand:SI 0 "register_operand" "")
5807 (sign_extend:SI (match_operand:QI 1 "register_operand" "")))]
5809 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 24)))
5810 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 24)))]
5812 operands[2] = simplify_gen_subreg (SImode, operands[1], QImode, 0);
5815 (define_insn "*arm_extendqisi"
5816 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5817 (sign_extend:SI (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "r,Uq")))]
5818 "TARGET_ARM && arm_arch4 && !arm_arch6"
5822 [(set_attr "length" "8,4")
5823 (set_attr "type" "alu_shift_reg,load_byte")
5824 (set_attr "predicable" "yes")
5825 (set_attr "pool_range" "*,256")
5826 (set_attr "neg_pool_range" "*,244")]
5829 (define_insn "*arm_extendqisi_v6"
5830 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5832 (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "r,Uq")))]
5833 "TARGET_ARM && arm_arch6"
5837 [(set_attr "type" "extend,load_byte")
5838 (set_attr "predicable" "yes")
5839 (set_attr "pool_range" "*,256")
5840 (set_attr "neg_pool_range" "*,244")]
5843 (define_insn "*arm_extendqisi2addsi"
5844 [(set (match_operand:SI 0 "s_register_operand" "=r")
5845 (plus:SI (sign_extend:SI (match_operand:QI 1 "s_register_operand" "r"))
5846 (match_operand:SI 2 "s_register_operand" "r")))]
5848 "sxtab%?\\t%0, %2, %1"
5849 [(set_attr "type" "alu_shift_reg")
5850 (set_attr "predicable" "yes")
5851 (set_attr "predicable_short_it" "no")]
5855 [(set (match_operand:SI 0 "register_operand" "")
5856 (sign_extend:SI (match_operand:QI 1 "memory_operand" "")))]
5857 "TARGET_THUMB1 && reload_completed"
5858 [(set (match_dup 0) (match_dup 2))
5859 (set (match_dup 0) (sign_extend:SI (match_dup 3)))]
5861 rtx addr = XEXP (operands[1], 0);
5863 if (GET_CODE (addr) == CONST)
5864 addr = XEXP (addr, 0);
5866 if (GET_CODE (addr) == PLUS
5867 && REG_P (XEXP (addr, 0)) && REG_P (XEXP (addr, 1)))
5868 /* No split necessary. */
5871 if (GET_CODE (addr) == PLUS
5872 && !REG_P (XEXP (addr, 0)) && !REG_P (XEXP (addr, 1)))
5875 if (reg_overlap_mentioned_p (operands[0], addr))
5877 rtx t = gen_lowpart (QImode, operands[0]);
5878 emit_move_insn (t, operands[1]);
5879 emit_insn (gen_thumb1_extendqisi2 (operands[0], t));
5885 addr = gen_rtx_PLUS (Pmode, addr, operands[0]);
5886 operands[2] = const0_rtx;
5888 else if (GET_CODE (addr) != PLUS)
5890 else if (REG_P (XEXP (addr, 0)))
5892 operands[2] = XEXP (addr, 1);
5893 addr = gen_rtx_PLUS (Pmode, XEXP (addr, 0), operands[0]);
5897 operands[2] = XEXP (addr, 0);
5898 addr = gen_rtx_PLUS (Pmode, XEXP (addr, 1), operands[0]);
5901 operands[3] = change_address (operands[1], QImode, addr);
5905 [(set (match_operand:SI 0 "register_operand" "")
5906 (plus:SI (match_dup 0) (match_operand 1 "const_int_operand")))
5907 (set (match_operand:SI 2 "register_operand" "") (const_int 0))
5908 (set (match_operand:SI 3 "register_operand" "")
5909 (sign_extend:SI (match_operand:QI 4 "memory_operand" "")))]
5911 && GET_CODE (XEXP (operands[4], 0)) == PLUS
5912 && rtx_equal_p (operands[0], XEXP (XEXP (operands[4], 0), 0))
5913 && rtx_equal_p (operands[2], XEXP (XEXP (operands[4], 0), 1))
5914 && (peep2_reg_dead_p (3, operands[0])
5915 || rtx_equal_p (operands[0], operands[3]))
5916 && (peep2_reg_dead_p (3, operands[2])
5917 || rtx_equal_p (operands[2], operands[3]))"
5918 [(set (match_dup 2) (match_dup 1))
5919 (set (match_dup 3) (sign_extend:SI (match_dup 4)))]
5921 rtx addr = gen_rtx_PLUS (Pmode, operands[0], operands[2]);
5922 operands[4] = change_address (operands[4], QImode, addr);
5925 (define_insn "thumb1_extendqisi2"
5926 [(set (match_operand:SI 0 "register_operand" "=l,l,l")
5927 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "l,V,m")))]
5932 if (which_alternative == 0 && arm_arch6)
5933 return "sxtb\\t%0, %1";
5934 if (which_alternative == 0)
5937 addr = XEXP (operands[1], 0);
5938 if (GET_CODE (addr) == PLUS
5939 && REG_P (XEXP (addr, 0)) && REG_P (XEXP (addr, 1)))
5940 return "ldrsb\\t%0, %1";
5944 [(set_attr_alternative "length"
5945 [(if_then_else (eq_attr "is_arch6" "yes")
5946 (const_int 2) (const_int 4))
5948 (if_then_else (eq_attr "is_arch6" "yes")
5949 (const_int 4) (const_int 6))])
5950 (set_attr "type" "extend,load_byte,load_byte")]
5953 (define_expand "extendsfdf2"
5954 [(set (match_operand:DF 0 "s_register_operand" "")
5955 (float_extend:DF (match_operand:SF 1 "s_register_operand" "")))]
5956 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
5960 /* HFmode -> DFmode conversions have to go through SFmode. */
5961 (define_expand "extendhfdf2"
5962 [(set (match_operand:DF 0 "general_operand" "")
5963 (float_extend:DF (match_operand:HF 1 "general_operand" "")))]
5968 op1 = convert_to_mode (SFmode, operands[1], 0);
5969 op1 = convert_to_mode (DFmode, op1, 0);
5970 emit_insn (gen_movdf (operands[0], op1));
5975 ;; Move insns (including loads and stores)
5977 ;; XXX Just some ideas about movti.
5978 ;; I don't think these are a good idea on the arm, there just aren't enough
5980 ;;(define_expand "loadti"
5981 ;; [(set (match_operand:TI 0 "s_register_operand" "")
5982 ;; (mem:TI (match_operand:SI 1 "address_operand" "")))]
5985 ;;(define_expand "storeti"
5986 ;; [(set (mem:TI (match_operand:TI 0 "address_operand" ""))
5987 ;; (match_operand:TI 1 "s_register_operand" ""))]
5990 ;;(define_expand "movti"
5991 ;; [(set (match_operand:TI 0 "general_operand" "")
5992 ;; (match_operand:TI 1 "general_operand" ""))]
5998 ;; if (MEM_P (operands[0]) && MEM_P (operands[1]))
5999 ;; operands[1] = copy_to_reg (operands[1]);
6000 ;; if (MEM_P (operands[0]))
6001 ;; insn = gen_storeti (XEXP (operands[0], 0), operands[1]);
6002 ;; else if (MEM_P (operands[1]))
6003 ;; insn = gen_loadti (operands[0], XEXP (operands[1], 0));
6007 ;; emit_insn (insn);
6011 ;; Recognize garbage generated above.
6014 ;; [(set (match_operand:TI 0 "general_operand" "=r,r,r,<,>,m")
6015 ;; (match_operand:TI 1 "general_operand" "<,>,m,r,r,r"))]
6019 ;; register mem = (which_alternative < 3);
6020 ;; register const char *template;
6022 ;; operands[mem] = XEXP (operands[mem], 0);
6023 ;; switch (which_alternative)
6025 ;; case 0: template = \"ldmdb\\t%1!, %M0\"; break;
6026 ;; case 1: template = \"ldmia\\t%1!, %M0\"; break;
6027 ;; case 2: template = \"ldmia\\t%1, %M0\"; break;
6028 ;; case 3: template = \"stmdb\\t%0!, %M1\"; break;
6029 ;; case 4: template = \"stmia\\t%0!, %M1\"; break;
6030 ;; case 5: template = \"stmia\\t%0, %M1\"; break;
6032 ;; output_asm_insn (template, operands);
6036 (define_expand "movdi"
6037 [(set (match_operand:DI 0 "general_operand" "")
6038 (match_operand:DI 1 "general_operand" ""))]
6041 if (can_create_pseudo_p ())
6043 if (!REG_P (operands[0]))
6044 operands[1] = force_reg (DImode, operands[1]);
6049 (define_insn "*arm_movdi"
6050 [(set (match_operand:DI 0 "nonimmediate_di_operand" "=r, r, r, q, m")
6051 (match_operand:DI 1 "di_operand" "rDa,Db,Dc,mi,q"))]
6053 && !(TARGET_HARD_FLOAT && TARGET_VFP)
6055 && ( register_operand (operands[0], DImode)
6056 || register_operand (operands[1], DImode))"
6058 switch (which_alternative)
6065 return output_move_double (operands, true, NULL);
6068 [(set_attr "length" "8,12,16,8,8")
6069 (set_attr "type" "multiple,multiple,multiple,load2,store2")
6070 (set_attr "arm_pool_range" "*,*,*,1020,*")
6071 (set_attr "arm_neg_pool_range" "*,*,*,1004,*")
6072 (set_attr "thumb2_pool_range" "*,*,*,4094,*")
6073 (set_attr "thumb2_neg_pool_range" "*,*,*,0,*")]
6077 [(set (match_operand:ANY64 0 "arm_general_register_operand" "")
6078 (match_operand:ANY64 1 "const_double_operand" ""))]
6081 && (arm_const_double_inline_cost (operands[1])
6082 <= arm_max_const_double_inline_cost ())"
6085 arm_split_constant (SET, SImode, curr_insn,
6086 INTVAL (gen_lowpart (SImode, operands[1])),
6087 gen_lowpart (SImode, operands[0]), NULL_RTX, 0);
6088 arm_split_constant (SET, SImode, curr_insn,
6089 INTVAL (gen_highpart_mode (SImode,
6090 GET_MODE (operands[0]),
6092 gen_highpart (SImode, operands[0]), NULL_RTX, 0);
6097 ; If optimizing for size, or if we have load delay slots, then
6098 ; we want to split the constant into two separate operations.
6099 ; In both cases this may split a trivial part into a single data op
6100 ; leaving a single complex constant to load. We can also get longer
6101 ; offsets in a LDR which means we get better chances of sharing the pool
6102 ; entries. Finally, we can normally do a better job of scheduling
6103 ; LDR instructions than we can with LDM.
6104 ; This pattern will only match if the one above did not.
6106 [(set (match_operand:ANY64 0 "arm_general_register_operand" "")
6107 (match_operand:ANY64 1 "const_double_operand" ""))]
6108 "TARGET_ARM && reload_completed
6109 && arm_const_double_by_parts (operands[1])"
6110 [(set (match_dup 0) (match_dup 1))
6111 (set (match_dup 2) (match_dup 3))]
6113 operands[2] = gen_highpart (SImode, operands[0]);
6114 operands[3] = gen_highpart_mode (SImode, GET_MODE (operands[0]),
6116 operands[0] = gen_lowpart (SImode, operands[0]);
6117 operands[1] = gen_lowpart (SImode, operands[1]);
6122 [(set (match_operand:ANY64 0 "arm_general_register_operand" "")
6123 (match_operand:ANY64 1 "arm_general_register_operand" ""))]
6124 "TARGET_EITHER && reload_completed"
6125 [(set (match_dup 0) (match_dup 1))
6126 (set (match_dup 2) (match_dup 3))]
6128 operands[2] = gen_highpart (SImode, operands[0]);
6129 operands[3] = gen_highpart (SImode, operands[1]);
6130 operands[0] = gen_lowpart (SImode, operands[0]);
6131 operands[1] = gen_lowpart (SImode, operands[1]);
6133 /* Handle a partial overlap. */
6134 if (rtx_equal_p (operands[0], operands[3]))
6136 rtx tmp0 = operands[0];
6137 rtx tmp1 = operands[1];
6139 operands[0] = operands[2];
6140 operands[1] = operands[3];
6147 ;; We can't actually do base+index doubleword loads if the index and
6148 ;; destination overlap. Split here so that we at least have chance to
6151 [(set (match_operand:DI 0 "s_register_operand" "")
6152 (mem:DI (plus:SI (match_operand:SI 1 "s_register_operand" "")
6153 (match_operand:SI 2 "s_register_operand" ""))))]
6155 && reg_overlap_mentioned_p (operands[0], operands[1])
6156 && reg_overlap_mentioned_p (operands[0], operands[2])"
6158 (plus:SI (match_dup 1)
6161 (mem:DI (match_dup 4)))]
6163 operands[4] = gen_rtx_REG (SImode, REGNO(operands[0]));
6167 ;;; ??? This should have alternatives for constants.
6168 ;;; ??? This was originally identical to the movdf_insn pattern.
6169 ;;; ??? The 'i' constraint looks funny, but it should always be replaced by
6170 ;;; thumb_reorg with a memory reference.
6171 (define_insn "*thumb1_movdi_insn"
6172 [(set (match_operand:DI 0 "nonimmediate_operand" "=l,l,l,l,>,l, m,*r")
6173 (match_operand:DI 1 "general_operand" "l, I,J,>,l,mi,l,*r"))]
6175 && ( register_operand (operands[0], DImode)
6176 || register_operand (operands[1], DImode))"
6179 switch (which_alternative)
6183 if (REGNO (operands[1]) == REGNO (operands[0]) + 1)
6184 return \"add\\t%0, %1, #0\;add\\t%H0, %H1, #0\";
6185 return \"add\\t%H0, %H1, #0\;add\\t%0, %1, #0\";
6187 return \"mov\\t%Q0, %1\;mov\\t%R0, #0\";
6189 operands[1] = GEN_INT (- INTVAL (operands[1]));
6190 return \"mov\\t%Q0, %1\;neg\\t%Q0, %Q0\;asr\\t%R0, %Q0, #31\";
6192 return \"ldmia\\t%1, {%0, %H0}\";
6194 return \"stmia\\t%0, {%1, %H1}\";
6196 return thumb_load_double_from_address (operands);
6198 operands[2] = gen_rtx_MEM (SImode,
6199 plus_constant (Pmode, XEXP (operands[0], 0), 4));
6200 output_asm_insn (\"str\\t%1, %0\;str\\t%H1, %2\", operands);
6203 if (REGNO (operands[1]) == REGNO (operands[0]) + 1)
6204 return \"mov\\t%0, %1\;mov\\t%H0, %H1\";
6205 return \"mov\\t%H0, %H1\;mov\\t%0, %1\";
6208 [(set_attr "length" "4,4,6,2,2,6,4,4")
6209 (set_attr "type" "multiple,multiple,multiple,load2,store2,load2,store2,multiple")
6210 (set_attr "pool_range" "*,*,*,*,*,1018,*,*")]
6213 (define_expand "movsi"
6214 [(set (match_operand:SI 0 "general_operand" "")
6215 (match_operand:SI 1 "general_operand" ""))]
6219 rtx base, offset, tmp;
6223 /* Everything except mem = const or mem = mem can be done easily. */
6224 if (MEM_P (operands[0]))
6225 operands[1] = force_reg (SImode, operands[1]);
6226 if (arm_general_register_operand (operands[0], SImode)
6227 && CONST_INT_P (operands[1])
6228 && !(const_ok_for_arm (INTVAL (operands[1]))
6229 || const_ok_for_arm (~INTVAL (operands[1]))))
6231 arm_split_constant (SET, SImode, NULL_RTX,
6232 INTVAL (operands[1]), operands[0], NULL_RTX,
6233 optimize && can_create_pseudo_p ());
6237 else /* TARGET_THUMB1... */
6239 if (can_create_pseudo_p ())
6241 if (!REG_P (operands[0]))
6242 operands[1] = force_reg (SImode, operands[1]);
6246 if (ARM_OFFSETS_MUST_BE_WITHIN_SECTIONS_P)
6248 split_const (operands[1], &base, &offset);
6249 if (GET_CODE (base) == SYMBOL_REF
6250 && !offset_within_block_p (base, INTVAL (offset)))
6252 tmp = can_create_pseudo_p () ? gen_reg_rtx (SImode) : operands[0];
6253 emit_move_insn (tmp, base);
6254 emit_insn (gen_addsi3 (operands[0], tmp, offset));
6259 /* Recognize the case where operand[1] is a reference to thread-local
6260 data and load its address to a register. */
6261 if (arm_tls_referenced_p (operands[1]))
6263 rtx tmp = operands[1];
6266 if (GET_CODE (tmp) == CONST && GET_CODE (XEXP (tmp, 0)) == PLUS)
6268 addend = XEXP (XEXP (tmp, 0), 1);
6269 tmp = XEXP (XEXP (tmp, 0), 0);
6272 gcc_assert (GET_CODE (tmp) == SYMBOL_REF);
6273 gcc_assert (SYMBOL_REF_TLS_MODEL (tmp) != 0);
6275 tmp = legitimize_tls_address (tmp,
6276 !can_create_pseudo_p () ? operands[0] : 0);
6279 tmp = gen_rtx_PLUS (SImode, tmp, addend);
6280 tmp = force_operand (tmp, operands[0]);
6285 && (CONSTANT_P (operands[1])
6286 || symbol_mentioned_p (operands[1])
6287 || label_mentioned_p (operands[1])))
6288 operands[1] = legitimize_pic_address (operands[1], SImode,
6289 (!can_create_pseudo_p ()
6296 ;; The ARM LO_SUM and HIGH are backwards - HIGH sets the low bits, and
6297 ;; LO_SUM adds in the high bits. Fortunately these are opaque operations
6298 ;; so this does not matter.
6299 (define_insn "*arm_movt"
6300 [(set (match_operand:SI 0 "nonimmediate_operand" "=r")
6301 (lo_sum:SI (match_operand:SI 1 "nonimmediate_operand" "0")
6302 (match_operand:SI 2 "general_operand" "i")))]
6304 "movt%?\t%0, #:upper16:%c2"
6305 [(set_attr "predicable" "yes")
6306 (set_attr "predicable_short_it" "no")
6307 (set_attr "length" "4")
6308 (set_attr "type" "mov_imm")]
6311 (define_insn "*arm_movsi_insn"
6312 [(set (match_operand:SI 0 "nonimmediate_operand" "=rk,r,r,r,rk,m")
6313 (match_operand:SI 1 "general_operand" "rk, I,K,j,mi,rk"))]
6314 "TARGET_ARM && ! TARGET_IWMMXT
6315 && !(TARGET_HARD_FLOAT && TARGET_VFP)
6316 && ( register_operand (operands[0], SImode)
6317 || register_operand (operands[1], SImode))"
6325 [(set_attr "type" "mov_reg,mov_imm,mvn_imm,mov_imm,load1,store1")
6326 (set_attr "predicable" "yes")
6327 (set_attr "pool_range" "*,*,*,*,4096,*")
6328 (set_attr "neg_pool_range" "*,*,*,*,4084,*")]
6332 [(set (match_operand:SI 0 "arm_general_register_operand" "")
6333 (match_operand:SI 1 "const_int_operand" ""))]
6335 && (!(const_ok_for_arm (INTVAL (operands[1]))
6336 || const_ok_for_arm (~INTVAL (operands[1]))))"
6337 [(clobber (const_int 0))]
6339 arm_split_constant (SET, SImode, NULL_RTX,
6340 INTVAL (operands[1]), operands[0], NULL_RTX, 0);
6345 ;; A normal way to do (symbol + offset) requires three instructions at least
6346 ;; (depends on how big the offset is) as below:
6347 ;; movw r0, #:lower16:g
6348 ;; movw r0, #:upper16:g
6351 ;; A better way would be:
6352 ;; movw r0, #:lower16:g+4
6353 ;; movw r0, #:upper16:g+4
6355 ;; The limitation of this way is that the length of offset should be a 16-bit
6356 ;; signed value, because current assembler only supports REL type relocation for
6357 ;; such case. If the more powerful RELA type is supported in future, we should
6358 ;; update this pattern to go with better way.
6360 [(set (match_operand:SI 0 "arm_general_register_operand" "")
6361 (const:SI (plus:SI (match_operand:SI 1 "general_operand" "")
6362 (match_operand:SI 2 "const_int_operand" ""))))]
6364 && arm_disable_literal_pool
6366 && GET_CODE (operands[1]) == SYMBOL_REF"
6367 [(clobber (const_int 0))]
6369 int offset = INTVAL (operands[2]);
6371 if (offset < -0x8000 || offset > 0x7fff)
6373 arm_emit_movpair (operands[0], operands[1]);
6374 emit_insn (gen_rtx_SET (SImode, operands[0],
6375 gen_rtx_PLUS (SImode, operands[0], operands[2])));
6379 rtx op = gen_rtx_CONST (SImode,
6380 gen_rtx_PLUS (SImode, operands[1], operands[2]));
6381 arm_emit_movpair (operands[0], op);
6386 ;; Split symbol_refs at the later stage (after cprop), instead of generating
6387 ;; movt/movw pair directly at expand. Otherwise corresponding high_sum
6388 ;; and lo_sum would be merged back into memory load at cprop. However,
6389 ;; if the default is to prefer movt/movw rather than a load from the constant
6390 ;; pool, the performance is better.
6392 [(set (match_operand:SI 0 "arm_general_register_operand" "")
6393 (match_operand:SI 1 "general_operand" ""))]
6395 && TARGET_USE_MOVT && GET_CODE (operands[1]) == SYMBOL_REF
6396 && !flag_pic && !target_word_relocations
6397 && !arm_tls_referenced_p (operands[1])"
6398 [(clobber (const_int 0))]
6400 arm_emit_movpair (operands[0], operands[1]);
6404 (define_insn "*thumb1_movsi_insn"
6405 [(set (match_operand:SI 0 "nonimmediate_operand" "=l,l,l,l,l,>,l, m,*l*h*k")
6406 (match_operand:SI 1 "general_operand" "l, I,J,K,>,l,mi,l,*l*h*k"))]
6408 && ( register_operand (operands[0], SImode)
6409 || register_operand (operands[1], SImode))"
6420 [(set_attr "length" "2,2,4,4,2,2,2,2,2")
6421 (set_attr "type" "mov_reg,mov_imm,multiple,multiple,load1,store1,load1,store1,mov_reg")
6422 (set_attr "pool_range" "*,*,*,*,*,*,1018,*,*")
6423 (set_attr "conds" "set,clob,*,*,nocond,nocond,nocond,nocond,nocond")])
6426 [(set (match_operand:SI 0 "register_operand" "")
6427 (match_operand:SI 1 "const_int_operand" ""))]
6428 "TARGET_THUMB1 && satisfies_constraint_J (operands[1])"
6429 [(set (match_dup 2) (match_dup 1))
6430 (set (match_dup 0) (neg:SI (match_dup 2)))]
6433 operands[1] = GEN_INT (- INTVAL (operands[1]));
6434 operands[2] = can_create_pseudo_p () ? gen_reg_rtx (SImode) : operands[0];
6439 [(set (match_operand:SI 0 "register_operand" "")
6440 (match_operand:SI 1 "const_int_operand" ""))]
6441 "TARGET_THUMB1 && satisfies_constraint_K (operands[1])"
6442 [(set (match_dup 2) (match_dup 1))
6443 (set (match_dup 0) (ashift:SI (match_dup 2) (match_dup 3)))]
6446 unsigned HOST_WIDE_INT val = INTVAL (operands[1]) & 0xffffffffu;
6447 unsigned HOST_WIDE_INT mask = 0xff;
6450 for (i = 0; i < 25; i++)
6451 if ((val & (mask << i)) == val)
6454 /* Don't split if the shift is zero. */
6458 operands[1] = GEN_INT (val >> i);
6459 operands[2] = can_create_pseudo_p () ? gen_reg_rtx (SImode) : operands[0];
6460 operands[3] = GEN_INT (i);
6464 ;; For thumb1 split imm move [256-510] into mov [1-255] and add #255
6466 [(set (match_operand:SI 0 "register_operand" "")
6467 (match_operand:SI 1 "const_int_operand" ""))]
6468 "TARGET_THUMB1 && satisfies_constraint_Pe (operands[1])"
6469 [(set (match_dup 2) (match_dup 1))
6470 (set (match_dup 0) (plus:SI (match_dup 2) (match_dup 3)))]
6473 operands[1] = GEN_INT (INTVAL (operands[1]) - 255);
6474 operands[2] = can_create_pseudo_p () ? gen_reg_rtx (SImode) : operands[0];
6475 operands[3] = GEN_INT (255);
6479 ;; When generating pic, we need to load the symbol offset into a register.
6480 ;; So that the optimizer does not confuse this with a normal symbol load
6481 ;; we use an unspec. The offset will be loaded from a constant pool entry,
6482 ;; since that is the only type of relocation we can use.
6484 ;; Wrap calculation of the whole PIC address in a single pattern for the
6485 ;; benefit of optimizers, particularly, PRE and HOIST. Calculation of
6486 ;; a PIC address involves two loads from memory, so we want to CSE it
6487 ;; as often as possible.
6488 ;; This pattern will be split into one of the pic_load_addr_* patterns
6489 ;; and a move after GCSE optimizations.
6491 ;; Note: Update arm.c: legitimize_pic_address() when changing this pattern.
6492 (define_expand "calculate_pic_address"
6493 [(set (match_operand:SI 0 "register_operand" "")
6494 (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "")
6495 (unspec:SI [(match_operand:SI 2 "" "")]
6500 ;; Split calculate_pic_address into pic_load_addr_* and a move.
6502 [(set (match_operand:SI 0 "register_operand" "")
6503 (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "")
6504 (unspec:SI [(match_operand:SI 2 "" "")]
6507 [(set (match_dup 3) (unspec:SI [(match_dup 2)] UNSPEC_PIC_SYM))
6508 (set (match_dup 0) (mem:SI (plus:SI (match_dup 1) (match_dup 3))))]
6509 "operands[3] = can_create_pseudo_p () ? gen_reg_rtx (SImode) : operands[0];"
6512 ;; operand1 is the memory address to go into
6513 ;; pic_load_addr_32bit.
6514 ;; operand2 is the PIC label to be emitted
6515 ;; from pic_add_dot_plus_eight.
6516 ;; We do this to allow hoisting of the entire insn.
6517 (define_insn_and_split "pic_load_addr_unified"
6518 [(set (match_operand:SI 0 "s_register_operand" "=r,r,l")
6519 (unspec:SI [(match_operand:SI 1 "" "mX,mX,mX")
6520 (match_operand:SI 2 "" "")]
6521 UNSPEC_PIC_UNIFIED))]
6524 "&& reload_completed"
6525 [(set (match_dup 0) (unspec:SI [(match_dup 1)] UNSPEC_PIC_SYM))
6526 (set (match_dup 0) (unspec:SI [(match_dup 0) (match_dup 3)
6527 (match_dup 2)] UNSPEC_PIC_BASE))]
6528 "operands[3] = TARGET_THUMB ? GEN_INT (4) : GEN_INT (8);"
6529 [(set_attr "type" "load1,load1,load1")
6530 (set_attr "pool_range" "4096,4094,1022")
6531 (set_attr "neg_pool_range" "4084,0,0")
6532 (set_attr "arch" "a,t2,t1")
6533 (set_attr "length" "8,6,4")]
6536 ;; The rather odd constraints on the following are to force reload to leave
6537 ;; the insn alone, and to force the minipool generation pass to then move
6538 ;; the GOT symbol to memory.
6540 (define_insn "pic_load_addr_32bit"
6541 [(set (match_operand:SI 0 "s_register_operand" "=r")
6542 (unspec:SI [(match_operand:SI 1 "" "mX")] UNSPEC_PIC_SYM))]
6543 "TARGET_32BIT && flag_pic"
6545 [(set_attr "type" "load1")
6546 (set (attr "pool_range")
6547 (if_then_else (eq_attr "is_thumb" "no")
6550 (set (attr "neg_pool_range")
6551 (if_then_else (eq_attr "is_thumb" "no")
6556 (define_insn "pic_load_addr_thumb1"
6557 [(set (match_operand:SI 0 "s_register_operand" "=l")
6558 (unspec:SI [(match_operand:SI 1 "" "mX")] UNSPEC_PIC_SYM))]
6559 "TARGET_THUMB1 && flag_pic"
6561 [(set_attr "type" "load1")
6562 (set (attr "pool_range") (const_int 1018))]
6565 (define_insn "pic_add_dot_plus_four"
6566 [(set (match_operand:SI 0 "register_operand" "=r")
6567 (unspec:SI [(match_operand:SI 1 "register_operand" "0")
6569 (match_operand 2 "" "")]
6573 (*targetm.asm_out.internal_label) (asm_out_file, \"LPIC\",
6574 INTVAL (operands[2]));
6575 return \"add\\t%0, %|pc\";
6577 [(set_attr "length" "2")
6578 (set_attr "type" "alu_reg")]
6581 (define_insn "pic_add_dot_plus_eight"
6582 [(set (match_operand:SI 0 "register_operand" "=r")
6583 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
6585 (match_operand 2 "" "")]
6589 (*targetm.asm_out.internal_label) (asm_out_file, \"LPIC\",
6590 INTVAL (operands[2]));
6591 return \"add%?\\t%0, %|pc, %1\";
6593 [(set_attr "predicable" "yes")
6594 (set_attr "type" "alu_reg")]
6597 (define_insn "tls_load_dot_plus_eight"
6598 [(set (match_operand:SI 0 "register_operand" "=r")
6599 (mem:SI (unspec:SI [(match_operand:SI 1 "register_operand" "r")
6601 (match_operand 2 "" "")]
6605 (*targetm.asm_out.internal_label) (asm_out_file, \"LPIC\",
6606 INTVAL (operands[2]));
6607 return \"ldr%?\\t%0, [%|pc, %1]\t\t@ tls_load_dot_plus_eight\";
6609 [(set_attr "predicable" "yes")
6610 (set_attr "type" "load1")]
6613 ;; PIC references to local variables can generate pic_add_dot_plus_eight
6614 ;; followed by a load. These sequences can be crunched down to
6615 ;; tls_load_dot_plus_eight by a peephole.
6618 [(set (match_operand:SI 0 "register_operand" "")
6619 (unspec:SI [(match_operand:SI 3 "register_operand" "")
6621 (match_operand 1 "" "")]
6623 (set (match_operand:SI 2 "arm_general_register_operand" "")
6624 (mem:SI (match_dup 0)))]
6625 "TARGET_ARM && peep2_reg_dead_p (2, operands[0])"
6627 (mem:SI (unspec:SI [(match_dup 3)
6634 (define_insn "pic_offset_arm"
6635 [(set (match_operand:SI 0 "register_operand" "=r")
6636 (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
6637 (unspec:SI [(match_operand:SI 2 "" "X")]
6638 UNSPEC_PIC_OFFSET))))]
6639 "TARGET_VXWORKS_RTP && TARGET_ARM && flag_pic"
6640 "ldr%?\\t%0, [%1,%2]"
6641 [(set_attr "type" "load1")]
6644 (define_expand "builtin_setjmp_receiver"
6645 [(label_ref (match_operand 0 "" ""))]
6649 /* r3 is clobbered by set/longjmp, so we can use it as a scratch
6651 if (arm_pic_register != INVALID_REGNUM)
6652 arm_load_pic_register (1UL << 3);
6656 ;; If copying one reg to another we can set the condition codes according to
6657 ;; its value. Such a move is common after a return from subroutine and the
6658 ;; result is being tested against zero.
6660 (define_insn "*movsi_compare0"
6661 [(set (reg:CC CC_REGNUM)
6662 (compare:CC (match_operand:SI 1 "s_register_operand" "0,r")
6664 (set (match_operand:SI 0 "s_register_operand" "=r,r")
6670 [(set_attr "conds" "set")
6671 (set_attr "type" "alus_imm,alus_imm")]
6674 ;; Subroutine to store a half word from a register into memory.
6675 ;; Operand 0 is the source register (HImode)
6676 ;; Operand 1 is the destination address in a register (SImode)
6678 ;; In both this routine and the next, we must be careful not to spill
6679 ;; a memory address of reg+large_const into a separate PLUS insn, since this
6680 ;; can generate unrecognizable rtl.
6682 (define_expand "storehi"
6683 [;; store the low byte
6684 (set (match_operand 1 "" "") (match_dup 3))
6685 ;; extract the high byte
6687 (ashiftrt:SI (match_operand 0 "" "") (const_int 8)))
6688 ;; store the high byte
6689 (set (match_dup 4) (match_dup 5))]
6693 rtx op1 = operands[1];
6694 rtx addr = XEXP (op1, 0);
6695 enum rtx_code code = GET_CODE (addr);
6697 if ((code == PLUS && !CONST_INT_P (XEXP (addr, 1)))
6699 op1 = replace_equiv_address (operands[1], force_reg (SImode, addr));
6701 operands[4] = adjust_address (op1, QImode, 1);
6702 operands[1] = adjust_address (operands[1], QImode, 0);
6703 operands[3] = gen_lowpart (QImode, operands[0]);
6704 operands[0] = gen_lowpart (SImode, operands[0]);
6705 operands[2] = gen_reg_rtx (SImode);
6706 operands[5] = gen_lowpart (QImode, operands[2]);
6710 (define_expand "storehi_bigend"
6711 [(set (match_dup 4) (match_dup 3))
6713 (ashiftrt:SI (match_operand 0 "" "") (const_int 8)))
6714 (set (match_operand 1 "" "") (match_dup 5))]
6718 rtx op1 = operands[1];
6719 rtx addr = XEXP (op1, 0);
6720 enum rtx_code code = GET_CODE (addr);
6722 if ((code == PLUS && !CONST_INT_P (XEXP (addr, 1)))
6724 op1 = replace_equiv_address (op1, force_reg (SImode, addr));
6726 operands[4] = adjust_address (op1, QImode, 1);
6727 operands[1] = adjust_address (operands[1], QImode, 0);
6728 operands[3] = gen_lowpart (QImode, operands[0]);
6729 operands[0] = gen_lowpart (SImode, operands[0]);
6730 operands[2] = gen_reg_rtx (SImode);
6731 operands[5] = gen_lowpart (QImode, operands[2]);
6735 ;; Subroutine to store a half word integer constant into memory.
6736 (define_expand "storeinthi"
6737 [(set (match_operand 0 "" "")
6738 (match_operand 1 "" ""))
6739 (set (match_dup 3) (match_dup 2))]
6743 HOST_WIDE_INT value = INTVAL (operands[1]);
6744 rtx addr = XEXP (operands[0], 0);
6745 rtx op0 = operands[0];
6746 enum rtx_code code = GET_CODE (addr);
6748 if ((code == PLUS && !CONST_INT_P (XEXP (addr, 1)))
6750 op0 = replace_equiv_address (op0, force_reg (SImode, addr));
6752 operands[1] = gen_reg_rtx (SImode);
6753 if (BYTES_BIG_ENDIAN)
6755 emit_insn (gen_movsi (operands[1], GEN_INT ((value >> 8) & 255)));
6756 if ((value & 255) == ((value >> 8) & 255))
6757 operands[2] = operands[1];
6760 operands[2] = gen_reg_rtx (SImode);
6761 emit_insn (gen_movsi (operands[2], GEN_INT (value & 255)));
6766 emit_insn (gen_movsi (operands[1], GEN_INT (value & 255)));
6767 if ((value & 255) == ((value >> 8) & 255))
6768 operands[2] = operands[1];
6771 operands[2] = gen_reg_rtx (SImode);
6772 emit_insn (gen_movsi (operands[2], GEN_INT ((value >> 8) & 255)));
6776 operands[3] = adjust_address (op0, QImode, 1);
6777 operands[0] = adjust_address (operands[0], QImode, 0);
6778 operands[2] = gen_lowpart (QImode, operands[2]);
6779 operands[1] = gen_lowpart (QImode, operands[1]);
6783 (define_expand "storehi_single_op"
6784 [(set (match_operand:HI 0 "memory_operand" "")
6785 (match_operand:HI 1 "general_operand" ""))]
6786 "TARGET_32BIT && arm_arch4"
6788 if (!s_register_operand (operands[1], HImode))
6789 operands[1] = copy_to_mode_reg (HImode, operands[1]);
6793 (define_expand "movhi"
6794 [(set (match_operand:HI 0 "general_operand" "")
6795 (match_operand:HI 1 "general_operand" ""))]
6800 if (can_create_pseudo_p ())
6802 if (MEM_P (operands[0]))
6806 emit_insn (gen_storehi_single_op (operands[0], operands[1]));
6809 if (CONST_INT_P (operands[1]))
6810 emit_insn (gen_storeinthi (operands[0], operands[1]));
6813 if (MEM_P (operands[1]))
6814 operands[1] = force_reg (HImode, operands[1]);
6815 if (BYTES_BIG_ENDIAN)
6816 emit_insn (gen_storehi_bigend (operands[1], operands[0]));
6818 emit_insn (gen_storehi (operands[1], operands[0]));
6822 /* Sign extend a constant, and keep it in an SImode reg. */
6823 else if (CONST_INT_P (operands[1]))
6825 rtx reg = gen_reg_rtx (SImode);
6826 HOST_WIDE_INT val = INTVAL (operands[1]) & 0xffff;
6828 /* If the constant is already valid, leave it alone. */
6829 if (!const_ok_for_arm (val))
6831 /* If setting all the top bits will make the constant
6832 loadable in a single instruction, then set them.
6833 Otherwise, sign extend the number. */
6835 if (const_ok_for_arm (~(val | ~0xffff)))
6837 else if (val & 0x8000)
6841 emit_insn (gen_movsi (reg, GEN_INT (val)));
6842 operands[1] = gen_lowpart (HImode, reg);
6844 else if (arm_arch4 && optimize && can_create_pseudo_p ()
6845 && MEM_P (operands[1]))
6847 rtx reg = gen_reg_rtx (SImode);
6849 emit_insn (gen_zero_extendhisi2 (reg, operands[1]));
6850 operands[1] = gen_lowpart (HImode, reg);
6852 else if (!arm_arch4)
6854 if (MEM_P (operands[1]))
6857 rtx offset = const0_rtx;
6858 rtx reg = gen_reg_rtx (SImode);
6860 if ((REG_P (base = XEXP (operands[1], 0))
6861 || (GET_CODE (base) == PLUS
6862 && (CONST_INT_P (offset = XEXP (base, 1)))
6863 && ((INTVAL(offset) & 1) != 1)
6864 && REG_P (base = XEXP (base, 0))))
6865 && REGNO_POINTER_ALIGN (REGNO (base)) >= 32)
6869 new_rtx = widen_memory_access (operands[1], SImode,
6870 ((INTVAL (offset) & ~3)
6871 - INTVAL (offset)));
6872 emit_insn (gen_movsi (reg, new_rtx));
6873 if (((INTVAL (offset) & 2) != 0)
6874 ^ (BYTES_BIG_ENDIAN ? 1 : 0))
6876 rtx reg2 = gen_reg_rtx (SImode);
6878 emit_insn (gen_lshrsi3 (reg2, reg, GEN_INT (16)));
6883 emit_insn (gen_movhi_bytes (reg, operands[1]));
6885 operands[1] = gen_lowpart (HImode, reg);
6889 /* Handle loading a large integer during reload. */
6890 else if (CONST_INT_P (operands[1])
6891 && !const_ok_for_arm (INTVAL (operands[1]))
6892 && !const_ok_for_arm (~INTVAL (operands[1])))
6894 /* Writing a constant to memory needs a scratch, which should
6895 be handled with SECONDARY_RELOADs. */
6896 gcc_assert (REG_P (operands[0]));
6898 operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
6899 emit_insn (gen_movsi (operands[0], operands[1]));
6903 else if (TARGET_THUMB2)
6905 /* Thumb-2 can do everything except mem=mem and mem=const easily. */
6906 if (can_create_pseudo_p ())
6908 if (!REG_P (operands[0]))
6909 operands[1] = force_reg (HImode, operands[1]);
6910 /* Zero extend a constant, and keep it in an SImode reg. */
6911 else if (CONST_INT_P (operands[1]))
6913 rtx reg = gen_reg_rtx (SImode);
6914 HOST_WIDE_INT val = INTVAL (operands[1]) & 0xffff;
6916 emit_insn (gen_movsi (reg, GEN_INT (val)));
6917 operands[1] = gen_lowpart (HImode, reg);
6921 else /* TARGET_THUMB1 */
6923 if (can_create_pseudo_p ())
6925 if (CONST_INT_P (operands[1]))
6927 rtx reg = gen_reg_rtx (SImode);
6929 emit_insn (gen_movsi (reg, operands[1]));
6930 operands[1] = gen_lowpart (HImode, reg);
6933 /* ??? We shouldn't really get invalid addresses here, but this can
6934 happen if we are passed a SP (never OK for HImode/QImode) or
6935 virtual register (also rejected as illegitimate for HImode/QImode)
6936 relative address. */
6937 /* ??? This should perhaps be fixed elsewhere, for instance, in
6938 fixup_stack_1, by checking for other kinds of invalid addresses,
6939 e.g. a bare reference to a virtual register. This may confuse the
6940 alpha though, which must handle this case differently. */
6941 if (MEM_P (operands[0])
6942 && !memory_address_p (GET_MODE (operands[0]),
6943 XEXP (operands[0], 0)))
6945 = replace_equiv_address (operands[0],
6946 copy_to_reg (XEXP (operands[0], 0)));
6948 if (MEM_P (operands[1])
6949 && !memory_address_p (GET_MODE (operands[1]),
6950 XEXP (operands[1], 0)))
6952 = replace_equiv_address (operands[1],
6953 copy_to_reg (XEXP (operands[1], 0)));
6955 if (MEM_P (operands[1]) && optimize > 0)
6957 rtx reg = gen_reg_rtx (SImode);
6959 emit_insn (gen_zero_extendhisi2 (reg, operands[1]));
6960 operands[1] = gen_lowpart (HImode, reg);
6963 if (MEM_P (operands[0]))
6964 operands[1] = force_reg (HImode, operands[1]);
6966 else if (CONST_INT_P (operands[1])
6967 && !satisfies_constraint_I (operands[1]))
6969 /* Handle loading a large integer during reload. */
6971 /* Writing a constant to memory needs a scratch, which should
6972 be handled with SECONDARY_RELOADs. */
6973 gcc_assert (REG_P (operands[0]));
6975 operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
6976 emit_insn (gen_movsi (operands[0], operands[1]));
6983 (define_insn "*thumb1_movhi_insn"
6984 [(set (match_operand:HI 0 "nonimmediate_operand" "=l,l,m,*r,*h,l")
6985 (match_operand:HI 1 "general_operand" "l,m,l,*h,*r,I"))]
6987 && ( register_operand (operands[0], HImode)
6988 || register_operand (operands[1], HImode))"
6990 switch (which_alternative)
6992 case 0: return \"add %0, %1, #0\";
6993 case 2: return \"strh %1, %0\";
6994 case 3: return \"mov %0, %1\";
6995 case 4: return \"mov %0, %1\";
6996 case 5: return \"mov %0, %1\";
6997 default: gcc_unreachable ();
6999 /* The stack pointer can end up being taken as an index register.
7000 Catch this case here and deal with it. */
7001 if (GET_CODE (XEXP (operands[1], 0)) == PLUS
7002 && REG_P (XEXP (XEXP (operands[1], 0), 0))
7003 && REGNO (XEXP (XEXP (operands[1], 0), 0)) == SP_REGNUM)
7006 ops[0] = operands[0];
7007 ops[1] = XEXP (XEXP (operands[1], 0), 0);
7009 output_asm_insn (\"mov %0, %1\", ops);
7011 XEXP (XEXP (operands[1], 0), 0) = operands[0];
7014 return \"ldrh %0, %1\";
7016 [(set_attr "length" "2,4,2,2,2,2")
7017 (set_attr "type" "alus_imm,load1,store1,mov_reg,mov_reg,mov_imm")
7018 (set_attr "conds" "clob,nocond,nocond,nocond,nocond,clob")])
7021 (define_expand "movhi_bytes"
7022 [(set (match_dup 2) (zero_extend:SI (match_operand:HI 1 "" "")))
7024 (zero_extend:SI (match_dup 6)))
7025 (set (match_operand:SI 0 "" "")
7026 (ior:SI (ashift:SI (match_dup 4) (const_int 8)) (match_dup 5)))]
7031 rtx addr = copy_to_mode_reg (SImode, XEXP (operands[1], 0));
7033 mem1 = change_address (operands[1], QImode, addr);
7034 mem2 = change_address (operands[1], QImode,
7035 plus_constant (Pmode, addr, 1));
7036 operands[0] = gen_lowpart (SImode, operands[0]);
7038 operands[2] = gen_reg_rtx (SImode);
7039 operands[3] = gen_reg_rtx (SImode);
7042 if (BYTES_BIG_ENDIAN)
7044 operands[4] = operands[2];
7045 operands[5] = operands[3];
7049 operands[4] = operands[3];
7050 operands[5] = operands[2];
7055 (define_expand "movhi_bigend"
7057 (rotate:SI (subreg:SI (match_operand:HI 1 "memory_operand" "") 0)
7060 (ashiftrt:SI (match_dup 2) (const_int 16)))
7061 (set (match_operand:HI 0 "s_register_operand" "")
7065 operands[2] = gen_reg_rtx (SImode);
7066 operands[3] = gen_reg_rtx (SImode);
7067 operands[4] = gen_lowpart (HImode, operands[3]);
7071 ;; Pattern to recognize insn generated default case above
7072 (define_insn "*movhi_insn_arch4"
7073 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,m,r")
7074 (match_operand:HI 1 "general_operand" "rI,K,r,mi"))]
7077 && (register_operand (operands[0], HImode)
7078 || register_operand (operands[1], HImode))"
7080 mov%?\\t%0, %1\\t%@ movhi
7081 mvn%?\\t%0, #%B1\\t%@ movhi
7082 str%(h%)\\t%1, %0\\t%@ movhi
7083 ldr%(h%)\\t%0, %1\\t%@ movhi"
7084 [(set_attr "predicable" "yes")
7085 (set_attr "pool_range" "*,*,*,256")
7086 (set_attr "neg_pool_range" "*,*,*,244")
7087 (set_attr_alternative "type"
7088 [(if_then_else (match_operand 1 "const_int_operand" "")
7089 (const_string "mov_imm" )
7090 (const_string "mov_reg"))
7091 (const_string "mvn_imm")
7092 (const_string "store1")
7093 (const_string "load1")])]
7096 (define_insn "*movhi_bytes"
7097 [(set (match_operand:HI 0 "s_register_operand" "=r,r,r")
7098 (match_operand:HI 1 "arm_rhs_operand" "I,r,K"))]
7101 mov%?\\t%0, %1\\t%@ movhi
7102 mov%?\\t%0, %1\\t%@ movhi
7103 mvn%?\\t%0, #%B1\\t%@ movhi"
7104 [(set_attr "predicable" "yes")
7105 (set_attr "type" "mov_imm,mov_reg,mvn_imm")]
7108 (define_expand "thumb_movhi_clobber"
7109 [(set (match_operand:HI 0 "memory_operand" "")
7110 (match_operand:HI 1 "register_operand" ""))
7111 (clobber (match_operand:DI 2 "register_operand" ""))]
7114 if (strict_memory_address_p (HImode, XEXP (operands[0], 0))
7115 && REGNO (operands[1]) <= LAST_LO_REGNUM)
7117 emit_insn (gen_movhi (operands[0], operands[1]));
7120 /* XXX Fixme, need to handle other cases here as well. */
7125 ;; We use a DImode scratch because we may occasionally need an additional
7126 ;; temporary if the address isn't offsettable -- push_reload doesn't seem
7127 ;; to take any notice of the "o" constraints on reload_memory_operand operand.
7128 (define_expand "reload_outhi"
7129 [(parallel [(match_operand:HI 0 "arm_reload_memory_operand" "=o")
7130 (match_operand:HI 1 "s_register_operand" "r")
7131 (match_operand:DI 2 "s_register_operand" "=&l")])]
7134 arm_reload_out_hi (operands);
7136 thumb_reload_out_hi (operands);
7141 (define_expand "reload_inhi"
7142 [(parallel [(match_operand:HI 0 "s_register_operand" "=r")
7143 (match_operand:HI 1 "arm_reload_memory_operand" "o")
7144 (match_operand:DI 2 "s_register_operand" "=&r")])]
7148 arm_reload_in_hi (operands);
7150 thumb_reload_out_hi (operands);
7154 (define_expand "movqi"
7155 [(set (match_operand:QI 0 "general_operand" "")
7156 (match_operand:QI 1 "general_operand" ""))]
7159 /* Everything except mem = const or mem = mem can be done easily */
7161 if (can_create_pseudo_p ())
7163 if (CONST_INT_P (operands[1]))
7165 rtx reg = gen_reg_rtx (SImode);
7167 /* For thumb we want an unsigned immediate, then we are more likely
7168 to be able to use a movs insn. */
7170 operands[1] = GEN_INT (INTVAL (operands[1]) & 255);
7172 emit_insn (gen_movsi (reg, operands[1]));
7173 operands[1] = gen_lowpart (QImode, reg);
7178 /* ??? We shouldn't really get invalid addresses here, but this can
7179 happen if we are passed a SP (never OK for HImode/QImode) or
7180 virtual register (also rejected as illegitimate for HImode/QImode)
7181 relative address. */
7182 /* ??? This should perhaps be fixed elsewhere, for instance, in
7183 fixup_stack_1, by checking for other kinds of invalid addresses,
7184 e.g. a bare reference to a virtual register. This may confuse the
7185 alpha though, which must handle this case differently. */
7186 if (MEM_P (operands[0])
7187 && !memory_address_p (GET_MODE (operands[0]),
7188 XEXP (operands[0], 0)))
7190 = replace_equiv_address (operands[0],
7191 copy_to_reg (XEXP (operands[0], 0)));
7192 if (MEM_P (operands[1])
7193 && !memory_address_p (GET_MODE (operands[1]),
7194 XEXP (operands[1], 0)))
7196 = replace_equiv_address (operands[1],
7197 copy_to_reg (XEXP (operands[1], 0)));
7200 if (MEM_P (operands[1]) && optimize > 0)
7202 rtx reg = gen_reg_rtx (SImode);
7204 emit_insn (gen_zero_extendqisi2 (reg, operands[1]));
7205 operands[1] = gen_lowpart (QImode, reg);
7208 if (MEM_P (operands[0]))
7209 operands[1] = force_reg (QImode, operands[1]);
7211 else if (TARGET_THUMB
7212 && CONST_INT_P (operands[1])
7213 && !satisfies_constraint_I (operands[1]))
7215 /* Handle loading a large integer during reload. */
7217 /* Writing a constant to memory needs a scratch, which should
7218 be handled with SECONDARY_RELOADs. */
7219 gcc_assert (REG_P (operands[0]));
7221 operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
7222 emit_insn (gen_movsi (operands[0], operands[1]));
7228 (define_insn "*arm_movqi_insn"
7229 [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,r,l,r,l,Uu,r,m")
7230 (match_operand:QI 1 "general_operand" "r,r,I,Py,K,Uu,l,m,r"))]
7232 && ( register_operand (operands[0], QImode)
7233 || register_operand (operands[1], QImode))"
7244 [(set_attr "type" "mov_reg,mov_reg,mov_imm,mov_imm,mvn_imm,load1,store1,load1,store1")
7245 (set_attr "predicable" "yes")
7246 (set_attr "predicable_short_it" "yes,yes,yes,no,no,no,no,no,no")
7247 (set_attr "arch" "t2,any,any,t2,any,t2,t2,any,any")
7248 (set_attr "length" "2,4,4,2,4,2,2,4,4")]
7251 (define_insn "*thumb1_movqi_insn"
7252 [(set (match_operand:QI 0 "nonimmediate_operand" "=l,l,m,*r,*h,l")
7253 (match_operand:QI 1 "general_operand" "l, m,l,*h,*r,I"))]
7255 && ( register_operand (operands[0], QImode)
7256 || register_operand (operands[1], QImode))"
7264 [(set_attr "length" "2")
7265 (set_attr "type" "alu_imm,load1,store1,mov_reg,mov_imm,mov_imm")
7266 (set_attr "pool_range" "*,32,*,*,*,*")
7267 (set_attr "conds" "clob,nocond,nocond,nocond,nocond,clob")])
7270 (define_expand "movhf"
7271 [(set (match_operand:HF 0 "general_operand" "")
7272 (match_operand:HF 1 "general_operand" ""))]
7277 if (MEM_P (operands[0]))
7278 operands[1] = force_reg (HFmode, operands[1]);
7280 else /* TARGET_THUMB1 */
7282 if (can_create_pseudo_p ())
7284 if (!REG_P (operands[0]))
7285 operands[1] = force_reg (HFmode, operands[1]);
7291 (define_insn "*arm32_movhf"
7292 [(set (match_operand:HF 0 "nonimmediate_operand" "=r,m,r,r")
7293 (match_operand:HF 1 "general_operand" " m,r,r,F"))]
7294 "TARGET_32BIT && !(TARGET_HARD_FLOAT && TARGET_FP16) && !arm_restrict_it
7295 && ( s_register_operand (operands[0], HFmode)
7296 || s_register_operand (operands[1], HFmode))"
7298 switch (which_alternative)
7300 case 0: /* ARM register from memory */
7301 return \"ldr%(h%)\\t%0, %1\\t%@ __fp16\";
7302 case 1: /* memory from ARM register */
7303 return \"str%(h%)\\t%1, %0\\t%@ __fp16\";
7304 case 2: /* ARM register from ARM register */
7305 return \"mov%?\\t%0, %1\\t%@ __fp16\";
7306 case 3: /* ARM register from constant */
7312 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
7313 bits = real_to_target (NULL, &r, HFmode);
7314 ops[0] = operands[0];
7315 ops[1] = GEN_INT (bits);
7316 ops[2] = GEN_INT (bits & 0xff00);
7317 ops[3] = GEN_INT (bits & 0x00ff);
7319 if (arm_arch_thumb2)
7320 output_asm_insn (\"movw%?\\t%0, %1\", ops);
7322 output_asm_insn (\"mov%?\\t%0, %2\;orr%?\\t%0, %0, %3\", ops);
7329 [(set_attr "conds" "unconditional")
7330 (set_attr "type" "load1,store1,mov_reg,multiple")
7331 (set_attr "length" "4,4,4,8")
7332 (set_attr "predicable" "yes")]
7335 (define_insn "*thumb1_movhf"
7336 [(set (match_operand:HF 0 "nonimmediate_operand" "=l,l,m,*r,*h")
7337 (match_operand:HF 1 "general_operand" "l,mF,l,*h,*r"))]
7339 && ( s_register_operand (operands[0], HFmode)
7340 || s_register_operand (operands[1], HFmode))"
7342 switch (which_alternative)
7347 gcc_assert (MEM_P (operands[1]));
7348 addr = XEXP (operands[1], 0);
7349 if (GET_CODE (addr) == LABEL_REF
7350 || (GET_CODE (addr) == CONST
7351 && GET_CODE (XEXP (addr, 0)) == PLUS
7352 && GET_CODE (XEXP (XEXP (addr, 0), 0)) == LABEL_REF
7353 && CONST_INT_P (XEXP (XEXP (addr, 0), 1))))
7355 /* Constant pool entry. */
7356 return \"ldr\\t%0, %1\";
7358 return \"ldrh\\t%0, %1\";
7360 case 2: return \"strh\\t%1, %0\";
7361 default: return \"mov\\t%0, %1\";
7364 [(set_attr "length" "2")
7365 (set_attr "type" "mov_reg,load1,store1,mov_reg,mov_reg")
7366 (set_attr "pool_range" "*,1018,*,*,*")
7367 (set_attr "conds" "clob,nocond,nocond,nocond,nocond")])
7369 (define_expand "movsf"
7370 [(set (match_operand:SF 0 "general_operand" "")
7371 (match_operand:SF 1 "general_operand" ""))]
7376 if (MEM_P (operands[0]))
7377 operands[1] = force_reg (SFmode, operands[1]);
7379 else /* TARGET_THUMB1 */
7381 if (can_create_pseudo_p ())
7383 if (!REG_P (operands[0]))
7384 operands[1] = force_reg (SFmode, operands[1]);
7390 ;; Transform a floating-point move of a constant into a core register into
7391 ;; an SImode operation.
7393 [(set (match_operand:SF 0 "arm_general_register_operand" "")
7394 (match_operand:SF 1 "immediate_operand" ""))]
7397 && CONST_DOUBLE_P (operands[1])"
7398 [(set (match_dup 2) (match_dup 3))]
7400 operands[2] = gen_lowpart (SImode, operands[0]);
7401 operands[3] = gen_lowpart (SImode, operands[1]);
7402 if (operands[2] == 0 || operands[3] == 0)
7407 (define_insn "*arm_movsf_soft_insn"
7408 [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,m")
7409 (match_operand:SF 1 "general_operand" "r,mE,r"))]
7411 && TARGET_SOFT_FLOAT
7412 && (!MEM_P (operands[0])
7413 || register_operand (operands[1], SFmode))"
7416 ldr%?\\t%0, %1\\t%@ float
7417 str%?\\t%1, %0\\t%@ float"
7418 [(set_attr "predicable" "yes")
7419 (set_attr "predicable_short_it" "no")
7420 (set_attr "type" "mov_reg,load1,store1")
7421 (set_attr "arm_pool_range" "*,4096,*")
7422 (set_attr "thumb2_pool_range" "*,4094,*")
7423 (set_attr "arm_neg_pool_range" "*,4084,*")
7424 (set_attr "thumb2_neg_pool_range" "*,0,*")]
7427 ;;; ??? This should have alternatives for constants.
7428 (define_insn "*thumb1_movsf_insn"
7429 [(set (match_operand:SF 0 "nonimmediate_operand" "=l,l,>,l, m,*r,*h")
7430 (match_operand:SF 1 "general_operand" "l, >,l,mF,l,*h,*r"))]
7432 && ( register_operand (operands[0], SFmode)
7433 || register_operand (operands[1], SFmode))"
7442 [(set_attr "length" "2")
7443 (set_attr "type" "alus_imm,load1,store1,load1,store1,mov_reg,mov_reg")
7444 (set_attr "pool_range" "*,*,*,1018,*,*,*")
7445 (set_attr "conds" "clob,nocond,nocond,nocond,nocond,nocond,nocond")]
7448 (define_expand "movdf"
7449 [(set (match_operand:DF 0 "general_operand" "")
7450 (match_operand:DF 1 "general_operand" ""))]
7455 if (MEM_P (operands[0]))
7456 operands[1] = force_reg (DFmode, operands[1]);
7458 else /* TARGET_THUMB */
7460 if (can_create_pseudo_p ())
7462 if (!REG_P (operands[0]))
7463 operands[1] = force_reg (DFmode, operands[1]);
7469 ;; Reloading a df mode value stored in integer regs to memory can require a
7471 (define_expand "reload_outdf"
7472 [(match_operand:DF 0 "arm_reload_memory_operand" "=o")
7473 (match_operand:DF 1 "s_register_operand" "r")
7474 (match_operand:SI 2 "s_register_operand" "=&r")]
7478 enum rtx_code code = GET_CODE (XEXP (operands[0], 0));
7481 operands[2] = XEXP (operands[0], 0);
7482 else if (code == POST_INC || code == PRE_DEC)
7484 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7485 operands[1] = gen_rtx_SUBREG (DImode, operands[1], 0);
7486 emit_insn (gen_movdi (operands[0], operands[1]));
7489 else if (code == PRE_INC)
7491 rtx reg = XEXP (XEXP (operands[0], 0), 0);
7493 emit_insn (gen_addsi3 (reg, reg, GEN_INT (8)));
7496 else if (code == POST_DEC)
7497 operands[2] = XEXP (XEXP (operands[0], 0), 0);
7499 emit_insn (gen_addsi3 (operands[2], XEXP (XEXP (operands[0], 0), 0),
7500 XEXP (XEXP (operands[0], 0), 1)));
7502 emit_insn (gen_rtx_SET (VOIDmode,
7503 replace_equiv_address (operands[0], operands[2]),
7506 if (code == POST_DEC)
7507 emit_insn (gen_addsi3 (operands[2], operands[2], GEN_INT (-8)));
7513 (define_insn "*movdf_soft_insn"
7514 [(set (match_operand:DF 0 "nonimmediate_soft_df_operand" "=r,r,r,q,m")
7515 (match_operand:DF 1 "soft_df_operand" "rDa,Db,Dc,mF,q"))]
7516 "TARGET_32BIT && TARGET_SOFT_FLOAT
7517 && ( register_operand (operands[0], DFmode)
7518 || register_operand (operands[1], DFmode))"
7520 switch (which_alternative)
7527 return output_move_double (operands, true, NULL);
7530 [(set_attr "length" "8,12,16,8,8")
7531 (set_attr "type" "multiple,multiple,multiple,load2,store2")
7532 (set_attr "arm_pool_range" "*,*,*,1020,*")
7533 (set_attr "thumb2_pool_range" "*,*,*,1018,*")
7534 (set_attr "arm_neg_pool_range" "*,*,*,1004,*")
7535 (set_attr "thumb2_neg_pool_range" "*,*,*,0,*")]
7538 ;;; ??? This should have alternatives for constants.
7539 ;;; ??? This was originally identical to the movdi_insn pattern.
7540 ;;; ??? The 'F' constraint looks funny, but it should always be replaced by
7541 ;;; thumb_reorg with a memory reference.
7542 (define_insn "*thumb_movdf_insn"
7543 [(set (match_operand:DF 0 "nonimmediate_operand" "=l,l,>,l, m,*r")
7544 (match_operand:DF 1 "general_operand" "l, >,l,mF,l,*r"))]
7546 && ( register_operand (operands[0], DFmode)
7547 || register_operand (operands[1], DFmode))"
7549 switch (which_alternative)
7553 if (REGNO (operands[1]) == REGNO (operands[0]) + 1)
7554 return \"add\\t%0, %1, #0\;add\\t%H0, %H1, #0\";
7555 return \"add\\t%H0, %H1, #0\;add\\t%0, %1, #0\";
7557 return \"ldmia\\t%1, {%0, %H0}\";
7559 return \"stmia\\t%0, {%1, %H1}\";
7561 return thumb_load_double_from_address (operands);
7563 operands[2] = gen_rtx_MEM (SImode,
7564 plus_constant (Pmode,
7565 XEXP (operands[0], 0), 4));
7566 output_asm_insn (\"str\\t%1, %0\;str\\t%H1, %2\", operands);
7569 if (REGNO (operands[1]) == REGNO (operands[0]) + 1)
7570 return \"mov\\t%0, %1\;mov\\t%H0, %H1\";
7571 return \"mov\\t%H0, %H1\;mov\\t%0, %1\";
7574 [(set_attr "length" "4,2,2,6,4,4")
7575 (set_attr "type" "multiple,load2,store2,load2,store2,multiple")
7576 (set_attr "pool_range" "*,*,*,1018,*,*")]
7580 ;; load- and store-multiple insns
7581 ;; The arm can load/store any set of registers, provided that they are in
7582 ;; ascending order, but these expanders assume a contiguous set.
7584 (define_expand "load_multiple"
7585 [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
7586 (match_operand:SI 1 "" ""))
7587 (use (match_operand:SI 2 "" ""))])]
7590 HOST_WIDE_INT offset = 0;
7592 /* Support only fixed point registers. */
7593 if (!CONST_INT_P (operands[2])
7594 || INTVAL (operands[2]) > 14
7595 || INTVAL (operands[2]) < 2
7596 || !MEM_P (operands[1])
7597 || !REG_P (operands[0])
7598 || REGNO (operands[0]) > (LAST_ARM_REGNUM - 1)
7599 || REGNO (operands[0]) + INTVAL (operands[2]) > LAST_ARM_REGNUM)
7603 = arm_gen_load_multiple (arm_regs_in_sequence + REGNO (operands[0]),
7604 INTVAL (operands[2]),
7605 force_reg (SImode, XEXP (operands[1], 0)),
7606 FALSE, operands[1], &offset);
7609 (define_expand "store_multiple"
7610 [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
7611 (match_operand:SI 1 "" ""))
7612 (use (match_operand:SI 2 "" ""))])]
7615 HOST_WIDE_INT offset = 0;
7617 /* Support only fixed point registers. */
7618 if (!CONST_INT_P (operands[2])
7619 || INTVAL (operands[2]) > 14
7620 || INTVAL (operands[2]) < 2
7621 || !REG_P (operands[1])
7622 || !MEM_P (operands[0])
7623 || REGNO (operands[1]) > (LAST_ARM_REGNUM - 1)
7624 || REGNO (operands[1]) + INTVAL (operands[2]) > LAST_ARM_REGNUM)
7628 = arm_gen_store_multiple (arm_regs_in_sequence + REGNO (operands[1]),
7629 INTVAL (operands[2]),
7630 force_reg (SImode, XEXP (operands[0], 0)),
7631 FALSE, operands[0], &offset);
7635 ;; Move a block of memory if it is word aligned and MORE than 2 words long.
7636 ;; We could let this apply for blocks of less than this, but it clobbers so
7637 ;; many registers that there is then probably a better way.
7639 (define_expand "movmemqi"
7640 [(match_operand:BLK 0 "general_operand" "")
7641 (match_operand:BLK 1 "general_operand" "")
7642 (match_operand:SI 2 "const_int_operand" "")
7643 (match_operand:SI 3 "const_int_operand" "")]
7648 if (TARGET_LDRD && current_tune->prefer_ldrd_strd
7649 && !optimize_function_for_size_p (cfun))
7651 if (gen_movmem_ldrd_strd (operands))
7656 if (arm_gen_movmemqi (operands))
7660 else /* TARGET_THUMB1 */
7662 if ( INTVAL (operands[3]) != 4
7663 || INTVAL (operands[2]) > 48)
7666 thumb_expand_movmemqi (operands);
7672 ;; Thumb block-move insns
7674 (define_insn "movmem12b"
7675 [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
7676 (mem:SI (match_operand:SI 3 "register_operand" "1")))
7677 (set (mem:SI (plus:SI (match_dup 2) (const_int 4)))
7678 (mem:SI (plus:SI (match_dup 3) (const_int 4))))
7679 (set (mem:SI (plus:SI (match_dup 2) (const_int 8)))
7680 (mem:SI (plus:SI (match_dup 3) (const_int 8))))
7681 (set (match_operand:SI 0 "register_operand" "=l")
7682 (plus:SI (match_dup 2) (const_int 12)))
7683 (set (match_operand:SI 1 "register_operand" "=l")
7684 (plus:SI (match_dup 3) (const_int 12)))
7685 (clobber (match_scratch:SI 4 "=&l"))
7686 (clobber (match_scratch:SI 5 "=&l"))
7687 (clobber (match_scratch:SI 6 "=&l"))]
7689 "* return thumb_output_move_mem_multiple (3, operands);"
7690 [(set_attr "length" "4")
7691 ; This isn't entirely accurate... It loads as well, but in terms of
7692 ; scheduling the following insn it is better to consider it as a store
7693 (set_attr "type" "store3")]
7696 (define_insn "movmem8b"
7697 [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
7698 (mem:SI (match_operand:SI 3 "register_operand" "1")))
7699 (set (mem:SI (plus:SI (match_dup 2) (const_int 4)))
7700 (mem:SI (plus:SI (match_dup 3) (const_int 4))))
7701 (set (match_operand:SI 0 "register_operand" "=l")
7702 (plus:SI (match_dup 2) (const_int 8)))
7703 (set (match_operand:SI 1 "register_operand" "=l")
7704 (plus:SI (match_dup 3) (const_int 8)))
7705 (clobber (match_scratch:SI 4 "=&l"))
7706 (clobber (match_scratch:SI 5 "=&l"))]
7708 "* return thumb_output_move_mem_multiple (2, operands);"
7709 [(set_attr "length" "4")
7710 ; This isn't entirely accurate... It loads as well, but in terms of
7711 ; scheduling the following insn it is better to consider it as a store
7712 (set_attr "type" "store2")]
7717 ;; Compare & branch insns
7718 ;; The range calculations are based as follows:
7719 ;; For forward branches, the address calculation returns the address of
7720 ;; the next instruction. This is 2 beyond the branch instruction.
7721 ;; For backward branches, the address calculation returns the address of
7722 ;; the first instruction in this pattern (cmp). This is 2 before the branch
7723 ;; instruction for the shortest sequence, and 4 before the branch instruction
7724 ;; if we have to jump around an unconditional branch.
7725 ;; To the basic branch range the PC offset must be added (this is +4).
7726 ;; So for forward branches we have
7727 ;; (pos_range - pos_base_offs + pc_offs) = (pos_range - 2 + 4).
7728 ;; And for backward branches we have
7729 ;; (neg_range - neg_base_offs + pc_offs) = (neg_range - (-2 or -4) + 4).
7731 ;; For a 'b' pos_range = 2046, neg_range = -2048 giving (-2040->2048).
7732 ;; For a 'b<cond>' pos_range = 254, neg_range = -256 giving (-250 ->256).
7734 (define_expand "cbranchsi4"
7735 [(set (pc) (if_then_else
7736 (match_operator 0 "expandable_comparison_operator"
7737 [(match_operand:SI 1 "s_register_operand" "")
7738 (match_operand:SI 2 "nonmemory_operand" "")])
7739 (label_ref (match_operand 3 "" ""))
7745 if (!arm_validize_comparison (&operands[0], &operands[1], &operands[2]))
7747 emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
7751 if (thumb1_cmpneg_operand (operands[2], SImode))
7753 emit_jump_insn (gen_cbranchsi4_scratch (NULL, operands[1], operands[2],
7754 operands[3], operands[0]));
7757 if (!thumb1_cmp_operand (operands[2], SImode))
7758 operands[2] = force_reg (SImode, operands[2]);
7761 ;; A pattern to recognize a special situation and optimize for it.
7762 ;; On the thumb, zero-extension from memory is preferrable to sign-extension
7763 ;; due to the available addressing modes. Hence, convert a signed comparison
7764 ;; with zero into an unsigned comparison with 127 if possible.
7765 (define_expand "cbranchqi4"
7766 [(set (pc) (if_then_else
7767 (match_operator 0 "lt_ge_comparison_operator"
7768 [(match_operand:QI 1 "memory_operand" "")
7769 (match_operand:QI 2 "const0_operand" "")])
7770 (label_ref (match_operand 3 "" ""))
7775 xops[1] = gen_reg_rtx (SImode);
7776 emit_insn (gen_zero_extendqisi2 (xops[1], operands[1]));
7777 xops[2] = GEN_INT (127);
7778 xops[0] = gen_rtx_fmt_ee (GET_CODE (operands[0]) == GE ? LEU : GTU,
7779 VOIDmode, xops[1], xops[2]);
7780 xops[3] = operands[3];
7781 emit_insn (gen_cbranchsi4 (xops[0], xops[1], xops[2], xops[3]));
7785 (define_expand "cbranchsf4"
7786 [(set (pc) (if_then_else
7787 (match_operator 0 "expandable_comparison_operator"
7788 [(match_operand:SF 1 "s_register_operand" "")
7789 (match_operand:SF 2 "arm_float_compare_operand" "")])
7790 (label_ref (match_operand 3 "" ""))
7792 "TARGET_32BIT && TARGET_HARD_FLOAT"
7793 "emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
7794 operands[3])); DONE;"
7797 (define_expand "cbranchdf4"
7798 [(set (pc) (if_then_else
7799 (match_operator 0 "expandable_comparison_operator"
7800 [(match_operand:DF 1 "s_register_operand" "")
7801 (match_operand:DF 2 "arm_float_compare_operand" "")])
7802 (label_ref (match_operand 3 "" ""))
7804 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
7805 "emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
7806 operands[3])); DONE;"
7809 (define_expand "cbranchdi4"
7810 [(set (pc) (if_then_else
7811 (match_operator 0 "expandable_comparison_operator"
7812 [(match_operand:DI 1 "s_register_operand" "")
7813 (match_operand:DI 2 "cmpdi_operand" "")])
7814 (label_ref (match_operand 3 "" ""))
7818 if (!arm_validize_comparison (&operands[0], &operands[1], &operands[2]))
7820 emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
7826 (define_insn "cbranchsi4_insn"
7827 [(set (pc) (if_then_else
7828 (match_operator 0 "arm_comparison_operator"
7829 [(match_operand:SI 1 "s_register_operand" "l,l*h")
7830 (match_operand:SI 2 "thumb1_cmp_operand" "lI*h,*r")])
7831 (label_ref (match_operand 3 "" ""))
7835 rtx t = cfun->machine->thumb1_cc_insn;
7838 if (!rtx_equal_p (cfun->machine->thumb1_cc_op0, operands[1])
7839 || !rtx_equal_p (cfun->machine->thumb1_cc_op1, operands[2]))
7841 if (cfun->machine->thumb1_cc_mode == CC_NOOVmode)
7843 if (!noov_comparison_operator (operands[0], VOIDmode))
7846 else if (cfun->machine->thumb1_cc_mode != CCmode)
7851 output_asm_insn ("cmp\t%1, %2", operands);
7852 cfun->machine->thumb1_cc_insn = insn;
7853 cfun->machine->thumb1_cc_op0 = operands[1];
7854 cfun->machine->thumb1_cc_op1 = operands[2];
7855 cfun->machine->thumb1_cc_mode = CCmode;
7858 /* Ensure we emit the right type of condition code on the jump. */
7859 XEXP (operands[0], 0) = gen_rtx_REG (cfun->machine->thumb1_cc_mode,
7862 switch (get_attr_length (insn))
7864 case 4: return \"b%d0\\t%l3\";
7865 case 6: return \"b%D0\\t.LCB%=\;b\\t%l3\\t%@long jump\\n.LCB%=:\";
7866 default: return \"b%D0\\t.LCB%=\;bl\\t%l3\\t%@far jump\\n.LCB%=:\";
7869 [(set (attr "far_jump")
7871 (eq_attr "length" "8")
7872 (const_string "yes")
7873 (const_string "no")))
7874 (set (attr "length")
7876 (and (ge (minus (match_dup 3) (pc)) (const_int -250))
7877 (le (minus (match_dup 3) (pc)) (const_int 256)))
7880 (and (ge (minus (match_dup 3) (pc)) (const_int -2040))
7881 (le (minus (match_dup 3) (pc)) (const_int 2048)))
7884 (set_attr "type" "multiple")]
7887 (define_insn "cbranchsi4_scratch"
7888 [(set (pc) (if_then_else
7889 (match_operator 4 "arm_comparison_operator"
7890 [(match_operand:SI 1 "s_register_operand" "l,0")
7891 (match_operand:SI 2 "thumb1_cmpneg_operand" "L,J")])
7892 (label_ref (match_operand 3 "" ""))
7894 (clobber (match_scratch:SI 0 "=l,l"))]
7897 output_asm_insn (\"add\\t%0, %1, #%n2\", operands);
7899 switch (get_attr_length (insn))
7901 case 4: return \"b%d4\\t%l3\";
7902 case 6: return \"b%D4\\t.LCB%=\;b\\t%l3\\t%@long jump\\n.LCB%=:\";
7903 default: return \"b%D4\\t.LCB%=\;bl\\t%l3\\t%@far jump\\n.LCB%=:\";
7906 [(set (attr "far_jump")
7908 (eq_attr "length" "8")
7909 (const_string "yes")
7910 (const_string "no")))
7911 (set (attr "length")
7913 (and (ge (minus (match_dup 3) (pc)) (const_int -250))
7914 (le (minus (match_dup 3) (pc)) (const_int 256)))
7917 (and (ge (minus (match_dup 3) (pc)) (const_int -2040))
7918 (le (minus (match_dup 3) (pc)) (const_int 2048)))
7921 (set_attr "type" "multiple")]
7924 (define_insn "*negated_cbranchsi4"
7927 (match_operator 0 "equality_operator"
7928 [(match_operand:SI 1 "s_register_operand" "l")
7929 (neg:SI (match_operand:SI 2 "s_register_operand" "l"))])
7930 (label_ref (match_operand 3 "" ""))
7934 output_asm_insn (\"cmn\\t%1, %2\", operands);
7935 switch (get_attr_length (insn))
7937 case 4: return \"b%d0\\t%l3\";
7938 case 6: return \"b%D0\\t.LCB%=\;b\\t%l3\\t%@long jump\\n.LCB%=:\";
7939 default: return \"b%D0\\t.LCB%=\;bl\\t%l3\\t%@far jump\\n.LCB%=:\";
7942 [(set (attr "far_jump")
7944 (eq_attr "length" "8")
7945 (const_string "yes")
7946 (const_string "no")))
7947 (set (attr "length")
7949 (and (ge (minus (match_dup 3) (pc)) (const_int -250))
7950 (le (minus (match_dup 3) (pc)) (const_int 256)))
7953 (and (ge (minus (match_dup 3) (pc)) (const_int -2040))
7954 (le (minus (match_dup 3) (pc)) (const_int 2048)))
7957 (set_attr "type" "multiple")]
7960 (define_insn "*tbit_cbranch"
7963 (match_operator 0 "equality_operator"
7964 [(zero_extract:SI (match_operand:SI 1 "s_register_operand" "l")
7966 (match_operand:SI 2 "const_int_operand" "i"))
7968 (label_ref (match_operand 3 "" ""))
7970 (clobber (match_scratch:SI 4 "=l"))]
7975 op[0] = operands[4];
7976 op[1] = operands[1];
7977 op[2] = GEN_INT (32 - 1 - INTVAL (operands[2]));
7979 output_asm_insn (\"lsl\\t%0, %1, %2\", op);
7980 switch (get_attr_length (insn))
7982 case 4: return \"b%d0\\t%l3\";
7983 case 6: return \"b%D0\\t.LCB%=\;b\\t%l3\\t%@long jump\\n.LCB%=:\";
7984 default: return \"b%D0\\t.LCB%=\;bl\\t%l3\\t%@far jump\\n.LCB%=:\";
7987 [(set (attr "far_jump")
7989 (eq_attr "length" "8")
7990 (const_string "yes")
7991 (const_string "no")))
7992 (set (attr "length")
7994 (and (ge (minus (match_dup 3) (pc)) (const_int -250))
7995 (le (minus (match_dup 3) (pc)) (const_int 256)))
7998 (and (ge (minus (match_dup 3) (pc)) (const_int -2040))
7999 (le (minus (match_dup 3) (pc)) (const_int 2048)))
8002 (set_attr "type" "multiple")]
8005 (define_insn "*tlobits_cbranch"
8008 (match_operator 0 "equality_operator"
8009 [(zero_extract:SI (match_operand:SI 1 "s_register_operand" "l")
8010 (match_operand:SI 2 "const_int_operand" "i")
8013 (label_ref (match_operand 3 "" ""))
8015 (clobber (match_scratch:SI 4 "=l"))]
8020 op[0] = operands[4];
8021 op[1] = operands[1];
8022 op[2] = GEN_INT (32 - INTVAL (operands[2]));
8024 output_asm_insn (\"lsl\\t%0, %1, %2\", op);
8025 switch (get_attr_length (insn))
8027 case 4: return \"b%d0\\t%l3\";
8028 case 6: return \"b%D0\\t.LCB%=\;b\\t%l3\\t%@long jump\\n.LCB%=:\";
8029 default: return \"b%D0\\t.LCB%=\;bl\\t%l3\\t%@far jump\\n.LCB%=:\";
8032 [(set (attr "far_jump")
8034 (eq_attr "length" "8")
8035 (const_string "yes")
8036 (const_string "no")))
8037 (set (attr "length")
8039 (and (ge (minus (match_dup 3) (pc)) (const_int -250))
8040 (le (minus (match_dup 3) (pc)) (const_int 256)))
8043 (and (ge (minus (match_dup 3) (pc)) (const_int -2040))
8044 (le (minus (match_dup 3) (pc)) (const_int 2048)))
8047 (set_attr "type" "multiple")]
8050 (define_insn "*tstsi3_cbranch"
8053 (match_operator 3 "equality_operator"
8054 [(and:SI (match_operand:SI 0 "s_register_operand" "%l")
8055 (match_operand:SI 1 "s_register_operand" "l"))
8057 (label_ref (match_operand 2 "" ""))
8062 output_asm_insn (\"tst\\t%0, %1\", operands);
8063 switch (get_attr_length (insn))
8065 case 4: return \"b%d3\\t%l2\";
8066 case 6: return \"b%D3\\t.LCB%=\;b\\t%l2\\t%@long jump\\n.LCB%=:\";
8067 default: return \"b%D3\\t.LCB%=\;bl\\t%l2\\t%@far jump\\n.LCB%=:\";
8070 [(set (attr "far_jump")
8072 (eq_attr "length" "8")
8073 (const_string "yes")
8074 (const_string "no")))
8075 (set (attr "length")
8077 (and (ge (minus (match_dup 2) (pc)) (const_int -250))
8078 (le (minus (match_dup 2) (pc)) (const_int 256)))
8081 (and (ge (minus (match_dup 2) (pc)) (const_int -2040))
8082 (le (minus (match_dup 2) (pc)) (const_int 2048)))
8085 (set_attr "type" "multiple")]
8088 (define_insn "*cbranchne_decr1"
8090 (if_then_else (match_operator 3 "equality_operator"
8091 [(match_operand:SI 2 "s_register_operand" "l,l,1,l")
8093 (label_ref (match_operand 4 "" ""))
8095 (set (match_operand:SI 0 "thumb_cbrch_target_operand" "=l,*?h,*?m,*?m")
8096 (plus:SI (match_dup 2) (const_int -1)))
8097 (clobber (match_scratch:SI 1 "=X,l,&l,&l"))]
8102 cond[0] = gen_rtx_fmt_ee ((GET_CODE (operands[3]) == NE
8104 VOIDmode, operands[2], const1_rtx);
8105 cond[1] = operands[4];
8107 if (which_alternative == 0)
8108 output_asm_insn (\"sub\\t%0, %2, #1\", operands);
8109 else if (which_alternative == 1)
8111 /* We must provide an alternative for a hi reg because reload
8112 cannot handle output reloads on a jump instruction, but we
8113 can't subtract into that. Fortunately a mov from lo to hi
8114 does not clobber the condition codes. */
8115 output_asm_insn (\"sub\\t%1, %2, #1\", operands);
8116 output_asm_insn (\"mov\\t%0, %1\", operands);
8120 /* Similarly, but the target is memory. */
8121 output_asm_insn (\"sub\\t%1, %2, #1\", operands);
8122 output_asm_insn (\"str\\t%1, %0\", operands);
8125 switch (get_attr_length (insn) - (which_alternative ? 2 : 0))
8128 output_asm_insn (\"b%d0\\t%l1\", cond);
8131 output_asm_insn (\"b%D0\\t.LCB%=\", cond);
8132 return \"b\\t%l4\\t%@long jump\\n.LCB%=:\";
8134 output_asm_insn (\"b%D0\\t.LCB%=\", cond);
8135 return \"bl\\t%l4\\t%@far jump\\n.LCB%=:\";
8139 [(set (attr "far_jump")
8141 (ior (and (eq (symbol_ref ("which_alternative"))
8143 (eq_attr "length" "8"))
8144 (eq_attr "length" "10"))
8145 (const_string "yes")
8146 (const_string "no")))
8147 (set_attr_alternative "length"
8151 (and (ge (minus (match_dup 4) (pc)) (const_int -250))
8152 (le (minus (match_dup 4) (pc)) (const_int 256)))
8155 (and (ge (minus (match_dup 4) (pc)) (const_int -2040))
8156 (le (minus (match_dup 4) (pc)) (const_int 2048)))
8161 (and (ge (minus (match_dup 4) (pc)) (const_int -248))
8162 (le (minus (match_dup 4) (pc)) (const_int 256)))
8165 (and (ge (minus (match_dup 4) (pc)) (const_int -2038))
8166 (le (minus (match_dup 4) (pc)) (const_int 2048)))
8171 (and (ge (minus (match_dup 4) (pc)) (const_int -248))
8172 (le (minus (match_dup 4) (pc)) (const_int 256)))
8175 (and (ge (minus (match_dup 4) (pc)) (const_int -2038))
8176 (le (minus (match_dup 4) (pc)) (const_int 2048)))
8181 (and (ge (minus (match_dup 4) (pc)) (const_int -248))
8182 (le (minus (match_dup 4) (pc)) (const_int 256)))
8185 (and (ge (minus (match_dup 4) (pc)) (const_int -2038))
8186 (le (minus (match_dup 4) (pc)) (const_int 2048)))
8189 (set_attr "type" "multiple")]
8192 (define_insn "*addsi3_cbranch"
8195 (match_operator 4 "arm_comparison_operator"
8197 (match_operand:SI 2 "s_register_operand" "%0,l,*l,1,1,1")
8198 (match_operand:SI 3 "reg_or_int_operand" "IJ,lL,*l,lIJ,lIJ,lIJ"))
8200 (label_ref (match_operand 5 "" ""))
8203 (match_operand:SI 0 "thumb_cbrch_target_operand" "=l,l,*!h,*?h,*?m,*?m")
8204 (plus:SI (match_dup 2) (match_dup 3)))
8205 (clobber (match_scratch:SI 1 "=X,X,l,l,&l,&l"))]
8207 && (GET_CODE (operands[4]) == EQ
8208 || GET_CODE (operands[4]) == NE
8209 || GET_CODE (operands[4]) == GE
8210 || GET_CODE (operands[4]) == LT)"
8215 cond[0] = (which_alternative < 2) ? operands[0] : operands[1];
8216 cond[1] = operands[2];
8217 cond[2] = operands[3];
8219 if (CONST_INT_P (cond[2]) && INTVAL (cond[2]) < 0)
8220 output_asm_insn (\"sub\\t%0, %1, #%n2\", cond);
8222 output_asm_insn (\"add\\t%0, %1, %2\", cond);
8224 if (which_alternative >= 2
8225 && which_alternative < 4)
8226 output_asm_insn (\"mov\\t%0, %1\", operands);
8227 else if (which_alternative >= 4)
8228 output_asm_insn (\"str\\t%1, %0\", operands);
8230 switch (get_attr_length (insn) - ((which_alternative >= 2) ? 2 : 0))
8233 return \"b%d4\\t%l5\";
8235 return \"b%D4\\t.LCB%=\;b\\t%l5\\t%@long jump\\n.LCB%=:\";
8237 return \"b%D4\\t.LCB%=\;bl\\t%l5\\t%@far jump\\n.LCB%=:\";
8241 [(set (attr "far_jump")
8243 (ior (and (lt (symbol_ref ("which_alternative"))
8245 (eq_attr "length" "8"))
8246 (eq_attr "length" "10"))
8247 (const_string "yes")
8248 (const_string "no")))
8249 (set (attr "length")
8251 (lt (symbol_ref ("which_alternative"))
8254 (and (ge (minus (match_dup 5) (pc)) (const_int -250))
8255 (le (minus (match_dup 5) (pc)) (const_int 256)))
8258 (and (ge (minus (match_dup 5) (pc)) (const_int -2040))
8259 (le (minus (match_dup 5) (pc)) (const_int 2048)))
8263 (and (ge (minus (match_dup 5) (pc)) (const_int -248))
8264 (le (minus (match_dup 5) (pc)) (const_int 256)))
8267 (and (ge (minus (match_dup 5) (pc)) (const_int -2038))
8268 (le (minus (match_dup 5) (pc)) (const_int 2048)))
8271 (set_attr "type" "multiple")]
8274 (define_insn "*addsi3_cbranch_scratch"
8277 (match_operator 3 "arm_comparison_operator"
8279 (match_operand:SI 1 "s_register_operand" "%l,l,l,0")
8280 (match_operand:SI 2 "reg_or_int_operand" "J,l,L,IJ"))
8282 (label_ref (match_operand 4 "" ""))
8284 (clobber (match_scratch:SI 0 "=X,X,l,l"))]
8286 && (GET_CODE (operands[3]) == EQ
8287 || GET_CODE (operands[3]) == NE
8288 || GET_CODE (operands[3]) == GE
8289 || GET_CODE (operands[3]) == LT)"
8292 switch (which_alternative)
8295 output_asm_insn (\"cmp\t%1, #%n2\", operands);
8298 output_asm_insn (\"cmn\t%1, %2\", operands);
8301 if (INTVAL (operands[2]) < 0)
8302 output_asm_insn (\"sub\t%0, %1, %2\", operands);
8304 output_asm_insn (\"add\t%0, %1, %2\", operands);
8307 if (INTVAL (operands[2]) < 0)
8308 output_asm_insn (\"sub\t%0, %0, %2\", operands);
8310 output_asm_insn (\"add\t%0, %0, %2\", operands);
8314 switch (get_attr_length (insn))
8317 return \"b%d3\\t%l4\";
8319 return \"b%D3\\t.LCB%=\;b\\t%l4\\t%@long jump\\n.LCB%=:\";
8321 return \"b%D3\\t.LCB%=\;bl\\t%l4\\t%@far jump\\n.LCB%=:\";
8325 [(set (attr "far_jump")
8327 (eq_attr "length" "8")
8328 (const_string "yes")
8329 (const_string "no")))
8330 (set (attr "length")
8332 (and (ge (minus (match_dup 4) (pc)) (const_int -250))
8333 (le (minus (match_dup 4) (pc)) (const_int 256)))
8336 (and (ge (minus (match_dup 4) (pc)) (const_int -2040))
8337 (le (minus (match_dup 4) (pc)) (const_int 2048)))
8340 (set_attr "type" "multiple")]
8344 ;; Comparison and test insns
8346 (define_insn "*arm_cmpsi_insn"
8347 [(set (reg:CC CC_REGNUM)
8348 (compare:CC (match_operand:SI 0 "s_register_operand" "l,r,r,r,r")
8349 (match_operand:SI 1 "arm_add_operand" "Py,r,r,I,L")))]
8357 [(set_attr "conds" "set")
8358 (set_attr "arch" "t2,t2,any,any,any")
8359 (set_attr "length" "2,2,4,4,4")
8360 (set_attr "predicable" "yes")
8361 (set_attr "predicable_short_it" "yes,yes,yes,no,no")
8362 (set_attr "type" "alus_imm,alus_reg,alus_reg,alus_imm,alus_imm")]
8365 (define_insn "*cmpsi_shiftsi"
8366 [(set (reg:CC CC_REGNUM)
8367 (compare:CC (match_operand:SI 0 "s_register_operand" "r,r,r")
8368 (match_operator:SI 3 "shift_operator"
8369 [(match_operand:SI 1 "s_register_operand" "r,r,r")
8370 (match_operand:SI 2 "shift_amount_operand" "M,r,M")])))]
8373 [(set_attr "conds" "set")
8374 (set_attr "shift" "1")
8375 (set_attr "arch" "32,a,a")
8376 (set_attr "type" "alus_shift_imm,alu_shift_reg,alus_shift_imm")])
8378 (define_insn "*cmpsi_shiftsi_swp"
8379 [(set (reg:CC_SWP CC_REGNUM)
8380 (compare:CC_SWP (match_operator:SI 3 "shift_operator"
8381 [(match_operand:SI 1 "s_register_operand" "r,r,r")
8382 (match_operand:SI 2 "shift_amount_operand" "M,r,M")])
8383 (match_operand:SI 0 "s_register_operand" "r,r,r")))]
8386 [(set_attr "conds" "set")
8387 (set_attr "shift" "1")
8388 (set_attr "arch" "32,a,a")
8389 (set_attr "type" "alus_shift_imm,alu_shift_reg,alus_shift_imm")])
8391 (define_insn "*arm_cmpsi_negshiftsi_si"
8392 [(set (reg:CC_Z CC_REGNUM)
8394 (neg:SI (match_operator:SI 1 "shift_operator"
8395 [(match_operand:SI 2 "s_register_operand" "r")
8396 (match_operand:SI 3 "reg_or_int_operand" "rM")]))
8397 (match_operand:SI 0 "s_register_operand" "r")))]
8400 [(set_attr "conds" "set")
8401 (set (attr "type") (if_then_else (match_operand 3 "const_int_operand" "")
8402 (const_string "alus_shift_imm")
8403 (const_string "alus_shift_reg")))
8404 (set_attr "predicable" "yes")]
8407 ;; DImode comparisons. The generic code generates branches that
8408 ;; if-conversion can not reduce to a conditional compare, so we do
8411 (define_insn_and_split "*arm_cmpdi_insn"
8412 [(set (reg:CC_NCV CC_REGNUM)
8413 (compare:CC_NCV (match_operand:DI 0 "s_register_operand" "r")
8414 (match_operand:DI 1 "arm_di_operand" "rDi")))
8415 (clobber (match_scratch:SI 2 "=r"))]
8417 "#" ; "cmp\\t%Q0, %Q1\;sbcs\\t%2, %R0, %R1"
8418 "&& reload_completed"
8419 [(set (reg:CC CC_REGNUM)
8420 (compare:CC (match_dup 0) (match_dup 1)))
8421 (parallel [(set (reg:CC CC_REGNUM)
8422 (compare:CC (match_dup 3) (match_dup 4)))
8424 (minus:SI (match_dup 5)
8425 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))])]
8427 operands[3] = gen_highpart (SImode, operands[0]);
8428 operands[0] = gen_lowpart (SImode, operands[0]);
8429 if (CONST_INT_P (operands[1]))
8431 operands[4] = GEN_INT (~INTVAL (gen_highpart_mode (SImode,
8434 operands[5] = gen_rtx_PLUS (SImode, operands[3], operands[4]);
8438 operands[4] = gen_highpart (SImode, operands[1]);
8439 operands[5] = gen_rtx_MINUS (SImode, operands[3], operands[4]);
8441 operands[1] = gen_lowpart (SImode, operands[1]);
8442 operands[2] = gen_lowpart (SImode, operands[2]);
8444 [(set_attr "conds" "set")
8445 (set_attr "length" "8")
8446 (set_attr "type" "multiple")]
8449 (define_insn_and_split "*arm_cmpdi_unsigned"
8450 [(set (reg:CC_CZ CC_REGNUM)
8451 (compare:CC_CZ (match_operand:DI 0 "s_register_operand" "l,r,r")
8452 (match_operand:DI 1 "arm_di_operand" "Py,r,rDi")))]
8455 "#" ; "cmp\\t%R0, %R1\;it eq\;cmpeq\\t%Q0, %Q1"
8456 "&& reload_completed"
8457 [(set (reg:CC CC_REGNUM)
8458 (compare:CC (match_dup 2) (match_dup 3)))
8459 (cond_exec (eq:SI (reg:CC CC_REGNUM) (const_int 0))
8460 (set (reg:CC CC_REGNUM)
8461 (compare:CC (match_dup 0) (match_dup 1))))]
8463 operands[2] = gen_highpart (SImode, operands[0]);
8464 operands[0] = gen_lowpart (SImode, operands[0]);
8465 if (CONST_INT_P (operands[1]))
8466 operands[3] = gen_highpart_mode (SImode, DImode, operands[1]);
8468 operands[3] = gen_highpart (SImode, operands[1]);
8469 operands[1] = gen_lowpart (SImode, operands[1]);
8471 [(set_attr "conds" "set")
8472 (set_attr "enabled_for_depr_it" "yes,yes,no")
8473 (set_attr "arch" "t2,t2,*")
8474 (set_attr "length" "6,6,8")
8475 (set_attr "type" "multiple")]
8478 (define_insn "*arm_cmpdi_zero"
8479 [(set (reg:CC_Z CC_REGNUM)
8480 (compare:CC_Z (match_operand:DI 0 "s_register_operand" "r")
8482 (clobber (match_scratch:SI 1 "=r"))]
8484 "orr%.\\t%1, %Q0, %R0"
8485 [(set_attr "conds" "set")
8486 (set_attr "type" "logics_reg")]
8489 (define_insn "*thumb_cmpdi_zero"
8490 [(set (reg:CC_Z CC_REGNUM)
8491 (compare:CC_Z (match_operand:DI 0 "s_register_operand" "l")
8493 (clobber (match_scratch:SI 1 "=l"))]
8495 "orr\\t%1, %Q0, %R0"
8496 [(set_attr "conds" "set")
8497 (set_attr "length" "2")
8498 (set_attr "type" "logics_reg")]
8501 ; This insn allows redundant compares to be removed by cse, nothing should
8502 ; ever appear in the output file since (set (reg x) (reg x)) is a no-op that
8503 ; is deleted later on. The match_dup will match the mode here, so that
8504 ; mode changes of the condition codes aren't lost by this even though we don't
8505 ; specify what they are.
8507 (define_insn "*deleted_compare"
8508 [(set (match_operand 0 "cc_register" "") (match_dup 0))]
8510 "\\t%@ deleted compare"
8511 [(set_attr "conds" "set")
8512 (set_attr "length" "0")
8513 (set_attr "type" "no_insn")]
8517 ;; Conditional branch insns
8519 (define_expand "cbranch_cc"
8521 (if_then_else (match_operator 0 "" [(match_operand 1 "" "")
8522 (match_operand 2 "" "")])
8523 (label_ref (match_operand 3 "" ""))
8526 "operands[1] = arm_gen_compare_reg (GET_CODE (operands[0]),
8527 operands[1], operands[2], NULL_RTX);
8528 operands[2] = const0_rtx;"
8532 ;; Patterns to match conditional branch insns.
8535 (define_insn "arm_cond_branch"
8537 (if_then_else (match_operator 1 "arm_comparison_operator"
8538 [(match_operand 2 "cc_register" "") (const_int 0)])
8539 (label_ref (match_operand 0 "" ""))
8543 if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
8545 arm_ccfsm_state += 2;
8548 return \"b%d1\\t%l0\";
8550 [(set_attr "conds" "use")
8551 (set_attr "type" "branch")
8552 (set (attr "length")
8554 (and (match_test "TARGET_THUMB2")
8555 (and (ge (minus (match_dup 0) (pc)) (const_int -250))
8556 (le (minus (match_dup 0) (pc)) (const_int 256))))
8561 (define_insn "*arm_cond_branch_reversed"
8563 (if_then_else (match_operator 1 "arm_comparison_operator"
8564 [(match_operand 2 "cc_register" "") (const_int 0)])
8566 (label_ref (match_operand 0 "" ""))))]
8569 if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
8571 arm_ccfsm_state += 2;
8574 return \"b%D1\\t%l0\";
8576 [(set_attr "conds" "use")
8577 (set_attr "type" "branch")
8578 (set (attr "length")
8580 (and (match_test "TARGET_THUMB2")
8581 (and (ge (minus (match_dup 0) (pc)) (const_int -250))
8582 (le (minus (match_dup 0) (pc)) (const_int 256))))
8591 (define_expand "cstore_cc"
8592 [(set (match_operand:SI 0 "s_register_operand" "")
8593 (match_operator:SI 1 "" [(match_operand 2 "" "")
8594 (match_operand 3 "" "")]))]
8596 "operands[2] = arm_gen_compare_reg (GET_CODE (operands[1]),
8597 operands[2], operands[3], NULL_RTX);
8598 operands[3] = const0_rtx;"
8601 (define_insn_and_split "*mov_scc"
8602 [(set (match_operand:SI 0 "s_register_operand" "=r")
8603 (match_operator:SI 1 "arm_comparison_operator"
8604 [(match_operand 2 "cc_register" "") (const_int 0)]))]
8606 "#" ; "mov%D1\\t%0, #0\;mov%d1\\t%0, #1"
8609 (if_then_else:SI (match_dup 1)
8613 [(set_attr "conds" "use")
8614 (set_attr "length" "8")
8615 (set_attr "type" "multiple")]
8618 (define_insn_and_split "*mov_negscc"
8619 [(set (match_operand:SI 0 "s_register_operand" "=r")
8620 (neg:SI (match_operator:SI 1 "arm_comparison_operator"
8621 [(match_operand 2 "cc_register" "") (const_int 0)])))]
8623 "#" ; "mov%D1\\t%0, #0\;mvn%d1\\t%0, #0"
8626 (if_then_else:SI (match_dup 1)
8630 operands[3] = GEN_INT (~0);
8632 [(set_attr "conds" "use")
8633 (set_attr "length" "8")
8634 (set_attr "type" "multiple")]
8637 (define_insn_and_split "*mov_notscc"
8638 [(set (match_operand:SI 0 "s_register_operand" "=r")
8639 (not:SI (match_operator:SI 1 "arm_comparison_operator"
8640 [(match_operand 2 "cc_register" "") (const_int 0)])))]
8642 "#" ; "mvn%D1\\t%0, #0\;mvn%d1\\t%0, #1"
8645 (if_then_else:SI (match_dup 1)
8649 operands[3] = GEN_INT (~1);
8650 operands[4] = GEN_INT (~0);
8652 [(set_attr "conds" "use")
8653 (set_attr "length" "8")
8654 (set_attr "type" "multiple")]
8657 (define_expand "cstoresi4"
8658 [(set (match_operand:SI 0 "s_register_operand" "")
8659 (match_operator:SI 1 "expandable_comparison_operator"
8660 [(match_operand:SI 2 "s_register_operand" "")
8661 (match_operand:SI 3 "reg_or_int_operand" "")]))]
8662 "TARGET_32BIT || TARGET_THUMB1"
8664 rtx op3, scratch, scratch2;
8668 if (!arm_add_operand (operands[3], SImode))
8669 operands[3] = force_reg (SImode, operands[3]);
8670 emit_insn (gen_cstore_cc (operands[0], operands[1],
8671 operands[2], operands[3]));
8675 if (operands[3] == const0_rtx)
8677 switch (GET_CODE (operands[1]))
8680 emit_insn (gen_cstoresi_eq0_thumb1 (operands[0], operands[2]));
8684 emit_insn (gen_cstoresi_ne0_thumb1 (operands[0], operands[2]));
8688 scratch = expand_binop (SImode, add_optab, operands[2], constm1_rtx,
8689 NULL_RTX, 0, OPTAB_WIDEN);
8690 scratch = expand_binop (SImode, ior_optab, operands[2], scratch,
8691 NULL_RTX, 0, OPTAB_WIDEN);
8692 expand_binop (SImode, lshr_optab, scratch, GEN_INT (31),
8693 operands[0], 1, OPTAB_WIDEN);
8697 scratch = expand_unop (SImode, one_cmpl_optab, operands[2],
8699 expand_binop (SImode, lshr_optab, scratch, GEN_INT (31),
8700 NULL_RTX, 1, OPTAB_WIDEN);
8704 scratch = expand_binop (SImode, ashr_optab, operands[2],
8705 GEN_INT (31), NULL_RTX, 0, OPTAB_WIDEN);
8706 scratch = expand_binop (SImode, sub_optab, scratch, operands[2],
8707 NULL_RTX, 0, OPTAB_WIDEN);
8708 expand_binop (SImode, lshr_optab, scratch, GEN_INT (31), operands[0],
8712 /* LT is handled by generic code. No need for unsigned with 0. */
8719 switch (GET_CODE (operands[1]))
8722 scratch = expand_binop (SImode, sub_optab, operands[2], operands[3],
8723 NULL_RTX, 0, OPTAB_WIDEN);
8724 emit_insn (gen_cstoresi_eq0_thumb1 (operands[0], scratch));
8728 scratch = expand_binop (SImode, sub_optab, operands[2], operands[3],
8729 NULL_RTX, 0, OPTAB_WIDEN);
8730 emit_insn (gen_cstoresi_ne0_thumb1 (operands[0], scratch));
8734 op3 = force_reg (SImode, operands[3]);
8736 scratch = expand_binop (SImode, lshr_optab, operands[2], GEN_INT (31),
8737 NULL_RTX, 1, OPTAB_WIDEN);
8738 scratch2 = expand_binop (SImode, ashr_optab, op3, GEN_INT (31),
8739 NULL_RTX, 0, OPTAB_WIDEN);
8740 emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch2,
8746 if (!thumb1_cmp_operand (op3, SImode))
8747 op3 = force_reg (SImode, op3);
8748 scratch = expand_binop (SImode, ashr_optab, operands[2], GEN_INT (31),
8749 NULL_RTX, 0, OPTAB_WIDEN);
8750 scratch2 = expand_binop (SImode, lshr_optab, op3, GEN_INT (31),
8751 NULL_RTX, 1, OPTAB_WIDEN);
8752 emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch2,
8757 op3 = force_reg (SImode, operands[3]);
8758 scratch = force_reg (SImode, const0_rtx);
8759 emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch,
8765 if (!thumb1_cmp_operand (op3, SImode))
8766 op3 = force_reg (SImode, op3);
8767 scratch = force_reg (SImode, const0_rtx);
8768 emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch,
8774 if (!thumb1_cmp_operand (op3, SImode))
8775 op3 = force_reg (SImode, op3);
8776 scratch = gen_reg_rtx (SImode);
8777 emit_insn (gen_cstoresi_ltu_thumb1 (operands[0], operands[2], op3));
8781 op3 = force_reg (SImode, operands[3]);
8782 scratch = gen_reg_rtx (SImode);
8783 emit_insn (gen_cstoresi_ltu_thumb1 (operands[0], op3, operands[2]));
8786 /* No good sequences for GT, LT. */
8793 (define_expand "cstoresf4"
8794 [(set (match_operand:SI 0 "s_register_operand" "")
8795 (match_operator:SI 1 "expandable_comparison_operator"
8796 [(match_operand:SF 2 "s_register_operand" "")
8797 (match_operand:SF 3 "arm_float_compare_operand" "")]))]
8798 "TARGET_32BIT && TARGET_HARD_FLOAT"
8799 "emit_insn (gen_cstore_cc (operands[0], operands[1],
8800 operands[2], operands[3])); DONE;"
8803 (define_expand "cstoredf4"
8804 [(set (match_operand:SI 0 "s_register_operand" "")
8805 (match_operator:SI 1 "expandable_comparison_operator"
8806 [(match_operand:DF 2 "s_register_operand" "")
8807 (match_operand:DF 3 "arm_float_compare_operand" "")]))]
8808 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
8809 "emit_insn (gen_cstore_cc (operands[0], operands[1],
8810 operands[2], operands[3])); DONE;"
8813 (define_expand "cstoredi4"
8814 [(set (match_operand:SI 0 "s_register_operand" "")
8815 (match_operator:SI 1 "expandable_comparison_operator"
8816 [(match_operand:DI 2 "s_register_operand" "")
8817 (match_operand:DI 3 "cmpdi_operand" "")]))]
8820 if (!arm_validize_comparison (&operands[1],
8824 emit_insn (gen_cstore_cc (operands[0], operands[1], operands[2],
8830 (define_expand "cstoresi_eq0_thumb1"
8832 [(set (match_operand:SI 0 "s_register_operand" "")
8833 (eq:SI (match_operand:SI 1 "s_register_operand" "")
8835 (clobber (match_dup:SI 2))])]
8837 "operands[2] = gen_reg_rtx (SImode);"
8840 (define_expand "cstoresi_ne0_thumb1"
8842 [(set (match_operand:SI 0 "s_register_operand" "")
8843 (ne:SI (match_operand:SI 1 "s_register_operand" "")
8845 (clobber (match_dup:SI 2))])]
8847 "operands[2] = gen_reg_rtx (SImode);"
8850 (define_insn "*cstoresi_eq0_thumb1_insn"
8851 [(set (match_operand:SI 0 "s_register_operand" "=&l,l")
8852 (eq:SI (match_operand:SI 1 "s_register_operand" "l,0")
8854 (clobber (match_operand:SI 2 "s_register_operand" "=X,l"))]
8857 neg\\t%0, %1\;adc\\t%0, %0, %1
8858 neg\\t%2, %1\;adc\\t%0, %1, %2"
8859 [(set_attr "length" "4")
8860 (set_attr "type" "multiple")]
8863 (define_insn "*cstoresi_ne0_thumb1_insn"
8864 [(set (match_operand:SI 0 "s_register_operand" "=l")
8865 (ne:SI (match_operand:SI 1 "s_register_operand" "0")
8867 (clobber (match_operand:SI 2 "s_register_operand" "=l"))]
8869 "sub\\t%2, %1, #1\;sbc\\t%0, %1, %2"
8870 [(set_attr "length" "4")]
8873 ;; Used as part of the expansion of thumb ltu and gtu sequences
8874 (define_insn "cstoresi_nltu_thumb1"
8875 [(set (match_operand:SI 0 "s_register_operand" "=l,l")
8876 (neg:SI (ltu:SI (match_operand:SI 1 "s_register_operand" "l,*h")
8877 (match_operand:SI 2 "thumb1_cmp_operand" "lI*h,*r"))))]
8879 "cmp\\t%1, %2\;sbc\\t%0, %0, %0"
8880 [(set_attr "length" "4")
8881 (set_attr "type" "multiple")]
8884 (define_insn_and_split "cstoresi_ltu_thumb1"
8885 [(set (match_operand:SI 0 "s_register_operand" "=l,l")
8886 (ltu:SI (match_operand:SI 1 "s_register_operand" "l,*h")
8887 (match_operand:SI 2 "thumb1_cmp_operand" "lI*h,*r")))]
8892 (neg:SI (ltu:SI (match_dup 1) (match_dup 2))))
8893 (set (match_dup 0) (neg:SI (match_dup 3)))]
8894 "operands[3] = gen_reg_rtx (SImode);"
8895 [(set_attr "length" "4")
8896 (set_attr "type" "multiple")]
8899 ;; Used as part of the expansion of thumb les sequence.
8900 (define_insn "thumb1_addsi3_addgeu"
8901 [(set (match_operand:SI 0 "s_register_operand" "=l")
8902 (plus:SI (plus:SI (match_operand:SI 1 "s_register_operand" "%0")
8903 (match_operand:SI 2 "s_register_operand" "l"))
8904 (geu:SI (match_operand:SI 3 "s_register_operand" "l")
8905 (match_operand:SI 4 "thumb1_cmp_operand" "lI"))))]
8907 "cmp\\t%3, %4\;adc\\t%0, %1, %2"
8908 [(set_attr "length" "4")
8909 (set_attr "type" "multiple")]
8913 ;; Conditional move insns
8915 (define_expand "movsicc"
8916 [(set (match_operand:SI 0 "s_register_operand" "")
8917 (if_then_else:SI (match_operand 1 "expandable_comparison_operator" "")
8918 (match_operand:SI 2 "arm_not_operand" "")
8919 (match_operand:SI 3 "arm_not_operand" "")))]
8926 if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0),
8927 &XEXP (operands[1], 1)))
8930 code = GET_CODE (operands[1]);
8931 ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
8932 XEXP (operands[1], 1), NULL_RTX);
8933 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
8937 (define_expand "movsfcc"
8938 [(set (match_operand:SF 0 "s_register_operand" "")
8939 (if_then_else:SF (match_operand 1 "arm_cond_move_operator" "")
8940 (match_operand:SF 2 "s_register_operand" "")
8941 (match_operand:SF 3 "s_register_operand" "")))]
8942 "TARGET_32BIT && TARGET_HARD_FLOAT"
8945 enum rtx_code code = GET_CODE (operands[1]);
8948 if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0),
8949 &XEXP (operands[1], 1)))
8952 code = GET_CODE (operands[1]);
8953 ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
8954 XEXP (operands[1], 1), NULL_RTX);
8955 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
8959 (define_expand "movdfcc"
8960 [(set (match_operand:DF 0 "s_register_operand" "")
8961 (if_then_else:DF (match_operand 1 "arm_cond_move_operator" "")
8962 (match_operand:DF 2 "s_register_operand" "")
8963 (match_operand:DF 3 "s_register_operand" "")))]
8964 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
8967 enum rtx_code code = GET_CODE (operands[1]);
8970 if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0),
8971 &XEXP (operands[1], 1)))
8973 code = GET_CODE (operands[1]);
8974 ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
8975 XEXP (operands[1], 1), NULL_RTX);
8976 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
8980 (define_insn "*cmov<mode>"
8981 [(set (match_operand:SDF 0 "s_register_operand" "=<F_constraint>")
8982 (if_then_else:SDF (match_operator 1 "arm_vsel_comparison_operator"
8983 [(match_operand 2 "cc_register" "") (const_int 0)])
8984 (match_operand:SDF 3 "s_register_operand"
8986 (match_operand:SDF 4 "s_register_operand"
8987 "<F_constraint>")))]
8988 "TARGET_HARD_FLOAT && TARGET_FPU_ARMV8 <vfp_double_cond>"
8991 enum arm_cond_code code = maybe_get_arm_condition_code (operands[1]);
8998 return \"vsel%d1.<V_if_elem>\\t%<V_reg>0, %<V_reg>3, %<V_reg>4\";
9003 return \"vsel%D1.<V_if_elem>\\t%<V_reg>0, %<V_reg>4, %<V_reg>3\";
9009 [(set_attr "conds" "use")
9010 (set_attr "type" "f_sel<vfp_type>")]
9013 (define_insn_and_split "*movsicc_insn"
9014 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r,r,r,r,r")
9016 (match_operator 3 "arm_comparison_operator"
9017 [(match_operand 4 "cc_register" "") (const_int 0)])
9018 (match_operand:SI 1 "arm_not_operand" "0,0,rI,K,rI,rI,K,K")
9019 (match_operand:SI 2 "arm_not_operand" "rI,K,0,0,rI,K,rI,K")))]
9030 ; alt4: mov%d3\\t%0, %1\;mov%D3\\t%0, %2
9031 ; alt5: mov%d3\\t%0, %1\;mvn%D3\\t%0, #%B2
9032 ; alt6: mvn%d3\\t%0, #%B1\;mov%D3\\t%0, %2
9033 ; alt7: mvn%d3\\t%0, #%B1\;mvn%D3\\t%0, #%B2"
9034 "&& reload_completed"
9037 enum rtx_code rev_code;
9038 enum machine_mode mode;
9041 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
9043 gen_rtx_SET (VOIDmode,
9047 rev_code = GET_CODE (operands[3]);
9048 mode = GET_MODE (operands[4]);
9049 if (mode == CCFPmode || mode == CCFPEmode)
9050 rev_code = reverse_condition_maybe_unordered (rev_code);
9052 rev_code = reverse_condition (rev_code);
9054 rev_cond = gen_rtx_fmt_ee (rev_code,
9058 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
9060 gen_rtx_SET (VOIDmode,
9065 [(set_attr "length" "4,4,4,4,8,8,8,8")
9066 (set_attr "conds" "use")
9067 (set_attr_alternative "type"
9068 [(if_then_else (match_operand 2 "const_int_operand" "")
9069 (const_string "mov_imm")
9070 (const_string "mov_reg"))
9071 (const_string "mvn_imm")
9072 (if_then_else (match_operand 1 "const_int_operand" "")
9073 (const_string "mov_imm")
9074 (const_string "mov_reg"))
9075 (const_string "mvn_imm")
9076 (const_string "mov_reg")
9077 (const_string "mov_reg")
9078 (const_string "mov_reg")
9079 (const_string "mov_reg")])]
9082 (define_insn "*movsfcc_soft_insn"
9083 [(set (match_operand:SF 0 "s_register_operand" "=r,r")
9084 (if_then_else:SF (match_operator 3 "arm_comparison_operator"
9085 [(match_operand 4 "cc_register" "") (const_int 0)])
9086 (match_operand:SF 1 "s_register_operand" "0,r")
9087 (match_operand:SF 2 "s_register_operand" "r,0")))]
9088 "TARGET_ARM && TARGET_SOFT_FLOAT"
9092 [(set_attr "conds" "use")
9093 (set_attr "type" "mov_reg")]
9097 ;; Jump and linkage insns
9099 (define_expand "jump"
9101 (label_ref (match_operand 0 "" "")))]
9106 (define_insn "*arm_jump"
9108 (label_ref (match_operand 0 "" "")))]
9112 if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
9114 arm_ccfsm_state += 2;
9117 return \"b%?\\t%l0\";
9120 [(set_attr "predicable" "yes")
9121 (set (attr "length")
9123 (and (match_test "TARGET_THUMB2")
9124 (and (ge (minus (match_dup 0) (pc)) (const_int -2044))
9125 (le (minus (match_dup 0) (pc)) (const_int 2048))))
9128 (set_attr "type" "branch")]
9131 (define_insn "*thumb_jump"
9133 (label_ref (match_operand 0 "" "")))]
9136 if (get_attr_length (insn) == 2)
9138 return \"bl\\t%l0\\t%@ far jump\";
9140 [(set (attr "far_jump")
9142 (eq_attr "length" "4")
9143 (const_string "yes")
9144 (const_string "no")))
9145 (set (attr "length")
9147 (and (ge (minus (match_dup 0) (pc)) (const_int -2044))
9148 (le (minus (match_dup 0) (pc)) (const_int 2048)))
9151 (set_attr "type" "branch")]
9154 (define_expand "call"
9155 [(parallel [(call (match_operand 0 "memory_operand" "")
9156 (match_operand 1 "general_operand" ""))
9157 (use (match_operand 2 "" ""))
9158 (clobber (reg:SI LR_REGNUM))])]
9164 /* In an untyped call, we can get NULL for operand 2. */
9165 if (operands[2] == NULL_RTX)
9166 operands[2] = const0_rtx;
9168 /* Decide if we should generate indirect calls by loading the
9169 32-bit address of the callee into a register before performing the
9171 callee = XEXP (operands[0], 0);
9172 if (GET_CODE (callee) == SYMBOL_REF
9173 ? arm_is_long_call_p (SYMBOL_REF_DECL (callee))
9175 XEXP (operands[0], 0) = force_reg (Pmode, callee);
9177 pat = gen_call_internal (operands[0], operands[1], operands[2]);
9178 arm_emit_call_insn (pat, XEXP (operands[0], 0));
9183 (define_expand "call_internal"
9184 [(parallel [(call (match_operand 0 "memory_operand" "")
9185 (match_operand 1 "general_operand" ""))
9186 (use (match_operand 2 "" ""))
9187 (clobber (reg:SI LR_REGNUM))])])
9189 (define_insn "*call_reg_armv5"
9190 [(call (mem:SI (match_operand:SI 0 "s_register_operand" "r"))
9191 (match_operand 1 "" ""))
9192 (use (match_operand 2 "" ""))
9193 (clobber (reg:SI LR_REGNUM))]
9194 "TARGET_ARM && arm_arch5 && !SIBLING_CALL_P (insn)"
9196 [(set_attr "type" "call")]
9199 (define_insn "*call_reg_arm"
9200 [(call (mem:SI (match_operand:SI 0 "s_register_operand" "r"))
9201 (match_operand 1 "" ""))
9202 (use (match_operand 2 "" ""))
9203 (clobber (reg:SI LR_REGNUM))]
9204 "TARGET_ARM && !arm_arch5 && !SIBLING_CALL_P (insn)"
9206 return output_call (operands);
9208 ;; length is worst case, normally it is only two
9209 [(set_attr "length" "12")
9210 (set_attr "type" "call")]
9214 ;; Note: not used for armv5+ because the sequence used (ldr pc, ...) is not
9215 ;; considered a function call by the branch predictor of some cores (PR40887).
9216 ;; Falls back to blx rN (*call_reg_armv5).
9218 (define_insn "*call_mem"
9219 [(call (mem:SI (match_operand:SI 0 "call_memory_operand" "m"))
9220 (match_operand 1 "" ""))
9221 (use (match_operand 2 "" ""))
9222 (clobber (reg:SI LR_REGNUM))]
9223 "TARGET_ARM && !arm_arch5 && !SIBLING_CALL_P (insn)"
9225 return output_call_mem (operands);
9227 [(set_attr "length" "12")
9228 (set_attr "type" "call")]
9231 (define_insn "*call_reg_thumb1_v5"
9232 [(call (mem:SI (match_operand:SI 0 "register_operand" "l*r"))
9233 (match_operand 1 "" ""))
9234 (use (match_operand 2 "" ""))
9235 (clobber (reg:SI LR_REGNUM))]
9236 "TARGET_THUMB1 && arm_arch5 && !SIBLING_CALL_P (insn)"
9238 [(set_attr "length" "2")
9239 (set_attr "type" "call")]
9242 (define_insn "*call_reg_thumb1"
9243 [(call (mem:SI (match_operand:SI 0 "register_operand" "l*r"))
9244 (match_operand 1 "" ""))
9245 (use (match_operand 2 "" ""))
9246 (clobber (reg:SI LR_REGNUM))]
9247 "TARGET_THUMB1 && !arm_arch5 && !SIBLING_CALL_P (insn)"
9250 if (!TARGET_CALLER_INTERWORKING)
9251 return thumb_call_via_reg (operands[0]);
9252 else if (operands[1] == const0_rtx)
9253 return \"bl\\t%__interwork_call_via_%0\";
9254 else if (frame_pointer_needed)
9255 return \"bl\\t%__interwork_r7_call_via_%0\";
9257 return \"bl\\t%__interwork_r11_call_via_%0\";
9259 [(set_attr "type" "call")]
9262 (define_expand "call_value"
9263 [(parallel [(set (match_operand 0 "" "")
9264 (call (match_operand 1 "memory_operand" "")
9265 (match_operand 2 "general_operand" "")))
9266 (use (match_operand 3 "" ""))
9267 (clobber (reg:SI LR_REGNUM))])]
9273 /* In an untyped call, we can get NULL for operand 2. */
9274 if (operands[3] == 0)
9275 operands[3] = const0_rtx;
9277 /* Decide if we should generate indirect calls by loading the
9278 32-bit address of the callee into a register before performing the
9280 callee = XEXP (operands[1], 0);
9281 if (GET_CODE (callee) == SYMBOL_REF
9282 ? arm_is_long_call_p (SYMBOL_REF_DECL (callee))
9284 XEXP (operands[1], 0) = force_reg (Pmode, callee);
9286 pat = gen_call_value_internal (operands[0], operands[1],
9287 operands[2], operands[3]);
9288 arm_emit_call_insn (pat, XEXP (operands[1], 0));
9293 (define_expand "call_value_internal"
9294 [(parallel [(set (match_operand 0 "" "")
9295 (call (match_operand 1 "memory_operand" "")
9296 (match_operand 2 "general_operand" "")))
9297 (use (match_operand 3 "" ""))
9298 (clobber (reg:SI LR_REGNUM))])])
9300 (define_insn "*call_value_reg_armv5"
9301 [(set (match_operand 0 "" "")
9302 (call (mem:SI (match_operand:SI 1 "s_register_operand" "r"))
9303 (match_operand 2 "" "")))
9304 (use (match_operand 3 "" ""))
9305 (clobber (reg:SI LR_REGNUM))]
9306 "TARGET_ARM && arm_arch5 && !SIBLING_CALL_P (insn)"
9308 [(set_attr "type" "call")]
9311 (define_insn "*call_value_reg_arm"
9312 [(set (match_operand 0 "" "")
9313 (call (mem:SI (match_operand:SI 1 "s_register_operand" "r"))
9314 (match_operand 2 "" "")))
9315 (use (match_operand 3 "" ""))
9316 (clobber (reg:SI LR_REGNUM))]
9317 "TARGET_ARM && !arm_arch5 && !SIBLING_CALL_P (insn)"
9319 return output_call (&operands[1]);
9321 [(set_attr "length" "12")
9322 (set_attr "type" "call")]
9325 ;; Note: see *call_mem
9327 (define_insn "*call_value_mem"
9328 [(set (match_operand 0 "" "")
9329 (call (mem:SI (match_operand:SI 1 "call_memory_operand" "m"))
9330 (match_operand 2 "" "")))
9331 (use (match_operand 3 "" ""))
9332 (clobber (reg:SI LR_REGNUM))]
9333 "TARGET_ARM && !arm_arch5 && (!CONSTANT_ADDRESS_P (XEXP (operands[1], 0)))
9334 && !SIBLING_CALL_P (insn)"
9336 return output_call_mem (&operands[1]);
9338 [(set_attr "length" "12")
9339 (set_attr "type" "call")]
9342 (define_insn "*call_value_reg_thumb1_v5"
9343 [(set (match_operand 0 "" "")
9344 (call (mem:SI (match_operand:SI 1 "register_operand" "l*r"))
9345 (match_operand 2 "" "")))
9346 (use (match_operand 3 "" ""))
9347 (clobber (reg:SI LR_REGNUM))]
9348 "TARGET_THUMB1 && arm_arch5"
9350 [(set_attr "length" "2")
9351 (set_attr "type" "call")]
9354 (define_insn "*call_value_reg_thumb1"
9355 [(set (match_operand 0 "" "")
9356 (call (mem:SI (match_operand:SI 1 "register_operand" "l*r"))
9357 (match_operand 2 "" "")))
9358 (use (match_operand 3 "" ""))
9359 (clobber (reg:SI LR_REGNUM))]
9360 "TARGET_THUMB1 && !arm_arch5"
9363 if (!TARGET_CALLER_INTERWORKING)
9364 return thumb_call_via_reg (operands[1]);
9365 else if (operands[2] == const0_rtx)
9366 return \"bl\\t%__interwork_call_via_%1\";
9367 else if (frame_pointer_needed)
9368 return \"bl\\t%__interwork_r7_call_via_%1\";
9370 return \"bl\\t%__interwork_r11_call_via_%1\";
9372 [(set_attr "type" "call")]
9375 ;; Allow calls to SYMBOL_REFs specially as they are not valid general addresses
9376 ;; The 'a' causes the operand to be treated as an address, i.e. no '#' output.
9378 (define_insn "*call_symbol"
9379 [(call (mem:SI (match_operand:SI 0 "" ""))
9380 (match_operand 1 "" ""))
9381 (use (match_operand 2 "" ""))
9382 (clobber (reg:SI LR_REGNUM))]
9384 && !SIBLING_CALL_P (insn)
9385 && (GET_CODE (operands[0]) == SYMBOL_REF)
9386 && !arm_is_long_call_p (SYMBOL_REF_DECL (operands[0]))"
9389 return NEED_PLT_RELOC ? \"bl%?\\t%a0(PLT)\" : \"bl%?\\t%a0\";
9391 [(set_attr "type" "call")]
9394 (define_insn "*call_value_symbol"
9395 [(set (match_operand 0 "" "")
9396 (call (mem:SI (match_operand:SI 1 "" ""))
9397 (match_operand:SI 2 "" "")))
9398 (use (match_operand 3 "" ""))
9399 (clobber (reg:SI LR_REGNUM))]
9401 && !SIBLING_CALL_P (insn)
9402 && (GET_CODE (operands[1]) == SYMBOL_REF)
9403 && !arm_is_long_call_p (SYMBOL_REF_DECL (operands[1]))"
9406 return NEED_PLT_RELOC ? \"bl%?\\t%a1(PLT)\" : \"bl%?\\t%a1\";
9408 [(set_attr "type" "call")]
9411 (define_insn "*call_insn"
9412 [(call (mem:SI (match_operand:SI 0 "" ""))
9413 (match_operand:SI 1 "" ""))
9414 (use (match_operand 2 "" ""))
9415 (clobber (reg:SI LR_REGNUM))]
9417 && GET_CODE (operands[0]) == SYMBOL_REF
9418 && !arm_is_long_call_p (SYMBOL_REF_DECL (operands[0]))"
9420 [(set_attr "length" "4")
9421 (set_attr "type" "call")]
9424 (define_insn "*call_value_insn"
9425 [(set (match_operand 0 "" "")
9426 (call (mem:SI (match_operand 1 "" ""))
9427 (match_operand 2 "" "")))
9428 (use (match_operand 3 "" ""))
9429 (clobber (reg:SI LR_REGNUM))]
9431 && GET_CODE (operands[1]) == SYMBOL_REF
9432 && !arm_is_long_call_p (SYMBOL_REF_DECL (operands[1]))"
9434 [(set_attr "length" "4")
9435 (set_attr "type" "call")]
9438 ;; We may also be able to do sibcalls for Thumb, but it's much harder...
9439 (define_expand "sibcall"
9440 [(parallel [(call (match_operand 0 "memory_operand" "")
9441 (match_operand 1 "general_operand" ""))
9443 (use (match_operand 2 "" ""))])]
9447 if (!REG_P (XEXP (operands[0], 0))
9448 && (GET_CODE (XEXP (operands[0], 0)) != SYMBOL_REF))
9449 XEXP (operands[0], 0) = force_reg (SImode, XEXP (operands[0], 0));
9451 if (operands[2] == NULL_RTX)
9452 operands[2] = const0_rtx;
9456 (define_expand "sibcall_value"
9457 [(parallel [(set (match_operand 0 "" "")
9458 (call (match_operand 1 "memory_operand" "")
9459 (match_operand 2 "general_operand" "")))
9461 (use (match_operand 3 "" ""))])]
9465 if (!REG_P (XEXP (operands[1], 0)) &&
9466 (GET_CODE (XEXP (operands[1],0)) != SYMBOL_REF))
9467 XEXP (operands[1], 0) = force_reg (SImode, XEXP (operands[1], 0));
9469 if (operands[3] == NULL_RTX)
9470 operands[3] = const0_rtx;
9474 (define_insn "*sibcall_insn"
9475 [(call (mem:SI (match_operand:SI 0 "call_insn_operand" "Cs, US"))
9476 (match_operand 1 "" ""))
9478 (use (match_operand 2 "" ""))]
9479 "TARGET_32BIT && SIBLING_CALL_P (insn)"
9481 if (which_alternative == 1)
9482 return NEED_PLT_RELOC ? \"b%?\\t%a0(PLT)\" : \"b%?\\t%a0\";
9485 if (arm_arch5 || arm_arch4t)
9486 return \"bx%?\\t%0\\t%@ indirect register sibling call\";
9488 return \"mov%?\\t%|pc, %0\\t%@ indirect register sibling call\";
9491 [(set_attr "type" "call")]
9494 (define_insn "*sibcall_value_insn"
9495 [(set (match_operand 0 "" "")
9496 (call (mem:SI (match_operand:SI 1 "call_insn_operand" "Cs,US"))
9497 (match_operand 2 "" "")))
9499 (use (match_operand 3 "" ""))]
9500 "TARGET_32BIT && SIBLING_CALL_P (insn)"
9502 if (which_alternative == 1)
9503 return NEED_PLT_RELOC ? \"b%?\\t%a1(PLT)\" : \"b%?\\t%a1\";
9506 if (arm_arch5 || arm_arch4t)
9507 return \"bx%?\\t%1\";
9509 return \"mov%?\\t%|pc, %1\\t@ indirect sibling call \";
9512 [(set_attr "type" "call")]
9515 (define_expand "<return_str>return"
9517 "(TARGET_ARM || (TARGET_THUMB2
9518 && ARM_FUNC_TYPE (arm_current_func_type ()) == ARM_FT_NORMAL
9519 && !IS_STACKALIGN (arm_current_func_type ())))
9520 <return_cond_false>"
9525 thumb2_expand_return (<return_simple_p>);
9532 ;; Often the return insn will be the same as loading from memory, so set attr
9533 (define_insn "*arm_return"
9535 "TARGET_ARM && USE_RETURN_INSN (FALSE)"
9538 if (arm_ccfsm_state == 2)
9540 arm_ccfsm_state += 2;
9543 return output_return_instruction (const_true_rtx, true, false, false);
9545 [(set_attr "type" "load1")
9546 (set_attr "length" "12")
9547 (set_attr "predicable" "yes")]
9550 (define_insn "*cond_<return_str>return"
9552 (if_then_else (match_operator 0 "arm_comparison_operator"
9553 [(match_operand 1 "cc_register" "") (const_int 0)])
9556 "TARGET_ARM <return_cond_true>"
9559 if (arm_ccfsm_state == 2)
9561 arm_ccfsm_state += 2;
9564 return output_return_instruction (operands[0], true, false,
9567 [(set_attr "conds" "use")
9568 (set_attr "length" "12")
9569 (set_attr "type" "load1")]
9572 (define_insn "*cond_<return_str>return_inverted"
9574 (if_then_else (match_operator 0 "arm_comparison_operator"
9575 [(match_operand 1 "cc_register" "") (const_int 0)])
9578 "TARGET_ARM <return_cond_true>"
9581 if (arm_ccfsm_state == 2)
9583 arm_ccfsm_state += 2;
9586 return output_return_instruction (operands[0], true, true,
9589 [(set_attr "conds" "use")
9590 (set_attr "length" "12")
9591 (set_attr "type" "load1")]
9594 (define_insn "*arm_simple_return"
9599 if (arm_ccfsm_state == 2)
9601 arm_ccfsm_state += 2;
9604 return output_return_instruction (const_true_rtx, true, false, true);
9606 [(set_attr "type" "branch")
9607 (set_attr "length" "4")
9608 (set_attr "predicable" "yes")]
9611 ;; Generate a sequence of instructions to determine if the processor is
9612 ;; in 26-bit or 32-bit mode, and return the appropriate return address
9615 (define_expand "return_addr_mask"
9617 (compare:CC_NOOV (unspec [(const_int 0)] UNSPEC_CHECK_ARCH)
9619 (set (match_operand:SI 0 "s_register_operand" "")
9620 (if_then_else:SI (eq (match_dup 1) (const_int 0))
9622 (const_int 67108860)))] ; 0x03fffffc
9625 operands[1] = gen_rtx_REG (CC_NOOVmode, CC_REGNUM);
9628 (define_insn "*check_arch2"
9629 [(set (match_operand:CC_NOOV 0 "cc_register" "")
9630 (compare:CC_NOOV (unspec [(const_int 0)] UNSPEC_CHECK_ARCH)
9633 "teq\\t%|r0, %|r0\;teq\\t%|pc, %|pc"
9634 [(set_attr "length" "8")
9635 (set_attr "conds" "set")
9636 (set_attr "type" "multiple")]
9639 ;; Call subroutine returning any type.
9641 (define_expand "untyped_call"
9642 [(parallel [(call (match_operand 0 "" "")
9644 (match_operand 1 "" "")
9645 (match_operand 2 "" "")])]
9650 rtx par = gen_rtx_PARALLEL (VOIDmode,
9651 rtvec_alloc (XVECLEN (operands[2], 0)));
9652 rtx addr = gen_reg_rtx (Pmode);
9656 emit_move_insn (addr, XEXP (operands[1], 0));
9657 mem = change_address (operands[1], BLKmode, addr);
9659 for (i = 0; i < XVECLEN (operands[2], 0); i++)
9661 rtx src = SET_SRC (XVECEXP (operands[2], 0, i));
9663 /* Default code only uses r0 as a return value, but we could
9664 be using anything up to 4 registers. */
9665 if (REGNO (src) == R0_REGNUM)
9666 src = gen_rtx_REG (TImode, R0_REGNUM);
9668 XVECEXP (par, 0, i) = gen_rtx_EXPR_LIST (VOIDmode, src,
9670 size += GET_MODE_SIZE (GET_MODE (src));
9673 emit_call_insn (GEN_CALL_VALUE (par, operands[0], const0_rtx, NULL,
9678 for (i = 0; i < XVECLEN (par, 0); i++)
9680 HOST_WIDE_INT offset = 0;
9681 rtx reg = XEXP (XVECEXP (par, 0, i), 0);
9684 emit_move_insn (addr, plus_constant (Pmode, addr, size));
9686 mem = change_address (mem, GET_MODE (reg), NULL);
9687 if (REGNO (reg) == R0_REGNUM)
9689 /* On thumb we have to use a write-back instruction. */
9690 emit_insn (arm_gen_store_multiple (arm_regs_in_sequence, 4, addr,
9691 TARGET_THUMB ? TRUE : FALSE, mem, &offset));
9692 size = TARGET_ARM ? 16 : 0;
9696 emit_move_insn (mem, reg);
9697 size = GET_MODE_SIZE (GET_MODE (reg));
9701 /* The optimizer does not know that the call sets the function value
9702 registers we stored in the result block. We avoid problems by
9703 claiming that all hard registers are used and clobbered at this
9705 emit_insn (gen_blockage ());
9711 (define_expand "untyped_return"
9712 [(match_operand:BLK 0 "memory_operand" "")
9713 (match_operand 1 "" "")]
9718 rtx addr = gen_reg_rtx (Pmode);
9722 emit_move_insn (addr, XEXP (operands[0], 0));
9723 mem = change_address (operands[0], BLKmode, addr);
9725 for (i = 0; i < XVECLEN (operands[1], 0); i++)
9727 HOST_WIDE_INT offset = 0;
9728 rtx reg = SET_DEST (XVECEXP (operands[1], 0, i));
9731 emit_move_insn (addr, plus_constant (Pmode, addr, size));
9733 mem = change_address (mem, GET_MODE (reg), NULL);
9734 if (REGNO (reg) == R0_REGNUM)
9736 /* On thumb we have to use a write-back instruction. */
9737 emit_insn (arm_gen_load_multiple (arm_regs_in_sequence, 4, addr,
9738 TARGET_THUMB ? TRUE : FALSE, mem, &offset));
9739 size = TARGET_ARM ? 16 : 0;
9743 emit_move_insn (reg, mem);
9744 size = GET_MODE_SIZE (GET_MODE (reg));
9748 /* Emit USE insns before the return. */
9749 for (i = 0; i < XVECLEN (operands[1], 0); i++)
9750 emit_use (SET_DEST (XVECEXP (operands[1], 0, i)));
9752 /* Construct the return. */
9753 expand_naked_return ();
9759 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
9760 ;; all of memory. This blocks insns from being moved across this point.
9762 (define_insn "blockage"
9763 [(unspec_volatile [(const_int 0)] VUNSPEC_BLOCKAGE)]
9766 [(set_attr "length" "0")
9767 (set_attr "type" "block")]
9770 (define_expand "casesi"
9771 [(match_operand:SI 0 "s_register_operand" "") ; index to jump on
9772 (match_operand:SI 1 "const_int_operand" "") ; lower bound
9773 (match_operand:SI 2 "const_int_operand" "") ; total range
9774 (match_operand:SI 3 "" "") ; table label
9775 (match_operand:SI 4 "" "")] ; Out of range label
9776 "TARGET_32BIT || optimize_size || flag_pic"
9779 enum insn_code code;
9780 if (operands[1] != const0_rtx)
9782 rtx reg = gen_reg_rtx (SImode);
9784 emit_insn (gen_addsi3 (reg, operands[0],
9785 gen_int_mode (-INTVAL (operands[1]),
9791 code = CODE_FOR_arm_casesi_internal;
9792 else if (TARGET_THUMB1)
9793 code = CODE_FOR_thumb1_casesi_internal_pic;
9795 code = CODE_FOR_thumb2_casesi_internal_pic;
9797 code = CODE_FOR_thumb2_casesi_internal;
9799 if (!insn_data[(int) code].operand[1].predicate(operands[2], SImode))
9800 operands[2] = force_reg (SImode, operands[2]);
9802 emit_jump_insn (GEN_FCN ((int) code) (operands[0], operands[2],
9803 operands[3], operands[4]));
9808 ;; The USE in this pattern is needed to tell flow analysis that this is
9809 ;; a CASESI insn. It has no other purpose.
9810 (define_insn "arm_casesi_internal"
9811 [(parallel [(set (pc)
9813 (leu (match_operand:SI 0 "s_register_operand" "r")
9814 (match_operand:SI 1 "arm_rhs_operand" "rI"))
9815 (mem:SI (plus:SI (mult:SI (match_dup 0) (const_int 4))
9816 (label_ref (match_operand 2 "" ""))))
9817 (label_ref (match_operand 3 "" ""))))
9818 (clobber (reg:CC CC_REGNUM))
9819 (use (label_ref (match_dup 2)))])]
9823 return \"cmp\\t%0, %1\;addls\\t%|pc, %|pc, %0, asl #2\;b\\t%l3\";
9824 return \"cmp\\t%0, %1\;ldrls\\t%|pc, [%|pc, %0, asl #2]\;b\\t%l3\";
9826 [(set_attr "conds" "clob")
9827 (set_attr "length" "12")
9828 (set_attr "type" "multiple")]
9831 (define_expand "thumb1_casesi_internal_pic"
9832 [(match_operand:SI 0 "s_register_operand" "")
9833 (match_operand:SI 1 "thumb1_cmp_operand" "")
9834 (match_operand 2 "" "")
9835 (match_operand 3 "" "")]
9839 rtx test = gen_rtx_GTU (VOIDmode, operands[0], operands[1]);
9840 emit_jump_insn (gen_cbranchsi4 (test, operands[0], operands[1],
9842 reg0 = gen_rtx_REG (SImode, 0);
9843 emit_move_insn (reg0, operands[0]);
9844 emit_jump_insn (gen_thumb1_casesi_dispatch (operands[2]/*, operands[3]*/));
9849 (define_insn "thumb1_casesi_dispatch"
9850 [(parallel [(set (pc) (unspec [(reg:SI 0)
9851 (label_ref (match_operand 0 "" ""))
9852 ;; (label_ref (match_operand 1 "" ""))
9854 UNSPEC_THUMB1_CASESI))
9855 (clobber (reg:SI IP_REGNUM))
9856 (clobber (reg:SI LR_REGNUM))])]
9858 "* return thumb1_output_casesi(operands);"
9859 [(set_attr "length" "4")
9860 (set_attr "type" "multiple")]
9863 (define_expand "indirect_jump"
9865 (match_operand:SI 0 "s_register_operand" ""))]
9868 /* Thumb-2 doesn't have mov pc, reg. Explicitly set the low bit of the
9869 address and use bx. */
9873 tmp = gen_reg_rtx (SImode);
9874 emit_insn (gen_iorsi3 (tmp, operands[0], GEN_INT(1)));
9880 ;; NB Never uses BX.
9881 (define_insn "*arm_indirect_jump"
9883 (match_operand:SI 0 "s_register_operand" "r"))]
9885 "mov%?\\t%|pc, %0\\t%@ indirect register jump"
9886 [(set_attr "predicable" "yes")
9887 (set_attr "type" "branch")]
9890 (define_insn "*load_indirect_jump"
9892 (match_operand:SI 0 "memory_operand" "m"))]
9894 "ldr%?\\t%|pc, %0\\t%@ indirect memory jump"
9895 [(set_attr "type" "load1")
9896 (set_attr "pool_range" "4096")
9897 (set_attr "neg_pool_range" "4084")
9898 (set_attr "predicable" "yes")]
9901 ;; NB Never uses BX.
9902 (define_insn "*thumb1_indirect_jump"
9904 (match_operand:SI 0 "register_operand" "l*r"))]
9907 [(set_attr "conds" "clob")
9908 (set_attr "length" "2")
9909 (set_attr "type" "branch")]
9919 if (TARGET_UNIFIED_ASM)
9922 return \"mov%?\\t%|r0, %|r0\\t%@ nop\";
9923 return \"mov\\tr8, r8\";
9925 [(set (attr "length")
9926 (if_then_else (eq_attr "is_thumb" "yes")
9929 (set_attr "type" "mov_reg")]
9933 [(trap_if (const_int 1) (const_int 0))]
9937 return \".inst\\t0xe7f000f0\";
9939 return \".inst\\t0xdeff\";
9941 [(set (attr "length")
9942 (if_then_else (eq_attr "is_thumb" "yes")
9945 (set_attr "type" "trap")
9946 (set_attr "conds" "unconditional")]
9950 ;; Patterns to allow combination of arithmetic, cond code and shifts
9952 (define_insn "*arith_shiftsi"
9953 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r")
9954 (match_operator:SI 1 "shiftable_operator"
9955 [(match_operator:SI 3 "shift_operator"
9956 [(match_operand:SI 4 "s_register_operand" "r,r,r,r")
9957 (match_operand:SI 5 "shift_amount_operand" "M,M,M,r")])
9958 (match_operand:SI 2 "s_register_operand" "rk,rk,r,rk")]))]
9960 "%i1%?\\t%0, %2, %4%S3"
9961 [(set_attr "predicable" "yes")
9962 (set_attr "shift" "4")
9963 (set_attr "arch" "a,t2,t2,a")
9964 ;; Thumb2 doesn't allow the stack pointer to be used for
9965 ;; operand1 for all operations other than add and sub. In this case
9966 ;; the minus operation is a candidate for an rsub and hence needs
9968 ;; We have to make sure to disable the fourth alternative if
9969 ;; the shift_operator is MULT, since otherwise the insn will
9970 ;; also match a multiply_accumulate pattern and validate_change
9971 ;; will allow a replacement of the constant with a register
9972 ;; despite the checks done in shift_operator.
9973 (set_attr_alternative "insn_enabled"
9974 [(const_string "yes")
9976 (match_operand:SI 1 "add_operator" "")
9977 (const_string "yes") (const_string "no"))
9978 (const_string "yes")
9980 (match_operand:SI 3 "mult_operator" "")
9981 (const_string "no") (const_string "yes"))])
9982 (set_attr "type" "alu_shift_imm,alu_shift_imm,alu_shift_imm,alu_shift_reg")])
9985 [(set (match_operand:SI 0 "s_register_operand" "")
9986 (match_operator:SI 1 "shiftable_operator"
9987 [(match_operator:SI 2 "shiftable_operator"
9988 [(match_operator:SI 3 "shift_operator"
9989 [(match_operand:SI 4 "s_register_operand" "")
9990 (match_operand:SI 5 "reg_or_int_operand" "")])
9991 (match_operand:SI 6 "s_register_operand" "")])
9992 (match_operand:SI 7 "arm_rhs_operand" "")]))
9993 (clobber (match_operand:SI 8 "s_register_operand" ""))]
9996 (match_op_dup 2 [(match_op_dup 3 [(match_dup 4) (match_dup 5)])
9999 (match_op_dup 1 [(match_dup 8) (match_dup 7)]))]
10002 (define_insn "*arith_shiftsi_compare0"
10003 [(set (reg:CC_NOOV CC_REGNUM)
10005 (match_operator:SI 1 "shiftable_operator"
10006 [(match_operator:SI 3 "shift_operator"
10007 [(match_operand:SI 4 "s_register_operand" "r,r")
10008 (match_operand:SI 5 "shift_amount_operand" "M,r")])
10009 (match_operand:SI 2 "s_register_operand" "r,r")])
10011 (set (match_operand:SI 0 "s_register_operand" "=r,r")
10012 (match_op_dup 1 [(match_op_dup 3 [(match_dup 4) (match_dup 5)])
10015 "%i1%.\\t%0, %2, %4%S3"
10016 [(set_attr "conds" "set")
10017 (set_attr "shift" "4")
10018 (set_attr "arch" "32,a")
10019 (set_attr "type" "alus_shift_imm,alus_shift_reg")])
10021 (define_insn "*arith_shiftsi_compare0_scratch"
10022 [(set (reg:CC_NOOV CC_REGNUM)
10024 (match_operator:SI 1 "shiftable_operator"
10025 [(match_operator:SI 3 "shift_operator"
10026 [(match_operand:SI 4 "s_register_operand" "r,r")
10027 (match_operand:SI 5 "shift_amount_operand" "M,r")])
10028 (match_operand:SI 2 "s_register_operand" "r,r")])
10030 (clobber (match_scratch:SI 0 "=r,r"))]
10032 "%i1%.\\t%0, %2, %4%S3"
10033 [(set_attr "conds" "set")
10034 (set_attr "shift" "4")
10035 (set_attr "arch" "32,a")
10036 (set_attr "type" "alus_shift_imm,alus_shift_reg")])
10038 (define_insn "*sub_shiftsi"
10039 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10040 (minus:SI (match_operand:SI 1 "s_register_operand" "r,r")
10041 (match_operator:SI 2 "shift_operator"
10042 [(match_operand:SI 3 "s_register_operand" "r,r")
10043 (match_operand:SI 4 "shift_amount_operand" "M,r")])))]
10045 "sub%?\\t%0, %1, %3%S2"
10046 [(set_attr "predicable" "yes")
10047 (set_attr "shift" "3")
10048 (set_attr "arch" "32,a")
10049 (set_attr "type" "alus_shift_imm,alus_shift_reg")])
10051 (define_insn "*sub_shiftsi_compare0"
10052 [(set (reg:CC_NOOV CC_REGNUM)
10054 (minus:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
10055 (match_operator:SI 2 "shift_operator"
10056 [(match_operand:SI 3 "s_register_operand" "r,r,r")
10057 (match_operand:SI 4 "shift_amount_operand" "M,r,M")]))
10059 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
10060 (minus:SI (match_dup 1)
10061 (match_op_dup 2 [(match_dup 3) (match_dup 4)])))]
10063 "sub%.\\t%0, %1, %3%S2"
10064 [(set_attr "conds" "set")
10065 (set_attr "shift" "3")
10066 (set_attr "arch" "32,a,a")
10067 (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")])
10069 (define_insn "*sub_shiftsi_compare0_scratch"
10070 [(set (reg:CC_NOOV CC_REGNUM)
10072 (minus:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
10073 (match_operator:SI 2 "shift_operator"
10074 [(match_operand:SI 3 "s_register_operand" "r,r,r")
10075 (match_operand:SI 4 "shift_amount_operand" "M,r,M")]))
10077 (clobber (match_scratch:SI 0 "=r,r,r"))]
10079 "sub%.\\t%0, %1, %3%S2"
10080 [(set_attr "conds" "set")
10081 (set_attr "shift" "3")
10082 (set_attr "arch" "32,a,a")
10083 (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")])
10086 (define_insn_and_split "*and_scc"
10087 [(set (match_operand:SI 0 "s_register_operand" "=r")
10088 (and:SI (match_operator:SI 1 "arm_comparison_operator"
10089 [(match_operand 2 "cc_register" "") (const_int 0)])
10090 (match_operand:SI 3 "s_register_operand" "r")))]
10092 "#" ; "mov%D1\\t%0, #0\;and%d1\\t%0, %3, #1"
10093 "&& reload_completed"
10094 [(cond_exec (match_dup 5) (set (match_dup 0) (const_int 0)))
10095 (cond_exec (match_dup 4) (set (match_dup 0)
10096 (and:SI (match_dup 3) (const_int 1))))]
10098 enum machine_mode mode = GET_MODE (operands[2]);
10099 enum rtx_code rc = GET_CODE (operands[1]);
10101 /* Note that operands[4] is the same as operands[1],
10102 but with VOIDmode as the result. */
10103 operands[4] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
10104 if (mode == CCFPmode || mode == CCFPEmode)
10105 rc = reverse_condition_maybe_unordered (rc);
10107 rc = reverse_condition (rc);
10108 operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
10110 [(set_attr "conds" "use")
10111 (set_attr "type" "multiple")
10112 (set_attr "length" "8")]
10115 (define_insn_and_split "*ior_scc"
10116 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10117 (ior:SI (match_operator:SI 1 "arm_comparison_operator"
10118 [(match_operand 2 "cc_register" "") (const_int 0)])
10119 (match_operand:SI 3 "s_register_operand" "0,?r")))]
10122 orr%d1\\t%0, %3, #1
10124 "&& reload_completed
10125 && REGNO (operands [0]) != REGNO (operands[3])"
10126 ;; && which_alternative == 1
10127 ; mov%D1\\t%0, %3\;orr%d1\\t%0, %3, #1
10128 [(cond_exec (match_dup 5) (set (match_dup 0) (match_dup 3)))
10129 (cond_exec (match_dup 4) (set (match_dup 0)
10130 (ior:SI (match_dup 3) (const_int 1))))]
10132 enum machine_mode mode = GET_MODE (operands[2]);
10133 enum rtx_code rc = GET_CODE (operands[1]);
10135 /* Note that operands[4] is the same as operands[1],
10136 but with VOIDmode as the result. */
10137 operands[4] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
10138 if (mode == CCFPmode || mode == CCFPEmode)
10139 rc = reverse_condition_maybe_unordered (rc);
10141 rc = reverse_condition (rc);
10142 operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
10144 [(set_attr "conds" "use")
10145 (set_attr "length" "4,8")
10146 (set_attr "type" "logic_imm,multiple")]
10149 ; A series of splitters for the compare_scc pattern below. Note that
10150 ; order is important.
10152 [(set (match_operand:SI 0 "s_register_operand" "")
10153 (lt:SI (match_operand:SI 1 "s_register_operand" "")
10155 (clobber (reg:CC CC_REGNUM))]
10156 "TARGET_32BIT && reload_completed"
10157 [(set (match_dup 0) (lshiftrt:SI (match_dup 1) (const_int 31)))])
10160 [(set (match_operand:SI 0 "s_register_operand" "")
10161 (ge:SI (match_operand:SI 1 "s_register_operand" "")
10163 (clobber (reg:CC CC_REGNUM))]
10164 "TARGET_32BIT && reload_completed"
10165 [(set (match_dup 0) (not:SI (match_dup 1)))
10166 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 31)))])
10169 [(set (match_operand:SI 0 "s_register_operand" "")
10170 (eq:SI (match_operand:SI 1 "s_register_operand" "")
10172 (clobber (reg:CC CC_REGNUM))]
10173 "arm_arch5 && TARGET_32BIT"
10174 [(set (match_dup 0) (clz:SI (match_dup 1)))
10175 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 5)))]
10179 [(set (match_operand:SI 0 "s_register_operand" "")
10180 (eq:SI (match_operand:SI 1 "s_register_operand" "")
10182 (clobber (reg:CC CC_REGNUM))]
10183 "TARGET_32BIT && reload_completed"
10185 [(set (reg:CC CC_REGNUM)
10186 (compare:CC (const_int 1) (match_dup 1)))
10188 (minus:SI (const_int 1) (match_dup 1)))])
10189 (cond_exec (ltu:CC (reg:CC CC_REGNUM) (const_int 0))
10190 (set (match_dup 0) (const_int 0)))])
10193 [(set (match_operand:SI 0 "s_register_operand" "")
10194 (ne:SI (match_operand:SI 1 "s_register_operand" "")
10195 (match_operand:SI 2 "const_int_operand" "")))
10196 (clobber (reg:CC CC_REGNUM))]
10197 "TARGET_32BIT && reload_completed"
10199 [(set (reg:CC CC_REGNUM)
10200 (compare:CC (match_dup 1) (match_dup 2)))
10201 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 3)))])
10202 (cond_exec (ne:CC (reg:CC CC_REGNUM) (const_int 0))
10203 (set (match_dup 0) (const_int 1)))]
10205 operands[3] = GEN_INT (-INTVAL (operands[2]));
10209 [(set (match_operand:SI 0 "s_register_operand" "")
10210 (ne:SI (match_operand:SI 1 "s_register_operand" "")
10211 (match_operand:SI 2 "arm_add_operand" "")))
10212 (clobber (reg:CC CC_REGNUM))]
10213 "TARGET_32BIT && reload_completed"
10215 [(set (reg:CC_NOOV CC_REGNUM)
10216 (compare:CC_NOOV (minus:SI (match_dup 1) (match_dup 2))
10218 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
10219 (cond_exec (ne:CC_NOOV (reg:CC_NOOV CC_REGNUM) (const_int 0))
10220 (set (match_dup 0) (const_int 1)))])
10222 (define_insn_and_split "*compare_scc"
10223 [(set (match_operand:SI 0 "s_register_operand" "=Ts,Ts")
10224 (match_operator:SI 1 "arm_comparison_operator"
10225 [(match_operand:SI 2 "s_register_operand" "r,r")
10226 (match_operand:SI 3 "arm_add_operand" "rI,L")]))
10227 (clobber (reg:CC CC_REGNUM))]
10230 "&& reload_completed"
10231 [(set (reg:CC CC_REGNUM) (compare:CC (match_dup 2) (match_dup 3)))
10232 (cond_exec (match_dup 4) (set (match_dup 0) (const_int 0)))
10233 (cond_exec (match_dup 5) (set (match_dup 0) (const_int 1)))]
10236 enum machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
10237 operands[2], operands[3]);
10238 enum rtx_code rc = GET_CODE (operands[1]);
10240 tmp1 = gen_rtx_REG (mode, CC_REGNUM);
10242 operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, tmp1, const0_rtx);
10243 if (mode == CCFPmode || mode == CCFPEmode)
10244 rc = reverse_condition_maybe_unordered (rc);
10246 rc = reverse_condition (rc);
10247 operands[4] = gen_rtx_fmt_ee (rc, VOIDmode, tmp1, const0_rtx);
10249 [(set_attr "type" "multiple")]
10252 ;; Attempt to improve the sequence generated by the compare_scc splitters
10253 ;; not to use conditional execution.
10255 ;; Rd = (eq (reg1) (const_int0)) // ARMv5
10259 [(set (reg:CC CC_REGNUM)
10260 (compare:CC (match_operand:SI 1 "register_operand" "")
10262 (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
10263 (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
10264 (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
10265 (set (match_dup 0) (const_int 1)))]
10266 "arm_arch5 && TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)"
10267 [(set (match_dup 0) (clz:SI (match_dup 1)))
10268 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 5)))]
10271 ;; Rd = (eq (reg1) (const_int0)) // !ARMv5
10273 ;; adc Rd, Rd, reg1
10275 [(set (reg:CC CC_REGNUM)
10276 (compare:CC (match_operand:SI 1 "register_operand" "")
10278 (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
10279 (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
10280 (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
10281 (set (match_dup 0) (const_int 1)))
10282 (match_scratch:SI 2 "r")]
10283 "TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)"
10285 [(set (reg:CC CC_REGNUM)
10286 (compare:CC (const_int 0) (match_dup 1)))
10287 (set (match_dup 2) (minus:SI (const_int 0) (match_dup 1)))])
10289 (plus:SI (plus:SI (match_dup 1) (match_dup 2))
10290 (geu:SI (reg:CC CC_REGNUM) (const_int 0))))]
10293 ;; Rd = (eq (reg1) (reg2/imm)) // ARMv5 and optimising for speed.
10294 ;; sub Rd, Reg1, reg2
10298 [(set (reg:CC CC_REGNUM)
10299 (compare:CC (match_operand:SI 1 "register_operand" "")
10300 (match_operand:SI 2 "arm_rhs_operand" "")))
10301 (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
10302 (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
10303 (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
10304 (set (match_dup 0) (const_int 1)))]
10305 "arm_arch5 && TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)
10306 && !(TARGET_THUMB2 && optimize_insn_for_size_p ())"
10307 [(set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))
10308 (set (match_dup 0) (clz:SI (match_dup 0)))
10309 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 5)))]
10313 ;; Rd = (eq (reg1) (reg2)) // ! ARMv5 or optimising for size.
10314 ;; sub T1, Reg1, reg2
10318 [(set (reg:CC CC_REGNUM)
10319 (compare:CC (match_operand:SI 1 "register_operand" "")
10320 (match_operand:SI 2 "arm_rhs_operand" "")))
10321 (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
10322 (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
10323 (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
10324 (set (match_dup 0) (const_int 1)))
10325 (match_scratch:SI 3 "r")]
10326 "TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)"
10327 [(set (match_dup 3) (match_dup 4))
10329 [(set (reg:CC CC_REGNUM)
10330 (compare:CC (const_int 0) (match_dup 3)))
10331 (set (match_dup 0) (minus:SI (const_int 0) (match_dup 3)))])
10333 (plus:SI (plus:SI (match_dup 0) (match_dup 3))
10334 (geu:SI (reg:CC CC_REGNUM) (const_int 0))))]
10336 if (CONST_INT_P (operands[2]))
10337 operands[4] = plus_constant (SImode, operands[1], -INTVAL (operands[2]));
10339 operands[4] = gen_rtx_MINUS (SImode, operands[1], operands[2]);
10342 (define_insn "*cond_move"
10343 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
10344 (if_then_else:SI (match_operator 3 "equality_operator"
10345 [(match_operator 4 "arm_comparison_operator"
10346 [(match_operand 5 "cc_register" "") (const_int 0)])
10348 (match_operand:SI 1 "arm_rhs_operand" "0,rI,?rI")
10349 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))]
10352 if (GET_CODE (operands[3]) == NE)
10354 if (which_alternative != 1)
10355 output_asm_insn (\"mov%D4\\t%0, %2\", operands);
10356 if (which_alternative != 0)
10357 output_asm_insn (\"mov%d4\\t%0, %1\", operands);
10360 if (which_alternative != 0)
10361 output_asm_insn (\"mov%D4\\t%0, %1\", operands);
10362 if (which_alternative != 1)
10363 output_asm_insn (\"mov%d4\\t%0, %2\", operands);
10366 [(set_attr "conds" "use")
10367 (set_attr "type" "mov_reg,mov_reg,multiple")
10368 (set_attr "length" "4,4,8")]
10371 (define_insn "*cond_arith"
10372 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10373 (match_operator:SI 5 "shiftable_operator"
10374 [(match_operator:SI 4 "arm_comparison_operator"
10375 [(match_operand:SI 2 "s_register_operand" "r,r")
10376 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
10377 (match_operand:SI 1 "s_register_operand" "0,?r")]))
10378 (clobber (reg:CC CC_REGNUM))]
10381 if (GET_CODE (operands[4]) == LT && operands[3] == const0_rtx)
10382 return \"%i5\\t%0, %1, %2, lsr #31\";
10384 output_asm_insn (\"cmp\\t%2, %3\", operands);
10385 if (GET_CODE (operands[5]) == AND)
10386 output_asm_insn (\"mov%D4\\t%0, #0\", operands);
10387 else if (GET_CODE (operands[5]) == MINUS)
10388 output_asm_insn (\"rsb%D4\\t%0, %1, #0\", operands);
10389 else if (which_alternative != 0)
10390 output_asm_insn (\"mov%D4\\t%0, %1\", operands);
10391 return \"%i5%d4\\t%0, %1, #1\";
10393 [(set_attr "conds" "clob")
10394 (set_attr "length" "12")
10395 (set_attr "type" "multiple")]
10398 (define_insn "*cond_sub"
10399 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10400 (minus:SI (match_operand:SI 1 "s_register_operand" "0,?r")
10401 (match_operator:SI 4 "arm_comparison_operator"
10402 [(match_operand:SI 2 "s_register_operand" "r,r")
10403 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))
10404 (clobber (reg:CC CC_REGNUM))]
10407 output_asm_insn (\"cmp\\t%2, %3\", operands);
10408 if (which_alternative != 0)
10409 output_asm_insn (\"mov%D4\\t%0, %1\", operands);
10410 return \"sub%d4\\t%0, %1, #1\";
10412 [(set_attr "conds" "clob")
10413 (set_attr "length" "8,12")
10414 (set_attr "type" "multiple")]
10417 (define_insn "*cmp_ite0"
10418 [(set (match_operand 6 "dominant_cc_register" "")
10421 (match_operator 4 "arm_comparison_operator"
10422 [(match_operand:SI 0 "s_register_operand"
10423 "l,l,l,r,r,r,r,r,r")
10424 (match_operand:SI 1 "arm_add_operand"
10425 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
10426 (match_operator:SI 5 "arm_comparison_operator"
10427 [(match_operand:SI 2 "s_register_operand"
10428 "l,r,r,l,l,r,r,r,r")
10429 (match_operand:SI 3 "arm_add_operand"
10430 "lPy,rI,L,lPy,lPy,rI,rI,L,L")])
10436 static const char * const cmp1[NUM_OF_COND_CMP][2] =
10438 {\"cmp%d5\\t%0, %1\",
10439 \"cmp%d4\\t%2, %3\"},
10440 {\"cmn%d5\\t%0, #%n1\",
10441 \"cmp%d4\\t%2, %3\"},
10442 {\"cmp%d5\\t%0, %1\",
10443 \"cmn%d4\\t%2, #%n3\"},
10444 {\"cmn%d5\\t%0, #%n1\",
10445 \"cmn%d4\\t%2, #%n3\"}
10447 static const char * const cmp2[NUM_OF_COND_CMP][2] =
10452 \"cmn\\t%0, #%n1\"},
10453 {\"cmn\\t%2, #%n3\",
10455 {\"cmn\\t%2, #%n3\",
10456 \"cmn\\t%0, #%n1\"}
10458 static const char * const ite[2] =
10463 static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
10464 CMP_CMP, CMN_CMP, CMP_CMP,
10465 CMN_CMP, CMP_CMN, CMN_CMN};
10467 comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4]));
10469 output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
10470 if (TARGET_THUMB2) {
10471 output_asm_insn (ite[swap], operands);
10473 output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
10476 [(set_attr "conds" "set")
10477 (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
10478 (set_attr "type" "multiple")
10479 (set_attr_alternative "length"
10485 (if_then_else (eq_attr "is_thumb" "no")
10488 (if_then_else (eq_attr "is_thumb" "no")
10491 (if_then_else (eq_attr "is_thumb" "no")
10494 (if_then_else (eq_attr "is_thumb" "no")
10499 (define_insn "*cmp_ite1"
10500 [(set (match_operand 6 "dominant_cc_register" "")
10503 (match_operator 4 "arm_comparison_operator"
10504 [(match_operand:SI 0 "s_register_operand"
10505 "l,l,l,r,r,r,r,r,r")
10506 (match_operand:SI 1 "arm_add_operand"
10507 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
10508 (match_operator:SI 5 "arm_comparison_operator"
10509 [(match_operand:SI 2 "s_register_operand"
10510 "l,r,r,l,l,r,r,r,r")
10511 (match_operand:SI 3 "arm_add_operand"
10512 "lPy,rI,L,lPy,lPy,rI,rI,L,L")])
10518 static const char * const cmp1[NUM_OF_COND_CMP][2] =
10522 {\"cmn\\t%0, #%n1\",
10525 \"cmn\\t%2, #%n3\"},
10526 {\"cmn\\t%0, #%n1\",
10527 \"cmn\\t%2, #%n3\"}
10529 static const char * const cmp2[NUM_OF_COND_CMP][2] =
10531 {\"cmp%d4\\t%2, %3\",
10532 \"cmp%D5\\t%0, %1\"},
10533 {\"cmp%d4\\t%2, %3\",
10534 \"cmn%D5\\t%0, #%n1\"},
10535 {\"cmn%d4\\t%2, #%n3\",
10536 \"cmp%D5\\t%0, %1\"},
10537 {\"cmn%d4\\t%2, #%n3\",
10538 \"cmn%D5\\t%0, #%n1\"}
10540 static const char * const ite[2] =
10545 static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
10546 CMP_CMP, CMN_CMP, CMP_CMP,
10547 CMN_CMP, CMP_CMN, CMN_CMN};
10549 comparison_dominates_p (GET_CODE (operands[5]),
10550 reverse_condition (GET_CODE (operands[4])));
10552 output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
10553 if (TARGET_THUMB2) {
10554 output_asm_insn (ite[swap], operands);
10556 output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
10559 [(set_attr "conds" "set")
10560 (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
10561 (set_attr_alternative "length"
10567 (if_then_else (eq_attr "is_thumb" "no")
10570 (if_then_else (eq_attr "is_thumb" "no")
10573 (if_then_else (eq_attr "is_thumb" "no")
10576 (if_then_else (eq_attr "is_thumb" "no")
10579 (set_attr "type" "multiple")]
10582 (define_insn "*cmp_and"
10583 [(set (match_operand 6 "dominant_cc_register" "")
10586 (match_operator 4 "arm_comparison_operator"
10587 [(match_operand:SI 0 "s_register_operand"
10588 "l,l,l,r,r,r,r,r,r")
10589 (match_operand:SI 1 "arm_add_operand"
10590 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
10591 (match_operator:SI 5 "arm_comparison_operator"
10592 [(match_operand:SI 2 "s_register_operand"
10593 "l,r,r,l,l,r,r,r,r")
10594 (match_operand:SI 3 "arm_add_operand"
10595 "lPy,rI,L,lPy,lPy,rI,rI,L,L")]))
10600 static const char *const cmp1[NUM_OF_COND_CMP][2] =
10602 {\"cmp%d5\\t%0, %1\",
10603 \"cmp%d4\\t%2, %3\"},
10604 {\"cmn%d5\\t%0, #%n1\",
10605 \"cmp%d4\\t%2, %3\"},
10606 {\"cmp%d5\\t%0, %1\",
10607 \"cmn%d4\\t%2, #%n3\"},
10608 {\"cmn%d5\\t%0, #%n1\",
10609 \"cmn%d4\\t%2, #%n3\"}
10611 static const char *const cmp2[NUM_OF_COND_CMP][2] =
10616 \"cmn\\t%0, #%n1\"},
10617 {\"cmn\\t%2, #%n3\",
10619 {\"cmn\\t%2, #%n3\",
10620 \"cmn\\t%0, #%n1\"}
10622 static const char *const ite[2] =
10627 static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
10628 CMP_CMP, CMN_CMP, CMP_CMP,
10629 CMN_CMP, CMP_CMN, CMN_CMN};
10631 comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4]));
10633 output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
10634 if (TARGET_THUMB2) {
10635 output_asm_insn (ite[swap], operands);
10637 output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
10640 [(set_attr "conds" "set")
10641 (set_attr "predicable" "no")
10642 (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
10643 (set_attr_alternative "length"
10649 (if_then_else (eq_attr "is_thumb" "no")
10652 (if_then_else (eq_attr "is_thumb" "no")
10655 (if_then_else (eq_attr "is_thumb" "no")
10658 (if_then_else (eq_attr "is_thumb" "no")
10661 (set_attr "type" "multiple")]
10664 (define_insn "*cmp_ior"
10665 [(set (match_operand 6 "dominant_cc_register" "")
10668 (match_operator 4 "arm_comparison_operator"
10669 [(match_operand:SI 0 "s_register_operand"
10670 "l,l,l,r,r,r,r,r,r")
10671 (match_operand:SI 1 "arm_add_operand"
10672 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
10673 (match_operator:SI 5 "arm_comparison_operator"
10674 [(match_operand:SI 2 "s_register_operand"
10675 "l,r,r,l,l,r,r,r,r")
10676 (match_operand:SI 3 "arm_add_operand"
10677 "lPy,rI,L,lPy,lPy,rI,rI,L,L")]))
10682 static const char *const cmp1[NUM_OF_COND_CMP][2] =
10686 {\"cmn\\t%0, #%n1\",
10689 \"cmn\\t%2, #%n3\"},
10690 {\"cmn\\t%0, #%n1\",
10691 \"cmn\\t%2, #%n3\"}
10693 static const char *const cmp2[NUM_OF_COND_CMP][2] =
10695 {\"cmp%D4\\t%2, %3\",
10696 \"cmp%D5\\t%0, %1\"},
10697 {\"cmp%D4\\t%2, %3\",
10698 \"cmn%D5\\t%0, #%n1\"},
10699 {\"cmn%D4\\t%2, #%n3\",
10700 \"cmp%D5\\t%0, %1\"},
10701 {\"cmn%D4\\t%2, #%n3\",
10702 \"cmn%D5\\t%0, #%n1\"}
10704 static const char *const ite[2] =
10709 static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
10710 CMP_CMP, CMN_CMP, CMP_CMP,
10711 CMN_CMP, CMP_CMN, CMN_CMN};
10713 comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4]));
10715 output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
10716 if (TARGET_THUMB2) {
10717 output_asm_insn (ite[swap], operands);
10719 output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
10723 [(set_attr "conds" "set")
10724 (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
10725 (set_attr_alternative "length"
10731 (if_then_else (eq_attr "is_thumb" "no")
10734 (if_then_else (eq_attr "is_thumb" "no")
10737 (if_then_else (eq_attr "is_thumb" "no")
10740 (if_then_else (eq_attr "is_thumb" "no")
10743 (set_attr "type" "multiple")]
10746 (define_insn_and_split "*ior_scc_scc"
10747 [(set (match_operand:SI 0 "s_register_operand" "=Ts")
10748 (ior:SI (match_operator:SI 3 "arm_comparison_operator"
10749 [(match_operand:SI 1 "s_register_operand" "r")
10750 (match_operand:SI 2 "arm_add_operand" "rIL")])
10751 (match_operator:SI 6 "arm_comparison_operator"
10752 [(match_operand:SI 4 "s_register_operand" "r")
10753 (match_operand:SI 5 "arm_add_operand" "rIL")])))
10754 (clobber (reg:CC CC_REGNUM))]
10756 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_OR_Y)
10759 "TARGET_32BIT && reload_completed"
10760 [(set (match_dup 7)
10763 (match_op_dup 3 [(match_dup 1) (match_dup 2)])
10764 (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
10766 (set (match_dup 0) (ne:SI (match_dup 7) (const_int 0)))]
10768 = gen_rtx_REG (arm_select_dominance_cc_mode (operands[3], operands[6],
10771 [(set_attr "conds" "clob")
10772 (set_attr "length" "16")
10773 (set_attr "type" "multiple")]
10776 ; If the above pattern is followed by a CMP insn, then the compare is
10777 ; redundant, since we can rework the conditional instruction that follows.
10778 (define_insn_and_split "*ior_scc_scc_cmp"
10779 [(set (match_operand 0 "dominant_cc_register" "")
10780 (compare (ior:SI (match_operator:SI 3 "arm_comparison_operator"
10781 [(match_operand:SI 1 "s_register_operand" "r")
10782 (match_operand:SI 2 "arm_add_operand" "rIL")])
10783 (match_operator:SI 6 "arm_comparison_operator"
10784 [(match_operand:SI 4 "s_register_operand" "r")
10785 (match_operand:SI 5 "arm_add_operand" "rIL")]))
10787 (set (match_operand:SI 7 "s_register_operand" "=Ts")
10788 (ior:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)])
10789 (match_op_dup 6 [(match_dup 4) (match_dup 5)])))]
10792 "TARGET_32BIT && reload_completed"
10793 [(set (match_dup 0)
10796 (match_op_dup 3 [(match_dup 1) (match_dup 2)])
10797 (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
10799 (set (match_dup 7) (ne:SI (match_dup 0) (const_int 0)))]
10801 [(set_attr "conds" "set")
10802 (set_attr "length" "16")
10803 (set_attr "type" "multiple")]
10806 (define_insn_and_split "*and_scc_scc"
10807 [(set (match_operand:SI 0 "s_register_operand" "=Ts")
10808 (and:SI (match_operator:SI 3 "arm_comparison_operator"
10809 [(match_operand:SI 1 "s_register_operand" "r")
10810 (match_operand:SI 2 "arm_add_operand" "rIL")])
10811 (match_operator:SI 6 "arm_comparison_operator"
10812 [(match_operand:SI 4 "s_register_operand" "r")
10813 (match_operand:SI 5 "arm_add_operand" "rIL")])))
10814 (clobber (reg:CC CC_REGNUM))]
10816 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y)
10819 "TARGET_32BIT && reload_completed
10820 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y)
10822 [(set (match_dup 7)
10825 (match_op_dup 3 [(match_dup 1) (match_dup 2)])
10826 (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
10828 (set (match_dup 0) (ne:SI (match_dup 7) (const_int 0)))]
10830 = gen_rtx_REG (arm_select_dominance_cc_mode (operands[3], operands[6],
10833 [(set_attr "conds" "clob")
10834 (set_attr "length" "16")
10835 (set_attr "type" "multiple")]
10838 ; If the above pattern is followed by a CMP insn, then the compare is
10839 ; redundant, since we can rework the conditional instruction that follows.
10840 (define_insn_and_split "*and_scc_scc_cmp"
10841 [(set (match_operand 0 "dominant_cc_register" "")
10842 (compare (and:SI (match_operator:SI 3 "arm_comparison_operator"
10843 [(match_operand:SI 1 "s_register_operand" "r")
10844 (match_operand:SI 2 "arm_add_operand" "rIL")])
10845 (match_operator:SI 6 "arm_comparison_operator"
10846 [(match_operand:SI 4 "s_register_operand" "r")
10847 (match_operand:SI 5 "arm_add_operand" "rIL")]))
10849 (set (match_operand:SI 7 "s_register_operand" "=Ts")
10850 (and:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)])
10851 (match_op_dup 6 [(match_dup 4) (match_dup 5)])))]
10854 "TARGET_32BIT && reload_completed"
10855 [(set (match_dup 0)
10858 (match_op_dup 3 [(match_dup 1) (match_dup 2)])
10859 (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
10861 (set (match_dup 7) (ne:SI (match_dup 0) (const_int 0)))]
10863 [(set_attr "conds" "set")
10864 (set_attr "length" "16")
10865 (set_attr "type" "multiple")]
10868 ;; If there is no dominance in the comparison, then we can still save an
10869 ;; instruction in the AND case, since we can know that the second compare
10870 ;; need only zero the value if false (if true, then the value is already
10872 (define_insn_and_split "*and_scc_scc_nodom"
10873 [(set (match_operand:SI 0 "s_register_operand" "=&Ts,&Ts,&Ts")
10874 (and:SI (match_operator:SI 3 "arm_comparison_operator"
10875 [(match_operand:SI 1 "s_register_operand" "r,r,0")
10876 (match_operand:SI 2 "arm_add_operand" "rIL,0,rIL")])
10877 (match_operator:SI 6 "arm_comparison_operator"
10878 [(match_operand:SI 4 "s_register_operand" "r,r,r")
10879 (match_operand:SI 5 "arm_add_operand" "rIL,rIL,rIL")])))
10880 (clobber (reg:CC CC_REGNUM))]
10882 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y)
10885 "TARGET_32BIT && reload_completed"
10886 [(parallel [(set (match_dup 0)
10887 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
10888 (clobber (reg:CC CC_REGNUM))])
10889 (set (match_dup 7) (match_op_dup 8 [(match_dup 4) (match_dup 5)]))
10891 (if_then_else:SI (match_op_dup 6 [(match_dup 7) (const_int 0)])
10894 "operands[7] = gen_rtx_REG (SELECT_CC_MODE (GET_CODE (operands[6]),
10895 operands[4], operands[5]),
10897 operands[8] = gen_rtx_COMPARE (GET_MODE (operands[7]), operands[4],
10899 [(set_attr "conds" "clob")
10900 (set_attr "length" "20")
10901 (set_attr "type" "multiple")]
10905 [(set (reg:CC_NOOV CC_REGNUM)
10906 (compare:CC_NOOV (ior:SI
10907 (and:SI (match_operand:SI 0 "s_register_operand" "")
10909 (match_operator:SI 1 "arm_comparison_operator"
10910 [(match_operand:SI 2 "s_register_operand" "")
10911 (match_operand:SI 3 "arm_add_operand" "")]))
10913 (clobber (match_operand:SI 4 "s_register_operand" ""))]
10915 [(set (match_dup 4)
10916 (ior:SI (match_op_dup 1 [(match_dup 2) (match_dup 3)])
10918 (set (reg:CC_NOOV CC_REGNUM)
10919 (compare:CC_NOOV (and:SI (match_dup 4) (const_int 1))
10924 [(set (reg:CC_NOOV CC_REGNUM)
10925 (compare:CC_NOOV (ior:SI
10926 (match_operator:SI 1 "arm_comparison_operator"
10927 [(match_operand:SI 2 "s_register_operand" "")
10928 (match_operand:SI 3 "arm_add_operand" "")])
10929 (and:SI (match_operand:SI 0 "s_register_operand" "")
10932 (clobber (match_operand:SI 4 "s_register_operand" ""))]
10934 [(set (match_dup 4)
10935 (ior:SI (match_op_dup 1 [(match_dup 2) (match_dup 3)])
10937 (set (reg:CC_NOOV CC_REGNUM)
10938 (compare:CC_NOOV (and:SI (match_dup 4) (const_int 1))
10941 ;; ??? The conditional patterns above need checking for Thumb-2 usefulness
10943 (define_insn_and_split "*negscc"
10944 [(set (match_operand:SI 0 "s_register_operand" "=r")
10945 (neg:SI (match_operator 3 "arm_comparison_operator"
10946 [(match_operand:SI 1 "s_register_operand" "r")
10947 (match_operand:SI 2 "arm_rhs_operand" "rI")])))
10948 (clobber (reg:CC CC_REGNUM))]
10951 "&& reload_completed"
10954 rtx cc_reg = gen_rtx_REG (CCmode, CC_REGNUM);
10956 if (GET_CODE (operands[3]) == LT && operands[2] == const0_rtx)
10958 /* Emit mov\\t%0, %1, asr #31 */
10959 emit_insn (gen_rtx_SET (VOIDmode,
10961 gen_rtx_ASHIFTRT (SImode,
10966 else if (GET_CODE (operands[3]) == NE)
10968 /* Emit subs\\t%0, %1, %2\;mvnne\\t%0, #0 */
10969 if (CONST_INT_P (operands[2]))
10970 emit_insn (gen_cmpsi2_addneg (operands[0], operands[1], operands[2],
10971 GEN_INT (- INTVAL (operands[2]))));
10973 emit_insn (gen_subsi3_compare (operands[0], operands[1], operands[2]));
10975 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
10976 gen_rtx_NE (SImode,
10979 gen_rtx_SET (SImode,
10986 /* Emit: cmp\\t%1, %2\;mov%D3\\t%0, #0\;mvn%d3\\t%0, #0 */
10987 emit_insn (gen_rtx_SET (VOIDmode,
10989 gen_rtx_COMPARE (CCmode, operands[1], operands[2])));
10990 enum rtx_code rc = GET_CODE (operands[3]);
10992 rc = reverse_condition (rc);
10993 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
10994 gen_rtx_fmt_ee (rc,
10998 gen_rtx_SET (VOIDmode, operands[0], const0_rtx)));
10999 rc = GET_CODE (operands[3]);
11000 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
11001 gen_rtx_fmt_ee (rc,
11005 gen_rtx_SET (VOIDmode,
11012 [(set_attr "conds" "clob")
11013 (set_attr "length" "12")
11014 (set_attr "type" "multiple")]
11017 (define_insn_and_split "movcond_addsi"
11018 [(set (match_operand:SI 0 "s_register_operand" "=r,l,r")
11020 (match_operator 5 "comparison_operator"
11021 [(plus:SI (match_operand:SI 3 "s_register_operand" "r,r,r")
11022 (match_operand:SI 4 "arm_add_operand" "rIL,rIL,rIL"))
11024 (match_operand:SI 1 "arm_rhs_operand" "rI,rPy,r")
11025 (match_operand:SI 2 "arm_rhs_operand" "rI,rPy,r")))
11026 (clobber (reg:CC CC_REGNUM))]
11029 "&& reload_completed"
11030 [(set (reg:CC_NOOV CC_REGNUM)
11032 (plus:SI (match_dup 3)
11035 (set (match_dup 0) (match_dup 1))
11036 (cond_exec (match_dup 6)
11037 (set (match_dup 0) (match_dup 2)))]
11040 enum machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[5]),
11041 operands[3], operands[4]);
11042 enum rtx_code rc = GET_CODE (operands[5]);
11044 operands[6] = gen_rtx_REG (mode, CC_REGNUM);
11045 gcc_assert (!(mode == CCFPmode || mode == CCFPEmode));
11046 rc = reverse_condition (rc);
11048 operands[6] = gen_rtx_fmt_ee (rc, VOIDmode, operands[6], const0_rtx);
11051 [(set_attr "conds" "clob")
11052 (set_attr "enabled_for_depr_it" "no,yes,yes")
11053 (set_attr "type" "multiple")]
11056 (define_insn "movcond"
11057 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
11059 (match_operator 5 "arm_comparison_operator"
11060 [(match_operand:SI 3 "s_register_operand" "r,r,r")
11061 (match_operand:SI 4 "arm_add_operand" "rIL,rIL,rIL")])
11062 (match_operand:SI 1 "arm_rhs_operand" "0,rI,?rI")
11063 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
11064 (clobber (reg:CC CC_REGNUM))]
11067 if (GET_CODE (operands[5]) == LT
11068 && (operands[4] == const0_rtx))
11070 if (which_alternative != 1 && REG_P (operands[1]))
11072 if (operands[2] == const0_rtx)
11073 return \"and\\t%0, %1, %3, asr #31\";
11074 return \"ands\\t%0, %1, %3, asr #32\;movcc\\t%0, %2\";
11076 else if (which_alternative != 0 && REG_P (operands[2]))
11078 if (operands[1] == const0_rtx)
11079 return \"bic\\t%0, %2, %3, asr #31\";
11080 return \"bics\\t%0, %2, %3, asr #32\;movcs\\t%0, %1\";
11082 /* The only case that falls through to here is when both ops 1 & 2
11086 if (GET_CODE (operands[5]) == GE
11087 && (operands[4] == const0_rtx))
11089 if (which_alternative != 1 && REG_P (operands[1]))
11091 if (operands[2] == const0_rtx)
11092 return \"bic\\t%0, %1, %3, asr #31\";
11093 return \"bics\\t%0, %1, %3, asr #32\;movcs\\t%0, %2\";
11095 else if (which_alternative != 0 && REG_P (operands[2]))
11097 if (operands[1] == const0_rtx)
11098 return \"and\\t%0, %2, %3, asr #31\";
11099 return \"ands\\t%0, %2, %3, asr #32\;movcc\\t%0, %1\";
11101 /* The only case that falls through to here is when both ops 1 & 2
11104 if (CONST_INT_P (operands[4])
11105 && !const_ok_for_arm (INTVAL (operands[4])))
11106 output_asm_insn (\"cmn\\t%3, #%n4\", operands);
11108 output_asm_insn (\"cmp\\t%3, %4\", operands);
11109 if (which_alternative != 0)
11110 output_asm_insn (\"mov%d5\\t%0, %1\", operands);
11111 if (which_alternative != 1)
11112 output_asm_insn (\"mov%D5\\t%0, %2\", operands);
11115 [(set_attr "conds" "clob")
11116 (set_attr "length" "8,8,12")
11117 (set_attr "type" "multiple")]
11120 ;; ??? The patterns below need checking for Thumb-2 usefulness.
11122 (define_insn "*ifcompare_plus_move"
11123 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
11124 (if_then_else:SI (match_operator 6 "arm_comparison_operator"
11125 [(match_operand:SI 4 "s_register_operand" "r,r")
11126 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
11128 (match_operand:SI 2 "s_register_operand" "r,r")
11129 (match_operand:SI 3 "arm_add_operand" "rIL,rIL"))
11130 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))
11131 (clobber (reg:CC CC_REGNUM))]
11134 [(set_attr "conds" "clob")
11135 (set_attr "length" "8,12")
11136 (set_attr "type" "multiple")]
11139 (define_insn "*if_plus_move"
11140 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r")
11142 (match_operator 4 "arm_comparison_operator"
11143 [(match_operand 5 "cc_register" "") (const_int 0)])
11145 (match_operand:SI 2 "s_register_operand" "r,r,r,r")
11146 (match_operand:SI 3 "arm_add_operand" "rI,L,rI,L"))
11147 (match_operand:SI 1 "arm_rhs_operand" "0,0,?rI,?rI")))]
11150 add%d4\\t%0, %2, %3
11151 sub%d4\\t%0, %2, #%n3
11152 add%d4\\t%0, %2, %3\;mov%D4\\t%0, %1
11153 sub%d4\\t%0, %2, #%n3\;mov%D4\\t%0, %1"
11154 [(set_attr "conds" "use")
11155 (set_attr "length" "4,4,8,8")
11156 (set_attr_alternative "type"
11157 [(if_then_else (match_operand 3 "const_int_operand" "")
11158 (const_string "alu_imm" )
11159 (const_string "alu_reg"))
11160 (const_string "alu_imm")
11161 (const_string "alu_reg")
11162 (const_string "alu_reg")])]
11165 (define_insn "*ifcompare_move_plus"
11166 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
11167 (if_then_else:SI (match_operator 6 "arm_comparison_operator"
11168 [(match_operand:SI 4 "s_register_operand" "r,r")
11169 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
11170 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
11172 (match_operand:SI 2 "s_register_operand" "r,r")
11173 (match_operand:SI 3 "arm_add_operand" "rIL,rIL"))))
11174 (clobber (reg:CC CC_REGNUM))]
11177 [(set_attr "conds" "clob")
11178 (set_attr "length" "8,12")
11179 (set_attr "type" "multiple")]
11182 (define_insn "*if_move_plus"
11183 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r")
11185 (match_operator 4 "arm_comparison_operator"
11186 [(match_operand 5 "cc_register" "") (const_int 0)])
11187 (match_operand:SI 1 "arm_rhs_operand" "0,0,?rI,?rI")
11189 (match_operand:SI 2 "s_register_operand" "r,r,r,r")
11190 (match_operand:SI 3 "arm_add_operand" "rI,L,rI,L"))))]
11193 add%D4\\t%0, %2, %3
11194 sub%D4\\t%0, %2, #%n3
11195 add%D4\\t%0, %2, %3\;mov%d4\\t%0, %1
11196 sub%D4\\t%0, %2, #%n3\;mov%d4\\t%0, %1"
11197 [(set_attr "conds" "use")
11198 (set_attr "length" "4,4,8,8")
11199 (set_attr "type" "alu_reg,alu_imm,multiple,multiple")]
11202 (define_insn "*ifcompare_arith_arith"
11203 [(set (match_operand:SI 0 "s_register_operand" "=r")
11204 (if_then_else:SI (match_operator 9 "arm_comparison_operator"
11205 [(match_operand:SI 5 "s_register_operand" "r")
11206 (match_operand:SI 6 "arm_add_operand" "rIL")])
11207 (match_operator:SI 8 "shiftable_operator"
11208 [(match_operand:SI 1 "s_register_operand" "r")
11209 (match_operand:SI 2 "arm_rhs_operand" "rI")])
11210 (match_operator:SI 7 "shiftable_operator"
11211 [(match_operand:SI 3 "s_register_operand" "r")
11212 (match_operand:SI 4 "arm_rhs_operand" "rI")])))
11213 (clobber (reg:CC CC_REGNUM))]
11216 [(set_attr "conds" "clob")
11217 (set_attr "length" "12")
11218 (set_attr "type" "multiple")]
11221 (define_insn "*if_arith_arith"
11222 [(set (match_operand:SI 0 "s_register_operand" "=r")
11223 (if_then_else:SI (match_operator 5 "arm_comparison_operator"
11224 [(match_operand 8 "cc_register" "") (const_int 0)])
11225 (match_operator:SI 6 "shiftable_operator"
11226 [(match_operand:SI 1 "s_register_operand" "r")
11227 (match_operand:SI 2 "arm_rhs_operand" "rI")])
11228 (match_operator:SI 7 "shiftable_operator"
11229 [(match_operand:SI 3 "s_register_operand" "r")
11230 (match_operand:SI 4 "arm_rhs_operand" "rI")])))]
11232 "%I6%d5\\t%0, %1, %2\;%I7%D5\\t%0, %3, %4"
11233 [(set_attr "conds" "use")
11234 (set_attr "length" "8")
11235 (set_attr "type" "multiple")]
11238 (define_insn "*ifcompare_arith_move"
11239 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
11240 (if_then_else:SI (match_operator 6 "arm_comparison_operator"
11241 [(match_operand:SI 2 "s_register_operand" "r,r")
11242 (match_operand:SI 3 "arm_add_operand" "rIL,rIL")])
11243 (match_operator:SI 7 "shiftable_operator"
11244 [(match_operand:SI 4 "s_register_operand" "r,r")
11245 (match_operand:SI 5 "arm_rhs_operand" "rI,rI")])
11246 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))
11247 (clobber (reg:CC CC_REGNUM))]
11250 /* If we have an operation where (op x 0) is the identity operation and
11251 the conditional operator is LT or GE and we are comparing against zero and
11252 everything is in registers then we can do this in two instructions. */
11253 if (operands[3] == const0_rtx
11254 && GET_CODE (operands[7]) != AND
11255 && REG_P (operands[5])
11256 && REG_P (operands[1])
11257 && REGNO (operands[1]) == REGNO (operands[4])
11258 && REGNO (operands[4]) != REGNO (operands[0]))
11260 if (GET_CODE (operands[6]) == LT)
11261 return \"and\\t%0, %5, %2, asr #31\;%I7\\t%0, %4, %0\";
11262 else if (GET_CODE (operands[6]) == GE)
11263 return \"bic\\t%0, %5, %2, asr #31\;%I7\\t%0, %4, %0\";
11265 if (CONST_INT_P (operands[3])
11266 && !const_ok_for_arm (INTVAL (operands[3])))
11267 output_asm_insn (\"cmn\\t%2, #%n3\", operands);
11269 output_asm_insn (\"cmp\\t%2, %3\", operands);
11270 output_asm_insn (\"%I7%d6\\t%0, %4, %5\", operands);
11271 if (which_alternative != 0)
11272 return \"mov%D6\\t%0, %1\";
11275 [(set_attr "conds" "clob")
11276 (set_attr "length" "8,12")
11277 (set_attr "type" "multiple")]
11280 (define_insn "*if_arith_move"
11281 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
11282 (if_then_else:SI (match_operator 4 "arm_comparison_operator"
11283 [(match_operand 6 "cc_register" "") (const_int 0)])
11284 (match_operator:SI 5 "shiftable_operator"
11285 [(match_operand:SI 2 "s_register_operand" "r,r")
11286 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
11287 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))]
11290 %I5%d4\\t%0, %2, %3
11291 %I5%d4\\t%0, %2, %3\;mov%D4\\t%0, %1"
11292 [(set_attr "conds" "use")
11293 (set_attr "length" "4,8")
11294 (set_attr "type" "alu_shift_reg,multiple")]
11297 (define_insn "*ifcompare_move_arith"
11298 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
11299 (if_then_else:SI (match_operator 6 "arm_comparison_operator"
11300 [(match_operand:SI 4 "s_register_operand" "r,r")
11301 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
11302 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
11303 (match_operator:SI 7 "shiftable_operator"
11304 [(match_operand:SI 2 "s_register_operand" "r,r")
11305 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))
11306 (clobber (reg:CC CC_REGNUM))]
11309 /* If we have an operation where (op x 0) is the identity operation and
11310 the conditional operator is LT or GE and we are comparing against zero and
11311 everything is in registers then we can do this in two instructions */
11312 if (operands[5] == const0_rtx
11313 && GET_CODE (operands[7]) != AND
11314 && REG_P (operands[3])
11315 && REG_P (operands[1])
11316 && REGNO (operands[1]) == REGNO (operands[2])
11317 && REGNO (operands[2]) != REGNO (operands[0]))
11319 if (GET_CODE (operands[6]) == GE)
11320 return \"and\\t%0, %3, %4, asr #31\;%I7\\t%0, %2, %0\";
11321 else if (GET_CODE (operands[6]) == LT)
11322 return \"bic\\t%0, %3, %4, asr #31\;%I7\\t%0, %2, %0\";
11325 if (CONST_INT_P (operands[5])
11326 && !const_ok_for_arm (INTVAL (operands[5])))
11327 output_asm_insn (\"cmn\\t%4, #%n5\", operands);
11329 output_asm_insn (\"cmp\\t%4, %5\", operands);
11331 if (which_alternative != 0)
11332 output_asm_insn (\"mov%d6\\t%0, %1\", operands);
11333 return \"%I7%D6\\t%0, %2, %3\";
11335 [(set_attr "conds" "clob")
11336 (set_attr "length" "8,12")
11337 (set_attr "type" "multiple")]
11340 (define_insn "*if_move_arith"
11341 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
11343 (match_operator 4 "arm_comparison_operator"
11344 [(match_operand 6 "cc_register" "") (const_int 0)])
11345 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
11346 (match_operator:SI 5 "shiftable_operator"
11347 [(match_operand:SI 2 "s_register_operand" "r,r")
11348 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))]
11351 %I5%D4\\t%0, %2, %3
11352 %I5%D4\\t%0, %2, %3\;mov%d4\\t%0, %1"
11353 [(set_attr "conds" "use")
11354 (set_attr "length" "4,8")
11355 (set_attr "type" "alu_shift_reg,multiple")]
11358 (define_insn "*ifcompare_move_not"
11359 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
11361 (match_operator 5 "arm_comparison_operator"
11362 [(match_operand:SI 3 "s_register_operand" "r,r")
11363 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
11364 (match_operand:SI 1 "arm_not_operand" "0,?rIK")
11366 (match_operand:SI 2 "s_register_operand" "r,r"))))
11367 (clobber (reg:CC CC_REGNUM))]
11370 [(set_attr "conds" "clob")
11371 (set_attr "length" "8,12")
11372 (set_attr "type" "multiple")]
11375 (define_insn "*if_move_not"
11376 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
11378 (match_operator 4 "arm_comparison_operator"
11379 [(match_operand 3 "cc_register" "") (const_int 0)])
11380 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")
11381 (not:SI (match_operand:SI 2 "s_register_operand" "r,r,r"))))]
11385 mov%d4\\t%0, %1\;mvn%D4\\t%0, %2
11386 mvn%d4\\t%0, #%B1\;mvn%D4\\t%0, %2"
11387 [(set_attr "conds" "use")
11388 (set_attr "type" "mvn_reg")
11389 (set_attr "length" "4,8,8")
11390 (set_attr "type" "mvn_reg,multiple,multiple")]
11393 (define_insn "*ifcompare_not_move"
11394 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
11396 (match_operator 5 "arm_comparison_operator"
11397 [(match_operand:SI 3 "s_register_operand" "r,r")
11398 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
11400 (match_operand:SI 2 "s_register_operand" "r,r"))
11401 (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
11402 (clobber (reg:CC CC_REGNUM))]
11405 [(set_attr "conds" "clob")
11406 (set_attr "length" "8,12")
11407 (set_attr "type" "multiple")]
11410 (define_insn "*if_not_move"
11411 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
11413 (match_operator 4 "arm_comparison_operator"
11414 [(match_operand 3 "cc_register" "") (const_int 0)])
11415 (not:SI (match_operand:SI 2 "s_register_operand" "r,r,r"))
11416 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")))]
11420 mov%D4\\t%0, %1\;mvn%d4\\t%0, %2
11421 mvn%D4\\t%0, #%B1\;mvn%d4\\t%0, %2"
11422 [(set_attr "conds" "use")
11423 (set_attr "type" "mvn_reg,multiple,multiple")
11424 (set_attr "length" "4,8,8")]
11427 (define_insn "*ifcompare_shift_move"
11428 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
11430 (match_operator 6 "arm_comparison_operator"
11431 [(match_operand:SI 4 "s_register_operand" "r,r")
11432 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
11433 (match_operator:SI 7 "shift_operator"
11434 [(match_operand:SI 2 "s_register_operand" "r,r")
11435 (match_operand:SI 3 "arm_rhs_operand" "rM,rM")])
11436 (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
11437 (clobber (reg:CC CC_REGNUM))]
11440 [(set_attr "conds" "clob")
11441 (set_attr "length" "8,12")
11442 (set_attr "type" "multiple")]
11445 (define_insn "*if_shift_move"
11446 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
11448 (match_operator 5 "arm_comparison_operator"
11449 [(match_operand 6 "cc_register" "") (const_int 0)])
11450 (match_operator:SI 4 "shift_operator"
11451 [(match_operand:SI 2 "s_register_operand" "r,r,r")
11452 (match_operand:SI 3 "arm_rhs_operand" "rM,rM,rM")])
11453 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")))]
11457 mov%D5\\t%0, %1\;mov%d5\\t%0, %2%S4
11458 mvn%D5\\t%0, #%B1\;mov%d5\\t%0, %2%S4"
11459 [(set_attr "conds" "use")
11460 (set_attr "shift" "2")
11461 (set_attr "length" "4,8,8")
11462 (set_attr "type" "mov_shift_reg,multiple,multiple")]
11465 (define_insn "*ifcompare_move_shift"
11466 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
11468 (match_operator 6 "arm_comparison_operator"
11469 [(match_operand:SI 4 "s_register_operand" "r,r")
11470 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
11471 (match_operand:SI 1 "arm_not_operand" "0,?rIK")
11472 (match_operator:SI 7 "shift_operator"
11473 [(match_operand:SI 2 "s_register_operand" "r,r")
11474 (match_operand:SI 3 "arm_rhs_operand" "rM,rM")])))
11475 (clobber (reg:CC CC_REGNUM))]
11478 [(set_attr "conds" "clob")
11479 (set_attr "length" "8,12")
11480 (set_attr "type" "multiple")]
11483 (define_insn "*if_move_shift"
11484 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
11486 (match_operator 5 "arm_comparison_operator"
11487 [(match_operand 6 "cc_register" "") (const_int 0)])
11488 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")
11489 (match_operator:SI 4 "shift_operator"
11490 [(match_operand:SI 2 "s_register_operand" "r,r,r")
11491 (match_operand:SI 3 "arm_rhs_operand" "rM,rM,rM")])))]
11495 mov%d5\\t%0, %1\;mov%D5\\t%0, %2%S4
11496 mvn%d5\\t%0, #%B1\;mov%D5\\t%0, %2%S4"
11497 [(set_attr "conds" "use")
11498 (set_attr "shift" "2")
11499 (set_attr "length" "4,8,8")
11500 (set_attr "type" "mov_shift_reg,multiple,multiple")]
11503 (define_insn "*ifcompare_shift_shift"
11504 [(set (match_operand:SI 0 "s_register_operand" "=r")
11506 (match_operator 7 "arm_comparison_operator"
11507 [(match_operand:SI 5 "s_register_operand" "r")
11508 (match_operand:SI 6 "arm_add_operand" "rIL")])
11509 (match_operator:SI 8 "shift_operator"
11510 [(match_operand:SI 1 "s_register_operand" "r")
11511 (match_operand:SI 2 "arm_rhs_operand" "rM")])
11512 (match_operator:SI 9 "shift_operator"
11513 [(match_operand:SI 3 "s_register_operand" "r")
11514 (match_operand:SI 4 "arm_rhs_operand" "rM")])))
11515 (clobber (reg:CC CC_REGNUM))]
11518 [(set_attr "conds" "clob")
11519 (set_attr "length" "12")
11520 (set_attr "type" "multiple")]
11523 (define_insn "*if_shift_shift"
11524 [(set (match_operand:SI 0 "s_register_operand" "=r")
11526 (match_operator 5 "arm_comparison_operator"
11527 [(match_operand 8 "cc_register" "") (const_int 0)])
11528 (match_operator:SI 6 "shift_operator"
11529 [(match_operand:SI 1 "s_register_operand" "r")
11530 (match_operand:SI 2 "arm_rhs_operand" "rM")])
11531 (match_operator:SI 7 "shift_operator"
11532 [(match_operand:SI 3 "s_register_operand" "r")
11533 (match_operand:SI 4 "arm_rhs_operand" "rM")])))]
11535 "mov%d5\\t%0, %1%S6\;mov%D5\\t%0, %3%S7"
11536 [(set_attr "conds" "use")
11537 (set_attr "shift" "1")
11538 (set_attr "length" "8")
11539 (set (attr "type") (if_then_else
11540 (and (match_operand 2 "const_int_operand" "")
11541 (match_operand 4 "const_int_operand" ""))
11542 (const_string "mov_shift")
11543 (const_string "mov_shift_reg")))]
11546 (define_insn "*ifcompare_not_arith"
11547 [(set (match_operand:SI 0 "s_register_operand" "=r")
11549 (match_operator 6 "arm_comparison_operator"
11550 [(match_operand:SI 4 "s_register_operand" "r")
11551 (match_operand:SI 5 "arm_add_operand" "rIL")])
11552 (not:SI (match_operand:SI 1 "s_register_operand" "r"))
11553 (match_operator:SI 7 "shiftable_operator"
11554 [(match_operand:SI 2 "s_register_operand" "r")
11555 (match_operand:SI 3 "arm_rhs_operand" "rI")])))
11556 (clobber (reg:CC CC_REGNUM))]
11559 [(set_attr "conds" "clob")
11560 (set_attr "length" "12")
11561 (set_attr "type" "multiple")]
11564 (define_insn "*if_not_arith"
11565 [(set (match_operand:SI 0 "s_register_operand" "=r")
11567 (match_operator 5 "arm_comparison_operator"
11568 [(match_operand 4 "cc_register" "") (const_int 0)])
11569 (not:SI (match_operand:SI 1 "s_register_operand" "r"))
11570 (match_operator:SI 6 "shiftable_operator"
11571 [(match_operand:SI 2 "s_register_operand" "r")
11572 (match_operand:SI 3 "arm_rhs_operand" "rI")])))]
11574 "mvn%d5\\t%0, %1\;%I6%D5\\t%0, %2, %3"
11575 [(set_attr "conds" "use")
11576 (set_attr "type" "mvn_reg")
11577 (set_attr "length" "8")]
11580 (define_insn "*ifcompare_arith_not"
11581 [(set (match_operand:SI 0 "s_register_operand" "=r")
11583 (match_operator 6 "arm_comparison_operator"
11584 [(match_operand:SI 4 "s_register_operand" "r")
11585 (match_operand:SI 5 "arm_add_operand" "rIL")])
11586 (match_operator:SI 7 "shiftable_operator"
11587 [(match_operand:SI 2 "s_register_operand" "r")
11588 (match_operand:SI 3 "arm_rhs_operand" "rI")])
11589 (not:SI (match_operand:SI 1 "s_register_operand" "r"))))
11590 (clobber (reg:CC CC_REGNUM))]
11593 [(set_attr "conds" "clob")
11594 (set_attr "length" "12")
11595 (set_attr "type" "multiple")]
11598 (define_insn "*if_arith_not"
11599 [(set (match_operand:SI 0 "s_register_operand" "=r")
11601 (match_operator 5 "arm_comparison_operator"
11602 [(match_operand 4 "cc_register" "") (const_int 0)])
11603 (match_operator:SI 6 "shiftable_operator"
11604 [(match_operand:SI 2 "s_register_operand" "r")
11605 (match_operand:SI 3 "arm_rhs_operand" "rI")])
11606 (not:SI (match_operand:SI 1 "s_register_operand" "r"))))]
11608 "mvn%D5\\t%0, %1\;%I6%d5\\t%0, %2, %3"
11609 [(set_attr "conds" "use")
11610 (set_attr "type" "multiple")
11611 (set_attr "length" "8")]
11614 (define_insn "*ifcompare_neg_move"
11615 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
11617 (match_operator 5 "arm_comparison_operator"
11618 [(match_operand:SI 3 "s_register_operand" "r,r")
11619 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
11620 (neg:SI (match_operand:SI 2 "s_register_operand" "r,r"))
11621 (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
11622 (clobber (reg:CC CC_REGNUM))]
11625 [(set_attr "conds" "clob")
11626 (set_attr "length" "8,12")
11627 (set_attr "type" "multiple")]
11630 (define_insn "*if_neg_move"
11631 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
11633 (match_operator 4 "arm_comparison_operator"
11634 [(match_operand 3 "cc_register" "") (const_int 0)])
11635 (neg:SI (match_operand:SI 2 "s_register_operand" "r,r,r"))
11636 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")))]
11639 rsb%d4\\t%0, %2, #0
11640 mov%D4\\t%0, %1\;rsb%d4\\t%0, %2, #0
11641 mvn%D4\\t%0, #%B1\;rsb%d4\\t%0, %2, #0"
11642 [(set_attr "conds" "use")
11643 (set_attr "length" "4,8,8")
11644 (set_attr "type" "logic_shift_imm,multiple,multiple")]
11647 (define_insn "*ifcompare_move_neg"
11648 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
11650 (match_operator 5 "arm_comparison_operator"
11651 [(match_operand:SI 3 "s_register_operand" "r,r")
11652 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
11653 (match_operand:SI 1 "arm_not_operand" "0,?rIK")
11654 (neg:SI (match_operand:SI 2 "s_register_operand" "r,r"))))
11655 (clobber (reg:CC CC_REGNUM))]
11658 [(set_attr "conds" "clob")
11659 (set_attr "length" "8,12")
11660 (set_attr "type" "multiple")]
11663 (define_insn "*if_move_neg"
11664 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
11666 (match_operator 4 "arm_comparison_operator"
11667 [(match_operand 3 "cc_register" "") (const_int 0)])
11668 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")
11669 (neg:SI (match_operand:SI 2 "s_register_operand" "r,r,r"))))]
11672 rsb%D4\\t%0, %2, #0
11673 mov%d4\\t%0, %1\;rsb%D4\\t%0, %2, #0
11674 mvn%d4\\t%0, #%B1\;rsb%D4\\t%0, %2, #0"
11675 [(set_attr "conds" "use")
11676 (set_attr "length" "4,8,8")
11677 (set_attr "type" "logic_shift_imm,multiple,multiple")]
11680 (define_insn "*arith_adjacentmem"
11681 [(set (match_operand:SI 0 "s_register_operand" "=r")
11682 (match_operator:SI 1 "shiftable_operator"
11683 [(match_operand:SI 2 "memory_operand" "m")
11684 (match_operand:SI 3 "memory_operand" "m")]))
11685 (clobber (match_scratch:SI 4 "=r"))]
11686 "TARGET_ARM && adjacent_mem_locations (operands[2], operands[3])"
11692 HOST_WIDE_INT val1 = 0, val2 = 0;
11694 if (REGNO (operands[0]) > REGNO (operands[4]))
11696 ldm[1] = operands[4];
11697 ldm[2] = operands[0];
11701 ldm[1] = operands[0];
11702 ldm[2] = operands[4];
11705 base_reg = XEXP (operands[2], 0);
11707 if (!REG_P (base_reg))
11709 val1 = INTVAL (XEXP (base_reg, 1));
11710 base_reg = XEXP (base_reg, 0);
11713 if (!REG_P (XEXP (operands[3], 0)))
11714 val2 = INTVAL (XEXP (XEXP (operands[3], 0), 1));
11716 arith[0] = operands[0];
11717 arith[3] = operands[1];
11731 if (val1 !=0 && val2 != 0)
11735 if (val1 == 4 || val2 == 4)
11736 /* Other val must be 8, since we know they are adjacent and neither
11738 output_asm_insn (\"ldm%(ib%)\\t%0, {%1, %2}\", ldm);
11739 else if (const_ok_for_arm (val1) || const_ok_for_arm (-val1))
11741 ldm[0] = ops[0] = operands[4];
11743 ops[2] = GEN_INT (val1);
11744 output_add_immediate (ops);
11746 output_asm_insn (\"ldm%(ia%)\\t%0, {%1, %2}\", ldm);
11748 output_asm_insn (\"ldm%(da%)\\t%0, {%1, %2}\", ldm);
11752 /* Offset is out of range for a single add, so use two ldr. */
11755 ops[2] = GEN_INT (val1);
11756 output_asm_insn (\"ldr%?\\t%0, [%1, %2]\", ops);
11758 ops[2] = GEN_INT (val2);
11759 output_asm_insn (\"ldr%?\\t%0, [%1, %2]\", ops);
11762 else if (val1 != 0)
11765 output_asm_insn (\"ldm%(da%)\\t%0, {%1, %2}\", ldm);
11767 output_asm_insn (\"ldm%(ia%)\\t%0, {%1, %2}\", ldm);
11772 output_asm_insn (\"ldm%(ia%)\\t%0, {%1, %2}\", ldm);
11774 output_asm_insn (\"ldm%(da%)\\t%0, {%1, %2}\", ldm);
11776 output_asm_insn (\"%I3%?\\t%0, %1, %2\", arith);
11779 [(set_attr "length" "12")
11780 (set_attr "predicable" "yes")
11781 (set_attr "type" "load1")]
11784 ; This pattern is never tried by combine, so do it as a peephole
11787 [(set (match_operand:SI 0 "arm_general_register_operand" "")
11788 (match_operand:SI 1 "arm_general_register_operand" ""))
11789 (set (reg:CC CC_REGNUM)
11790 (compare:CC (match_dup 1) (const_int 0)))]
11792 [(parallel [(set (reg:CC CC_REGNUM) (compare:CC (match_dup 1) (const_int 0)))
11793 (set (match_dup 0) (match_dup 1))])]
11798 [(set (match_operand:SI 0 "s_register_operand" "")
11799 (and:SI (ge:SI (match_operand:SI 1 "s_register_operand" "")
11801 (neg:SI (match_operator:SI 2 "arm_comparison_operator"
11802 [(match_operand:SI 3 "s_register_operand" "")
11803 (match_operand:SI 4 "arm_rhs_operand" "")]))))
11804 (clobber (match_operand:SI 5 "s_register_operand" ""))]
11806 [(set (match_dup 5) (not:SI (ashiftrt:SI (match_dup 1) (const_int 31))))
11807 (set (match_dup 0) (and:SI (match_op_dup 2 [(match_dup 3) (match_dup 4)])
11812 ;; This split can be used because CC_Z mode implies that the following
11813 ;; branch will be an equality, or an unsigned inequality, so the sign
11814 ;; extension is not needed.
11817 [(set (reg:CC_Z CC_REGNUM)
11819 (ashift:SI (subreg:SI (match_operand:QI 0 "memory_operand" "") 0)
11821 (match_operand 1 "const_int_operand" "")))
11822 (clobber (match_scratch:SI 2 ""))]
11824 && (((unsigned HOST_WIDE_INT) INTVAL (operands[1]))
11825 == (((unsigned HOST_WIDE_INT) INTVAL (operands[1])) >> 24) << 24)"
11826 [(set (match_dup 2) (zero_extend:SI (match_dup 0)))
11827 (set (reg:CC CC_REGNUM) (compare:CC (match_dup 2) (match_dup 1)))]
11829 operands[1] = GEN_INT (((unsigned long) INTVAL (operands[1])) >> 24);
11832 ;; ??? Check the patterns above for Thumb-2 usefulness
11834 (define_expand "prologue"
11835 [(clobber (const_int 0))]
11838 arm_expand_prologue ();
11840 thumb1_expand_prologue ();
11845 (define_expand "epilogue"
11846 [(clobber (const_int 0))]
11849 if (crtl->calls_eh_return)
11850 emit_insn (gen_force_register_use (gen_rtx_REG (Pmode, 2)));
11853 thumb1_expand_epilogue ();
11854 emit_jump_insn (gen_rtx_UNSPEC_VOLATILE (VOIDmode,
11855 gen_rtvec (1, ret_rtx), VUNSPEC_EPILOGUE));
11857 else if (HAVE_return)
11859 /* HAVE_return is testing for USE_RETURN_INSN (FALSE). Hence,
11860 no need for explicit testing again. */
11861 emit_jump_insn (gen_return ());
11863 else if (TARGET_32BIT)
11865 arm_expand_epilogue (true);
11871 (define_insn "prologue_thumb1_interwork"
11872 [(unspec_volatile [(const_int 0)] VUNSPEC_THUMB1_INTERWORK)]
11874 "* return thumb1_output_interwork ();"
11875 [(set_attr "length" "8")
11876 (set_attr "type" "multiple")]
11879 ;; Note - although unspec_volatile's USE all hard registers,
11880 ;; USEs are ignored after relaod has completed. Thus we need
11881 ;; to add an unspec of the link register to ensure that flow
11882 ;; does not think that it is unused by the sibcall branch that
11883 ;; will replace the standard function epilogue.
11884 (define_expand "sibcall_epilogue"
11885 [(parallel [(unspec:SI [(reg:SI LR_REGNUM)] UNSPEC_REGISTER_USE)
11886 (unspec_volatile [(return)] VUNSPEC_EPILOGUE)])]
11889 arm_expand_epilogue (false);
11894 (define_insn "*epilogue_insns"
11895 [(unspec_volatile [(return)] VUNSPEC_EPILOGUE)]
11898 return thumb1_unexpanded_epilogue ();
11900 ; Length is absolute worst case
11901 [(set_attr "length" "44")
11902 (set_attr "type" "block")
11903 ;; We don't clobber the conditions, but the potential length of this
11904 ;; operation is sufficient to make conditionalizing the sequence
11905 ;; unlikely to be profitable.
11906 (set_attr "conds" "clob")]
11909 (define_expand "eh_epilogue"
11910 [(use (match_operand:SI 0 "register_operand" ""))
11911 (use (match_operand:SI 1 "register_operand" ""))
11912 (use (match_operand:SI 2 "register_operand" ""))]
11916 cfun->machine->eh_epilogue_sp_ofs = operands[1];
11917 if (!REG_P (operands[2]) || REGNO (operands[2]) != 2)
11919 rtx ra = gen_rtx_REG (Pmode, 2);
11921 emit_move_insn (ra, operands[2]);
11924 /* This is a hack -- we may have crystalized the function type too
11926 cfun->machine->func_type = 0;
11930 ;; This split is only used during output to reduce the number of patterns
11931 ;; that need assembler instructions adding to them. We allowed the setting
11932 ;; of the conditions to be implicit during rtl generation so that
11933 ;; the conditional compare patterns would work. However this conflicts to
11934 ;; some extent with the conditional data operations, so we have to split them
11937 ;; ??? Need to audit these splitters for Thumb-2. Why isn't normal
11938 ;; conditional execution sufficient?
11941 [(set (match_operand:SI 0 "s_register_operand" "")
11942 (if_then_else:SI (match_operator 1 "arm_comparison_operator"
11943 [(match_operand 2 "" "") (match_operand 3 "" "")])
11945 (match_operand 4 "" "")))
11946 (clobber (reg:CC CC_REGNUM))]
11947 "TARGET_ARM && reload_completed"
11948 [(set (match_dup 5) (match_dup 6))
11949 (cond_exec (match_dup 7)
11950 (set (match_dup 0) (match_dup 4)))]
11953 enum machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
11954 operands[2], operands[3]);
11955 enum rtx_code rc = GET_CODE (operands[1]);
11957 operands[5] = gen_rtx_REG (mode, CC_REGNUM);
11958 operands[6] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
11959 if (mode == CCFPmode || mode == CCFPEmode)
11960 rc = reverse_condition_maybe_unordered (rc);
11962 rc = reverse_condition (rc);
11964 operands[7] = gen_rtx_fmt_ee (rc, VOIDmode, operands[5], const0_rtx);
11969 [(set (match_operand:SI 0 "s_register_operand" "")
11970 (if_then_else:SI (match_operator 1 "arm_comparison_operator"
11971 [(match_operand 2 "" "") (match_operand 3 "" "")])
11972 (match_operand 4 "" "")
11974 (clobber (reg:CC CC_REGNUM))]
11975 "TARGET_ARM && reload_completed"
11976 [(set (match_dup 5) (match_dup 6))
11977 (cond_exec (match_op_dup 1 [(match_dup 5) (const_int 0)])
11978 (set (match_dup 0) (match_dup 4)))]
11981 enum machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
11982 operands[2], operands[3]);
11984 operands[5] = gen_rtx_REG (mode, CC_REGNUM);
11985 operands[6] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
11990 [(set (match_operand:SI 0 "s_register_operand" "")
11991 (if_then_else:SI (match_operator 1 "arm_comparison_operator"
11992 [(match_operand 2 "" "") (match_operand 3 "" "")])
11993 (match_operand 4 "" "")
11994 (match_operand 5 "" "")))
11995 (clobber (reg:CC CC_REGNUM))]
11996 "TARGET_ARM && reload_completed"
11997 [(set (match_dup 6) (match_dup 7))
11998 (cond_exec (match_op_dup 1 [(match_dup 6) (const_int 0)])
11999 (set (match_dup 0) (match_dup 4)))
12000 (cond_exec (match_dup 8)
12001 (set (match_dup 0) (match_dup 5)))]
12004 enum machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
12005 operands[2], operands[3]);
12006 enum rtx_code rc = GET_CODE (operands[1]);
12008 operands[6] = gen_rtx_REG (mode, CC_REGNUM);
12009 operands[7] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
12010 if (mode == CCFPmode || mode == CCFPEmode)
12011 rc = reverse_condition_maybe_unordered (rc);
12013 rc = reverse_condition (rc);
12015 operands[8] = gen_rtx_fmt_ee (rc, VOIDmode, operands[6], const0_rtx);
12020 [(set (match_operand:SI 0 "s_register_operand" "")
12021 (if_then_else:SI (match_operator 1 "arm_comparison_operator"
12022 [(match_operand:SI 2 "s_register_operand" "")
12023 (match_operand:SI 3 "arm_add_operand" "")])
12024 (match_operand:SI 4 "arm_rhs_operand" "")
12026 (match_operand:SI 5 "s_register_operand" ""))))
12027 (clobber (reg:CC CC_REGNUM))]
12028 "TARGET_ARM && reload_completed"
12029 [(set (match_dup 6) (match_dup 7))
12030 (cond_exec (match_op_dup 1 [(match_dup 6) (const_int 0)])
12031 (set (match_dup 0) (match_dup 4)))
12032 (cond_exec (match_dup 8)
12033 (set (match_dup 0) (not:SI (match_dup 5))))]
12036 enum machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
12037 operands[2], operands[3]);
12038 enum rtx_code rc = GET_CODE (operands[1]);
12040 operands[6] = gen_rtx_REG (mode, CC_REGNUM);
12041 operands[7] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
12042 if (mode == CCFPmode || mode == CCFPEmode)
12043 rc = reverse_condition_maybe_unordered (rc);
12045 rc = reverse_condition (rc);
12047 operands[8] = gen_rtx_fmt_ee (rc, VOIDmode, operands[6], const0_rtx);
12051 (define_insn "*cond_move_not"
12052 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
12053 (if_then_else:SI (match_operator 4 "arm_comparison_operator"
12054 [(match_operand 3 "cc_register" "") (const_int 0)])
12055 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
12057 (match_operand:SI 2 "s_register_operand" "r,r"))))]
12061 mov%d4\\t%0, %1\;mvn%D4\\t%0, %2"
12062 [(set_attr "conds" "use")
12063 (set_attr "type" "mvn_reg,multiple")
12064 (set_attr "length" "4,8")]
12067 ;; The next two patterns occur when an AND operation is followed by a
12068 ;; scc insn sequence
12070 (define_insn "*sign_extract_onebit"
12071 [(set (match_operand:SI 0 "s_register_operand" "=r")
12072 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
12074 (match_operand:SI 2 "const_int_operand" "n")))
12075 (clobber (reg:CC CC_REGNUM))]
12078 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
12079 output_asm_insn (\"ands\\t%0, %1, %2\", operands);
12080 return \"mvnne\\t%0, #0\";
12082 [(set_attr "conds" "clob")
12083 (set_attr "length" "8")
12084 (set_attr "type" "multiple")]
12087 (define_insn "*not_signextract_onebit"
12088 [(set (match_operand:SI 0 "s_register_operand" "=r")
12090 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
12092 (match_operand:SI 2 "const_int_operand" "n"))))
12093 (clobber (reg:CC CC_REGNUM))]
12096 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
12097 output_asm_insn (\"tst\\t%1, %2\", operands);
12098 output_asm_insn (\"mvneq\\t%0, #0\", operands);
12099 return \"movne\\t%0, #0\";
12101 [(set_attr "conds" "clob")
12102 (set_attr "length" "12")
12103 (set_attr "type" "multiple")]
12105 ;; ??? The above patterns need auditing for Thumb-2
12107 ;; Push multiple registers to the stack. Registers are in parallel (use ...)
12108 ;; expressions. For simplicity, the first register is also in the unspec
12110 ;; To avoid the usage of GNU extension, the length attribute is computed
12111 ;; in a C function arm_attr_length_push_multi.
12112 (define_insn "*push_multi"
12113 [(match_parallel 2 "multi_register_push"
12114 [(set (match_operand:BLK 0 "push_mult_memory_operand" "")
12115 (unspec:BLK [(match_operand:SI 1 "s_register_operand" "")]
12116 UNSPEC_PUSH_MULT))])]
12120 int num_saves = XVECLEN (operands[2], 0);
12122 /* For the StrongARM at least it is faster to
12123 use STR to store only a single register.
12124 In Thumb mode always use push, and the assembler will pick
12125 something appropriate. */
12126 if (num_saves == 1 && TARGET_ARM)
12127 output_asm_insn (\"str%?\\t%1, [%m0, #-4]!\", operands);
12134 strcpy (pattern, \"stm%(fd%)\\t%m0!, {%1\");
12135 else if (TARGET_THUMB2)
12136 strcpy (pattern, \"push%?\\t{%1\");
12138 strcpy (pattern, \"push\\t{%1\");
12140 for (i = 1; i < num_saves; i++)
12142 strcat (pattern, \", %|\");
12144 reg_names[REGNO (XEXP (XVECEXP (operands[2], 0, i), 0))]);
12147 strcat (pattern, \"}\");
12148 output_asm_insn (pattern, operands);
12153 [(set_attr "type" "store4")
12154 (set (attr "length")
12155 (symbol_ref "arm_attr_length_push_multi (operands[2], operands[1])"))]
12158 (define_insn "stack_tie"
12159 [(set (mem:BLK (scratch))
12160 (unspec:BLK [(match_operand:SI 0 "s_register_operand" "rk")
12161 (match_operand:SI 1 "s_register_operand" "rk")]
12165 [(set_attr "length" "0")
12166 (set_attr "type" "block")]
12169 ;; Pop (as used in epilogue RTL)
12171 (define_insn "*load_multiple_with_writeback"
12172 [(match_parallel 0 "load_multiple_operation"
12173 [(set (match_operand:SI 1 "s_register_operand" "+rk")
12174 (plus:SI (match_dup 1)
12175 (match_operand:SI 2 "const_int_operand" "I")))
12176 (set (match_operand:SI 3 "s_register_operand" "=rk")
12177 (mem:SI (match_dup 1)))
12179 "TARGET_32BIT && (reload_in_progress || reload_completed)"
12182 arm_output_multireg_pop (operands, /*return_pc=*/false,
12183 /*cond=*/const_true_rtx,
12189 [(set_attr "type" "load4")
12190 (set_attr "predicable" "yes")]
12193 ;; Pop with return (as used in epilogue RTL)
12195 ;; This instruction is generated when the registers are popped at the end of
12196 ;; epilogue. Here, instead of popping the value into LR and then generating
12197 ;; jump to LR, value is popped into PC directly. Hence, the pattern is combined
12199 (define_insn "*pop_multiple_with_writeback_and_return"
12200 [(match_parallel 0 "pop_multiple_return"
12202 (set (match_operand:SI 1 "s_register_operand" "+rk")
12203 (plus:SI (match_dup 1)
12204 (match_operand:SI 2 "const_int_operand" "I")))
12205 (set (match_operand:SI 3 "s_register_operand" "=rk")
12206 (mem:SI (match_dup 1)))
12208 "TARGET_32BIT && (reload_in_progress || reload_completed)"
12211 arm_output_multireg_pop (operands, /*return_pc=*/true,
12212 /*cond=*/const_true_rtx,
12218 [(set_attr "type" "load4")
12219 (set_attr "predicable" "yes")]
12222 (define_insn "*pop_multiple_with_return"
12223 [(match_parallel 0 "pop_multiple_return"
12225 (set (match_operand:SI 2 "s_register_operand" "=rk")
12226 (mem:SI (match_operand:SI 1 "s_register_operand" "rk")))
12228 "TARGET_32BIT && (reload_in_progress || reload_completed)"
12231 arm_output_multireg_pop (operands, /*return_pc=*/true,
12232 /*cond=*/const_true_rtx,
12238 [(set_attr "type" "load4")
12239 (set_attr "predicable" "yes")]
12242 ;; Load into PC and return
12243 (define_insn "*ldr_with_return"
12245 (set (reg:SI PC_REGNUM)
12246 (mem:SI (post_inc:SI (match_operand:SI 0 "s_register_operand" "+rk"))))]
12247 "TARGET_32BIT && (reload_in_progress || reload_completed)"
12248 "ldr%?\t%|pc, [%0], #4"
12249 [(set_attr "type" "load1")
12250 (set_attr "predicable" "yes")]
12252 ;; Pop for floating point registers (as used in epilogue RTL)
12253 (define_insn "*vfp_pop_multiple_with_writeback"
12254 [(match_parallel 0 "pop_multiple_fp"
12255 [(set (match_operand:SI 1 "s_register_operand" "+rk")
12256 (plus:SI (match_dup 1)
12257 (match_operand:SI 2 "const_int_operand" "I")))
12258 (set (match_operand:DF 3 "vfp_hard_register_operand" "")
12259 (mem:DF (match_dup 1)))])]
12260 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
12263 int num_regs = XVECLEN (operands[0], 0);
12266 strcpy (pattern, \"fldmfdd\\t\");
12267 strcat (pattern, reg_names[REGNO (SET_DEST (XVECEXP (operands[0], 0, 0)))]);
12268 strcat (pattern, \"!, {\");
12269 op_list[0] = XEXP (XVECEXP (operands[0], 0, 1), 0);
12270 strcat (pattern, \"%P0\");
12271 if ((num_regs - 1) > 1)
12273 strcat (pattern, \"-%P1\");
12274 op_list [1] = XEXP (XVECEXP (operands[0], 0, num_regs - 1), 0);
12277 strcat (pattern, \"}\");
12278 output_asm_insn (pattern, op_list);
12282 [(set_attr "type" "load4")
12283 (set_attr "conds" "unconditional")
12284 (set_attr "predicable" "no")]
12287 ;; Special patterns for dealing with the constant pool
12289 (define_insn "align_4"
12290 [(unspec_volatile [(const_int 0)] VUNSPEC_ALIGN)]
12293 assemble_align (32);
12296 [(set_attr "type" "no_insn")]
12299 (define_insn "align_8"
12300 [(unspec_volatile [(const_int 0)] VUNSPEC_ALIGN8)]
12303 assemble_align (64);
12306 [(set_attr "type" "no_insn")]
12309 (define_insn "consttable_end"
12310 [(unspec_volatile [(const_int 0)] VUNSPEC_POOL_END)]
12313 making_const_table = FALSE;
12316 [(set_attr "type" "no_insn")]
12319 (define_insn "consttable_1"
12320 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_1)]
12323 making_const_table = TRUE;
12324 assemble_integer (operands[0], 1, BITS_PER_WORD, 1);
12325 assemble_zeros (3);
12328 [(set_attr "length" "4")
12329 (set_attr "type" "no_insn")]
12332 (define_insn "consttable_2"
12333 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_2)]
12336 making_const_table = TRUE;
12337 gcc_assert (GET_MODE_CLASS (GET_MODE (operands[0])) != MODE_FLOAT);
12338 assemble_integer (operands[0], 2, BITS_PER_WORD, 1);
12339 assemble_zeros (2);
12342 [(set_attr "length" "4")
12343 (set_attr "type" "no_insn")]
12346 (define_insn "consttable_4"
12347 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_4)]
12351 rtx x = operands[0];
12352 making_const_table = TRUE;
12353 switch (GET_MODE_CLASS (GET_MODE (x)))
12356 if (GET_MODE (x) == HFmode)
12357 arm_emit_fp16_const (x);
12361 REAL_VALUE_FROM_CONST_DOUBLE (r, x);
12362 assemble_real (r, GET_MODE (x), BITS_PER_WORD);
12366 /* XXX: Sometimes gcc does something really dumb and ends up with
12367 a HIGH in a constant pool entry, usually because it's trying to
12368 load into a VFP register. We know this will always be used in
12369 combination with a LO_SUM which ignores the high bits, so just
12370 strip off the HIGH. */
12371 if (GET_CODE (x) == HIGH)
12373 assemble_integer (x, 4, BITS_PER_WORD, 1);
12374 mark_symbol_refs_as_used (x);
12379 [(set_attr "length" "4")
12380 (set_attr "type" "no_insn")]
12383 (define_insn "consttable_8"
12384 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_8)]
12388 making_const_table = TRUE;
12389 switch (GET_MODE_CLASS (GET_MODE (operands[0])))
12394 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[0]);
12395 assemble_real (r, GET_MODE (operands[0]), BITS_PER_WORD);
12399 assemble_integer (operands[0], 8, BITS_PER_WORD, 1);
12404 [(set_attr "length" "8")
12405 (set_attr "type" "no_insn")]
12408 (define_insn "consttable_16"
12409 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_16)]
12413 making_const_table = TRUE;
12414 switch (GET_MODE_CLASS (GET_MODE (operands[0])))
12419 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[0]);
12420 assemble_real (r, GET_MODE (operands[0]), BITS_PER_WORD);
12424 assemble_integer (operands[0], 16, BITS_PER_WORD, 1);
12429 [(set_attr "length" "16")
12430 (set_attr "type" "no_insn")]
12433 ;; Miscellaneous Thumb patterns
12435 (define_expand "tablejump"
12436 [(parallel [(set (pc) (match_operand:SI 0 "register_operand" ""))
12437 (use (label_ref (match_operand 1 "" "")))])]
12442 /* Hopefully, CSE will eliminate this copy. */
12443 rtx reg1 = copy_addr_to_reg (gen_rtx_LABEL_REF (Pmode, operands[1]));
12444 rtx reg2 = gen_reg_rtx (SImode);
12446 emit_insn (gen_addsi3 (reg2, operands[0], reg1));
12447 operands[0] = reg2;
12452 ;; NB never uses BX.
12453 (define_insn "*thumb1_tablejump"
12454 [(set (pc) (match_operand:SI 0 "register_operand" "l*r"))
12455 (use (label_ref (match_operand 1 "" "")))]
12458 [(set_attr "length" "2")
12459 (set_attr "type" "no_insn")]
12462 ;; V5 Instructions,
12464 (define_insn "clzsi2"
12465 [(set (match_operand:SI 0 "s_register_operand" "=r")
12466 (clz:SI (match_operand:SI 1 "s_register_operand" "r")))]
12467 "TARGET_32BIT && arm_arch5"
12469 [(set_attr "predicable" "yes")
12470 (set_attr "type" "clz")])
12472 (define_insn "rbitsi2"
12473 [(set (match_operand:SI 0 "s_register_operand" "=r")
12474 (unspec:SI [(match_operand:SI 1 "s_register_operand" "r")] UNSPEC_RBIT))]
12475 "TARGET_32BIT && arm_arch_thumb2"
12477 [(set_attr "predicable" "yes")
12478 (set_attr "type" "clz")])
12480 (define_expand "ctzsi2"
12481 [(set (match_operand:SI 0 "s_register_operand" "")
12482 (ctz:SI (match_operand:SI 1 "s_register_operand" "")))]
12483 "TARGET_32BIT && arm_arch_thumb2"
12486 rtx tmp = gen_reg_rtx (SImode);
12487 emit_insn (gen_rbitsi2 (tmp, operands[1]));
12488 emit_insn (gen_clzsi2 (operands[0], tmp));
12494 ;; V5E instructions.
12496 (define_insn "prefetch"
12497 [(prefetch (match_operand:SI 0 "address_operand" "p")
12498 (match_operand:SI 1 "" "")
12499 (match_operand:SI 2 "" ""))]
12500 "TARGET_32BIT && arm_arch5e"
12502 [(set_attr "type" "load1")]
12505 ;; General predication pattern
12508 [(match_operator 0 "arm_comparison_operator"
12509 [(match_operand 1 "cc_register" "")
12513 [(set_attr "predicated" "yes")]
12516 (define_insn "force_register_use"
12517 [(unspec:SI [(match_operand:SI 0 "register_operand" "")] UNSPEC_REGISTER_USE)]
12520 [(set_attr "length" "0")
12521 (set_attr "type" "no_insn")]
12525 ;; Patterns for exception handling
12527 (define_expand "eh_return"
12528 [(use (match_operand 0 "general_operand" ""))]
12533 emit_insn (gen_arm_eh_return (operands[0]));
12535 emit_insn (gen_thumb_eh_return (operands[0]));
12540 ;; We can't expand this before we know where the link register is stored.
12541 (define_insn_and_split "arm_eh_return"
12542 [(unspec_volatile [(match_operand:SI 0 "s_register_operand" "r")]
12544 (clobber (match_scratch:SI 1 "=&r"))]
12547 "&& reload_completed"
12551 arm_set_return_address (operands[0], operands[1]);
12556 (define_insn_and_split "thumb_eh_return"
12557 [(unspec_volatile [(match_operand:SI 0 "s_register_operand" "l")]
12559 (clobber (match_scratch:SI 1 "=&l"))]
12562 "&& reload_completed"
12566 thumb_set_return_address (operands[0], operands[1]);
12569 [(set_attr "type" "mov_reg")]
12575 (define_insn "load_tp_hard"
12576 [(set (match_operand:SI 0 "register_operand" "=r")
12577 (unspec:SI [(const_int 0)] UNSPEC_TLS))]
12579 "mrc%?\\tp15, 0, %0, c13, c0, 3\\t@ load_tp_hard"
12580 [(set_attr "predicable" "yes")
12581 (set_attr "type" "mrs")]
12584 ;; Doesn't clobber R1-R3. Must use r0 for the first operand.
12585 (define_insn "load_tp_soft"
12586 [(set (reg:SI 0) (unspec:SI [(const_int 0)] UNSPEC_TLS))
12587 (clobber (reg:SI LR_REGNUM))
12588 (clobber (reg:SI IP_REGNUM))
12589 (clobber (reg:CC CC_REGNUM))]
12591 "bl\\t__aeabi_read_tp\\t@ load_tp_soft"
12592 [(set_attr "conds" "clob")
12593 (set_attr "type" "branch")]
12596 ;; tls descriptor call
12597 (define_insn "tlscall"
12598 [(set (reg:SI R0_REGNUM)
12599 (unspec:SI [(reg:SI R0_REGNUM)
12600 (match_operand:SI 0 "" "X")
12601 (match_operand 1 "" "")] UNSPEC_TLS))
12602 (clobber (reg:SI R1_REGNUM))
12603 (clobber (reg:SI LR_REGNUM))
12604 (clobber (reg:SI CC_REGNUM))]
12607 targetm.asm_out.internal_label (asm_out_file, "LPIC",
12608 INTVAL (operands[1]));
12609 return "bl\\t%c0(tlscall)";
12611 [(set_attr "conds" "clob")
12612 (set_attr "length" "4")
12613 (set_attr "type" "branch")]
12616 ;; For thread pointer builtin
12617 (define_expand "get_thread_pointersi"
12618 [(match_operand:SI 0 "s_register_operand" "=r")]
12622 arm_load_tp (operands[0]);
12628 ;; We only care about the lower 16 bits of the constant
12629 ;; being inserted into the upper 16 bits of the register.
12630 (define_insn "*arm_movtas_ze"
12631 [(set (zero_extract:SI (match_operand:SI 0 "s_register_operand" "+r")
12634 (match_operand:SI 1 "const_int_operand" ""))]
12637 [(set_attr "predicable" "yes")
12638 (set_attr "predicable_short_it" "no")
12639 (set_attr "length" "4")
12640 (set_attr "type" "mov_imm")]
12643 (define_insn "*arm_rev"
12644 [(set (match_operand:SI 0 "s_register_operand" "=l,l,r")
12645 (bswap:SI (match_operand:SI 1 "s_register_operand" "l,l,r")))]
12651 [(set_attr "arch" "t1,t2,32")
12652 (set_attr "length" "2,2,4")
12653 (set_attr "type" "rev")]
12656 (define_expand "arm_legacy_rev"
12657 [(set (match_operand:SI 2 "s_register_operand" "")
12658 (xor:SI (rotatert:SI (match_operand:SI 1 "s_register_operand" "")
12662 (lshiftrt:SI (match_dup 2)
12664 (set (match_operand:SI 3 "s_register_operand" "")
12665 (rotatert:SI (match_dup 1)
12668 (and:SI (match_dup 2)
12669 (const_int -65281)))
12670 (set (match_operand:SI 0 "s_register_operand" "")
12671 (xor:SI (match_dup 3)
12677 ;; Reuse temporaries to keep register pressure down.
12678 (define_expand "thumb_legacy_rev"
12679 [(set (match_operand:SI 2 "s_register_operand" "")
12680 (ashift:SI (match_operand:SI 1 "s_register_operand" "")
12682 (set (match_operand:SI 3 "s_register_operand" "")
12683 (lshiftrt:SI (match_dup 1)
12686 (ior:SI (match_dup 3)
12688 (set (match_operand:SI 4 "s_register_operand" "")
12690 (set (match_operand:SI 5 "s_register_operand" "")
12691 (rotatert:SI (match_dup 1)
12694 (ashift:SI (match_dup 5)
12697 (lshiftrt:SI (match_dup 5)
12700 (ior:SI (match_dup 5)
12703 (rotatert:SI (match_dup 5)
12705 (set (match_operand:SI 0 "s_register_operand" "")
12706 (ior:SI (match_dup 5)
12712 (define_expand "bswapsi2"
12713 [(set (match_operand:SI 0 "s_register_operand" "=r")
12714 (bswap:SI (match_operand:SI 1 "s_register_operand" "r")))]
12715 "TARGET_EITHER && (arm_arch6 || !optimize_size)"
12719 rtx op2 = gen_reg_rtx (SImode);
12720 rtx op3 = gen_reg_rtx (SImode);
12724 rtx op4 = gen_reg_rtx (SImode);
12725 rtx op5 = gen_reg_rtx (SImode);
12727 emit_insn (gen_thumb_legacy_rev (operands[0], operands[1],
12728 op2, op3, op4, op5));
12732 emit_insn (gen_arm_legacy_rev (operands[0], operands[1],
12741 ;; bswap16 patterns: use revsh and rev16 instructions for the signed
12742 ;; and unsigned variants, respectively. For rev16, expose
12743 ;; byte-swapping in the lower 16 bits only.
12744 (define_insn "*arm_revsh"
12745 [(set (match_operand:SI 0 "s_register_operand" "=l,l,r")
12746 (sign_extend:SI (bswap:HI (match_operand:HI 1 "s_register_operand" "l,l,r"))))]
12752 [(set_attr "arch" "t1,t2,32")
12753 (set_attr "length" "2,2,4")
12754 (set_attr "type" "rev")]
12757 (define_insn "*arm_rev16"
12758 [(set (match_operand:HI 0 "s_register_operand" "=l,l,r")
12759 (bswap:HI (match_operand:HI 1 "s_register_operand" "l,l,r")))]
12765 [(set_attr "arch" "t1,t2,32")
12766 (set_attr "length" "2,2,4")
12767 (set_attr "type" "rev")]
12770 (define_expand "bswaphi2"
12771 [(set (match_operand:HI 0 "s_register_operand" "=r")
12772 (bswap:HI (match_operand:HI 1 "s_register_operand" "r")))]
12777 ;; Patterns for LDRD/STRD in Thumb2 mode
12779 (define_insn "*thumb2_ldrd"
12780 [(set (match_operand:SI 0 "s_register_operand" "=r")
12781 (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "rk")
12782 (match_operand:SI 2 "ldrd_strd_offset_operand" "Do"))))
12783 (set (match_operand:SI 3 "s_register_operand" "=r")
12784 (mem:SI (plus:SI (match_dup 1)
12785 (match_operand:SI 4 "const_int_operand" ""))))]
12786 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
12787 && current_tune->prefer_ldrd_strd
12788 && ((INTVAL (operands[2]) + 4) == INTVAL (operands[4]))
12789 && (operands_ok_ldrd_strd (operands[0], operands[3],
12790 operands[1], INTVAL (operands[2]),
12792 "ldrd%?\t%0, %3, [%1, %2]"
12793 [(set_attr "type" "load2")
12794 (set_attr "predicable" "yes")
12795 (set_attr "predicable_short_it" "no")])
12797 (define_insn "*thumb2_ldrd_base"
12798 [(set (match_operand:SI 0 "s_register_operand" "=r")
12799 (mem:SI (match_operand:SI 1 "s_register_operand" "rk")))
12800 (set (match_operand:SI 2 "s_register_operand" "=r")
12801 (mem:SI (plus:SI (match_dup 1)
12803 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
12804 && current_tune->prefer_ldrd_strd
12805 && (operands_ok_ldrd_strd (operands[0], operands[2],
12806 operands[1], 0, false, true))"
12807 "ldrd%?\t%0, %2, [%1]"
12808 [(set_attr "type" "load2")
12809 (set_attr "predicable" "yes")
12810 (set_attr "predicable_short_it" "no")])
12812 (define_insn "*thumb2_ldrd_base_neg"
12813 [(set (match_operand:SI 0 "s_register_operand" "=r")
12814 (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "rk")
12816 (set (match_operand:SI 2 "s_register_operand" "=r")
12817 (mem:SI (match_dup 1)))]
12818 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
12819 && current_tune->prefer_ldrd_strd
12820 && (operands_ok_ldrd_strd (operands[0], operands[2],
12821 operands[1], -4, false, true))"
12822 "ldrd%?\t%0, %2, [%1, #-4]"
12823 [(set_attr "type" "load2")
12824 (set_attr "predicable" "yes")
12825 (set_attr "predicable_short_it" "no")])
12827 (define_insn "*thumb2_strd"
12828 [(set (mem:SI (plus:SI (match_operand:SI 0 "s_register_operand" "rk")
12829 (match_operand:SI 1 "ldrd_strd_offset_operand" "Do")))
12830 (match_operand:SI 2 "s_register_operand" "r"))
12831 (set (mem:SI (plus:SI (match_dup 0)
12832 (match_operand:SI 3 "const_int_operand" "")))
12833 (match_operand:SI 4 "s_register_operand" "r"))]
12834 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
12835 && current_tune->prefer_ldrd_strd
12836 && ((INTVAL (operands[1]) + 4) == INTVAL (operands[3]))
12837 && (operands_ok_ldrd_strd (operands[2], operands[4],
12838 operands[0], INTVAL (operands[1]),
12840 "strd%?\t%2, %4, [%0, %1]"
12841 [(set_attr "type" "store2")
12842 (set_attr "predicable" "yes")
12843 (set_attr "predicable_short_it" "no")])
12845 (define_insn "*thumb2_strd_base"
12846 [(set (mem:SI (match_operand:SI 0 "s_register_operand" "rk"))
12847 (match_operand:SI 1 "s_register_operand" "r"))
12848 (set (mem:SI (plus:SI (match_dup 0)
12850 (match_operand:SI 2 "s_register_operand" "r"))]
12851 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
12852 && current_tune->prefer_ldrd_strd
12853 && (operands_ok_ldrd_strd (operands[1], operands[2],
12854 operands[0], 0, false, false))"
12855 "strd%?\t%1, %2, [%0]"
12856 [(set_attr "type" "store2")
12857 (set_attr "predicable" "yes")
12858 (set_attr "predicable_short_it" "no")])
12860 (define_insn "*thumb2_strd_base_neg"
12861 [(set (mem:SI (plus:SI (match_operand:SI 0 "s_register_operand" "rk")
12863 (match_operand:SI 1 "s_register_operand" "r"))
12864 (set (mem:SI (match_dup 0))
12865 (match_operand:SI 2 "s_register_operand" "r"))]
12866 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
12867 && current_tune->prefer_ldrd_strd
12868 && (operands_ok_ldrd_strd (operands[1], operands[2],
12869 operands[0], -4, false, false))"
12870 "strd%?\t%1, %2, [%0, #-4]"
12871 [(set_attr "type" "store2")
12872 (set_attr "predicable" "yes")
12873 (set_attr "predicable_short_it" "no")])
12875 ;; ARMv8 CRC32 instructions.
12876 (define_insn "<crc_variant>"
12877 [(set (match_operand:SI 0 "s_register_operand" "=r")
12878 (unspec:SI [(match_operand:SI 1 "s_register_operand" "r")
12879 (match_operand:<crc_mode> 2 "s_register_operand" "r")]
12882 "<crc_variant>\\t%0, %1, %2"
12883 [(set_attr "type" "crc")
12884 (set_attr "conds" "unconditional")]
12887 ;; Load the load/store double peephole optimizations.
12888 (include "ldrdstrd.md")
12890 ;; Load the load/store multiple patterns
12891 (include "ldmstm.md")
12893 ;; Patterns in ldmstm.md don't cover more than 4 registers. This pattern covers
12894 ;; large lists without explicit writeback generated for APCS_FRAME epilogue.
12895 (define_insn "*load_multiple"
12896 [(match_parallel 0 "load_multiple_operation"
12897 [(set (match_operand:SI 2 "s_register_operand" "=rk")
12898 (mem:SI (match_operand:SI 1 "s_register_operand" "rk")))
12903 arm_output_multireg_pop (operands, /*return_pc=*/false,
12904 /*cond=*/const_true_rtx,
12910 [(set_attr "predicable" "yes")]
12913 ;; Vector bits common to IWMMXT and Neon
12914 (include "vec-common.md")
12915 ;; Load the Intel Wireless Multimedia Extension patterns
12916 (include "iwmmxt.md")
12917 ;; Load the VFP co-processor patterns
12919 ;; Thumb-2 patterns
12920 (include "thumb2.md")
12922 (include "neon.md")
12924 (include "crypto.md")
12925 ;; Synchronization Primitives
12926 (include "sync.md")
12927 ;; Fixed-point patterns
12928 (include "arm-fixed.md")