2014-01-17 Richard Biener <rguenther@suse.de>
[official-gcc.git] / gcc / config / arm / arm.md
blob2ddda020863a2dc910a215432a20ef5b535644e1
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
42 ;; sbc or adc.
45 ;;---------------------------------------------------------------------------
46 ;; Constants
48 ;; Register numbers -- All machine registers should be defined here
49 (define_constants
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
59   ]
61 ;; 3rd operand to select_dominance_cc_mode
62 (define_constants
63   [(DOM_CC_X_AND_Y  0)
64    (DOM_CC_NX_OR_Y  1)
65    (DOM_CC_X_OR_Y   2)
66   ]
68 ;; conditional compare combination
69 (define_constants
70   [(CMP_CMP 0)
71    (CMN_CMP 1)
72    (CMP_CMN 2)
73    (CMN_CMN 3)
74    (NUM_OF_COND_CMP 4)
75   ]
79 ;;---------------------------------------------------------------------------
80 ;; Attributes
82 ;; Processor type.  This is created automatically from arm-cores.def.
83 (include "arm-tune.md")
85 ;; Instruction classification types
86 (include "types.md")
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
105 ; arm_restrict_it.
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" ""
122   (const_int 4))
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")
135          (const_string "yes")
137          (and (eq_attr "arch" "a")
138               (match_test "TARGET_ARM"))
139          (const_string "yes")
141          (and (eq_attr "arch" "t")
142               (match_test "TARGET_THUMB"))
143          (const_string "yes")
145          (and (eq_attr "arch" "t1")
146               (match_test "TARGET_THUMB1"))
147          (const_string "yes")
149          (and (eq_attr "arch" "t2")
150               (match_test "TARGET_THUMB2"))
151          (const_string "yes")
153          (and (eq_attr "arch" "32")
154               (match_test "TARGET_32BIT"))
155          (const_string "yes")
157          (and (eq_attr "arch" "v6")
158               (match_test "TARGET_32BIT && arm_arch6"))
159          (const_string "yes")
161          (and (eq_attr "arch" "nov6")
162               (match_test "TARGET_32BIT && !arm_arch6"))
163          (const_string "yes")
165          (and (eq_attr "arch" "avoid_neon_for_64bits")
166               (match_test "TARGET_NEON")
167               (not (match_test "TARGET_PREFER_NEON_64BITS")))
168          (const_string "yes")
170          (and (eq_attr "arch" "neon_for_64bits")
171               (match_test "TARGET_NEON")
172               (match_test "TARGET_PREFER_NEON_64BITS"))
173          (const_string "yes")
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")
186          (const_string "yes")
188          (and (eq_attr "opt" "speed")
189               (match_test "optimize_function_for_speed_p (cfun)"))
190          (const_string "yes")
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
204 ; arch support.
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")
211           (const_string "no")
213           (and (eq_attr "predicable_short_it" "no")
214                (and (eq_attr "predicated" "yes")
215                     (match_test "arm_restrict_it")))
216           (const_string "no")
218           (and (eq_attr "enabled_for_depr_it" "no")
219                (match_test "arm_restrict_it"))
220           (const_string "no")
222           (and (eq_attr "use_literal_pool" "yes")
223                (match_test "arm_disable_literal_pool"))
224           (const_string "no")
226           (eq_attr "arch_enabled" "no")
227           (const_string "no")
229           (eq_attr "opt_enabled" "no")
230           (const_string "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,\
345           neon_fp_recpe_s_q,\
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,\
360           crypto_sha256_slow")
361         (const_string "yes")
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
370 ;   inlined branches
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"
385         (if_then_else
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"
409                  "block,call,load1")
410                 (const_string "yes")
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 ;;---------------------------------------------------------------------------
446 ;; Unspecs
448 (include "unspecs.md")
450 ;;---------------------------------------------------------------------------
451 ;; Mode iterators
453 (include "iterators.md")
455 ;;---------------------------------------------------------------------------
456 ;; Predicates
458 (include "predicates.md")
459 (include "constraints.md")
461 ;;---------------------------------------------------------------------------
462 ;; Pipeline descriptions
464 (define_attr "tune_cortexr4" "yes,no"
465   (const (if_then_else
466           (eq_attr "tune" "cortexr4,cortexr4f,cortexr5")
467           (const_string "yes")
468           (const_string "no"))))
470 ;; True if the generic scheduling description should be used.
472 (define_attr "generic_sched" "yes,no"
473   (const (if_then_else
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"))
476           (const_string "no")
477           (const_string "yes"))))
479 (define_attr "generic_vfp" "yes,no"
480   (const (if_then_else
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"))
484           (const_string "yes")
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")
493 (include "fa526.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")
508 (include "vfp11.md")
509 (include "marvell-pj4.md")
512 ;;---------------------------------------------------------------------------
513 ;; Insn patterns
515 ;; Addition insns.
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"
522  [(parallel
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))])]
527   "TARGET_EITHER"
528   "
529   if (TARGET_THUMB1)
530     {
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]);
535      }
536   "
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))
544   ]
545   "TARGET_THUMB1"
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"
557   "#"
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))
562                                  (match_dup 1)))
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))))]
566   "
567   {
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]);
574   }"
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))]
586   "TARGET_32BIT"
587   "#"
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))
591                                  (match_dup 1)))
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)
594                                                      (const_int 31))
595                                         (match_dup 4))
596                                (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
597   "
598   {
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]);
604   }"
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))]
616   "TARGET_32BIT"
617   "#"
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))
621                                  (match_dup 1)))
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))))]
625   "
626   {
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]);
632   }"
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" "")))]
642   "TARGET_EITHER"
643   "
644   if (TARGET_32BIT && CONST_INT_P (operands[2]))
645     {
646       arm_split_constant (PLUS, SImode, NULL_RTX,
647                           INTVAL (operands[2]), operands[0], operands[1],
648                           optimize && can_create_pseudo_p ());
649       DONE;
650     }
651   "
654 ; If there is a scratch available, this will be faster than synthesizing the
655 ; addition.
656 (define_peephole2
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"  "")))]
661   "TARGET_32BIT &&
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)))]
667   ""
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")))]
677   "TARGET_32BIT"
678   "@
679    add%?\\t%0, %0, %2
680    add%?\\t%0, %1, %2
681    add%?\\t%0, %1, %2
682    add%?\\t%0, %1, %2
683    add%?\\t%0, %1, %2
684    add%?\\t%0, %1, %2
685    add%?\\t%0, %2, %1
686    addw%?\\t%0, %1, %2
687    addw%?\\t%0, %1, %2
688    sub%?\\t%0, %1, #%n2
689    sub%?\\t%0, %1, #%n2
690    sub%?\\t%0, %1, #%n2
691    subw%?\\t%0, %1, #%n2
692    subw%?\\t%0, %1, #%n2
693    #"
694   "TARGET_32BIT
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))]
699   "
700   arm_split_constant (PLUS, SImode, curr_insn,
701                       INTVAL (operands[2]), operands[0],
702                       operands[1], 0);
703   DONE;
704   "
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")))]
719   "TARGET_THUMB1"
720   "*
721    static const char * const asms[] = 
722    {
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\",
730      \"#\",
731      \"#\",
732      \"#\"
733    };
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];
739   "
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)))]
747   {
748     HOST_WIDE_INT offset = INTVAL (operands[2]);
749     if (operands[1] == stack_pointer_rtx)
750       offset -= 1020;
751     else
752       {
753         if (offset > 255)
754           offset = 255;
755         else if (offset < -255)
756           offset = -255;
757       }
758     operands[3] = GEN_INT (offset);
759     operands[2] = GEN_INT (INTVAL (operands[2]) - offset);
760   }
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.
768 (define_peephole2
769   [(set (match_operand:SI 0 "arm_general_register_operand" "")
770         (match_operand:SI 1 "const_int_operand" ""))
771    (set (match_dup 0)
772         (plus:SI (match_dup 0) (reg:SI SP_REGNUM)))]
773   "TARGET_THUMB1
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)))]
777   ""
780 (define_insn "addsi3_compare0"
781   [(set (reg:CC_NOOV CC_REGNUM)
782         (compare:CC_NOOV
783          (plus:SI (match_operand:SI 1 "s_register_operand" "r, r,r")
784                   (match_operand:SI 2 "arm_add_operand"    "I,L,r"))
785          (const_int 0)))
786    (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
787         (plus:SI (match_dup 1) (match_dup 2)))]
788   "TARGET_ARM"
789   "@
790    add%.\\t%0, %1, %2
791    sub%.\\t%0, %1, #%n2
792    add%.\\t%0, %1, %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)
799         (compare:CC_NOOV
800          (plus:SI (match_operand:SI 0 "s_register_operand" "r, r, r")
801                   (match_operand:SI 1 "arm_add_operand"    "I,L, r"))
802          (const_int 0)))]
803   "TARGET_ARM"
804   "@
805    cmn%?\\t%0, %1
806    cmp%?\\t%0, #%n1
807    cmn%?\\t%0, %1"
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)
815         (compare:CC_Z
816          (neg:SI (match_operand:SI 0 "s_register_operand" "l,r"))
817          (match_operand:SI 1 "s_register_operand" "l,r")))]
818   "TARGET_32BIT"
819   "cmn%?\\t%1, %0"
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)
832         (compare:CC
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])"
839   "@
840    add%.\\t%0, %1, %3
841    sub%.\\t%0, %1, #%n3"
842   [(set_attr "conds" "set")
843    (set_attr "type" "alus_reg")]
846 ;; Convert the sequence
847 ;;  sub  rd, rn, #1
848 ;;  cmn  rd, #1 (equivalent to cmp rd, #-1)
849 ;;  bne  dest
850 ;; into
851 ;;  subs rd, rn, #1
852 ;;  bcs  dest   ((unsigned)rn >= 1)
853 ;; similarly for the beq variant using bcc.
854 ;; This is a common looping idiom (while (n--))
855 (define_peephole2
856   [(set (match_operand:SI 0 "arm_general_register_operand" "")
857         (plus:SI (match_operand:SI 1 "arm_general_register_operand" "")
858                  (const_int -1)))
859    (set (match_operand 2 "cc_register" "")
860         (compare (match_dup 0) (const_int -1)))
861    (set (pc)
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])"
867   [(parallel[
868     (set (match_dup 2)
869          (compare:CC
870           (match_dup 1) (const_int 1)))
871     (set (match_dup 0) (plus:SI (match_dup 1) (const_int -1)))])
872    (set (pc)
873         (if_then_else (match_op_dup 3 [(match_dup 2) (const_int 0)])
874                       (match_dup 4)
875                       (match_dup 5)))]
876   "operands[2] = gen_rtx_REG (CCmode, CC_REGNUM);
877    operands[3] = gen_rtx_fmt_ee ((GET_CODE (operands[3]) == NE
878                                   ? GEU : LTU),
879                                  VOIDmode, 
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)
889         (compare:CC_C
890          (plus:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
891                   (match_operand:SI 2 "arm_add_operand" "I,L,r"))
892          (match_dup 1)))
893    (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
894         (plus:SI (match_dup 1) (match_dup 2)))]
895   "TARGET_32BIT"
896   "@
897    add%.\\t%0, %1, %2
898    sub%.\\t%0, %1, #%n2
899    add%.\\t%0, %1, %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)
906         (compare:CC_C
907          (plus:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
908                   (match_operand:SI 2 "arm_add_operand" "I,L,r"))
909          (match_dup 2)))
910    (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
911         (plus:SI (match_dup 1) (match_dup 2)))]
912   "TARGET_32BIT"
913   "@
914    add%.\\t%0, %1, %2
915    add%.\\t%0, %1, %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)
923         (compare:CC_C
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"))
926           (match_dup 0)))]
927   "TARGET_32BIT"
928   "@
929    cmp%?\\t%0, #%n1
930    cmn%?\\t%0, %1
931    cmn%?\\t%0, %1
932    cmp%?\\t%0, #%n1
933    cmn%?\\t%0, %1"
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)
944         (compare:CC_C
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"))
947           (match_dup 1)))]
948   "TARGET_32BIT"
949   "@
950    cmp%?\\t%0, #%n1
951    cmn%?\\t%0, %1
952    cmn%?\\t%0, %1
953    cmp%?\\t%0, #%n1
954    cmn%?\\t%0, %1"
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))))]
968   "TARGET_32BIT"
969   "@
970    adc%?\\t%0, %1, %2
971    adc%?\\t%0, %1, %2
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")))]
986   "TARGET_32BIT"
987   "@
988    adc%?\\t%0, %1, %2
989    adc%?\\t%0, %1, %2
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")
1001         (plus:SI (plus:SI
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))))]
1007   "TARGET_32BIT"
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))]
1023    "TARGET_32BIT"
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))))]
1034   "TARGET_32BIT"
1035   "@
1036    sbc%?\\t%0, %1, %2
1037    rsc%?\\t%0, %2, %1"
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))))]
1050   "TARGET_32BIT"
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)
1062                             (match_dup 2))
1063                   (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1064   "TARGET_32BIT"
1065   "sbcs\\t%0, %1, %2"
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)
1076                            (match_dup 2))
1077                   (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1078   "TARGET_32BIT"
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")
1086         (minus:SI (minus:SI
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))))]
1092   "TARGET_32BIT"
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")
1103         (minus:SI (minus:SI
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))))]
1109   "TARGET_ARM"
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.
1119 (define_split
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" ""))
1123                  (const_int -1)))
1124    (clobber (match_operand:SI 3 "s_register_operand" ""))]
1125   "TARGET_32BIT"
1126   [(set (match_dup 3) (match_dup 1))
1127    (set (match_dup 0) (not:SI (ashift:SI (match_dup 3) (match_dup 2))))]
1128   "
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"
1137   "
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"
1145   "
1148 (define_expand "subdi3"
1149  [(parallel
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))])]
1154   "TARGET_EITHER"
1155   "
1156   if (TARGET_THUMB1)
1157     {
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]);
1162      }  
1163   "
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))))]
1179   {
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]);
1186    }
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))]
1197   "TARGET_THUMB1"
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")
1206                   (zero_extend:DI
1207                    (match_operand:SI 2 "s_register_operand"  "r,r"))))
1208    (clobber (reg:CC CC_REGNUM))]
1209   "TARGET_32BIT"
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))))]
1217   {
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);
1223    }
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")
1232                   (sign_extend:DI
1233                    (match_operand:SI 2 "s_register_operand"  "r,r"))))
1234    (clobber (reg:CC CC_REGNUM))]
1235   "TARGET_32BIT"
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)
1243                                                       (const_int 31)))
1244                                 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1245   {
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]);
1250   }
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))]
1262   "TARGET_ARM"
1263   "#"   ; "rsbs\\t%Q0, %Q1, %2\;rsc\\t%R0, %R1, #0"
1264         ; is equivalent to:
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))))]
1272   {
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]);
1277   }
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))]
1289   "TARGET_ARM"
1290   "#"   ; "rsbs\\t%Q0, %Q1, %2\;rsc\\t%R0, %R1, %2, asr #31"
1291         ; is equivalent to:
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)
1299                                              (const_int 31))
1300                                 (match_dup 4))
1301                                (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1302   {
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]);
1307   }
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"))
1317                   (zero_extend:DI
1318                    (match_operand:SI 2 "s_register_operand"  "r"))))
1319    (clobber (reg:CC CC_REGNUM))]
1320   "TARGET_32BIT"
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))))]
1328   {
1329        operands[3] = gen_highpart (SImode, operands[0]);
1330        operands[0] = gen_lowpart (SImode, operands[0]);
1331   }
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" "")))]
1341   "TARGET_EITHER"
1342   "
1343   if (CONST_INT_P (operands[1]))
1344     {
1345       if (TARGET_32BIT)
1346         {
1347           arm_split_constant (MINUS, SImode, NULL_RTX,
1348                               INTVAL (operands[1]), operands[0],
1349                               operands[2], optimize && can_create_pseudo_p ());
1350           DONE;
1351         }
1352       else /* TARGET_THUMB1 */
1353         operands[1] = force_reg (SImode, operands[1]);
1354     }
1355   "
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")))]
1362   "TARGET_THUMB1"
1363   "sub\\t%0, %1, %2"
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")))]
1374   "TARGET_32BIT"
1375   "@
1376    sub%?\\t%0, %1, %2
1377    sub%?\\t%0, %2
1378    sub%?\\t%0, %1, %2
1379    rsb%?\\t%0, %2, %1
1380    rsb%?\\t%0, %2, %1
1381    sub%?\\t%0, %1, %2
1382    sub%?\\t%0, %1, %2
1383    sub%?\\t%0, %1, %2
1384    #"
1385   "&& (CONST_INT_P (operands[1])
1386        && !const_ok_for_arm (INTVAL (operands[1])))"
1387   [(clobber (const_int 0))]
1388   "
1389   arm_split_constant (MINUS, SImode, curr_insn,
1390                       INTVAL (operands[1]), operands[0], operands[2], 0);
1391   DONE;
1392   "
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")]
1400 (define_peephole2
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" "")))]
1405   "TARGET_32BIT
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)))]
1410   ""
1413 (define_insn "*subsi3_compare0"
1414   [(set (reg:CC_NOOV CC_REGNUM)
1415         (compare:CC_NOOV
1416          (minus:SI (match_operand:SI 1 "arm_rhs_operand" "r,r,I")
1417                    (match_operand:SI 2 "arm_rhs_operand" "I,r,r"))
1418          (const_int 0)))
1419    (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
1420         (minus:SI (match_dup 1) (match_dup 2)))]
1421   "TARGET_32BIT"
1422   "@
1423    sub%.\\t%0, %1, %2
1424    sub%.\\t%0, %1, %2
1425    rsb%.\\t%0, %2, %1"
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)))]
1436   "TARGET_32BIT"
1437   "@
1438    sub%.\\t%0, %1, %2
1439    sub%.\\t%0, %1, %2
1440    rsb%.\\t%0, %2, %1"
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"
1450   "
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"
1458   "
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"
1469   "
1470   {
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));
1474     DONE;
1475   }"
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" "")))]
1482   "TARGET_EITHER"
1483   ""
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"
1520   "*
1521   if (which_alternative < 2)
1522     return \"mov\\t%0, %1\;mul\\t%0, %2\";
1523   else
1524     return \"mul\\t%0, %2\";
1525   "
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"
1535   "@
1536    mul\\t%0, %2
1537    mul\\t%0, %1
1538    mul\\t%0, %1"
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"))
1548                          (const_int 0)))
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"))
1562                          (const_int 0)))
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"))
1576                          (const_int 0)))
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"))
1589                          (const_int 0)))
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")
1601         (plus:SI
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")
1613         (plus:SI
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)
1626         (compare:CC_NOOV
1627          (plus:SI (mult:SI
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"))
1631          (const_int 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))
1634                  (match_dup 3)))]
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)
1643         (compare:CC_NOOV
1644          (plus:SI (mult:SI
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"))
1648          (const_int 0)))
1649    (set (match_operand:SI 0 "s_register_operand" "=r")
1650         (plus:SI (mult:SI (match_dup 2) (match_dup 1))
1651                  (match_dup 3)))]
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)
1660         (compare:CC_NOOV
1661          (plus:SI (mult:SI
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"))
1665          (const_int 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)
1675         (compare:CC_NOOV
1676          (plus:SI (mult:SI
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"))
1680          (const_int 0)))
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")
1690         (minus:SI
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" "")
1703         (plus:DI
1704          (mult:DI
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"
1709   "")
1711 (define_insn "*mulsidi3adddi"
1712   [(set (match_operand:DI 0 "s_register_operand" "=&r")
1713         (plus:DI
1714          (mult:DI
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")
1726         (plus:DI
1727          (mult:DI
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" "")
1746         (mult:DI
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"
1750   ""
1753 (define_insn "*mulsidi3_nov6"
1754   [(set (match_operand:DI 0 "s_register_operand" "=&r")
1755         (mult:DI
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")
1766         (mult:DI
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" "")
1778         (mult:DI
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"
1782   ""
1785 (define_insn "*umulsidi3_nov6"
1786   [(set (match_operand:DI 0 "s_register_operand" "=&r")
1787         (mult:DI
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")
1798         (mult:DI
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" "")
1810         (plus:DI
1811          (mult:DI
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"
1816   "")
1818 (define_insn "*umulsidi3adddi"
1819   [(set (match_operand:DI 0 "s_register_operand" "=&r")
1820         (plus:DI
1821          (mult:DI
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")
1833         (plus:DI
1834          (mult:DI
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"
1846   [(parallel
1847     [(set (match_operand:SI 0 "s_register_operand" "")
1848           (truncate:SI
1849            (lshiftrt:DI
1850             (mult:DI
1851              (sign_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1852              (sign_extend:DI (match_operand:SI 2 "s_register_operand" "")))
1853             (const_int 32))))
1854      (clobber (match_scratch:SI 3 ""))])]
1855   "TARGET_32BIT && arm_arch3m"
1856   ""
1859 (define_insn "*smulsi3_highpart_nov6"
1860   [(set (match_operand:SI 0 "s_register_operand" "=&r,&r")
1861         (truncate:SI
1862          (lshiftrt:DI
1863           (mult:DI
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")))
1866           (const_int 32))))
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")
1876         (truncate:SI
1877          (lshiftrt:DI
1878           (mult:DI
1879            (sign_extend:DI (match_operand:SI 1 "s_register_operand" "r"))
1880            (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r")))
1881           (const_int 32))))
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"
1891   [(parallel
1892     [(set (match_operand:SI 0 "s_register_operand" "")
1893           (truncate:SI
1894            (lshiftrt:DI
1895             (mult:DI
1896              (zero_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1897               (zero_extend:DI (match_operand:SI 2 "s_register_operand" "")))
1898             (const_int 32))))
1899      (clobber (match_scratch:SI 3 ""))])]
1900   "TARGET_32BIT && arm_arch3m"
1901   ""
1904 (define_insn "*umulsi3_highpart_nov6"
1905   [(set (match_operand:SI 0 "s_register_operand" "=&r,&r")
1906         (truncate:SI
1907          (lshiftrt:DI
1908           (mult:DI
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")))
1911           (const_int 32))))
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")
1921         (truncate:SI
1922          (lshiftrt:DI
1923           (mult:DI
1924            (zero_extend:DI (match_operand:SI 1 "s_register_operand" "r"))
1925            (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r")))
1926           (const_int 32))))
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"))
1939                  (sign_extend:SI
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")
1951                   (const_int 16))
1952                  (sign_extend:SI
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"))
1965                  (ashiftrt:SI
1966                   (match_operand:SI 2 "s_register_operand" "r")
1967                   (const_int 16))))]
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")
1979                   (const_int 16))
1980                  (ashiftrt:SI
1981                   (match_operand:SI 2 "s_register_operand" "r")
1982                   (const_int 16))))]
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"))
1994                           (sign_extend:SI
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")
2009                            (const_int 16))
2010                           (sign_extend:SI
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")
2024                            (const_int 16))
2025                           (ashiftrt:SI
2026                            (match_operand:SI 2 "s_register_operand" "r")
2027                            (const_int 16)))
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")
2038         (plus:DI
2039           (mult:DI (sign_extend:DI
2040                     (match_operand:HI 1 "s_register_operand" "r"))
2041                    (sign_extend:DI
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")
2053         (plus:DI
2054           (mult:DI (sign_extend:DI
2055                     (ashiftrt:SI
2056                      (match_operand:SI 1 "s_register_operand" "r")
2057                      (const_int 16)))
2058                    (sign_extend:DI
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")
2069         (plus:DI
2070           (mult:DI (sign_extend:DI
2071                     (ashiftrt:SI
2072                      (match_operand:SI 1 "s_register_operand" "r")
2073                      (const_int 16)))
2074                    (sign_extend:DI
2075                     (ashiftrt:SI
2076                      (match_operand:SI 2 "s_register_operand" "r")
2077                      (const_int 16))))
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"
2090   "
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"
2098   "
2101 ;; Division insns
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"
2108   "")
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"
2115   "")
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.
2123 (define_split
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)]))]
2133   "
2134   {
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]);
2141   }"
2144 (define_split
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))
2153                          (match_dup 4)]))]
2154   "
2155   {
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]);
2162   }"
2165 ;; The zero extend of operand 2 means we can just copy the high part of
2166 ;; operand1 into operand0.
2167 (define_split
2168   [(set (match_operand:DI 0 "s_register_operand" "")
2169         (ior:DI
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))]
2175   "
2176   {
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]);
2181   }"
2184 ;; The zero extend of operand 2 means we can just copy the high part of
2185 ;; operand1 into operand0.
2186 (define_split
2187   [(set (match_operand:DI 0 "s_register_operand" "")
2188         (xor:DI
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))]
2194   "
2195   {
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]);
2200   }"
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" "")))]
2207   "TARGET_32BIT"
2208   ""
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)
2218     {
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));
2224     case 2:
2225     case 3:
2226     case 4:
2227     case 5: /* fall through */
2228       return "#";
2229     default: gcc_unreachable ();
2230     }
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))]
2236   "
2237   {
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]));
2248   }"
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,*,*")
2254   ]
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")))]
2262   "TARGET_32BIT"
2263   "#"
2264   "TARGET_32BIT && reload_completed"
2265   ; The zero extend of operand 2 clears the high word of the output
2266   ; operand.
2267   [(set (match_dup 0) (and:SI (match_dup 1) (match_dup 2)))
2268    (set (match_dup 3) (const_int 0))]
2269   "
2270   {
2271     operands[3] = gen_highpart (SImode, operands[0]);
2272     operands[0] = gen_lowpart (SImode, operands[0]);
2273     operands[1] = gen_lowpart (SImode, operands[1]);
2274   }"
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")))]
2284   "TARGET_32BIT"
2285   "#"
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" "")))]
2294   "TARGET_EITHER"
2295   "
2296   if (TARGET_32BIT)
2297     {
2298       if (CONST_INT_P (operands[2]))
2299         {
2300           if (INTVAL (operands[2]) == 255 && arm_arch6)
2301             {
2302               operands[1] = convert_to_mode (QImode, operands[1], 1);
2303               emit_insn (gen_thumb2_zero_extendqisi2_v6 (operands[0],
2304                                                          operands[1]));
2305             }
2306           else
2307             arm_split_constant (AND, SImode, NULL_RTX,
2308                                 INTVAL (operands[2]), operands[0],
2309                                 operands[1],
2310                                 optimize && can_create_pseudo_p ());
2312           DONE;
2313         }
2314     }
2315   else /* TARGET_THUMB1 */
2316     {
2317       if (!CONST_INT_P (operands[2]))
2318         {
2319           rtx tmp = force_reg (SImode, operands[2]);
2320           if (rtx_equal_p (operands[0], operands[1]))
2321             operands[2] = tmp;
2322           else
2323             {
2324               operands[2] = operands[1];
2325               operands[1] = tmp;
2326             }
2327         }
2328       else
2329         {
2330           int i;
2331           
2332           if (((unsigned HOST_WIDE_INT) ~INTVAL (operands[2])) < 256)
2333             {
2334               operands[2] = force_reg (SImode,
2335                                        GEN_INT (~INTVAL (operands[2])));
2336               
2337               emit_insn (gen_thumb1_bicsi3 (operands[0], operands[2], operands[1]));
2338               
2339               DONE;
2340             }
2342           for (i = 9; i <= 31; i++)
2343             {
2344               if ((((HOST_WIDE_INT) 1) << i) - 1 == INTVAL (operands[2]))
2345                 {
2346                   emit_insn (gen_extzv (operands[0], operands[1], GEN_INT (i),
2347                                         const0_rtx));
2348                   DONE;
2349                 }
2350               else if ((((HOST_WIDE_INT) 1) << i) - 1
2351                        == ~INTVAL (operands[2]))
2352                 {
2353                   rtx shift = GEN_INT (i);
2354                   rtx reg = gen_reg_rtx (SImode);
2355                 
2356                   emit_insn (gen_lshrsi3 (reg, operands[1], shift));
2357                   emit_insn (gen_ashlsi3 (operands[0], reg, shift));
2358                   
2359                   DONE;
2360                 }
2361             }
2363           operands[2] = force_reg (SImode, operands[2]);
2364         }
2365     }
2366   "
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")))]
2374   "TARGET_32BIT"
2375   "@
2376    and%?\\t%0, %1, %2
2377    and%?\\t%0, %1, %2
2378    bic%?\\t%0, %1, #%B2
2379    and%?\\t%0, %1, %2
2380    #"
2381   "TARGET_32BIT
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))]
2386   "
2387   arm_split_constant  (AND, SImode, curr_insn, 
2388                        INTVAL (operands[2]), operands[0], operands[1], 0);
2389   DONE;
2390   "
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")))]
2401   "TARGET_THUMB1"
2402   "and\\t%0, %2"
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)
2409         (compare:CC_NOOV
2410          (and:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
2411                  (match_operand:SI 2 "arm_not_operand" "I,K,r"))
2412          (const_int 0)))
2413    (set (match_operand:SI          0 "s_register_operand" "=r,r,r")
2414         (and:SI (match_dup 1) (match_dup 2)))]
2415   "TARGET_32BIT"
2416   "@
2417    and%.\\t%0, %1, %2
2418    bic%.\\t%0, %1, #%B2
2419    and%.\\t%0, %1, %2"
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)
2426         (compare:CC_NOOV
2427          (and:SI (match_operand:SI 0 "s_register_operand" "r,r,r")
2428                  (match_operand:SI 1 "arm_not_operand" "I,K,r"))
2429          (const_int 0)))
2430    (clobber (match_scratch:SI 2 "=X,r,X"))]
2431   "TARGET_32BIT"
2432   "@
2433    tst%?\\t%0, %1
2434    bic%.\\t%2, %0, #%B1
2435    tst%?\\t%0, %1"
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"))
2446                          (const_int 0)))]
2447   "TARGET_32BIT
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)"
2452   "*
2453   operands[1] = GEN_INT (((1 << INTVAL (operands[1])) - 1)
2454                          << INTVAL (operands[2]));
2455   output_asm_insn (\"tst%?\\t%0, %1\", operands);
2456   return \"\";
2457   "
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"))
2470                (const_int 0)))
2471    (clobber (reg:CC CC_REGNUM))]
2472   "TARGET_32BIT
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)"
2477   "#"
2478   "TARGET_32BIT
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))
2485                                     (const_int 0)))
2486               (set (match_dup 0) (and:SI (match_dup 1) (match_dup 2)))])
2487    (set (match_dup 0)
2488         (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
2489                          (match_dup 0) (const_int 1)))]
2490   "
2491   operands[2] = GEN_INT (((1 << INTVAL (operands[2])) - 1)
2492                          << INTVAL (operands[3])); 
2493   "
2494   [(set_attr "conds" "clob")
2495    (set (attr "length")
2496         (if_then_else (eq_attr "is_thumb" "yes")
2497                       (const_int 12)
2498                       (const_int 8)))
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")
2507                 (const_int 0))
2508                (const_int 0)))
2509    (clobber (reg:CC CC_REGNUM))]
2510   "TARGET_ARM"
2511   "#"
2512   "TARGET_ARM"
2513   [(parallel [(set (reg:CC_NOOV CC_REGNUM)
2514                    (compare:CC_NOOV (ashift:SI (match_dup 1) (match_dup 2))
2515                                     (const_int 0)))
2516               (set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 2)))])
2517    (set (match_dup 0)
2518         (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
2519                          (match_dup 0) (const_int 1)))]
2520   "
2521   operands[2] = GEN_INT (32 - INTVAL (operands[2]));
2522   "
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"))
2534                              (const_int 0))
2535                          (match_operand:SI 4 "arm_not_operand" "rIK")
2536                          (const_int 0)))
2537    (clobber (reg:CC CC_REGNUM))]
2538   "TARGET_ARM
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])"
2544   "#"
2545   "TARGET_ARM
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))
2553                                     (const_int 0)))
2554               (set (match_dup 0) (and:SI (match_dup 1) (match_dup 2)))])
2555    (set (match_dup 0)
2556         (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
2557                          (match_dup 0) (match_dup 4)))]
2558   "
2559   operands[2] = GEN_INT (((1 << INTVAL (operands[2])) - 1)
2560                          << INTVAL (operands[3])); 
2561   "
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")
2572                               (const_int 0))
2573                              (const_int 0))
2574                          (match_operand:SI 3 "arm_not_operand" "rIK")
2575                          (const_int 0)))
2576    (clobber (reg:CC CC_REGNUM))]
2577   "TARGET_ARM && !reg_overlap_mentioned_p (operands[0], operands[3])"
2578   "#"
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))
2582                                     (const_int 0)))
2583               (set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 2)))])
2584    (set (match_dup 0)
2585         (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
2586                          (match_dup 0) (match_dup 3)))]
2587   "
2588   operands[2] = GEN_INT (32 - INTVAL (operands[2]));
2589   "
2590   [(set_attr "conds" "clob")
2591    (set_attr "length" "8")
2592    (set_attr "type" "multiple")]
2595 (define_split
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" ""))]
2601   "TARGET_THUMB1"
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)))]
2604   "{
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);
2609    }"
2612 ;; ??? Use Thumb-2 has bitfield insert/extract instructions.
2613 (define_split
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" ""))]
2621   "TARGET_ARM"
2622   [(set (match_dup 6) (ashift:SI (match_dup 2) (match_dup 3)))
2623    (set (match_dup 0)
2624         (match_op_dup 1
2625          [(lshiftrt:SI (match_dup 6) (match_dup 4))
2626           (match_dup 5)]))]
2627   "{
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);
2632    }"
2634   
2635 (define_split
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" "")))]
2640   "TARGET_THUMB1"
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)))]
2643   "{
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);
2648    }"
2651 (define_split
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" ""))]
2659   "TARGET_ARM"
2660   [(set (match_dup 6) (ashift:SI (match_dup 2) (match_dup 3)))
2661    (set (match_dup 0)
2662         (match_op_dup 1
2663          [(ashiftrt:SI (match_dup 6) (match_dup 4))
2664           (match_dup 5)]))]
2665   "{
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);
2670    }"
2672   
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"
2688   "
2689   {
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)
2696       {
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)
2700           {
2701             rtx base_addr;
2703             if (BYTES_BIG_ENDIAN)
2704               start_bit = GET_MODE_BITSIZE (GET_MODE (operands[3])) - width
2705                           - start_bit;
2707             if (width == 32)
2708               {
2709                 base_addr = adjust_address (operands[0], SImode,
2710                                             start_bit / BITS_PER_UNIT);
2711                 emit_insn (gen_unaligned_storesi (base_addr, operands[3]));
2712               }
2713             else
2714               {
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));
2721               }
2722             DONE;
2723           }
2724         else if (s_register_operand (operands[0], GET_MODE (operands[0])))
2725           {
2726             bool use_bfi = TRUE;
2728             if (CONST_INT_P (operands[3]))
2729               {
2730                 HOST_WIDE_INT val = INTVAL (operands[3]) & mask;
2732                 if (val == 0)
2733                   {
2734                     emit_insn (gen_insv_zero (operands[0], operands[1],
2735                                               operands[2]));
2736                     DONE;
2737                   }
2739                 /* See if the set can be done with a single orr instruction.  */
2740                 if (val == mask && const_ok_for_arm (val << start_bit))
2741                   use_bfi = FALSE;
2742               }
2744             if (use_bfi)
2745               {
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],
2750                                         operands[3]));
2751                 DONE;
2752               }
2753           }
2754         else
2755           FAIL;
2756       }
2758     if (!s_register_operand (operands[0], GET_MODE (operands[0])))
2759       FAIL;
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)
2765       {
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);
2770       }
2771     else
2772       subtarget = target;    
2774     if (CONST_INT_P (operands[3]))
2775       {
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)));
2791       }
2792     else if (start_bit == 0
2793              && !(const_ok_for_arm (mask)
2794                   || const_ok_for_arm (~mask)))
2795       {
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]));
2809       }
2810     else if ((width + start_bit == 32)
2811              && !(const_ok_for_arm (mask)
2812                   || const_ok_for_arm (~mask)))
2813       {
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));
2823       }
2824     else
2825       {
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)))
2831           {
2832             rtx tmp = gen_reg_rtx (SImode);
2834             emit_insn (gen_movsi (tmp, op0));
2835             op0 = tmp;
2836           }
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))))
2844           {
2845             op0 = gen_int_mode (~(mask << start_bit), SImode);
2846             emit_insn (gen_andsi3 (op2, operands[0], op0));
2847           }
2848         else
2849           {
2850             if (CONST_INT_P (op0))
2851               {
2852                 rtx tmp = gen_reg_rtx (SImode);
2854                 emit_insn (gen_movsi (tmp, op0));
2855                 op0 = tmp;
2856               }
2858             if (start_bit != 0)
2859               emit_insn (gen_ashlsi3 (op0, op0, operands[2]));
2860             
2861             emit_insn (gen_andsi_notsi_si (op2, operands[0], op0));
2862           }
2864         if (start_bit != 0)
2865           emit_insn (gen_ashlsi3 (op1, op1, operands[2]));
2867         emit_insn (gen_iorsi3 (subtarget, op1, op2));
2868       }
2870     if (subtarget != target)
2871       {
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);
2876         else
2877           emit_move_insn (target, gen_lowpart (GET_MODE (target), subtarget));
2878       }
2880     DONE;
2881   }"
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"))
2888         (const_int 0))]
2889   "arm_arch_thumb2"
2890   "bfc%?\t%0, %2, %1"
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"))]
2902   "arm_arch_thumb2"
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")))]
2915   "TARGET_32BIT"
2916   "#"
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)))]
2922   "
2923   {
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]);
2930   }"
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")))]
2941   "TARGET_32BIT"
2942   "@
2943    bic%?\\t%Q0, %Q1, %2
2944    #"
2945   ; (not (zero_extend ...)) allows us to just copy the high word from
2946   ; operand1 to operand0.
2947   "TARGET_32BIT
2948    && reload_completed
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))]
2952   "
2953   {
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]);
2958   }"
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")))]
2970   "TARGET_32BIT"
2971   "#"
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)))
2976                                (match_dup 4)))]
2977   "
2978   {
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]);
2983   }"
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")))]
2994   "TARGET_32BIT"
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")))]
3005   "TARGET_THUMB1"
3006   "bic\\t%0, %1"
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")))]
3018   "TARGET_ARM"
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)
3029         (compare:CC_NOOV
3030          (and:SI (not:SI (match_operand:SI 2 "s_register_operand" "r"))
3031                  (match_operand:SI 1 "s_register_operand" "r"))
3032          (const_int 0)))
3033    (set (match_operand:SI 0 "s_register_operand" "=r")
3034         (and:SI (not:SI (match_dup 2)) (match_dup 1)))]
3035   "TARGET_32BIT"
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)
3043         (compare:CC_NOOV
3044          (and:SI (not:SI (match_operand:SI 2 "s_register_operand" "r"))
3045                  (match_operand:SI 1 "s_register_operand" "r"))
3046          (const_int 0)))
3047    (clobber (match_scratch:SI 0 "=r"))]
3048   "TARGET_32BIT"
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" "")))]
3058   "TARGET_32BIT"
3059   ""
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"
3067   {
3068   switch (which_alternative)
3069     {
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));
3075     case 2:
3076     case 3:
3077     case 4:
3078     case 5:
3079       return "#";
3080     default: gcc_unreachable ();
3081     }
3082   }
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))]
3087   "
3088   {
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]));
3099   }"
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")))]
3111   "TARGET_32BIT"
3112   "@
3113    orr%?\\t%Q0, %Q1, %2
3114    #"
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")))]
3126   "TARGET_32BIT"
3127   "#"
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" "")))]
3137   "TARGET_EITHER"
3138   "
3139   if (CONST_INT_P (operands[2]))
3140     {
3141       if (TARGET_32BIT)
3142         {
3143           arm_split_constant (IOR, SImode, NULL_RTX,
3144                               INTVAL (operands[2]), operands[0], operands[1],
3145                               optimize && can_create_pseudo_p ());
3146           DONE;
3147         }
3148       else /* TARGET_THUMB1 */
3149         {
3150           rtx tmp = force_reg (SImode, operands[2]);
3151           if (rtx_equal_p (operands[0], operands[1]))
3152             operands[2] = tmp;
3153           else
3154             {
3155               operands[2] = operands[1];
3156               operands[1] = tmp;
3157             }
3158         }
3159     }
3160   "
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")))]
3167   "TARGET_32BIT"
3168   "@
3169    orr%?\\t%0, %1, %2
3170    orr%?\\t%0, %1, %2
3171    orn%?\\t%0, %1, #%B2
3172    orr%?\\t%0, %1, %2
3173    #"
3174   "TARGET_32BIT
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);
3182   DONE;
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")))]
3195   "TARGET_THUMB1"
3196   "orr\\t%0, %2"
3197   [(set_attr "length" "2")
3198    (set_attr "conds" "set")
3199    (set_attr "type" "logics_reg")])
3201 (define_peephole2
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" "")))]
3206   "TARGET_ARM
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)))]
3211   ""
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"))
3218                          (const_int 0)))
3219    (set (match_operand:SI 0 "s_register_operand" "=r,r")
3220         (ior:SI (match_dup 1) (match_dup 2)))]
3221   "TARGET_32BIT"
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"))
3231                          (const_int 0)))
3232    (clobber (match_scratch:SI 0 "=r,r"))]
3233   "TARGET_32BIT"
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" "")))]
3243   "TARGET_32BIT"
3244   ""
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)
3254     {
3255     case 1:
3256     case 2:
3257     case 3:
3258     case 4:  /* fall through */
3259       return "#";
3260     case 0: /* fall through */
3261     case 5: return "veor\t%P0, %P1, %P2";
3262     default: gcc_unreachable ();
3263     }
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))]
3269   "
3270   {
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]));
3281   }"
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")))]
3292   "TARGET_32BIT"
3293   "@
3294    eor%?\\t%Q0, %Q1, %2
3295    #"
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")))]
3307   "TARGET_32BIT"
3308   "#"
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" "")))]
3318   "TARGET_EITHER"
3319   "if (CONST_INT_P (operands[2]))
3320     {
3321       if (TARGET_32BIT)
3322         {
3323           arm_split_constant (XOR, SImode, NULL_RTX,
3324                               INTVAL (operands[2]), operands[0], operands[1],
3325                               optimize && can_create_pseudo_p ());
3326           DONE;
3327         }
3328       else /* TARGET_THUMB1 */
3329         {
3330           rtx tmp = force_reg (SImode, operands[2]);
3331           if (rtx_equal_p (operands[0], operands[1]))
3332             operands[2] = tmp;
3333           else
3334             {
3335               operands[2] = operands[1];
3336               operands[1] = tmp;
3337             }
3338         }
3339     }"
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")))]
3346   "TARGET_32BIT"
3347   "@
3348    eor%?\\t%0, %1, %2
3349    eor%?\\t%0, %1, %2
3350    eor%?\\t%0, %1, %2
3351    #"
3352   "TARGET_32BIT
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);
3359   DONE;
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")))]
3371   "TARGET_THUMB1"
3372   "eor\\t%0, %2"
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"))
3382                          (const_int 0)))
3383    (set (match_operand:SI 0 "s_register_operand" "=r,r")
3384         (xor:SI (match_dup 1) (match_dup 2)))]
3385   "TARGET_32BIT"
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"))
3395                          (const_int 0)))]
3396   "TARGET_32BIT"
3397   "teq%?\\t%0, %1"
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
3404 ; insns.
3406 (define_split
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" ""))]
3412   "TARGET_32BIT"
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)))]
3416   ""
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"))))]
3424   "TARGET_32BIT"
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)))]
3429   ""
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?
3439 (define_split
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" ""))]
3450   "TARGET_32BIT
3451    && GET_CODE (operands[1]) == GET_CODE (operands[9])
3452    && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
3453   [(set (match_dup 8)
3454         (match_op_dup 1
3455          [(ashift:SI (match_dup 2) (match_dup 4))
3456           (match_dup 5)]))
3457    (set (match_dup 0)
3458         (match_op_dup 1
3459          [(lshiftrt:SI (match_dup 8) (match_dup 6))
3460           (match_dup 7)]))]
3461   "
3462   operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
3465 (define_split
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" ""))]
3476   "TARGET_32BIT
3477    && GET_CODE (operands[1]) == GET_CODE (operands[9])
3478    && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
3479   [(set (match_dup 8)
3480         (match_op_dup 1
3481          [(ashift:SI (match_dup 2) (match_dup 4))
3482           (match_dup 5)]))
3483    (set (match_dup 0)
3484         (match_op_dup 1
3485          [(lshiftrt:SI (match_dup 8) (match_dup 6))
3486           (match_dup 7)]))]
3487   "
3488   operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
3491 (define_split
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" ""))]
3502   "TARGET_32BIT
3503    && GET_CODE (operands[1]) == GET_CODE (operands[9])
3504    && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
3505   [(set (match_dup 8)
3506         (match_op_dup 1
3507          [(ashift:SI (match_dup 2) (match_dup 4))
3508           (match_dup 5)]))
3509    (set (match_dup 0)
3510         (match_op_dup 1
3511          [(ashiftrt:SI (match_dup 8) (match_dup 6))
3512           (match_dup 7)]))]
3513   "
3514   operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
3517 (define_split
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" ""))]
3528   "TARGET_32BIT
3529    && GET_CODE (operands[1]) == GET_CODE (operands[9])
3530    && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
3531   [(set (match_dup 8)
3532         (match_op_dup 1
3533          [(ashift:SI (match_dup 2) (match_dup 4))
3534           (match_dup 5)]))
3535    (set (match_dup 0)
3536         (match_op_dup 1
3537          [(ashiftrt:SI (match_dup 8) (match_dup 6))
3538           (match_dup 7)]))]
3539   "
3540   operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
3544 ;; Minimum and maximum insns
3546 (define_expand "smaxsi3"
3547   [(parallel [
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))])]
3552   "TARGET_32BIT"
3553   "
3554   if (operands[2] == const0_rtx || operands[2] == constm1_rtx)
3555     {
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],
3559                                             operands[2])));
3560       DONE;
3561     }
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")
3567                  (const_int 0)))]
3568   "TARGET_32BIT"
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")
3578                  (const_int -1)))]
3579   "TARGET_32BIT"
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))]
3591   "TARGET_ARM"
3592   "#"
3593    ; cmp\\t%1, %2\;movlt\\t%0, %2
3594    ; cmp\\t%1, %2\;movge\\t%0, %1\;movlt\\t%0, %2"
3595   "TARGET_ARM"
3596   [(set (reg:CC CC_REGNUM)
3597         (compare:CC (match_dup 1) (match_dup 2)))
3598    (set (match_dup 0)
3599         (if_then_else:SI (ge:SI (reg:CC CC_REGNUM) (const_int 0))
3600                          (match_dup 1)
3601                          (match_dup 2)))]
3602   ""
3603   [(set_attr "conds" "clob")
3604    (set_attr "length" "8,12")
3605    (set_attr "type" "multiple")]
3608 (define_expand "sminsi3"
3609   [(parallel [
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))])]
3614   "TARGET_32BIT"
3615   "
3616   if (operands[2] == const0_rtx)
3617     {
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],
3621                                             operands[2])));
3622       DONE;
3623     }
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")
3629                  (const_int 0)))]
3630   "TARGET_32BIT"
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))]
3642   "TARGET_ARM"
3643   "#"
3644     ; cmp\\t%1, %2\;movge\\t%0, %2
3645     ; cmp\\t%1, %2\;movlt\\t%0, %1\;movge\\t%0, %2"
3646   "TARGET_ARM"
3647   [(set (reg:CC CC_REGNUM)
3648         (compare:CC (match_dup 1) (match_dup 2)))
3649    (set (match_dup 0)
3650         (if_then_else:SI (lt:SI (reg:CC CC_REGNUM) (const_int 0))
3651                          (match_dup 1)
3652                          (match_dup 2)))]
3653   ""
3654   [(set_attr "conds" "clob")
3655    (set_attr "length" "8,12")
3656    (set_attr "type" "multiple,multiple")]
3659 (define_expand "umaxsi3"
3660   [(parallel [
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))])]
3665   "TARGET_32BIT"
3666   ""
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))]
3674   "TARGET_ARM"
3675   "#"
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"
3679   "TARGET_ARM"
3680   [(set (reg:CC CC_REGNUM)
3681         (compare:CC (match_dup 1) (match_dup 2)))
3682    (set (match_dup 0)
3683         (if_then_else:SI (geu:SI (reg:CC CC_REGNUM) (const_int 0))
3684                          (match_dup 1)
3685                          (match_dup 2)))]
3686   ""
3687   [(set_attr "conds" "clob")
3688    (set_attr "length" "8,8,12")
3689    (set_attr "type" "store1")]
3692 (define_expand "uminsi3"
3693   [(parallel [
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))])]
3698   "TARGET_32BIT"
3699   ""
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))]
3707   "TARGET_ARM"
3708   "#"
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"
3712   "TARGET_ARM"
3713   [(set (reg:CC CC_REGNUM)
3714         (compare:CC (match_dup 1) (match_dup 2)))
3715    (set (match_dup 0)
3716         (if_then_else:SI (ltu:SI (reg:CC CC_REGNUM) (const_int 0))
3717                          (match_dup 1)
3718                          (match_dup 2)))]
3719   ""
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)"
3732   "*
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);
3736   if (TARGET_THUMB2)
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);
3740   return \"\";
3741   "
3742   [(set_attr "conds" "clob")
3743    (set (attr "length")
3744         (if_then_else (eq_attr "is_thumb" "yes")
3745                       (const_int 14)
3746                       (const_int 12)))
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"
3761   "*
3762   {
3763     enum rtx_code code = GET_CODE (operands[4]);
3764     bool need_else;
3766     if (which_alternative != 0 || operands[3] != const0_rtx
3767         || (code != PLUS && code != IOR && code != XOR))
3768       need_else = true;
3769     else
3770       need_else = false;
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);
3775     if (TARGET_THUMB2)
3776       {
3777         if (need_else)
3778           output_asm_insn (\"ite\\t%d5\", operands);
3779         else
3780           output_asm_insn (\"it\\t%d5\", operands);
3781       }
3782     output_asm_insn (\"%i4%d5\\t%0, %1, %2\", operands);
3783     if (need_else)
3784       output_asm_insn (\"%i4%D5\\t%0, %1, %3\", operands);
3785     return \"\";
3786   }"
3787   [(set_attr "conds" "clob")
3788    (set (attr "length")
3789         (if_then_else (eq_attr "is_thumb" "yes")
3790                       (const_int 14)
3791                       (const_int 12)))
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")
3799         (minus:SI
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]))"
3807   "#"
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)])
3813               (set (match_dup 0)
3814                    (minus:SI (match_dup 1)
3815                              (match_dup 2))))
3816    (cond_exec (match_op_dup 5 [(reg:CC CC_REGNUM) (const_int 0)])
3817               (set (match_dup 0)
3818                    (match_dup 6)))]
3819   {
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);
3828   else
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]));
3833   else
3834     operands[6] = gen_rtx_MINUS (SImode, operands[1], operands[3]);
3835   }
3836   [(set_attr "conds" "clob")
3837    (set (attr "length")
3838         (if_then_else (eq_attr "is_thumb" "yes")
3839                       (const_int 14)
3840                       (const_int 12)))
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)"
3857   int mask;
3858   bool signed_sat;
3859   if (!arm_sat_operator_match (operands[<SAT:SATlo>], operands[<SAT:SAThi>],
3860                                &mask, &signed_sat))
3861     gcc_unreachable ();
3863   operands[1] = GEN_INT (mask);
3864   if (signed_sat)
3865     return "ssat%?\t%0, %1, %3";
3866   else
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)"
3884   int mask;
3885   bool signed_sat;
3886   if (!arm_sat_operator_match (operands[<SAT:SATlo>], operands[<SAT:SAThi>],
3887                                &mask, &signed_sat))
3888     gcc_unreachable ();
3890   operands[1] = GEN_INT (mask);
3891   if (signed_sat)
3892     return "ssat%?\t%0, %1, %4%S3";
3893   else
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" "")))]
3907   "TARGET_32BIT"
3908   "
3909   if (TARGET_NEON)
3910     {
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]));
3914       DONE;
3915     }
3916   else
3917     {
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]);
3921     }
3923   if (!CONST_INT_P (operands[2]) && TARGET_REALLY_IWMMXT)
3924     ; /* No special preparation statements; expand pattern as above.  */
3925   else
3926     {
3927       rtx scratch1, scratch2;
3929       if (CONST_INT_P (operands[2])
3930           && (HOST_WIDE_INT) INTVAL (operands[2]) == 1)
3931         {
3932           emit_insn (gen_arm_ashldi3_1bit (operands[0], operands[1]));
3933           DONE;
3934         }
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))
3943         FAIL;
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);
3951       DONE;
3952     }
3953   "
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")
3959                    (const_int 1)))
3960    (clobber (reg:CC CC_REGNUM))]
3961   "TARGET_32BIT"
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" "")))]
3972   "TARGET_EITHER"
3973   "
3974   if (CONST_INT_P (operands[2])
3975       && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) > 31)
3976     {
3977       emit_insn (gen_movsi (operands[0], const0_rtx));
3978       DONE;
3979     }
3980   "
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")))]
3987   "TARGET_THUMB1"
3988   "lsl\\t%0, %1, %2"
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" "")))]
3997   "TARGET_32BIT"
3998   "
3999   if (TARGET_NEON)
4000     {
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]));
4004       DONE;
4005     }
4007   if (!CONST_INT_P (operands[2]) && TARGET_REALLY_IWMMXT)
4008     ; /* No special preparation statements; expand pattern as above.  */
4009   else
4010     {
4011       rtx scratch1, scratch2;
4013       if (CONST_INT_P (operands[2])
4014           && (HOST_WIDE_INT) INTVAL (operands[2]) == 1)
4015         {
4016           emit_insn (gen_arm_ashrdi3_1bit (operands[0], operands[1]));
4017           DONE;
4018         }
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))
4027         FAIL;
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);
4035       DONE;
4036     }
4037   "
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")
4043                      (const_int 1)))
4044    (clobber (reg:CC CC_REGNUM))]
4045   "TARGET_32BIT"
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" "")))]
4056   "TARGET_EITHER"
4057   "
4058   if (CONST_INT_P (operands[2])
4059       && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) > 31)
4060     operands[2] = GEN_INT (31);
4061   "
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")))]
4068   "TARGET_THUMB1"
4069   "asr\\t%0, %1, %2"
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" "")))]
4078   "TARGET_32BIT"
4079   "
4080   if (TARGET_NEON)
4081     {
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]));
4085       DONE;
4086     }
4088   if (!CONST_INT_P (operands[2]) && TARGET_REALLY_IWMMXT)
4089     ; /* No special preparation statements; expand pattern as above.  */
4090   else
4091     {
4092       rtx scratch1, scratch2;
4094       if (CONST_INT_P (operands[2])
4095           && (HOST_WIDE_INT) INTVAL (operands[2]) == 1)
4096         {
4097           emit_insn (gen_arm_lshrdi3_1bit (operands[0], operands[1]));
4098           DONE;
4099         }
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))
4108         FAIL;
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);
4116       DONE;
4117     }
4118   "
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")
4124                      (const_int 1)))
4125    (clobber (reg:CC CC_REGNUM))]
4126   "TARGET_32BIT"
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" "")))]
4137   "TARGET_EITHER"
4138   "
4139   if (CONST_INT_P (operands[2])
4140       && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) > 31)
4141     {
4142       emit_insn (gen_movsi (operands[0], const0_rtx));
4143       DONE;
4144     }
4145   "
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")))]
4152   "TARGET_THUMB1"
4153   "lsr\\t%0, %1, %2"
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" "")))]
4162   "TARGET_32BIT"
4163   "
4164   if (CONST_INT_P (operands[2]))
4165     operands[2] = GEN_INT ((32 - INTVAL (operands[2])) % 32);
4166   else
4167     {
4168       rtx reg = gen_reg_rtx (SImode);
4169       emit_insn (gen_subsi3 (reg, GEN_INT (32), operands[2]));
4170       operands[2] = reg;
4171     }
4172   "
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" "")))]
4179   "TARGET_EITHER"
4180   "
4181   if (TARGET_32BIT)
4182     {
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);
4186     }
4187   else /* TARGET_THUMB1 */
4188     {
4189       if (CONST_INT_P (operands [2]))
4190         operands [2] = force_reg (SImode, operands[2]);
4191     }
4192   "
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")))]
4199   "TARGET_THUMB1"
4200   "ror\\t%0, %0, %2"
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")]))]
4210   "TARGET_32BIT"
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")])
4225                          (const_int 0)))
4226    (set (match_operand:SI 0 "s_register_operand" "=r,r")
4227         (match_op_dup 3 [(match_dup 1) (match_dup 2)]))]
4228   "TARGET_32BIT"
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")])
4240                          (const_int 0)))
4241    (clobber (match_scratch:SI 0 "=r,r"))]
4242   "TARGET_32BIT"
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")])))]
4254   "TARGET_32BIT"
4255   "mvn%?\\t%0, %1%S3"
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)
4264         (compare:CC_NOOV
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")]))
4268          (const_int 0)))
4269    (set (match_operand:SI 0 "s_register_operand" "=r,r")
4270         (not:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)])))]
4271   "TARGET_32BIT"
4272   "mvn%.\\t%0, %1%S3"
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)
4280         (compare:CC_NOOV
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")]))
4284          (const_int 0)))
4285    (clobber (match_scratch:SI 0 "=r,r"))]
4286   "TARGET_32BIT"
4287   "mvn%.\\t%0, %1%S3"
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"
4302   "
4303   {
4304     HOST_WIDE_INT lshift = 32 - INTVAL (operands[2]) - INTVAL (operands[3]);
4305     HOST_WIDE_INT rshift = 32 - INTVAL (operands[2]);
4306     
4307     if (arm_arch_thumb2)
4308       {
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)
4314           {
4315             rtx base_addr;
4317             if (BYTES_BIG_ENDIAN)
4318               bitpos = GET_MODE_BITSIZE (GET_MODE (operands[0])) - width
4319                        - bitpos;
4321             if (width == 32)
4322               {
4323                 base_addr = adjust_address (operands[1], SImode,
4324                                             bitpos / BITS_PER_UNIT);
4325                 emit_insn (gen_unaligned_loadsi (operands[0], base_addr));
4326               }
4327             else
4328               {
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)
4339                   FAIL;
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);
4345               }
4346             DONE;
4347           }
4348         else if (s_register_operand (operands[1], GET_MODE (operands[1])))
4349           {
4350             emit_insn (gen_extzv_t2 (operands[0], operands[1], operands[2],
4351                                      operands[3]));
4352             DONE;
4353           }
4354         else
4355           FAIL;
4356       }
4357     
4358     if (!s_register_operand (operands[1], GET_MODE (operands[1])))
4359       FAIL;
4361     operands[3] = GEN_INT (rshift);
4362     
4363     if (lshift == 0)
4364       {
4365         emit_insn (gen_lshrsi3 (operands[0], operands[1], operands[3]));
4366         DONE;
4367       }
4368       
4369     emit_insn (gen_extzv_t1 (operands[0], operands[1], GEN_INT (lshift),
4370                              operands[3], gen_reg_rtx (SImode)));
4371     DONE;
4372   }"
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" "")))]
4384   "TARGET_THUMB1"
4385   "")
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" "")))]
4392   "arm_arch_thumb2"
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)
4399     {
4400       rtx base_addr;
4401       
4402       if (BYTES_BIG_ENDIAN)
4403         bitpos = GET_MODE_BITSIZE (GET_MODE (operands[0])) - width - bitpos;
4404       
4405       if (width == 32)
4406         {
4407           base_addr = adjust_address (operands[1], SImode,
4408                                       bitpos / BITS_PER_UNIT);
4409           emit_insn (gen_unaligned_loadsi (operands[0], base_addr));
4410         }
4411       else
4412         {
4413           rtx dest = operands[0];
4414           rtx tmp = gen_reg_rtx (SImode);
4415           
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);
4421           
4422           if (GET_MODE_BITSIZE (GET_MODE (dest)) != width)
4423             FAIL;
4424           
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);
4429         }
4431       DONE;
4432     }
4433   else if (!s_register_operand (operands[1], GET_MODE (operands[1])))
4434     FAIL;
4435   else if (GET_MODE (operands[0]) == SImode
4436            && GET_MODE (operands[1]) == SImode)
4437     {
4438       emit_insn (gen_extv_regsi (operands[0], operands[1], operands[2],
4439                                  operands[3]));
4440       DONE;
4441     }
4443   FAIL;
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" "")))]
4453   ""
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")
4473         (sign_extend:SI
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")
4486         (zero_extend:SI
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"
4531   "#"
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))]
4535   {
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]))
4544       {
4545         rtx tmp = operands[1];
4546         operands[1] = operands[3];
4547         operands[3] = tmp;
4548         tmp = operands[0];
4549         operands[0] = operands[2];
4550         operands[2] = tmp;
4551       }
4552   }
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"
4563   "#"
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))]
4567   {
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]);
4572   }
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")))]
4584   "arm_arch_thumb2"
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")))]
4597   "arm_arch_thumb2"
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")))]
4611   "TARGET_IDIV"
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")))]
4622   "TARGET_IDIV"
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"
4633  [(parallel
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))])]
4637   "TARGET_EITHER"
4638   {
4639     if (TARGET_NEON)
4640       {
4641         emit_insn (gen_negdi2_neon (operands[0], operands[1]));
4642         DONE;
4643       }
4644   }
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))]
4653   "TARGET_ARM"
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))))]
4661   {
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]);
4666   }
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))]
4676   "TARGET_THUMB1"
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" "")))]
4685   "TARGET_EITHER"
4686   ""
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")))]
4692   "TARGET_32BIT"
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")))]
4704   "TARGET_THUMB1"
4705   "neg\\t%0, %1"
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"
4714   ""
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"
4721   "")
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"))))]
4726    "TARGET_32BIT"
4727    "#"
4728    ""
4729    [(set (match_dup 2)
4730          (neg:SI (match_dup 1)))
4731     (set (match_dup 3)
4732          (const_int 0))]
4733    {
4734       operands[2] = gen_lowpart (SImode, operands[0]);
4735       operands[3] = gen_highpart (SImode, operands[0]);
4736    }
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))]
4747   "TARGET_32BIT"
4748   "#"
4749   "&& reload_completed"
4750   [(const_int 0)]
4751   {
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]))
4756       {
4757         /* Input overlaps the low word of the output.  Use:
4758                 asr     Rhi, Rin, #31
4759                 rsbs    Rlo, Rin, #0
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],
4765                                                   GEN_INT (31))));
4767         emit_insn (gen_subsi3_compare (low, const0_rtx, operands[1]));
4768         if (TARGET_ARM)
4769           emit_insn (gen_rtx_SET (VOIDmode, high,
4770                                   gen_rtx_MINUS (SImode,
4771                                                  gen_rtx_MINUS (SImode,
4772                                                                 const0_rtx,
4773                                                                 high),
4774                                                  gen_rtx_LTU (SImode,
4775                                                               cc_reg,
4776                                                               const0_rtx))));
4777         else
4778           {
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,
4783                                                                   high,
4784                                                                   two_x),
4785                                                    gen_rtx_LTU (SImode,
4786                                                                 cc_reg,
4787                                                                 const0_rtx))));
4788           }
4789       }
4790     else
4791       {
4792         /* No overlap, or overlap on high word.  Use:
4793                 rsb     Rlo, Rin, #0
4794                 bic     Rhi, Rlo, Rin
4795                 asr     Rhi, Rhi, #31
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]),
4802                                              low)));
4803         emit_insn (gen_rtx_SET (VOIDmode, high,
4804                                 gen_rtx_ASHIFTRT (SImode, high,
4805                                                   GEN_INT (31))));
4806       }
4807     DONE;
4808   }
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))]
4818   "TARGET_32BIT"
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))))]
4828   {
4829     operands[2] = gen_highpart (SImode, operands[0]);
4830     operands[0] = gen_lowpart (SImode, operands[0]);
4831   }
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
4840 ;; (neg (abs...))
4842 (define_expand "abssi2"
4843   [(parallel
4844     [(set (match_operand:SI         0 "s_register_operand" "")
4845           (abs:SI (match_operand:SI 1 "s_register_operand" "")))
4846      (clobber (match_dup 2))])]
4847   "TARGET_EITHER"
4848   "
4849   if (TARGET_THUMB1)
4850     operands[2] = gen_rtx_SCRATCH (SImode);
4851   else
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))]
4859   "TARGET_ARM"
4860   "#"
4861   "&& reload_completed"
4862   [(const_int 0)]
4863   {
4864    /* if (which_alternative == 0) */
4865    if (REGNO(operands[0]) == REGNO(operands[1]))
4866      {
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))))]
4873       */
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),
4880                                                  const0_rtx)),
4881                                     (gen_rtx_SET (VOIDmode,
4882                                                   operands[0],
4883                                                   (gen_rtx_MINUS (SImode,
4884                                                                   const0_rtx,
4885                                                                   operands[1]))))));
4886       DONE;
4887      }
4888    else
4889      {
4890       /* Emit the pattern:
4891          alt1: eor%?\\t%0, %1, %1, asr #31\;sub%?\\t%0, %0, %1, asr #31
4892          [(set (match_dup 0)
4893                (xor:SI (match_dup 1)
4894                        (ashiftrt:SI (match_dup 1) (const_int 31))))
4895           (set (match_dup 0)
4896                (minus:SI (match_dup 0)
4897                       (ashiftrt:SI (match_dup 1) (const_int 31))))]
4898       */
4899       emit_insn (gen_rtx_SET (VOIDmode,
4900                               operands[0],
4901                               gen_rtx_XOR (SImode,
4902                                            gen_rtx_ASHIFTRT (SImode,
4903                                                              operands[1],
4904                                                              GEN_INT (31)),
4905                                            operands[1])));
4906       emit_insn (gen_rtx_SET (VOIDmode,
4907                               operands[0],
4908                               gen_rtx_MINUS (SImode,
4909                                              operands[0],
4910                                              gen_rtx_ASHIFTRT (SImode,
4911                                                                operands[1],
4912                                                                GEN_INT (31)))));
4913       DONE;
4914      }
4915   }
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"))]
4927   "TARGET_THUMB1"
4928   "#"
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)))]
4933   ""
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))]
4942   "TARGET_ARM"
4943   "#"
4944   "&& reload_completed"
4945   [(const_int 0)]
4946   {
4947    /* if (which_alternative == 0) */
4948    if (REGNO (operands[0]) == REGNO (operands[1]))
4949      {
4950       /* Emit the pattern:
4951          cmp\\t%0, #0\;rsbgt\\t%0, %0, #0
4952       */
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,
4957                                     gen_rtx_GT (SImode,
4958                                                 gen_rtx_REG (CCmode, CC_REGNUM),
4959                                                 const0_rtx),
4960                                     gen_rtx_SET (VOIDmode,
4961                                                  operands[0],
4962                                                  (gen_rtx_MINUS (SImode,
4963                                                                  const0_rtx,
4964                                                                  operands[1])))));
4965      }
4966    else
4967      {
4968       /* Emit the pattern:
4969          eor%?\\t%0, %1, %1, asr #31\;rsb%?\\t%0, %0, %1, asr #31
4970       */
4971       emit_insn (gen_rtx_SET (VOIDmode,
4972                               operands[0],
4973                               gen_rtx_XOR (SImode,
4974                                            gen_rtx_ASHIFTRT (SImode,
4975                                                              operands[1],
4976                                                              GEN_INT (31)),
4977                                            operands[1])));
4978       emit_insn (gen_rtx_SET (VOIDmode,
4979                               operands[0],
4980                               gen_rtx_MINUS (SImode,
4981                                              gen_rtx_ASHIFTRT (SImode,
4982                                                                operands[1],
4983                                                                GEN_INT (31)),
4984                                              operands[0])));
4985      }
4986    DONE;
4987   }
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"))]
4999   "TARGET_THUMB1"
5000   "#"
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)))]
5005   ""
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"
5014   "")
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"
5020   "")
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"
5026   "")
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"
5032   "")
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")))]
5037   "TARGET_32BIT"
5038   "@
5039    vmvn\t%P0, %P1
5040    #
5041    #
5042    vmvn\t%P0, %P1"
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)))]
5047   "
5048   {
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]);
5053   }"
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" "")))]
5063   "TARGET_EITHER"
5064   ""
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")))]
5070   "TARGET_32BIT"
5071   "mvn%?\\t%0, %1"
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")))]
5082   "TARGET_THUMB1"
5083   "mvn\\t%0, %1"
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"))
5091                          (const_int 0)))
5092    (set (match_operand:SI 0 "s_register_operand" "=r")
5093         (not:SI (match_dup 1)))]
5094   "TARGET_32BIT"
5095   "mvn%.\\t%0, %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"))
5103                          (const_int 0)))
5104    (clobber (match_scratch:SI 0 "=r"))]
5105   "TARGET_32BIT"
5106   "mvn%.\\t%0, %1"
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" "")))]
5116   "TARGET_EITHER"
5117   "
5118   {
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);
5123     DONE;
5124   }"
5127 (define_expand "floatdihf2"
5128   [(set (match_operand:HF           0 "general_operand" "")
5129         (float:HF (match_operand:DI 1 "general_operand" "")))]
5130   "TARGET_EITHER"
5131   "
5132   {
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);
5137     DONE;
5138   }"
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"
5145   "
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"
5152   "
5155 (define_expand "fix_trunchfsi2"
5156   [(set (match_operand:SI         0 "general_operand" "")
5157         (fix:SI (fix:HF (match_operand:HF 1 "general_operand"  ""))))]
5158   "TARGET_EITHER"
5159   "
5160   {
5161     rtx op1 = convert_to_mode (SFmode, operands[1], 0);
5162     expand_fix (operands[0], op1, 0);
5163     DONE;
5164   }"
5167 (define_expand "fix_trunchfdi2"
5168   [(set (match_operand:DI         0 "general_operand" "")
5169         (fix:DI (fix:HF (match_operand:HF 1 "general_operand"  ""))))]
5170   "TARGET_EITHER"
5171   "
5172   {
5173     rtx op1 = convert_to_mode (SFmode, operands[1], 0);
5174     expand_fix (operands[0], op1, 0);
5175     DONE;
5176   }"
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"
5183   "
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"
5190   "
5193 ;; Truncation insns
5195 (define_expand "truncdfsf2"
5196   [(set (match_operand:SF  0 "s_register_operand" "")
5197         (float_truncate:SF
5198          (match_operand:DF 1 "s_register_operand" "")))]
5199   "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
5200   ""
5203 /* DFmode -> HFmode conversions have to go through SFmode.  */
5204 (define_expand "truncdfhf2"
5205   [(set (match_operand:HF  0 "general_operand" "")
5206         (float_truncate:HF
5207          (match_operand:DF 1 "general_operand" "")))]
5208   "TARGET_EITHER"
5209   "
5210   {
5211     rtx op1;
5212     op1 = convert_to_mode (SFmode, operands[1], 0);
5213     op1 = convert_to_mode (HFmode, op1, 0);
5214     emit_move_insn (operands[0], op1);
5215     DONE;
5216   }"
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>"
5226   "#"
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>"
5239   "#"
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
5249 (define_split
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]))
5263     {
5264       if (src_mode == SImode)
5265         emit_move_insn (lo_part, operands[1]);
5266       else
5267         emit_insn (gen_rtx_SET (VOIDmode, lo_part,
5268                                 gen_rtx_ZERO_EXTEND (SImode, operands[1])));
5269       operands[1] = lo_part;
5270     }
5271   operands[0] = gen_highpart (SImode, operands[0]);
5272   operands[1] = const0_rtx;
5275 (define_split
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]))
5290     {
5291       if (src_mode == SImode)
5292         emit_move_insn (lo_part, operands[1]);
5293       else
5294         emit_insn (gen_rtx_SET (VOIDmode, lo_part,
5295                                 gen_rtx_SIGN_EXTEND (SImode, operands[1])));
5296       operands[1] = lo_part;
5297     }
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" "")))]
5304   "TARGET_EITHER"
5306   if (TARGET_ARM && !arm_arch4 && MEM_P (operands[1]))
5307     {
5308       emit_insn (gen_movhi_bytes (operands[0], operands[1]));
5309       DONE;
5310     }
5311   if (!arm_arch6 && !MEM_P (operands[1]))
5312     {
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)));
5317       DONE;
5318     }
5321 (define_split
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")))]
5334   "TARGET_THUMB1"
5336   rtx mem;
5338   if (which_alternative == 0 && arm_arch6)
5339     return "uxth\t%0, %1";
5340   if (which_alternative == 0)
5341     return "#";
5343   mem = XEXP (operands[1], 0);
5345   if (GET_CODE (mem) == CONST)
5346     mem = XEXP (mem, 0);
5347     
5348   if (GET_CODE (mem) == PLUS)
5349     {
5350       rtx a = XEXP (mem, 0);
5352       /* This can happen due to bugs in reload.  */
5353       if (REG_P (a) && REGNO (a) == SP_REGNUM)
5354         {
5355           rtx ops[2];
5356           ops[0] = operands[0];
5357           ops[1] = a;
5358       
5359           output_asm_insn ("mov\t%0, %1", ops);
5361           XEXP (mem, 0) = operands[0];
5362        }
5363     }
5364     
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))
5370                          (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"
5378   "@
5379    #
5380    ldr%(h%)\\t%0, %1"
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"
5389   "@
5390    uxth%?\\t%0, %1
5391    ldr%(h%)\\t%0, %1"
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")))]
5400   "TARGET_INT_SIMD"
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" "")))]
5410   "TARGET_EITHER"
5412   if (TARGET_ARM && !arm_arch6 && !MEM_P (operands[1]))
5413     {
5414       emit_insn (gen_andsi3 (operands[0],
5415                              gen_lowpart (SImode, operands[1]),
5416                                           GEN_INT (255)));
5417       DONE;
5418     }
5419   if (!arm_arch6 && !MEM_P (operands[1]))
5420     {
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)));
5425       DONE;
5426     }
5429 (define_split
5430   [(set (match_operand:SI 0 "s_register_operand" "")
5431         (zero_extend:SI (match_operand:QI 1 "s_register_operand" "")))]
5432   "!arm_arch6"
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);
5437   if (TARGET_ARM)
5438     {
5439       emit_insn (gen_andsi3 (operands[0], operands[2], GEN_INT (255)));
5440       DONE;
5441     }
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"
5448   "@
5449    #
5450    ldrb\\t%0, %1"
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"
5460   "@
5461    uxtb\\t%0, %1
5462    ldrb\\t%0, %1"
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"
5471   "@
5472    #
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"
5483   "@
5484    uxtb%(%)\\t%0, %1
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")))]
5494   "TARGET_INT_SIMD"
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")]
5501 (define_split
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)))]
5508   ""
5511 (define_split
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)))]
5518   ""
5522 (define_split
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" ""))
5528                     (zero_extend:SI
5529                      (match_operator 5 "subreg_lowpart_operator"
5530                       [(match_operand:SI 4 "s_register_operand" "")]))))]
5531   "TARGET_32BIT
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))
5537                                   (match_dup 4)))
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")
5545                          (const_int 0)))]
5546   "TARGET_32BIT"
5547   "tst%?\\t%0, #255"
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" "")))]
5557   "TARGET_EITHER"
5559   if (TARGET_THUMB1)
5560     {
5561       emit_insn (gen_thumb1_extendhisi2 (operands[0], operands[1]));
5562       DONE;
5563     }
5564   if (MEM_P (operands[1]) && TARGET_ARM && !arm_arch4)
5565     {
5566       emit_insn (gen_extendhisi2_mem (operands[0], operands[1]));
5567       DONE;
5568     }
5570   if (!arm_arch6 && !MEM_P (operands[1]))
5571     {
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)));
5576       DONE;
5577     }
5580 (define_split
5581   [(parallel
5582     [(set (match_operand:SI 0 "register_operand" "")
5583           (sign_extend:SI (match_operand:HI 1 "register_operand" "")))
5584      (clobber (match_scratch:SI 2 ""))])]
5585   "!arm_arch6"
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"))]
5603   "TARGET_THUMB1"
5604   "*
5605   {
5606     rtx ops[4];
5607     rtx mem;
5609     if (which_alternative == 0 && !arm_arch6)
5610       return \"#\";
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
5619        address check.  */
5620        
5621     if (GET_CODE (mem) == CONST)
5622       mem = XEXP (mem, 0);
5623     
5624     if (GET_CODE (mem) == LABEL_REF)
5625       return \"ldr\\t%0, %1\";
5626     
5627     if (GET_CODE (mem) == PLUS)
5628       {
5629         rtx a = XEXP (mem, 0);
5630         rtx b = XEXP (mem, 1);
5632         if (GET_CODE (a) == LABEL_REF
5633             && CONST_INT_P (b))
5634           return \"ldr\\t%0, %1\";
5636         if (REG_P (b))
5637           return \"ldrsh\\t%0, %1\";
5638           
5639         ops[1] = a;
5640         ops[2] = b;
5641       }
5642     else
5643       {
5644         ops[1] = mem;
5645         ops[2] = const0_rtx;
5646       }
5647       
5648     gcc_assert (REG_P (ops[1]));
5650     ops[0] = operands[0];
5651     if (reg_mentioned_p (operands[2], ops[1]))
5652       ops[3] = ops[0];
5653     else
5654       ops[3] = operands[2];
5655     output_asm_insn (\"mov\\t%3, %2\;ldrsh\\t%0, [%1, %3]\", ops);
5656     return \"\";
5657   }"
5658   [(set_attr_alternative "length"
5659                          [(if_then_else (eq_attr "is_arch6" "yes")
5660                                         (const_int 2) (const_int 4))
5661                           (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 "" "")))
5669    (set (match_dup 3)
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)))]
5674   "TARGET_ARM"
5675   "
5676   {
5677     rtx mem1, mem2;
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]);
5684     operands[1] = mem1;
5685     operands[2] = gen_reg_rtx (SImode);
5686     operands[3] = gen_reg_rtx (SImode);
5687     operands[6] = gen_reg_rtx (SImode);
5688     operands[7] = mem2;
5690     if (BYTES_BIG_ENDIAN)
5691       {
5692         operands[4] = operands[2];
5693         operands[5] = operands[3];
5694       }
5695     else
5696       {
5697         operands[4] = operands[3];
5698         operands[5] = operands[2];
5699       }
5700   }"
5703 (define_split
5704   [(set (match_operand:SI 0 "register_operand" "")
5705         (sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
5706   "!arm_arch6"
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"
5717   "@
5718    #
5719    ldr%(sh%)\\t%0, %1"
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"
5732   "@
5733    sxth%?\\t%0, %1
5734    ldr%(sh%)\\t%0, %1"
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")))]
5746   "TARGET_INT_SIMD"
5747   "sxtah%?\\t%0, %2, %1"
5748   [(set_attr "type" "alu_shift_reg")]
5751 (define_expand "extendqihi2"
5752   [(set (match_dup 2)
5753         (ashift:SI (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "")
5754                    (const_int 24)))
5755    (set (match_operand:HI 0 "s_register_operand" "")
5756         (ashiftrt:SI (match_dup 2)
5757                      (const_int 24)))]
5758   "TARGET_ARM"
5759   "
5760   {
5761     if (arm_arch4 && MEM_P (operands[1]))
5762       {
5763         emit_insn (gen_rtx_SET (VOIDmode,
5764                                 operands[0],
5765                                 gen_rtx_SIGN_EXTEND (HImode, operands[1])));
5766         DONE;
5767       }
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);
5773   }"
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" "")))]
5790   "TARGET_EITHER"
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]))
5796     {
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)));
5801       DONE;
5802     }
5805 (define_split
5806   [(set (match_operand:SI 0 "register_operand" "")
5807         (sign_extend:SI (match_operand:QI 1 "register_operand" "")))]
5808   "!arm_arch6"
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"
5819   "@
5820    #
5821    ldr%(sb%)\\t%0, %1"
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")
5831         (sign_extend:SI
5832          (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "r,Uq")))]
5833   "TARGET_ARM && arm_arch6"
5834   "@
5835    sxtb%?\\t%0, %1
5836    ldr%(sb%)\\t%0, %1"
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")))]
5847   "TARGET_INT_SIMD"
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")]
5854 (define_split
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.  */
5869     FAIL;
5871   if (GET_CODE (addr) == PLUS
5872       && !REG_P (XEXP (addr, 0)) && !REG_P (XEXP (addr, 1)))
5873     FAIL;
5875   if (reg_overlap_mentioned_p (operands[0], addr))
5876     {
5877       rtx t = gen_lowpart (QImode, operands[0]);
5878       emit_move_insn (t, operands[1]);
5879       emit_insn (gen_thumb1_extendqisi2 (operands[0], t));
5880       DONE;
5881     }
5883   if (REG_P (addr))
5884     {
5885       addr = gen_rtx_PLUS (Pmode, addr, operands[0]);
5886       operands[2] = const0_rtx;
5887     }
5888   else if (GET_CODE (addr) != PLUS)
5889     FAIL;
5890   else if (REG_P (XEXP (addr, 0)))
5891     {
5892       operands[2] = XEXP (addr, 1);
5893       addr = gen_rtx_PLUS (Pmode, XEXP (addr, 0), operands[0]);
5894     }
5895   else
5896     {
5897       operands[2] = XEXP (addr, 0);
5898       addr = gen_rtx_PLUS (Pmode, XEXP (addr, 1), operands[0]);
5899     }
5901   operands[3] = change_address (operands[1], QImode, addr);
5904 (define_peephole2
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" "")))]
5910   "TARGET_THUMB1
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")))]
5928   "TARGET_THUMB1"
5930   rtx addr;
5932   if (which_alternative == 0 && arm_arch6)
5933     return "sxtb\\t%0, %1";
5934   if (which_alternative == 0)
5935     return "#";
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";
5941       
5942   return "#";
5944   [(set_attr_alternative "length"
5945                          [(if_then_else (eq_attr "is_arch6" "yes")
5946                                         (const_int 2) (const_int 4))
5947                           (const_int 2)
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"
5957   ""
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"  "")))]
5964   "TARGET_EITHER"
5965   "
5966   {
5967     rtx op1;
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));
5971     DONE;
5972   }"
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
5979 ;; registers
5980 ;;(define_expand "loadti"
5981 ;;  [(set (match_operand:TI 0 "s_register_operand" "")
5982 ;;      (mem:TI (match_operand:SI 1 "address_operand" "")))]
5983 ;;  "" "")
5985 ;;(define_expand "storeti"
5986 ;;  [(set (mem:TI (match_operand:TI 0 "address_operand" ""))
5987 ;;      (match_operand:TI 1 "s_register_operand" ""))]
5988 ;;  "" "")
5990 ;;(define_expand "movti"
5991 ;;  [(set (match_operand:TI 0 "general_operand" "")
5992 ;;      (match_operand:TI 1 "general_operand" ""))]
5993 ;;  ""
5994 ;;  "
5996 ;;  rtx insn;
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));
6004 ;;  else
6005 ;;    FAIL;
6007 ;;  emit_insn (insn);
6008 ;;  DONE;
6009 ;;}")
6011 ;; Recognize garbage generated above.
6013 ;;(define_insn ""
6014 ;;  [(set (match_operand:TI 0 "general_operand" "=r,r,r,<,>,m")
6015 ;;      (match_operand:TI 1 "general_operand" "<,>,m,r,r,r"))]
6016 ;;  ""
6017 ;;  "*
6018 ;;  {
6019 ;;    register mem = (which_alternative < 3);
6020 ;;    register const char *template;
6022 ;;    operands[mem] = XEXP (operands[mem], 0);
6023 ;;    switch (which_alternative)
6024 ;;      {
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;
6031 ;;      }
6032 ;;    output_asm_insn (template, operands);
6033 ;;    return \"\";
6034 ;;  }")
6036 (define_expand "movdi"
6037   [(set (match_operand:DI 0 "general_operand" "")
6038         (match_operand:DI 1 "general_operand" ""))]
6039   "TARGET_EITHER"
6040   "
6041   if (can_create_pseudo_p ())
6042     {
6043       if (!REG_P (operands[0]))
6044         operands[1] = force_reg (DImode, operands[1]);
6045     }
6046   "
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"))]
6052   "TARGET_32BIT
6053    && !(TARGET_HARD_FLOAT && TARGET_VFP)
6054    && !TARGET_IWMMXT
6055    && (   register_operand (operands[0], DImode)
6056        || register_operand (operands[1], DImode))"
6057   "*
6058   switch (which_alternative)
6059     {
6060     case 0:
6061     case 1:
6062     case 2:
6063       return \"#\";
6064     default:
6065       return output_move_double (operands, true, NULL);
6066     }
6067   "
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,*")]
6076 (define_split
6077   [(set (match_operand:ANY64 0 "arm_general_register_operand" "")
6078         (match_operand:ANY64 1 "const_double_operand" ""))]
6079   "TARGET_32BIT
6080    && reload_completed
6081    && (arm_const_double_inline_cost (operands[1])
6082        <= arm_max_const_double_inline_cost ())"
6083   [(const_int 0)]
6084   "
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]),
6091                                                  operands[1])),
6092                       gen_highpart (SImode, operands[0]), NULL_RTX, 0);
6093   DONE;
6094   "
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.
6105 (define_split
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))]
6112   "
6113   operands[2] = gen_highpart (SImode, operands[0]);
6114   operands[3] = gen_highpart_mode (SImode, GET_MODE (operands[0]),
6115                                    operands[1]);
6116   operands[0] = gen_lowpart (SImode, operands[0]);
6117   operands[1] = gen_lowpart (SImode, operands[1]);
6118   "
6121 (define_split
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))]
6127   "
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]))
6135     {
6136       rtx tmp0 = operands[0];
6137       rtx tmp1 = operands[1];
6139       operands[0] = operands[2];
6140       operands[1] = operands[3];
6141       operands[2] = tmp0;
6142       operands[3] = tmp1;
6143     }
6144   "
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
6149 ;; schedule.
6150 (define_split
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" ""))))]
6154   "TARGET_LDRD
6155   && reg_overlap_mentioned_p (operands[0], operands[1])
6156   && reg_overlap_mentioned_p (operands[0], operands[2])"
6157   [(set (match_dup 4)
6158         (plus:SI (match_dup 1)
6159                  (match_dup 2)))
6160    (set (match_dup 0)
6161         (mem:DI (match_dup 4)))]
6162   "
6163   operands[4] = gen_rtx_REG (SImode, REGNO(operands[0]));
6164   "
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"))]
6174   "TARGET_THUMB1
6175    && (   register_operand (operands[0], DImode)
6176        || register_operand (operands[1], DImode))"
6177   "*
6178   {
6179   switch (which_alternative)
6180     {
6181     default:
6182     case 0:
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\";
6186     case 1:
6187       return \"mov\\t%Q0, %1\;mov\\t%R0, #0\";
6188     case 2:
6189       operands[1] = GEN_INT (- INTVAL (operands[1]));
6190       return \"mov\\t%Q0, %1\;neg\\t%Q0, %Q0\;asr\\t%R0, %Q0, #31\";
6191     case 3:
6192       return \"ldmia\\t%1, {%0, %H0}\";
6193     case 4:
6194       return \"stmia\\t%0, {%1, %H1}\";
6195     case 5:
6196       return thumb_load_double_from_address (operands);
6197     case 6:
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);
6201       return \"\";
6202     case 7:
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\";
6206     }
6207   }"
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" ""))]
6216   "TARGET_EITHER"
6217   "
6218   {
6219   rtx base, offset, tmp;
6221   if (TARGET_32BIT)
6222     {
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]))))
6230         {
6231            arm_split_constant (SET, SImode, NULL_RTX,
6232                                INTVAL (operands[1]), operands[0], NULL_RTX,
6233                                optimize && can_create_pseudo_p ());
6234           DONE;
6235         }
6236     }
6237   else /* TARGET_THUMB1...  */
6238     {
6239       if (can_create_pseudo_p ())
6240         {
6241           if (!REG_P (operands[0]))
6242             operands[1] = force_reg (SImode, operands[1]);
6243         }
6244     }
6246   if (ARM_OFFSETS_MUST_BE_WITHIN_SECTIONS_P)
6247     {
6248       split_const (operands[1], &base, &offset);
6249       if (GET_CODE (base) == SYMBOL_REF
6250           && !offset_within_block_p (base, INTVAL (offset)))
6251         {
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));
6255           DONE;
6256         }
6257     }
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]))
6262     {
6263       rtx tmp = operands[1];
6264       rtx addend = NULL;
6266       if (GET_CODE (tmp) == CONST && GET_CODE (XEXP (tmp, 0)) == PLUS)
6267         {
6268           addend = XEXP (XEXP (tmp, 0), 1);
6269           tmp = XEXP (XEXP (tmp, 0), 0);
6270         }
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);
6277       if (addend)
6278         {
6279           tmp = gen_rtx_PLUS (SImode, tmp, addend);
6280           tmp = force_operand (tmp, operands[0]);
6281         }
6282       operands[1] = tmp;
6283     }
6284   else if (flag_pic
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 ()
6290                                              ? operands[0]
6291                                              : 0));
6292   }
6293   "
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")))]
6303   "arm_arch_thumb2"
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))"
6318   "@
6319    mov%?\\t%0, %1
6320    mov%?\\t%0, %1
6321    mvn%?\\t%0, #%B1
6322    movw%?\\t%0, %1
6323    ldr%?\\t%0, %1
6324    str%?\\t%1, %0"
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,*")]
6331 (define_split
6332   [(set (match_operand:SI 0 "arm_general_register_operand" "")
6333         (match_operand:SI 1 "const_int_operand" ""))]
6334   "TARGET_32BIT
6335   && (!(const_ok_for_arm (INTVAL (operands[1]))
6336         || const_ok_for_arm (~INTVAL (operands[1]))))"
6337   [(clobber (const_int 0))]
6338   "
6339   arm_split_constant (SET, SImode, NULL_RTX, 
6340                       INTVAL (operands[1]), operands[0], NULL_RTX, 0);
6341   DONE;
6342   "
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
6349 ;; adds r0, #4
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.
6359 (define_split
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" ""))))]
6363   "TARGET_THUMB2
6364    && arm_disable_literal_pool
6365    && reload_completed
6366    && GET_CODE (operands[1]) == SYMBOL_REF"
6367   [(clobber (const_int 0))]
6368   "
6369     int offset = INTVAL (operands[2]);
6371     if (offset < -0x8000 || offset > 0x7fff)
6372       {
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])));
6376       }
6377     else
6378       {
6379         rtx op = gen_rtx_CONST (SImode,
6380                                 gen_rtx_PLUS (SImode, operands[1], operands[2]));
6381         arm_emit_movpair (operands[0], op);
6382       }
6383   "
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.
6391 (define_split
6392   [(set (match_operand:SI 0 "arm_general_register_operand" "")
6393        (match_operand:SI 1 "general_operand" ""))]
6394   "TARGET_32BIT
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]);
6401   DONE;
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"))]
6407   "TARGET_THUMB1
6408    && (   register_operand (operands[0], SImode) 
6409        || register_operand (operands[1], SImode))"
6410   "@
6411    mov  %0, %1
6412    mov  %0, %1
6413    #
6414    #
6415    ldmia\\t%1, {%0}
6416    stmia\\t%0, {%1}
6417    ldr\\t%0, %1
6418    str\\t%1, %0
6419    mov\\t%0, %1"
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")])
6425 (define_split 
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)))]
6431   "
6432   {
6433     operands[1] = GEN_INT (- INTVAL (operands[1]));
6434     operands[2] = can_create_pseudo_p () ? gen_reg_rtx (SImode) : operands[0];
6435   }"
6438 (define_split 
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)))]
6444   "
6445   {
6446     unsigned HOST_WIDE_INT val = INTVAL (operands[1]) & 0xffffffffu;
6447     unsigned HOST_WIDE_INT mask = 0xff;
6448     int i;
6449     
6450     for (i = 0; i < 25; i++)
6451       if ((val & (mask << i)) == val)
6452         break;
6454     /* Don't split if the shift is zero.  */
6455     if (i == 0)
6456       FAIL;
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);
6461   }"
6464 ;; For thumb1 split imm move [256-510] into mov [1-255] and add #255
6465 (define_split 
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)))]
6471   "
6472   {
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);
6476   }"
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 "" "")]
6496                                     UNSPEC_PIC_SYM))))]
6497   "flag_pic"
6500 ;; Split calculate_pic_address into pic_load_addr_* and a move.
6501 (define_split
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 "" "")]
6505                                     UNSPEC_PIC_SYM))))]
6506   "flag_pic"
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))]
6522  "flag_pic"
6523  "#"
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"
6544   "ldr%?\\t%0, %1"
6545   [(set_attr "type" "load1")
6546    (set (attr "pool_range")
6547         (if_then_else (eq_attr "is_thumb" "no")
6548                       (const_int 4096)
6549                       (const_int 4094)))
6550    (set (attr "neg_pool_range")
6551         (if_then_else (eq_attr "is_thumb" "no")
6552                       (const_int 4084)
6553                       (const_int 0)))]
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"
6560   "ldr\\t%0, %1"
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")
6568                     (const_int 4)
6569                     (match_operand 2 "" "")]
6570                    UNSPEC_PIC_BASE))]
6571   "TARGET_THUMB"
6572   "*
6573   (*targetm.asm_out.internal_label) (asm_out_file, \"LPIC\",
6574                                      INTVAL (operands[2]));
6575   return \"add\\t%0, %|pc\";
6576   "
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")
6584                     (const_int 8)
6585                     (match_operand 2 "" "")]
6586                    UNSPEC_PIC_BASE))]
6587   "TARGET_ARM"
6588   "*
6589     (*targetm.asm_out.internal_label) (asm_out_file, \"LPIC\",
6590                                        INTVAL (operands[2]));
6591     return \"add%?\\t%0, %|pc, %1\";
6592   "
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")
6600                             (const_int 8)
6601                             (match_operand 2 "" "")]
6602                            UNSPEC_PIC_BASE)))]
6603   "TARGET_ARM"
6604   "*
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\";
6608   "
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.
6617 (define_peephole2
6618   [(set (match_operand:SI 0 "register_operand" "")
6619         (unspec:SI [(match_operand:SI 3 "register_operand" "")
6620                     (const_int 8)
6621                     (match_operand 1 "" "")]
6622                    UNSPEC_PIC_BASE))
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])"
6626   [(set (match_dup 2)
6627         (mem:SI (unspec:SI [(match_dup 3)
6628                             (const_int 8)
6629                             (match_dup 1)]
6630                            UNSPEC_PIC_BASE)))]
6631   ""
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 "" ""))]
6646   "flag_pic"
6647   "
6649   /* r3 is clobbered by set/longjmp, so we can use it as a scratch
6650      register.  */
6651   if (arm_pic_register != INVALID_REGNUM)
6652     arm_load_pic_register (1UL << 3);
6653   DONE;
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")
6663                     (const_int 0)))
6664    (set (match_operand:SI 0 "s_register_operand" "=r,r")
6665         (match_dup 1))]
6666   "TARGET_32BIT"
6667   "@
6668    cmp%?\\t%0, #0
6669    sub%.\\t%0, %1, #0"
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
6686    (set (match_dup 2)
6687         (ashiftrt:SI (match_operand 0 "" "") (const_int 8)))
6688    ;; store the high byte
6689    (set (match_dup 4) (match_dup 5))]
6690   "TARGET_ARM"
6691   "
6692   {
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)))
6698         || code == MINUS)
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]);
6707   }"
6710 (define_expand "storehi_bigend"
6711   [(set (match_dup 4) (match_dup 3))
6712    (set (match_dup 2)
6713         (ashiftrt:SI (match_operand 0 "" "") (const_int 8)))
6714    (set (match_operand 1 "" "") (match_dup 5))]
6715   "TARGET_ARM"
6716   "
6717   {
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)))
6723         || code == MINUS)
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]);
6732   }"
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))]
6740   "TARGET_ARM"
6741   "
6742   {
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)))
6749         || code == MINUS)
6750       op0 = replace_equiv_address (op0, force_reg (SImode, addr));
6752     operands[1] = gen_reg_rtx (SImode);
6753     if (BYTES_BIG_ENDIAN)
6754       {
6755         emit_insn (gen_movsi (operands[1], GEN_INT ((value >> 8) & 255)));
6756         if ((value & 255) == ((value >> 8) & 255))
6757           operands[2] = operands[1];
6758         else
6759           {
6760             operands[2] = gen_reg_rtx (SImode);
6761             emit_insn (gen_movsi (operands[2], GEN_INT (value & 255)));
6762           }
6763       }
6764     else
6765       {
6766         emit_insn (gen_movsi (operands[1], GEN_INT (value & 255)));
6767         if ((value & 255) == ((value >> 8) & 255))
6768           operands[2] = operands[1];
6769         else
6770           {
6771             operands[2] = gen_reg_rtx (SImode);
6772             emit_insn (gen_movsi (operands[2], GEN_INT ((value >> 8) & 255)));
6773           }
6774       }
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]);
6780   }"
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"
6787   "
6788   if (!s_register_operand (operands[1], HImode))
6789     operands[1] = copy_to_mode_reg (HImode, operands[1]);
6790   "
6793 (define_expand "movhi"
6794   [(set (match_operand:HI 0 "general_operand" "")
6795         (match_operand:HI 1 "general_operand" ""))]
6796   "TARGET_EITHER"
6797   "
6798   if (TARGET_ARM)
6799     {
6800       if (can_create_pseudo_p ())
6801         {
6802           if (MEM_P (operands[0]))
6803             {
6804               if (arm_arch4)
6805                 {
6806                   emit_insn (gen_storehi_single_op (operands[0], operands[1]));
6807                   DONE;
6808                 }
6809               if (CONST_INT_P (operands[1]))
6810                 emit_insn (gen_storeinthi (operands[0], operands[1]));
6811               else
6812                 {
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]));
6817                   else
6818                    emit_insn (gen_storehi (operands[1], operands[0]));
6819                 }
6820               DONE;
6821             }
6822           /* Sign extend a constant, and keep it in an SImode reg.  */
6823           else if (CONST_INT_P (operands[1]))
6824             {
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))
6830                 {
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)))
6836                     val |= ~0xffff;
6837                   else if (val & 0x8000)
6838                     val |= ~0xffff;
6839                 }
6841               emit_insn (gen_movsi (reg, GEN_INT (val)));
6842               operands[1] = gen_lowpart (HImode, reg);
6843             }
6844           else if (arm_arch4 && optimize && can_create_pseudo_p ()
6845                    && MEM_P (operands[1]))
6846             {
6847               rtx reg = gen_reg_rtx (SImode);
6849               emit_insn (gen_zero_extendhisi2 (reg, operands[1]));
6850               operands[1] = gen_lowpart (HImode, reg);
6851             }
6852           else if (!arm_arch4)
6853             {
6854               if (MEM_P (operands[1]))
6855                 {
6856                   rtx base;
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)
6866                     {
6867                       rtx new_rtx;
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))
6875                         {
6876                           rtx reg2 = gen_reg_rtx (SImode);
6878                           emit_insn (gen_lshrsi3 (reg2, reg, GEN_INT (16)));
6879                           reg = reg2;
6880                         }
6881                     }
6882                   else
6883                     emit_insn (gen_movhi_bytes (reg, operands[1]));
6885                   operands[1] = gen_lowpart (HImode, reg);
6886                }
6887            }
6888         }
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])))
6893         {
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]));
6900           DONE;
6901        }
6902     }
6903   else if (TARGET_THUMB2)
6904     {
6905       /* Thumb-2 can do everything except mem=mem and mem=const easily.  */
6906       if (can_create_pseudo_p ())
6907         {
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]))
6912             {
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);
6918             }
6919         }
6920     }
6921   else /* TARGET_THUMB1 */
6922     {
6923       if (can_create_pseudo_p ())
6924         {
6925           if (CONST_INT_P (operands[1]))
6926             {
6927               rtx reg = gen_reg_rtx (SImode);
6929               emit_insn (gen_movsi (reg, operands[1]));
6930               operands[1] = gen_lowpart (HImode, reg);
6931             }
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)))
6944             operands[0]
6945               = replace_equiv_address (operands[0],
6946                                        copy_to_reg (XEXP (operands[0], 0)));
6947    
6948           if (MEM_P (operands[1])
6949               && !memory_address_p (GET_MODE (operands[1]),
6950                                     XEXP (operands[1], 0)))
6951             operands[1]
6952               = replace_equiv_address (operands[1],
6953                                        copy_to_reg (XEXP (operands[1], 0)));
6955           if (MEM_P (operands[1]) && optimize > 0)
6956             {
6957               rtx reg = gen_reg_rtx (SImode);
6959               emit_insn (gen_zero_extendhisi2 (reg, operands[1]));
6960               operands[1] = gen_lowpart (HImode, reg);
6961             }
6963           if (MEM_P (operands[0]))
6964             operands[1] = force_reg (HImode, operands[1]);
6965         }
6966       else if (CONST_INT_P (operands[1])
6967                 && !satisfies_constraint_I (operands[1]))
6968         {
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]));
6977           DONE;
6978         }
6979     }
6980   "
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"))]
6986   "TARGET_THUMB1
6987    && (   register_operand (operands[0], HImode)
6988        || register_operand (operands[1], HImode))"
6989   "*
6990   switch (which_alternative)
6991     {
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 ();
6998     case 1:
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)
7004         {
7005           rtx ops[2];
7006           ops[0] = operands[0];
7007           ops[1] = XEXP (XEXP (operands[1], 0), 0);
7008       
7009           output_asm_insn (\"mov        %0, %1\", ops);
7011           XEXP (XEXP (operands[1], 0), 0) = operands[0];
7012     
7013         }
7014       return \"ldrh     %0, %1\";
7015     }"
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 "" "")))
7023    (set (match_dup 3)
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)))]
7027   "TARGET_ARM"
7028   "
7029   {
7030     rtx mem1, mem2;
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]);
7037     operands[1] = mem1;
7038     operands[2] = gen_reg_rtx (SImode);
7039     operands[3] = gen_reg_rtx (SImode);
7040     operands[6] = mem2;
7042     if (BYTES_BIG_ENDIAN)
7043       {
7044         operands[4] = operands[2];
7045         operands[5] = operands[3];
7046       }
7047     else
7048       {
7049         operands[4] = operands[3];
7050         operands[5] = operands[2];
7051       }
7052   }"
7055 (define_expand "movhi_bigend"
7056   [(set (match_dup 2)
7057         (rotate:SI (subreg:SI (match_operand:HI 1 "memory_operand" "") 0)
7058                    (const_int 16)))
7059    (set (match_dup 3)
7060         (ashiftrt:SI (match_dup 2) (const_int 16)))
7061    (set (match_operand:HI 0 "s_register_operand" "")
7062         (match_dup 4))]
7063   "TARGET_ARM"
7064   "
7065   operands[2] = gen_reg_rtx (SImode);
7066   operands[3] = gen_reg_rtx (SImode);
7067   operands[4] = gen_lowpart (HImode, operands[3]);
7068   "
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"))]
7075   "TARGET_ARM
7076    && arm_arch4
7077    && (register_operand (operands[0], HImode)
7078        || register_operand (operands[1], HImode))"
7079   "@
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"))]
7099   "TARGET_ARM"
7100   "@
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" ""))]
7112   "TARGET_THUMB1"
7113   "
7114   if (strict_memory_address_p (HImode, XEXP (operands[0], 0))
7115       && REGNO (operands[1]) <= LAST_LO_REGNUM)
7116     {
7117       emit_insn (gen_movhi (operands[0], operands[1]));
7118       DONE;
7119     }
7120   /* XXX Fixme, need to handle other cases here as well.  */
7121   gcc_unreachable ();
7122   "
7124         
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")])]
7132   "TARGET_EITHER"
7133   "if (TARGET_ARM)
7134      arm_reload_out_hi (operands);
7135    else
7136      thumb_reload_out_hi (operands);
7137   DONE;
7138   "
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")])]
7145   "TARGET_EITHER"
7146   "
7147   if (TARGET_ARM)
7148     arm_reload_in_hi (operands);
7149   else
7150     thumb_reload_out_hi (operands);
7151   DONE;
7154 (define_expand "movqi"
7155   [(set (match_operand:QI 0 "general_operand" "")
7156         (match_operand:QI 1 "general_operand" ""))]
7157   "TARGET_EITHER"
7158   "
7159   /* Everything except mem = const or mem = mem can be done easily */
7161   if (can_create_pseudo_p ())
7162     {
7163       if (CONST_INT_P (operands[1]))
7164         {
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.  */
7169           if (TARGET_THUMB)
7170             operands[1] = GEN_INT (INTVAL (operands[1]) & 255);
7172           emit_insn (gen_movsi (reg, operands[1]));
7173           operands[1] = gen_lowpart (QImode, reg);
7174         }
7176       if (TARGET_THUMB)
7177         {
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)))
7189             operands[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)))
7195              operands[1]
7196                = replace_equiv_address (operands[1],
7197                                         copy_to_reg (XEXP (operands[1], 0)));
7198         }
7200       if (MEM_P (operands[1]) && optimize > 0)
7201         {
7202           rtx reg = gen_reg_rtx (SImode);
7204           emit_insn (gen_zero_extendqisi2 (reg, operands[1]));
7205           operands[1] = gen_lowpart (QImode, reg);
7206         }
7208       if (MEM_P (operands[0]))
7209         operands[1] = force_reg (QImode, operands[1]);
7210     }
7211   else if (TARGET_THUMB
7212            && CONST_INT_P (operands[1])
7213            && !satisfies_constraint_I (operands[1]))
7214     {
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]));
7223       DONE;
7224     }
7225   "
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"))]
7231   "TARGET_32BIT
7232    && (   register_operand (operands[0], QImode)
7233        || register_operand (operands[1], QImode))"
7234   "@
7235    mov%?\\t%0, %1
7236    mov%?\\t%0, %1
7237    mov%?\\t%0, %1
7238    mov%?\\t%0, %1
7239    mvn%?\\t%0, #%B1
7240    ldr%(b%)\\t%0, %1
7241    str%(b%)\\t%1, %0
7242    ldr%(b%)\\t%0, %1
7243    str%(b%)\\t%1, %0"
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"))]
7254   "TARGET_THUMB1
7255    && (   register_operand (operands[0], QImode)
7256        || register_operand (operands[1], QImode))"
7257   "@
7258    add\\t%0, %1, #0
7259    ldrb\\t%0, %1
7260    strb\\t%1, %0
7261    mov\\t%0, %1
7262    mov\\t%0, %1
7263    mov\\t%0, %1"
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")])
7269 ;; HFmode moves
7270 (define_expand "movhf"
7271   [(set (match_operand:HF 0 "general_operand" "")
7272         (match_operand:HF 1 "general_operand" ""))]
7273   "TARGET_EITHER"
7274   "
7275   if (TARGET_32BIT)
7276     {
7277       if (MEM_P (operands[0]))
7278         operands[1] = force_reg (HFmode, operands[1]);
7279     }
7280   else /* TARGET_THUMB1 */
7281     {
7282       if (can_create_pseudo_p ())
7283         {
7284            if (!REG_P (operands[0]))
7285              operands[1] = force_reg (HFmode, operands[1]);
7286         }
7287     }
7288   "
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))"
7297   "*
7298   switch (which_alternative)
7299     {
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 */
7307       {
7308         REAL_VALUE_TYPE r;
7309         long bits;
7310         rtx ops[4];
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);
7321         else
7322           output_asm_insn (\"mov%?\\t%0, %2\;orr%?\\t%0, %0, %3\", ops);
7323         return \"\";
7324        }
7325     default:
7326       gcc_unreachable ();
7327     }
7328   "
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"))]
7338   "TARGET_THUMB1
7339    && (   s_register_operand (operands[0], HFmode) 
7340        || s_register_operand (operands[1], HFmode))"
7341   "*
7342   switch (which_alternative)
7343     {
7344     case 1:
7345       {
7346         rtx addr;
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))))
7354           {
7355             /* Constant pool entry.  */
7356             return \"ldr\\t%0, %1\";
7357           }
7358         return \"ldrh\\t%0, %1\";
7359       }
7360     case 2: return \"strh\\t%1, %0\";
7361     default: return \"mov\\t%0, %1\";
7362     }
7363   "
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" ""))]
7372   "TARGET_EITHER"
7373   "
7374   if (TARGET_32BIT)
7375     {
7376       if (MEM_P (operands[0]))
7377         operands[1] = force_reg (SFmode, operands[1]);
7378     }
7379   else /* TARGET_THUMB1 */
7380     {
7381       if (can_create_pseudo_p ())
7382         {
7383            if (!REG_P (operands[0]))
7384              operands[1] = force_reg (SFmode, operands[1]);
7385         }
7386     }
7387   "
7390 ;; Transform a floating-point move of a constant into a core register into
7391 ;; an SImode operation.
7392 (define_split
7393   [(set (match_operand:SF 0 "arm_general_register_operand" "")
7394         (match_operand:SF 1 "immediate_operand" ""))]
7395   "TARGET_EITHER
7396    && reload_completed
7397    && CONST_DOUBLE_P (operands[1])"
7398   [(set (match_dup 2) (match_dup 3))]
7399   "
7400   operands[2] = gen_lowpart (SImode, operands[0]);
7401   operands[3] = gen_lowpart (SImode, operands[1]);
7402   if (operands[2] == 0 || operands[3] == 0)
7403     FAIL;
7404   "
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"))]
7410   "TARGET_32BIT
7411    && TARGET_SOFT_FLOAT
7412    && (!MEM_P (operands[0])
7413        || register_operand (operands[1], SFmode))"
7414   "@
7415    mov%?\\t%0, %1
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"))]
7431   "TARGET_THUMB1
7432    && (   register_operand (operands[0], SFmode) 
7433        || register_operand (operands[1], SFmode))"
7434   "@
7435    add\\t%0, %1, #0
7436    ldmia\\t%1, {%0}
7437    stmia\\t%0, {%1}
7438    ldr\\t%0, %1
7439    str\\t%1, %0
7440    mov\\t%0, %1
7441    mov\\t%0, %1"
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" ""))]
7451   "TARGET_EITHER"
7452   "
7453   if (TARGET_32BIT)
7454     {
7455       if (MEM_P (operands[0]))
7456         operands[1] = force_reg (DFmode, operands[1]);
7457     }
7458   else /* TARGET_THUMB */
7459     {
7460       if (can_create_pseudo_p ())
7461         {
7462           if (!REG_P (operands[0]))
7463             operands[1] = force_reg (DFmode, operands[1]);
7464         }
7465     }
7466   "
7469 ;; Reloading a df mode value stored in integer regs to memory can require a
7470 ;; scratch reg.
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")]
7475   "TARGET_THUMB2"
7476   "
7477   {
7478     enum rtx_code code = GET_CODE (XEXP (operands[0], 0));
7480     if (code == REG)
7481       operands[2] = XEXP (operands[0], 0);
7482     else if (code == POST_INC || code == PRE_DEC)
7483       {
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]));
7487         DONE;
7488       }
7489     else if (code == PRE_INC)
7490       {
7491         rtx reg = XEXP (XEXP (operands[0], 0), 0);
7493         emit_insn (gen_addsi3 (reg, reg, GEN_INT (8)));
7494         operands[2] = reg;
7495       }
7496     else if (code == POST_DEC)
7497       operands[2] = XEXP (XEXP (operands[0], 0), 0);
7498     else
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]),
7504                             operands[1]));
7506     if (code == POST_DEC)
7507       emit_insn (gen_addsi3 (operands[2], operands[2], GEN_INT (-8)));
7509     DONE;
7510   }"
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))"
7519   "*
7520   switch (which_alternative)
7521     {
7522     case 0:
7523     case 1:
7524     case 2:
7525       return \"#\";
7526     default:
7527       return output_move_double (operands, true, NULL);
7528     }
7529   "
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"))]
7545   "TARGET_THUMB1
7546    && (   register_operand (operands[0], DFmode)
7547        || register_operand (operands[1], DFmode))"
7548   "*
7549   switch (which_alternative)
7550     {
7551     default:
7552     case 0:
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\";
7556     case 1:
7557       return \"ldmia\\t%1, {%0, %H0}\";
7558     case 2:
7559       return \"stmia\\t%0, {%1, %H1}\";
7560     case 3:
7561       return thumb_load_double_from_address (operands);
7562     case 4:
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);
7567       return \"\";
7568     case 5:
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\";
7572     }
7573   "
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 "" ""))])]
7588   "TARGET_32BIT"
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)
7600     FAIL;
7602   operands[3]
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 "" ""))])]
7613   "TARGET_32BIT"
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)
7625     FAIL;
7627   operands[3]
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" "")]
7644   ""
7645   "
7646   if (TARGET_32BIT)
7647     {
7648       if (TARGET_LDRD && current_tune->prefer_ldrd_strd
7649           && !optimize_function_for_size_p (cfun))
7650         {
7651           if (gen_movmem_ldrd_strd (operands))
7652             DONE;
7653           FAIL;
7654         }
7656       if (arm_gen_movmemqi (operands))
7657         DONE;
7658       FAIL;
7659     }
7660   else /* TARGET_THUMB1 */
7661     {
7662       if (   INTVAL (operands[3]) != 4
7663           || INTVAL (operands[2]) > 48)
7664         FAIL;
7666       thumb_expand_movmemqi (operands);
7667       DONE;
7668     }
7669   "
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"))]
7688   "TARGET_THUMB1"
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"))]
7707   "TARGET_THUMB1"
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 "" ""))
7740               (pc)))]
7741   "TARGET_EITHER"
7742   "
7743   if (!TARGET_THUMB1)
7744     {
7745       if (!arm_validize_comparison (&operands[0], &operands[1], &operands[2]))
7746         FAIL;
7747       emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
7748                                       operands[3]));
7749       DONE;
7750     }
7751   if (thumb1_cmpneg_operand (operands[2], SImode))
7752     {
7753       emit_jump_insn (gen_cbranchsi4_scratch (NULL, operands[1], operands[2],
7754                                               operands[3], operands[0]));
7755       DONE;
7756     }
7757   if (!thumb1_cmp_operand (operands[2], SImode))
7758     operands[2] = force_reg (SImode, operands[2]);
7759   ")
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 "" ""))
7771               (pc)))]
7772   "TARGET_THUMB1"
7774   rtx xops[4];
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]));
7782   DONE;
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 "" ""))
7791               (pc)))]
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 "" ""))
7803               (pc)))]
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 "" ""))
7815               (pc)))]
7816   "TARGET_32BIT"
7817   "{
7818      if (!arm_validize_comparison (&operands[0], &operands[1], &operands[2]))
7819        FAIL;
7820      emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
7821                                        operands[3]));
7822      DONE;
7823    }"
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 "" ""))
7832               (pc)))]
7833   "TARGET_THUMB1"
7835   rtx t = cfun->machine->thumb1_cc_insn;
7836   if (t != NULL_RTX)
7837     {
7838       if (!rtx_equal_p (cfun->machine->thumb1_cc_op0, operands[1])
7839           || !rtx_equal_p (cfun->machine->thumb1_cc_op1, operands[2]))
7840         t = NULL_RTX;
7841       if (cfun->machine->thumb1_cc_mode == CC_NOOVmode)
7842         {
7843           if (!noov_comparison_operator (operands[0], VOIDmode))
7844             t = NULL_RTX;
7845         }
7846       else if (cfun->machine->thumb1_cc_mode != CCmode)
7847         t = NULL_RTX;
7848     }
7849   if (t == NULL_RTX)
7850     {
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;
7856     }
7857   else
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,
7860                                          CC_REGNUM);
7862   switch (get_attr_length (insn))
7863     {
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%=:\";
7867     }
7869   [(set (attr "far_jump")
7870         (if_then_else
7871             (eq_attr "length" "8")
7872             (const_string "yes")
7873             (const_string "no")))
7874    (set (attr "length") 
7875         (if_then_else
7876             (and (ge (minus (match_dup 3) (pc)) (const_int -250))
7877                  (le (minus (match_dup 3) (pc)) (const_int 256)))
7878             (const_int 4)
7879             (if_then_else
7880                 (and (ge (minus (match_dup 3) (pc)) (const_int -2040))
7881                      (le (minus (match_dup 3) (pc)) (const_int 2048)))
7882                 (const_int 6)
7883                 (const_int 8))))
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 "" ""))
7893               (pc)))
7894    (clobber (match_scratch:SI 0 "=l,l"))]
7895   "TARGET_THUMB1"
7896   "*
7897   output_asm_insn (\"add\\t%0, %1, #%n2\", operands);
7899   switch (get_attr_length (insn))
7900     {
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%=:\";
7904     }
7905   "
7906   [(set (attr "far_jump")
7907         (if_then_else
7908             (eq_attr "length" "8")
7909             (const_string "yes")
7910             (const_string "no")))
7911    (set (attr "length") 
7912         (if_then_else
7913             (and (ge (minus (match_dup 3) (pc)) (const_int -250))
7914                  (le (minus (match_dup 3) (pc)) (const_int 256)))
7915             (const_int 4)
7916             (if_then_else
7917                 (and (ge (minus (match_dup 3) (pc)) (const_int -2040))
7918                      (le (minus (match_dup 3) (pc)) (const_int 2048)))
7919                 (const_int 6)
7920                 (const_int 8))))
7921    (set_attr "type" "multiple")]
7924 (define_insn "*negated_cbranchsi4"
7925   [(set (pc)
7926         (if_then_else
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 "" ""))
7931          (pc)))]
7932   "TARGET_THUMB1"
7933   "*
7934   output_asm_insn (\"cmn\\t%1, %2\", operands);
7935   switch (get_attr_length (insn))
7936     {
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%=:\";
7940     }
7941   "
7942   [(set (attr "far_jump")
7943         (if_then_else
7944             (eq_attr "length" "8")
7945             (const_string "yes")
7946             (const_string "no")))
7947    (set (attr "length") 
7948         (if_then_else
7949             (and (ge (minus (match_dup 3) (pc)) (const_int -250))
7950                  (le (minus (match_dup 3) (pc)) (const_int 256)))
7951             (const_int 4)
7952             (if_then_else
7953                 (and (ge (minus (match_dup 3) (pc)) (const_int -2040))
7954                      (le (minus (match_dup 3) (pc)) (const_int 2048)))
7955                 (const_int 6)
7956                 (const_int 8))))
7957    (set_attr "type" "multiple")]
7960 (define_insn "*tbit_cbranch"
7961   [(set (pc)
7962         (if_then_else
7963          (match_operator 0 "equality_operator"
7964           [(zero_extract:SI (match_operand:SI 1 "s_register_operand" "l")
7965                             (const_int 1)
7966                             (match_operand:SI 2 "const_int_operand" "i"))
7967            (const_int 0)])
7968          (label_ref (match_operand 3 "" ""))
7969          (pc)))
7970    (clobber (match_scratch:SI 4 "=l"))]
7971   "TARGET_THUMB1"
7972   "*
7973   {
7974   rtx op[3];
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))
7981     {
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%=:\";
7985     }
7986   }"
7987   [(set (attr "far_jump")
7988         (if_then_else
7989             (eq_attr "length" "8")
7990             (const_string "yes")
7991             (const_string "no")))
7992    (set (attr "length") 
7993         (if_then_else
7994             (and (ge (minus (match_dup 3) (pc)) (const_int -250))
7995                  (le (minus (match_dup 3) (pc)) (const_int 256)))
7996             (const_int 4)
7997             (if_then_else
7998                 (and (ge (minus (match_dup 3) (pc)) (const_int -2040))
7999                      (le (minus (match_dup 3) (pc)) (const_int 2048)))
8000                 (const_int 6)
8001                 (const_int 8))))
8002    (set_attr "type" "multiple")]
8004   
8005 (define_insn "*tlobits_cbranch"
8006   [(set (pc)
8007         (if_then_else
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")
8011                             (const_int 0))
8012            (const_int 0)])
8013          (label_ref (match_operand 3 "" ""))
8014          (pc)))
8015    (clobber (match_scratch:SI 4 "=l"))]
8016   "TARGET_THUMB1"
8017   "*
8018   {
8019   rtx op[3];
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))
8026     {
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%=:\";
8030     }
8031   }"
8032   [(set (attr "far_jump")
8033         (if_then_else
8034             (eq_attr "length" "8")
8035             (const_string "yes")
8036             (const_string "no")))
8037    (set (attr "length") 
8038         (if_then_else
8039             (and (ge (minus (match_dup 3) (pc)) (const_int -250))
8040                  (le (minus (match_dup 3) (pc)) (const_int 256)))
8041             (const_int 4)
8042             (if_then_else
8043                 (and (ge (minus (match_dup 3) (pc)) (const_int -2040))
8044                      (le (minus (match_dup 3) (pc)) (const_int 2048)))
8045                 (const_int 6)
8046                 (const_int 8))))
8047    (set_attr "type" "multiple")]
8050 (define_insn "*tstsi3_cbranch"
8051   [(set (pc)
8052         (if_then_else
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"))
8056            (const_int 0)])
8057          (label_ref (match_operand 2 "" ""))
8058          (pc)))]
8059   "TARGET_THUMB1"
8060   "*
8061   {
8062   output_asm_insn (\"tst\\t%0, %1\", operands);
8063   switch (get_attr_length (insn))
8064     {
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%=:\";
8068     }
8069   }"
8070   [(set (attr "far_jump")
8071         (if_then_else
8072             (eq_attr "length" "8")
8073             (const_string "yes")
8074             (const_string "no")))
8075    (set (attr "length") 
8076         (if_then_else
8077             (and (ge (minus (match_dup 2) (pc)) (const_int -250))
8078                  (le (minus (match_dup 2) (pc)) (const_int 256)))
8079             (const_int 4)
8080             (if_then_else
8081                 (and (ge (minus (match_dup 2) (pc)) (const_int -2040))
8082                      (le (minus (match_dup 2) (pc)) (const_int 2048)))
8083                 (const_int 6)
8084                 (const_int 8))))
8085    (set_attr "type" "multiple")]
8087   
8088 (define_insn "*cbranchne_decr1"
8089   [(set (pc)
8090         (if_then_else (match_operator 3 "equality_operator"
8091                        [(match_operand:SI 2 "s_register_operand" "l,l,1,l")
8092                         (const_int 0)])
8093                       (label_ref (match_operand 4 "" ""))
8094                       (pc)))
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"))]
8098   "TARGET_THUMB1"
8099   "*
8100    {
8101      rtx cond[2];
8102      cond[0] = gen_rtx_fmt_ee ((GET_CODE (operands[3]) == NE
8103                                 ? GEU : LTU),
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)
8110        {
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);
8117        }
8118      else
8119        {
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);
8123        }
8125      switch (get_attr_length (insn) - (which_alternative ? 2 : 0))
8126        {
8127          case 4:
8128            output_asm_insn (\"b%d0\\t%l1\", cond);
8129            return \"\";
8130          case 6:
8131            output_asm_insn (\"b%D0\\t.LCB%=\", cond);
8132            return \"b\\t%l4\\t%@long jump\\n.LCB%=:\";
8133          default:
8134            output_asm_insn (\"b%D0\\t.LCB%=\", cond);
8135            return \"bl\\t%l4\\t%@far jump\\n.LCB%=:\";
8136        }
8137    }
8138   "
8139   [(set (attr "far_jump")
8140         (if_then_else
8141             (ior (and (eq (symbol_ref ("which_alternative"))
8142                           (const_int 0))
8143                       (eq_attr "length" "8"))
8144                  (eq_attr "length" "10"))
8145             (const_string "yes")
8146             (const_string "no")))
8147    (set_attr_alternative "length"
8148       [
8149        ;; Alternative 0
8150        (if_then_else
8151          (and (ge (minus (match_dup 4) (pc)) (const_int -250))
8152               (le (minus (match_dup 4) (pc)) (const_int 256)))
8153          (const_int 4)
8154          (if_then_else
8155            (and (ge (minus (match_dup 4) (pc)) (const_int -2040))
8156                 (le (minus (match_dup 4) (pc)) (const_int 2048)))
8157            (const_int 6)
8158            (const_int 8)))
8159        ;; Alternative 1
8160        (if_then_else
8161          (and (ge (minus (match_dup 4) (pc)) (const_int -248))
8162               (le (minus (match_dup 4) (pc)) (const_int 256)))
8163          (const_int 6)
8164          (if_then_else
8165            (and (ge (minus (match_dup 4) (pc)) (const_int -2038))
8166                 (le (minus (match_dup 4) (pc)) (const_int 2048)))
8167            (const_int 8)
8168            (const_int 10)))
8169        ;; Alternative 2
8170        (if_then_else
8171          (and (ge (minus (match_dup 4) (pc)) (const_int -248))
8172               (le (minus (match_dup 4) (pc)) (const_int 256)))
8173          (const_int 6)
8174          (if_then_else
8175            (and (ge (minus (match_dup 4) (pc)) (const_int -2038))
8176                 (le (minus (match_dup 4) (pc)) (const_int 2048)))
8177            (const_int 8)
8178            (const_int 10)))
8179        ;; Alternative 3
8180        (if_then_else
8181          (and (ge (minus (match_dup 4) (pc)) (const_int -248))
8182               (le (minus (match_dup 4) (pc)) (const_int 256)))
8183          (const_int 6)
8184          (if_then_else
8185            (and (ge (minus (match_dup 4) (pc)) (const_int -2038))
8186                 (le (minus (match_dup 4) (pc)) (const_int 2048)))
8187            (const_int 8)
8188            (const_int 10)))])
8189    (set_attr "type" "multiple")]
8192 (define_insn "*addsi3_cbranch"
8193   [(set (pc)
8194         (if_then_else
8195          (match_operator 4 "arm_comparison_operator"
8196           [(plus:SI
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"))
8199            (const_int 0)])
8200          (label_ref (match_operand 5 "" ""))
8201          (pc)))
8202    (set
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"))]
8206   "TARGET_THUMB1
8207    && (GET_CODE (operands[4]) == EQ
8208        || GET_CODE (operands[4]) == NE
8209        || GET_CODE (operands[4]) == GE
8210        || GET_CODE (operands[4]) == LT)"
8211   "*
8212    {
8213      rtx cond[3];
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);
8221      else
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))
8231        {
8232          case 4:
8233            return \"b%d4\\t%l5\";
8234          case 6:
8235            return \"b%D4\\t.LCB%=\;b\\t%l5\\t%@long jump\\n.LCB%=:\";
8236          default:
8237            return \"b%D4\\t.LCB%=\;bl\\t%l5\\t%@far jump\\n.LCB%=:\";
8238        }
8239    }
8240   "
8241   [(set (attr "far_jump")
8242         (if_then_else
8243             (ior (and (lt (symbol_ref ("which_alternative"))
8244                           (const_int 2))
8245                       (eq_attr "length" "8"))
8246                  (eq_attr "length" "10"))
8247             (const_string "yes")
8248             (const_string "no")))
8249    (set (attr "length")
8250      (if_then_else
8251        (lt (symbol_ref ("which_alternative"))
8252                        (const_int 2))
8253        (if_then_else
8254          (and (ge (minus (match_dup 5) (pc)) (const_int -250))
8255               (le (minus (match_dup 5) (pc)) (const_int 256)))
8256          (const_int 4)
8257          (if_then_else
8258            (and (ge (minus (match_dup 5) (pc)) (const_int -2040))
8259                 (le (minus (match_dup 5) (pc)) (const_int 2048)))
8260            (const_int 6)
8261            (const_int 8)))
8262        (if_then_else
8263          (and (ge (minus (match_dup 5) (pc)) (const_int -248))
8264               (le (minus (match_dup 5) (pc)) (const_int 256)))
8265          (const_int 6)
8266          (if_then_else
8267            (and (ge (minus (match_dup 5) (pc)) (const_int -2038))
8268                 (le (minus (match_dup 5) (pc)) (const_int 2048)))
8269            (const_int 8)
8270            (const_int 10)))))
8271    (set_attr "type" "multiple")]
8274 (define_insn "*addsi3_cbranch_scratch"
8275   [(set (pc)
8276         (if_then_else
8277          (match_operator 3 "arm_comparison_operator"
8278           [(plus:SI
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"))
8281            (const_int 0)])
8282          (label_ref (match_operand 4 "" ""))
8283          (pc)))
8284    (clobber (match_scratch:SI 0 "=X,X,l,l"))]
8285   "TARGET_THUMB1
8286    && (GET_CODE (operands[3]) == EQ
8287        || GET_CODE (operands[3]) == NE
8288        || GET_CODE (operands[3]) == GE
8289        || GET_CODE (operands[3]) == LT)"
8290   "*
8291    {
8292      switch (which_alternative)
8293        {
8294        case 0:
8295          output_asm_insn (\"cmp\t%1, #%n2\", operands);
8296          break;
8297        case 1:
8298          output_asm_insn (\"cmn\t%1, %2\", operands);
8299          break;
8300        case 2:
8301          if (INTVAL (operands[2]) < 0)
8302            output_asm_insn (\"sub\t%0, %1, %2\", operands);
8303          else
8304            output_asm_insn (\"add\t%0, %1, %2\", operands);
8305          break;
8306        case 3:
8307          if (INTVAL (operands[2]) < 0)
8308            output_asm_insn (\"sub\t%0, %0, %2\", operands);
8309          else
8310            output_asm_insn (\"add\t%0, %0, %2\", operands);
8311          break;
8312        }
8314      switch (get_attr_length (insn))
8315        {
8316          case 4:
8317            return \"b%d3\\t%l4\";
8318          case 6:
8319            return \"b%D3\\t.LCB%=\;b\\t%l4\\t%@long jump\\n.LCB%=:\";
8320          default:
8321            return \"b%D3\\t.LCB%=\;bl\\t%l4\\t%@far jump\\n.LCB%=:\";
8322        }
8323    }
8324   "
8325   [(set (attr "far_jump")
8326         (if_then_else
8327             (eq_attr "length" "8")
8328             (const_string "yes")
8329             (const_string "no")))
8330    (set (attr "length")
8331        (if_then_else
8332          (and (ge (minus (match_dup 4) (pc)) (const_int -250))
8333               (le (minus (match_dup 4) (pc)) (const_int 256)))
8334          (const_int 4)
8335          (if_then_else
8336            (and (ge (minus (match_dup 4) (pc)) (const_int -2040))
8337                 (le (minus (match_dup 4) (pc)) (const_int 2048)))
8338            (const_int 6)
8339            (const_int 8))))
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")))]
8350   "TARGET_32BIT"
8351   "@
8352    cmp%?\\t%0, %1
8353    cmp%?\\t%0, %1
8354    cmp%?\\t%0, %1
8355    cmp%?\\t%0, %1
8356    cmn%?\\t%0, #%n1"
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")])))]
8371   "TARGET_32BIT"
8372   "cmp\\t%0, %1%S3"
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")))]
8384   "TARGET_32BIT"
8385   "cmp%?\\t%0, %1%S3"
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)
8393         (compare:CC_Z
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")))]
8398   "TARGET_ARM"
8399   "cmn%?\\t%0, %2%S1"
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
8409 ;; that directly.
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"))]
8416   "TARGET_32BIT"
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)))
8423               (set (match_dup 2)
8424                    (minus:SI (match_dup 5)
8425                             (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))])]
8426   {
8427     operands[3] = gen_highpart (SImode, operands[0]);
8428     operands[0] = gen_lowpart (SImode, operands[0]);
8429     if (CONST_INT_P (operands[1]))
8430       {
8431         operands[4] = GEN_INT (~INTVAL (gen_highpart_mode (SImode,
8432                                                            DImode,
8433                                                            operands[1])));
8434         operands[5] = gen_rtx_PLUS (SImode, operands[3], operands[4]);
8435       }
8436     else
8437       {
8438         operands[4] = gen_highpart (SImode, operands[1]);
8439         operands[5] = gen_rtx_MINUS (SImode, operands[3], operands[4]);
8440       }
8441     operands[1] = gen_lowpart (SImode, operands[1]);
8442     operands[2] = gen_lowpart (SImode, operands[2]);
8443   }
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")))]
8454   "TARGET_32BIT"
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))))]
8462   {
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]);
8467     else
8468       operands[3] = gen_highpart (SImode, operands[1]);
8469     operands[1] = gen_lowpart (SImode, operands[1]);
8470   }
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")
8481                       (const_int 0)))
8482    (clobber (match_scratch:SI 1 "=r"))]
8483   "TARGET_32BIT"
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")
8492                       (const_int 0)))
8493    (clobber (match_scratch:SI 1 "=l"))]
8494   "TARGET_THUMB1"
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))]
8509   "TARGET_32BIT"
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"
8520   [(set (pc)
8521         (if_then_else (match_operator 0 "" [(match_operand 1 "" "")
8522                                             (match_operand 2 "" "")])
8523                       (label_ref (match_operand 3 "" ""))
8524                       (pc)))]
8525   "TARGET_32BIT"
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"
8536   [(set (pc)
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 "" ""))
8540                       (pc)))]
8541   "TARGET_32BIT"
8542   "*
8543   if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
8544     {
8545       arm_ccfsm_state += 2;
8546       return \"\";
8547     }
8548   return \"b%d1\\t%l0\";
8549   "
8550   [(set_attr "conds" "use")
8551    (set_attr "type" "branch")
8552    (set (attr "length")
8553         (if_then_else
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))))
8557            (const_int 2)
8558            (const_int 4)))]
8561 (define_insn "*arm_cond_branch_reversed"
8562   [(set (pc)
8563         (if_then_else (match_operator 1 "arm_comparison_operator"
8564                        [(match_operand 2 "cc_register" "") (const_int 0)])
8565                       (pc)
8566                       (label_ref (match_operand 0 "" ""))))]
8567   "TARGET_32BIT"
8568   "*
8569   if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
8570     {
8571       arm_ccfsm_state += 2;
8572       return \"\";
8573     }
8574   return \"b%D1\\t%l0\";
8575   "
8576   [(set_attr "conds" "use")
8577    (set_attr "type" "branch")
8578    (set (attr "length")
8579         (if_then_else
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))))
8583            (const_int 2)
8584            (const_int 4)))]
8589 ; scc insns
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 "" "")]))]
8595   "TARGET_32BIT"
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)]))]
8605   "TARGET_ARM"
8606   "#"   ; "mov%D1\\t%0, #0\;mov%d1\\t%0, #1"
8607   "TARGET_ARM"
8608   [(set (match_dup 0)
8609         (if_then_else:SI (match_dup 1)
8610                          (const_int 1)
8611                          (const_int 0)))]
8612   ""
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)])))]
8622   "TARGET_ARM"
8623   "#"   ; "mov%D1\\t%0, #0\;mvn%d1\\t%0, #0"
8624   "TARGET_ARM"
8625   [(set (match_dup 0)
8626         (if_then_else:SI (match_dup 1)
8627                          (match_dup 3)
8628                          (const_int 0)))]
8629   {
8630     operands[3] = GEN_INT (~0);
8631   }
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)])))]
8641   "TARGET_ARM"
8642   "#"   ; "mvn%D1\\t%0, #0\;mvn%d1\\t%0, #1"
8643   "TARGET_ARM"
8644   [(set (match_dup 0)
8645         (if_then_else:SI (match_dup 1)
8646                          (match_dup 3)
8647                          (match_dup 4)))]
8648   {
8649     operands[3] = GEN_INT (~1);
8650     operands[4] = GEN_INT (~0);
8651   }
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"
8663   "{
8664   rtx op3, scratch, scratch2;
8666   if (!TARGET_THUMB1)
8667     {
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]));
8672       DONE;
8673     }
8675   if (operands[3] == const0_rtx)
8676     {
8677       switch (GET_CODE (operands[1]))
8678         {
8679         case EQ:
8680           emit_insn (gen_cstoresi_eq0_thumb1 (operands[0], operands[2]));
8681           break;
8683         case NE:
8684           emit_insn (gen_cstoresi_ne0_thumb1 (operands[0], operands[2]));
8685           break;
8687         case LE:
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);
8694           break;
8696         case GE:
8697           scratch = expand_unop (SImode, one_cmpl_optab, operands[2],
8698                                  NULL_RTX, 1);
8699           expand_binop (SImode, lshr_optab, scratch, GEN_INT (31),
8700                         NULL_RTX, 1, OPTAB_WIDEN);
8701           break;
8703         case GT:
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],
8709                         0, OPTAB_WIDEN);
8710           break;
8712         /* LT is handled by generic code.  No need for unsigned with 0.  */
8713         default:
8714           FAIL;
8715         }
8716       DONE;
8717     }
8719   switch (GET_CODE (operands[1]))
8720     {
8721     case EQ:
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));
8725       break;
8727     case NE:
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));
8731       break;
8733     case LE:
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,
8741                                           op3, operands[2]));
8742       break;
8744     case GE:
8745       op3 = operands[3];
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,
8753                                           operands[2], op3));
8754       break;
8756     case LEU:
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,
8760                                           op3, operands[2]));
8761       break;
8763     case GEU:
8764       op3 = operands[3];
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,
8769                                           operands[2], op3));
8770       break;
8772     case LTU:
8773       op3 = operands[3];
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));
8778       break;
8780     case GTU:
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]));
8784       break;
8786     /* No good sequences for GT, LT.  */
8787     default:
8788       FAIL;
8789     }
8790   DONE;
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" "")]))]
8818   "TARGET_32BIT"
8819   "{
8820      if (!arm_validize_comparison (&operands[1],
8821                                    &operands[2],
8822                                    &operands[3]))
8823        FAIL;
8824      emit_insn (gen_cstore_cc (operands[0], operands[1], operands[2],
8825                                  operands[3]));
8826      DONE;
8827    }"
8830 (define_expand "cstoresi_eq0_thumb1"
8831   [(parallel
8832     [(set (match_operand:SI 0 "s_register_operand" "")
8833           (eq:SI (match_operand:SI 1 "s_register_operand" "")
8834                  (const_int 0)))
8835      (clobber (match_dup:SI 2))])]
8836   "TARGET_THUMB1"
8837   "operands[2] = gen_reg_rtx (SImode);"
8840 (define_expand "cstoresi_ne0_thumb1"
8841   [(parallel
8842     [(set (match_operand:SI 0 "s_register_operand" "")
8843           (ne:SI (match_operand:SI 1 "s_register_operand" "")
8844                  (const_int 0)))
8845      (clobber (match_dup:SI 2))])]
8846   "TARGET_THUMB1"
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")
8853                (const_int 0)))
8854    (clobber (match_operand:SI 2 "s_register_operand" "=X,l"))]
8855   "TARGET_THUMB1"
8856   "@
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")
8866                (const_int 0)))
8867    (clobber (match_operand:SI 2 "s_register_operand" "=l"))]
8868   "TARGET_THUMB1"
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"))))]
8878   "TARGET_THUMB1"
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")))]
8888   "TARGET_THUMB1"
8889   "#"
8890   "TARGET_THUMB1"
8891   [(set (match_dup 3)
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"))))]
8906   "TARGET_THUMB1"
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" "")))]
8920   "TARGET_32BIT"
8921   "
8922   {
8923     enum rtx_code code;
8924     rtx ccreg;
8926     if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0), 
8927                                   &XEXP (operands[1], 1)))
8928       FAIL;
8929     
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);
8934   }"
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"
8943   "
8944   {
8945     enum rtx_code code = GET_CODE (operands[1]);
8946     rtx ccreg;
8948     if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0), 
8949                                   &XEXP (operands[1], 1)))
8950        FAIL;
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);
8956   }"
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"
8965   "
8966   {
8967     enum rtx_code code = GET_CODE (operands[1]);
8968     rtx ccreg;
8970     if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0), 
8971                                   &XEXP (operands[1], 1)))
8972        FAIL;
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);
8977   }"
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"
8985                                               "<F_constraint>")
8986                           (match_operand:SDF 4 "s_register_operand"
8987                                               "<F_constraint>")))]
8988   "TARGET_HARD_FLOAT && TARGET_FPU_ARMV8 <vfp_double_cond>"
8989   "*
8990   {
8991     enum arm_cond_code code = maybe_get_arm_condition_code (operands[1]);
8992     switch (code)
8993       {
8994       case ARM_GE:
8995       case ARM_GT:
8996       case ARM_EQ:
8997       case ARM_VS:
8998         return \"vsel%d1.<V_if_elem>\\t%<V_reg>0, %<V_reg>3, %<V_reg>4\";
8999       case ARM_LT:
9000       case ARM_LE:
9001       case ARM_NE:
9002       case ARM_VC:
9003         return \"vsel%D1.<V_if_elem>\\t%<V_reg>0, %<V_reg>4, %<V_reg>3\";
9004       default:
9005         gcc_unreachable ();
9006       }
9007     return \"\";
9008   }"
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")
9015         (if_then_else:SI
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")))]
9020   "TARGET_ARM"
9021   "@
9022    mov%D3\\t%0, %2
9023    mvn%D3\\t%0, #%B2
9024    mov%d3\\t%0, %1
9025    mvn%d3\\t%0, #%B1
9026    #
9027    #
9028    #
9029    #"
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"
9035   [(const_int 0)]
9036   {
9037     enum rtx_code rev_code;
9038     enum machine_mode mode;
9039     rtx rev_cond;
9041     emit_insn (gen_rtx_COND_EXEC (VOIDmode,
9042                                   operands[3],
9043                                   gen_rtx_SET (VOIDmode,
9044                                                operands[0],
9045                                                operands[1])));
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);
9051     else
9052       rev_code = reverse_condition (rev_code);
9054     rev_cond = gen_rtx_fmt_ee (rev_code,
9055                                VOIDmode,
9056                                operands[4],
9057                                const0_rtx);
9058     emit_insn (gen_rtx_COND_EXEC (VOIDmode,
9059                                   rev_cond,
9060                                   gen_rtx_SET (VOIDmode,
9061                                                operands[0],
9062                                                operands[2])));
9063     DONE;
9064   }
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"
9089   "@
9090    mov%D3\\t%0, %2
9091    mov%d3\\t%0, %1"
9092   [(set_attr "conds" "use")
9093    (set_attr "type" "mov_reg")]
9097 ;; Jump and linkage insns
9099 (define_expand "jump"
9100   [(set (pc)
9101         (label_ref (match_operand 0 "" "")))]
9102   "TARGET_EITHER"
9103   ""
9106 (define_insn "*arm_jump"
9107   [(set (pc)
9108         (label_ref (match_operand 0 "" "")))]
9109   "TARGET_32BIT"
9110   "*
9111   {
9112     if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
9113       {
9114         arm_ccfsm_state += 2;
9115         return \"\";
9116       }
9117     return \"b%?\\t%l0\";
9118   }
9119   "
9120   [(set_attr "predicable" "yes")
9121    (set (attr "length")
9122         (if_then_else
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))))
9126            (const_int 2)
9127            (const_int 4)))
9128    (set_attr "type" "branch")]
9131 (define_insn "*thumb_jump"
9132   [(set (pc)
9133         (label_ref (match_operand 0 "" "")))]
9134   "TARGET_THUMB1"
9135   "*
9136   if (get_attr_length (insn) == 2)
9137     return \"b\\t%l0\";
9138   return \"bl\\t%l0\\t%@ far jump\";
9139   "
9140   [(set (attr "far_jump")
9141         (if_then_else
9142             (eq_attr "length" "4")
9143             (const_string "yes")
9144             (const_string "no")))
9145    (set (attr "length") 
9146         (if_then_else
9147             (and (ge (minus (match_dup 0) (pc)) (const_int -2044))
9148                  (le (minus (match_dup 0) (pc)) (const_int 2048)))
9149             (const_int 2)
9150             (const_int 4)))
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))])]
9159   "TARGET_EITHER"
9160   "
9161   {
9162     rtx callee, pat;
9163     
9164     /* In an untyped call, we can get NULL for operand 2.  */
9165     if (operands[2] == NULL_RTX)
9166       operands[2] = const0_rtx;
9167       
9168     /* Decide if we should generate indirect calls by loading the
9169        32-bit address of the callee into a register before performing the
9170        branch and link.  */
9171     callee = XEXP (operands[0], 0);
9172     if (GET_CODE (callee) == SYMBOL_REF
9173         ? arm_is_long_call_p (SYMBOL_REF_DECL (callee))
9174         : !REG_P (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));
9179     DONE;
9180   }"
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)"
9195   "blx%?\\t%0"
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)"
9205   "*
9206   return output_call (operands);
9207   "
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)"
9224   "*
9225   return output_call_mem (operands);
9226   "
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)"
9237   "blx\\t%0"
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)"
9248   "*
9249   {
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\";
9256     else
9257       return \"bl\\t%__interwork_r11_call_via_%0\";
9258   }"
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))])]
9268   "TARGET_EITHER"
9269   "
9270   {
9271     rtx pat, callee;
9272     
9273     /* In an untyped call, we can get NULL for operand 2.  */
9274     if (operands[3] == 0)
9275       operands[3] = const0_rtx;
9276       
9277     /* Decide if we should generate indirect calls by loading the
9278        32-bit address of the callee into a register before performing the
9279        branch and link.  */
9280     callee = XEXP (operands[1], 0);
9281     if (GET_CODE (callee) == SYMBOL_REF
9282         ? arm_is_long_call_p (SYMBOL_REF_DECL (callee))
9283         : !REG_P (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));
9289     DONE;
9290   }"
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)"
9307   "blx%?\\t%1"
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)"
9318   "*
9319   return output_call (&operands[1]);
9320   "
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)"
9335   "*
9336   return output_call_mem (&operands[1]);
9337   "
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"
9349   "blx\\t%1"
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"
9361   "*
9362   {
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\";
9369     else
9370       return \"bl\\t%__interwork_r11_call_via_%1\";
9371   }"
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))]
9383   "TARGET_32BIT
9384    && !SIBLING_CALL_P (insn)
9385    && (GET_CODE (operands[0]) == SYMBOL_REF)
9386    && !arm_is_long_call_p (SYMBOL_REF_DECL (operands[0]))"
9387   "*
9388   {
9389     return NEED_PLT_RELOC ? \"bl%?\\t%a0(PLT)\" : \"bl%?\\t%a0\";
9390   }"
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))]
9400   "TARGET_32BIT
9401    && !SIBLING_CALL_P (insn)
9402    && (GET_CODE (operands[1]) == SYMBOL_REF)
9403    && !arm_is_long_call_p (SYMBOL_REF_DECL (operands[1]))"
9404   "*
9405   {
9406     return NEED_PLT_RELOC ? \"bl%?\\t%a1(PLT)\" : \"bl%?\\t%a1\";
9407   }"
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))]
9416   "TARGET_THUMB1
9417    && GET_CODE (operands[0]) == SYMBOL_REF
9418    && !arm_is_long_call_p (SYMBOL_REF_DECL (operands[0]))"
9419   "bl\\t%a0"
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))]
9430   "TARGET_THUMB1
9431    && GET_CODE (operands[1]) == SYMBOL_REF
9432    && !arm_is_long_call_p (SYMBOL_REF_DECL (operands[1]))"
9433   "bl\\t%a1"
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" ""))
9442               (return)
9443               (use (match_operand 2 "" ""))])]
9444   "TARGET_32BIT"
9445   "
9446   {
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;
9453   }"
9456 (define_expand "sibcall_value"
9457   [(parallel [(set (match_operand 0 "" "")
9458                    (call (match_operand 1 "memory_operand" "")
9459                          (match_operand 2 "general_operand" "")))
9460               (return)
9461               (use (match_operand 3 "" ""))])]
9462   "TARGET_32BIT"
9463   "
9464   {
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;
9471   }"
9474 (define_insn "*sibcall_insn"
9475  [(call (mem:SI (match_operand:SI 0 "call_insn_operand" "Cs, US"))
9476         (match_operand 1 "" ""))
9477   (return)
9478   (use (match_operand 2 "" ""))]
9479   "TARGET_32BIT && SIBLING_CALL_P (insn)"
9480   "*
9481   if (which_alternative == 1)
9482     return NEED_PLT_RELOC ? \"b%?\\t%a0(PLT)\" : \"b%?\\t%a0\";
9483   else
9484     {
9485       if (arm_arch5 || arm_arch4t)
9486         return \"bx%?\\t%0\\t%@ indirect register sibling call\";
9487       else
9488         return \"mov%?\\t%|pc, %0\\t%@ indirect register sibling call\";
9489     }
9490   "
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 "" "")))
9498   (return)
9499   (use (match_operand 3 "" ""))]
9500   "TARGET_32BIT && SIBLING_CALL_P (insn)"
9501   "*
9502   if (which_alternative == 1)
9503    return NEED_PLT_RELOC ? \"b%?\\t%a1(PLT)\" : \"b%?\\t%a1\";
9504   else
9505     {
9506       if (arm_arch5 || arm_arch4t)
9507         return \"bx%?\\t%1\";
9508       else
9509         return \"mov%?\\t%|pc, %1\\t@ indirect sibling call \";
9510     }
9511   "
9512   [(set_attr "type" "call")]
9515 (define_expand "<return_str>return"
9516   [(returns)]
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>"
9521   "
9522   {
9523     if (TARGET_THUMB2)
9524       {
9525         thumb2_expand_return (<return_simple_p>);
9526         DONE;
9527       }
9528   }
9529   "
9532 ;; Often the return insn will be the same as loading from memory, so set attr
9533 (define_insn "*arm_return"
9534   [(return)]
9535   "TARGET_ARM && USE_RETURN_INSN (FALSE)"
9536   "*
9537   {
9538     if (arm_ccfsm_state == 2)
9539       {
9540         arm_ccfsm_state += 2;
9541         return \"\";
9542       }
9543     return output_return_instruction (const_true_rtx, true, false, false);
9544   }"
9545   [(set_attr "type" "load1")
9546    (set_attr "length" "12")
9547    (set_attr "predicable" "yes")]
9550 (define_insn "*cond_<return_str>return"
9551   [(set (pc)
9552         (if_then_else (match_operator 0 "arm_comparison_operator"
9553                        [(match_operand 1 "cc_register" "") (const_int 0)])
9554                       (returns)
9555                       (pc)))]
9556   "TARGET_ARM  <return_cond_true>"
9557   "*
9558   {
9559     if (arm_ccfsm_state == 2)
9560       {
9561         arm_ccfsm_state += 2;
9562         return \"\";
9563       }
9564     return output_return_instruction (operands[0], true, false,
9565                                       <return_simple_p>);
9566   }"
9567   [(set_attr "conds" "use")
9568    (set_attr "length" "12")
9569    (set_attr "type" "load1")]
9572 (define_insn "*cond_<return_str>return_inverted"
9573   [(set (pc)
9574         (if_then_else (match_operator 0 "arm_comparison_operator"
9575                        [(match_operand 1 "cc_register" "") (const_int 0)])
9576                       (pc)
9577                       (returns)))]
9578   "TARGET_ARM <return_cond_true>"
9579   "*
9580   {
9581     if (arm_ccfsm_state == 2)
9582       {
9583         arm_ccfsm_state += 2;
9584         return \"\";
9585       }
9586     return output_return_instruction (operands[0], true, true,
9587                                       <return_simple_p>);
9588   }"
9589   [(set_attr "conds" "use")
9590    (set_attr "length" "12")
9591    (set_attr "type" "load1")]
9594 (define_insn "*arm_simple_return"
9595   [(simple_return)]
9596   "TARGET_ARM"
9597   "*
9598   {
9599     if (arm_ccfsm_state == 2)
9600       {
9601         arm_ccfsm_state += 2;
9602         return \"\";
9603       }
9604     return output_return_instruction (const_true_rtx, true, false, true);
9605   }"
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
9613 ;; mask.
9615 (define_expand "return_addr_mask"
9616   [(set (match_dup 1)
9617       (compare:CC_NOOV (unspec [(const_int 0)] UNSPEC_CHECK_ARCH)
9618                        (const_int 0)))
9619    (set (match_operand:SI 0 "s_register_operand" "")
9620       (if_then_else:SI (eq (match_dup 1) (const_int 0))
9621                        (const_int -1)
9622                        (const_int 67108860)))] ; 0x03fffffc
9623   "TARGET_ARM"
9624   "
9625   operands[1] = gen_rtx_REG (CC_NOOVmode, CC_REGNUM);
9626   ")
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)
9631                        (const_int 0)))]
9632   "TARGET_ARM"
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 "" "")
9643                     (const_int 0))
9644               (match_operand 1 "" "")
9645               (match_operand 2 "" "")])]
9646   "TARGET_EITHER"
9647   "
9648   {
9649     int i;
9650     rtx par = gen_rtx_PARALLEL (VOIDmode,
9651                                 rtvec_alloc (XVECLEN (operands[2], 0)));
9652     rtx addr = gen_reg_rtx (Pmode);
9653     rtx mem;
9654     int size = 0;
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++)
9660       {
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,
9669                                                  GEN_INT (size));
9670         size += GET_MODE_SIZE (GET_MODE (src));
9671       }
9673     emit_call_insn (GEN_CALL_VALUE (par, operands[0], const0_rtx, NULL,
9674                                     const0_rtx));
9676     size = 0;
9678     for (i = 0; i < XVECLEN (par, 0); i++)
9679       {
9680         HOST_WIDE_INT offset = 0;
9681         rtx reg = XEXP (XVECEXP (par, 0, i), 0);
9683         if (size != 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)
9688           {
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;
9693           }
9694         else
9695           {
9696             emit_move_insn (mem, reg);
9697             size = GET_MODE_SIZE (GET_MODE (reg));
9698           }
9699       }
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
9704        point.  */
9705     emit_insn (gen_blockage ());
9707     DONE;
9708   }"
9711 (define_expand "untyped_return"
9712   [(match_operand:BLK 0 "memory_operand" "")
9713    (match_operand 1 "" "")]
9714   "TARGET_EITHER"
9715   "
9716   {
9717     int i;
9718     rtx addr = gen_reg_rtx (Pmode);
9719     rtx mem;
9720     int size = 0;
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++)
9726       {
9727         HOST_WIDE_INT offset = 0;
9728         rtx reg = SET_DEST (XVECEXP (operands[1], 0, i));
9730         if (size != 0)
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)
9735           {
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;
9740           }
9741         else
9742           {
9743             emit_move_insn (reg, mem);
9744             size = GET_MODE_SIZE (GET_MODE (reg));
9745           }
9746       }
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 ();
9755     DONE;
9756   }"
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)]
9764   "TARGET_EITHER"
9765   ""
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"
9777   "
9778   {
9779     enum insn_code code;
9780     if (operands[1] != const0_rtx)
9781       {
9782         rtx reg = gen_reg_rtx (SImode);
9784         emit_insn (gen_addsi3 (reg, operands[0],
9785                                gen_int_mode (-INTVAL (operands[1]),
9786                                              SImode)));
9787         operands[0] = reg;
9788       }
9790     if (TARGET_ARM)
9791       code = CODE_FOR_arm_casesi_internal;
9792     else if (TARGET_THUMB1)
9793       code = CODE_FOR_thumb1_casesi_internal_pic;
9794     else if (flag_pic)
9795       code = CODE_FOR_thumb2_casesi_internal_pic;
9796     else
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]));
9804     DONE;
9805   }"
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)
9812                (if_then_else
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)))])]
9820   "TARGET_ARM"
9821   "*
9822     if (flag_pic)
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\";
9825   "
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 "" "")]
9836   "TARGET_THUMB1"
9837   {
9838     rtx reg0;
9839     rtx test = gen_rtx_GTU (VOIDmode, operands[0], operands[1]);
9840     emit_jump_insn (gen_cbranchsi4 (test, operands[0], operands[1],
9841                                     operands[3]));
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]*/));
9845     DONE;
9846   }
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))])]
9857   "TARGET_THUMB1"
9858   "* return thumb1_output_casesi(operands);"
9859   [(set_attr "length" "4")
9860    (set_attr "type" "multiple")]
9863 (define_expand "indirect_jump"
9864   [(set (pc)
9865         (match_operand:SI 0 "s_register_operand" ""))]
9866   "TARGET_EITHER"
9867   "
9868   /* Thumb-2 doesn't have mov pc, reg.  Explicitly set the low bit of the
9869      address and use bx.  */
9870   if (TARGET_THUMB2)
9871     {
9872       rtx tmp;
9873       tmp = gen_reg_rtx (SImode);
9874       emit_insn (gen_iorsi3 (tmp, operands[0], GEN_INT(1)));
9875       operands[0] = tmp;
9876     }
9877   "
9880 ;; NB Never uses BX.
9881 (define_insn "*arm_indirect_jump"
9882   [(set (pc)
9883         (match_operand:SI 0 "s_register_operand" "r"))]
9884   "TARGET_ARM"
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"
9891   [(set (pc)
9892         (match_operand:SI 0 "memory_operand" "m"))]
9893   "TARGET_ARM"
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"
9903   [(set (pc)
9904         (match_operand:SI 0 "register_operand" "l*r"))]
9905   "TARGET_THUMB1"
9906   "mov\\tpc, %0"
9907   [(set_attr "conds" "clob")
9908    (set_attr "length" "2")
9909    (set_attr "type" "branch")]
9913 ;; Misc insns
9915 (define_insn "nop"
9916   [(const_int 0)]
9917   "TARGET_EITHER"
9918   "*
9919   if (TARGET_UNIFIED_ASM)
9920     return \"nop\";
9921   if (TARGET_ARM)
9922     return \"mov%?\\t%|r0, %|r0\\t%@ nop\";
9923   return  \"mov\\tr8, r8\";
9924   "
9925   [(set (attr "length")
9926         (if_then_else (eq_attr "is_thumb" "yes")
9927                       (const_int 2)
9928                       (const_int 4)))
9929    (set_attr "type" "mov_reg")]
9932 (define_insn "trap"
9933   [(trap_if (const_int 1) (const_int 0))]
9934   ""
9935   "*
9936   if (TARGET_ARM)
9937     return \".inst\\t0xe7f000f0\";
9938   else
9939     return \".inst\\t0xdeff\";
9940   "
9941   [(set (attr "length")
9942         (if_then_else (eq_attr "is_thumb" "yes")
9943                       (const_int 2)
9944                       (const_int 4)))
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")]))]
9959   "TARGET_32BIT"
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
9967    ;; to be disabled.
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")
9975                           (if_then_else
9976                            (match_operand:SI 1 "add_operator" "")
9977                            (const_string "yes") (const_string "no"))
9978                           (const_string "yes")
9979                           (if_then_else
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")])
9984 (define_split
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" ""))]
9994   "TARGET_32BIT"
9995   [(set (match_dup 8)
9996         (match_op_dup 2 [(match_op_dup 3 [(match_dup 4) (match_dup 5)])
9997                          (match_dup 6)]))
9998    (set (match_dup 0)
9999         (match_op_dup 1 [(match_dup 8) (match_dup 7)]))]
10000   "")
10002 (define_insn "*arith_shiftsi_compare0"
10003   [(set (reg:CC_NOOV CC_REGNUM)
10004         (compare:CC_NOOV
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")])
10010          (const_int 0)))
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)])
10013                          (match_dup 2)]))]
10014   "TARGET_32BIT"
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)
10023         (compare:CC_NOOV
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")])
10029          (const_int 0)))
10030    (clobber (match_scratch:SI 0 "=r,r"))]
10031   "TARGET_32BIT"
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")])))]
10044   "TARGET_32BIT"
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)
10053         (compare:CC_NOOV
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")]))
10058          (const_int 0)))
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)])))]
10062   "TARGET_32BIT"
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)
10071         (compare:CC_NOOV
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")]))
10076          (const_int 0)))
10077    (clobber (match_scratch:SI 0 "=r,r,r"))]
10078   "TARGET_32BIT"
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")))]
10091   "TARGET_ARM"
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))))]
10097   {
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);
10106     else
10107       rc = reverse_condition (rc);
10108     operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
10109   }
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")))]
10120   "TARGET_ARM"
10121   "@
10122    orr%d1\\t%0, %3, #1
10123    #"
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))))]
10131   {
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);
10140     else
10141       rc = reverse_condition (rc);
10142     operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
10143   }
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.
10151 (define_split
10152   [(set (match_operand:SI 0 "s_register_operand" "")
10153         (lt:SI (match_operand:SI 1 "s_register_operand" "")
10154                (const_int 0)))
10155    (clobber (reg:CC CC_REGNUM))]
10156   "TARGET_32BIT && reload_completed"
10157   [(set (match_dup 0) (lshiftrt:SI (match_dup 1) (const_int 31)))])
10159 (define_split
10160   [(set (match_operand:SI 0 "s_register_operand" "")
10161         (ge:SI (match_operand:SI 1 "s_register_operand" "")
10162                (const_int 0)))
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)))])
10168 (define_split
10169   [(set (match_operand:SI 0 "s_register_operand" "")
10170         (eq:SI (match_operand:SI 1 "s_register_operand" "")
10171                (const_int 0)))
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)))]
10178 (define_split
10179   [(set (match_operand:SI 0 "s_register_operand" "")
10180         (eq:SI (match_operand:SI 1 "s_register_operand" "")
10181                (const_int 0)))
10182    (clobber (reg:CC CC_REGNUM))]
10183   "TARGET_32BIT && reload_completed"
10184   [(parallel
10185     [(set (reg:CC CC_REGNUM)
10186           (compare:CC (const_int 1) (match_dup 1)))
10187      (set (match_dup 0)
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)))])
10192 (define_split
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"
10198   [(parallel
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]));
10208 (define_split
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"
10214   [(parallel
10215     [(set (reg:CC_NOOV CC_REGNUM)
10216           (compare:CC_NOOV (minus:SI (match_dup 1) (match_dup 2))
10217                            (const_int 0)))
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))]
10228   "TARGET_32BIT"
10229   "#"
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)))]
10235   rtx tmp1;
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);
10245   else
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
10256 ;;      clz Rd, reg1
10257 ;;      lsr Rd, Rd, #5
10258 (define_peephole2
10259   [(set (reg:CC CC_REGNUM)
10260         (compare:CC (match_operand:SI 1 "register_operand" "")
10261                     (const_int 0)))
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
10272 ;;      negs Rd, reg1
10273 ;;      adc  Rd, Rd, reg1
10274 (define_peephole2
10275   [(set (reg:CC CC_REGNUM)
10276         (compare:CC (match_operand:SI 1 "register_operand" "")
10277                     (const_int 0)))
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)"
10284   [(parallel
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)))])
10288    (set (match_dup 0)
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
10295 ;;      clz  Rd, Rd
10296 ;;      lsr  Rd, Rd, #5
10297 (define_peephole2
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
10315 ;;      negs Rd, T1
10316 ;;      adc  Rd, Rd, T1
10317 (define_peephole2
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))
10328    (parallel
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)))])
10332    (set (match_dup 0)
10333         (plus:SI (plus:SI (match_dup 0) (match_dup 3))
10334                  (geu:SI (reg:CC CC_REGNUM) (const_int 0))))]
10335   "
10336   if (CONST_INT_P (operands[2]))
10337     operands[4] = plus_constant (SImode, operands[1], -INTVAL (operands[2]));
10338   else
10339     operands[4] = gen_rtx_MINUS (SImode, operands[1], operands[2]);
10340   ")
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)])
10347                            (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")))]
10350   "TARGET_ARM"
10351   "*
10352     if (GET_CODE (operands[3]) == NE)
10353       {
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);
10358         return \"\";
10359       }
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);
10364     return \"\";
10365   "
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))]
10379   "TARGET_ARM"
10380   "*
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\";
10392   "
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))]
10405   "TARGET_ARM"
10406   "*
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\";
10411   "
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" "")
10419         (compare
10420          (if_then_else:SI
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")])
10431           (const_int 0))
10432          (const_int 0)))]
10433   "TARGET_32BIT"
10434   "*
10435   {
10436     static const char * const cmp1[NUM_OF_COND_CMP][2] =
10437     {
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\"}
10446     };
10447     static const char * const cmp2[NUM_OF_COND_CMP][2] =
10448     {
10449       {\"cmp\\t%2, %3\",
10450        \"cmp\\t%0, %1\"},
10451       {\"cmp\\t%2, %3\",
10452        \"cmn\\t%0, #%n1\"},
10453       {\"cmn\\t%2, #%n3\",
10454        \"cmp\\t%0, %1\"},
10455       {\"cmn\\t%2, #%n3\",
10456        \"cmn\\t%0, #%n1\"}
10457     };
10458     static const char * const ite[2] =
10459     {
10460       \"it\\t%d5\",
10461       \"it\\t%d4\"
10462     };
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};
10466     int swap =
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);
10472     }
10473     output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
10474     return \"\";
10475   }"
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"
10480       [(const_int 6)
10481        (const_int 8)
10482        (const_int 8)
10483        (const_int 8)
10484        (const_int 8)
10485        (if_then_else (eq_attr "is_thumb" "no")
10486            (const_int 8)
10487            (const_int 10))
10488        (if_then_else (eq_attr "is_thumb" "no")
10489            (const_int 8)
10490            (const_int 10))
10491        (if_then_else (eq_attr "is_thumb" "no")
10492            (const_int 8)
10493            (const_int 10))
10494        (if_then_else (eq_attr "is_thumb" "no")
10495            (const_int 8)
10496            (const_int 10))])]
10499 (define_insn "*cmp_ite1"
10500   [(set (match_operand 6 "dominant_cc_register" "")
10501         (compare
10502          (if_then_else:SI
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")])
10513           (const_int 1))
10514          (const_int 0)))]
10515   "TARGET_32BIT"
10516   "*
10517   {
10518     static const char * const cmp1[NUM_OF_COND_CMP][2] =
10519     {
10520       {\"cmp\\t%0, %1\",
10521        \"cmp\\t%2, %3\"},
10522       {\"cmn\\t%0, #%n1\",
10523        \"cmp\\t%2, %3\"},
10524       {\"cmp\\t%0, %1\",
10525        \"cmn\\t%2, #%n3\"},
10526       {\"cmn\\t%0, #%n1\",
10527        \"cmn\\t%2, #%n3\"}
10528     };
10529     static const char * const cmp2[NUM_OF_COND_CMP][2] =
10530     {
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\"}
10539     };
10540     static const char * const ite[2] =
10541     {
10542       \"it\\t%d4\",
10543       \"it\\t%D5\"
10544     };
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};
10548     int swap =
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);
10555     }
10556     output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
10557     return \"\";
10558   }"
10559   [(set_attr "conds" "set")
10560    (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
10561    (set_attr_alternative "length"
10562       [(const_int 6)
10563        (const_int 8)
10564        (const_int 8)
10565        (const_int 8)
10566        (const_int 8)
10567        (if_then_else (eq_attr "is_thumb" "no")
10568            (const_int 8)
10569            (const_int 10))
10570        (if_then_else (eq_attr "is_thumb" "no")
10571            (const_int 8)
10572            (const_int 10))
10573        (if_then_else (eq_attr "is_thumb" "no")
10574            (const_int 8)
10575            (const_int 10))
10576        (if_then_else (eq_attr "is_thumb" "no")
10577            (const_int 8)
10578            (const_int 10))])
10579    (set_attr "type" "multiple")]
10582 (define_insn "*cmp_and"
10583   [(set (match_operand 6 "dominant_cc_register" "")
10584         (compare
10585          (and:SI
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")]))
10596          (const_int 0)))]
10597   "TARGET_32BIT"
10598   "*
10599   {
10600     static const char *const cmp1[NUM_OF_COND_CMP][2] =
10601     {
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\"}
10610     };
10611     static const char *const cmp2[NUM_OF_COND_CMP][2] =
10612     {
10613       {\"cmp\\t%2, %3\",
10614        \"cmp\\t%0, %1\"},
10615       {\"cmp\\t%2, %3\",
10616        \"cmn\\t%0, #%n1\"},
10617       {\"cmn\\t%2, #%n3\",
10618        \"cmp\\t%0, %1\"},
10619       {\"cmn\\t%2, #%n3\",
10620        \"cmn\\t%0, #%n1\"}
10621     };
10622     static const char *const ite[2] =
10623     {
10624       \"it\\t%d5\",
10625       \"it\\t%d4\"
10626     };
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};
10630     int swap =
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);
10636     }
10637     output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
10638     return \"\";
10639   }"
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"
10644       [(const_int 6)
10645        (const_int 8)
10646        (const_int 8)
10647        (const_int 8)
10648        (const_int 8)
10649        (if_then_else (eq_attr "is_thumb" "no")
10650            (const_int 8)
10651            (const_int 10))
10652        (if_then_else (eq_attr "is_thumb" "no")
10653            (const_int 8)
10654            (const_int 10))
10655        (if_then_else (eq_attr "is_thumb" "no")
10656            (const_int 8)
10657            (const_int 10))
10658        (if_then_else (eq_attr "is_thumb" "no")
10659            (const_int 8)
10660            (const_int 10))])
10661    (set_attr "type" "multiple")]
10664 (define_insn "*cmp_ior"
10665   [(set (match_operand 6 "dominant_cc_register" "")
10666         (compare
10667          (ior:SI
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")]))
10678          (const_int 0)))]
10679   "TARGET_32BIT"
10680   "*
10681   {
10682     static const char *const cmp1[NUM_OF_COND_CMP][2] =
10683     {
10684       {\"cmp\\t%0, %1\",
10685        \"cmp\\t%2, %3\"},
10686       {\"cmn\\t%0, #%n1\",
10687        \"cmp\\t%2, %3\"},
10688       {\"cmp\\t%0, %1\",
10689        \"cmn\\t%2, #%n3\"},
10690       {\"cmn\\t%0, #%n1\",
10691        \"cmn\\t%2, #%n3\"}
10692     };
10693     static const char *const cmp2[NUM_OF_COND_CMP][2] =
10694     {
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\"}
10703     };
10704     static const char *const ite[2] =
10705     {
10706       \"it\\t%D4\",
10707       \"it\\t%D5\"
10708     };
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};
10712     int swap =
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);
10718     }
10719     output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
10720     return \"\";
10721   }
10722   "
10723   [(set_attr "conds" "set")
10724    (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
10725    (set_attr_alternative "length"
10726       [(const_int 6)
10727        (const_int 8)
10728        (const_int 8)
10729        (const_int 8)
10730        (const_int 8)
10731        (if_then_else (eq_attr "is_thumb" "no")
10732            (const_int 8)
10733            (const_int 10))
10734        (if_then_else (eq_attr "is_thumb" "no")
10735            (const_int 8)
10736            (const_int 10))
10737        (if_then_else (eq_attr "is_thumb" "no")
10738            (const_int 8)
10739            (const_int 10))
10740        (if_then_else (eq_attr "is_thumb" "no")
10741            (const_int 8)
10742            (const_int 10))])
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))]
10755   "TARGET_32BIT
10756    && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_OR_Y)
10757        != CCmode)"
10758   "#"
10759   "TARGET_32BIT && reload_completed"
10760   [(set (match_dup 7)
10761         (compare
10762          (ior:SI
10763           (match_op_dup 3 [(match_dup 1) (match_dup 2)])
10764           (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
10765          (const_int 0)))
10766    (set (match_dup 0) (ne:SI (match_dup 7) (const_int 0)))]
10767   "operands[7]
10768      = gen_rtx_REG (arm_select_dominance_cc_mode (operands[3], operands[6],
10769                                                   DOM_CC_X_OR_Y),
10770                     CC_REGNUM);"
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")]))
10786                  (const_int 0)))
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)])))]
10790   "TARGET_32BIT"
10791   "#"
10792   "TARGET_32BIT && reload_completed"
10793   [(set (match_dup 0)
10794         (compare
10795          (ior:SI
10796           (match_op_dup 3 [(match_dup 1) (match_dup 2)])
10797           (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
10798          (const_int 0)))
10799    (set (match_dup 7) (ne:SI (match_dup 0) (const_int 0)))]
10800   ""
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))]
10815   "TARGET_32BIT
10816    && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y)
10817        != CCmode)"
10818   "#"
10819   "TARGET_32BIT && reload_completed
10820    && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y)
10821        != CCmode)"
10822   [(set (match_dup 7)
10823         (compare
10824          (and:SI
10825           (match_op_dup 3 [(match_dup 1) (match_dup 2)])
10826           (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
10827          (const_int 0)))
10828    (set (match_dup 0) (ne:SI (match_dup 7) (const_int 0)))]
10829   "operands[7]
10830      = gen_rtx_REG (arm_select_dominance_cc_mode (operands[3], operands[6],
10831                                                   DOM_CC_X_AND_Y),
10832                     CC_REGNUM);"
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")]))
10848                  (const_int 0)))
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)])))]
10852   "TARGET_32BIT"
10853   "#"
10854   "TARGET_32BIT && reload_completed"
10855   [(set (match_dup 0)
10856         (compare
10857          (and:SI
10858           (match_op_dup 3 [(match_dup 1) (match_dup 2)])
10859           (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
10860          (const_int 0)))
10861    (set (match_dup 7) (ne:SI (match_dup 0) (const_int 0)))]
10862   ""
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
10871 ;; correct).
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))]
10881   "TARGET_32BIT
10882    && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y)
10883        == CCmode)"
10884   "#"
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)]))
10890    (set (match_dup 0)
10891         (if_then_else:SI (match_op_dup 6 [(match_dup 7) (const_int 0)])
10892                          (match_dup 0)
10893                          (const_int 0)))]
10894   "operands[7] = gen_rtx_REG (SELECT_CC_MODE (GET_CODE (operands[6]),
10895                                               operands[4], operands[5]),
10896                               CC_REGNUM);
10897    operands[8] = gen_rtx_COMPARE (GET_MODE (operands[7]), operands[4],
10898                                   operands[5]);"
10899   [(set_attr "conds" "clob")
10900    (set_attr "length" "20")
10901    (set_attr "type" "multiple")]
10904 (define_split
10905   [(set (reg:CC_NOOV CC_REGNUM)
10906         (compare:CC_NOOV (ior:SI
10907                           (and:SI (match_operand:SI 0 "s_register_operand" "")
10908                                   (const_int 1))
10909                           (match_operator:SI 1 "arm_comparison_operator"
10910                            [(match_operand:SI 2 "s_register_operand" "")
10911                             (match_operand:SI 3 "arm_add_operand" "")]))
10912                          (const_int 0)))
10913    (clobber (match_operand:SI 4 "s_register_operand" ""))]
10914   "TARGET_ARM"
10915   [(set (match_dup 4)
10916         (ior:SI (match_op_dup 1 [(match_dup 2) (match_dup 3)])
10917                 (match_dup 0)))
10918    (set (reg:CC_NOOV CC_REGNUM)
10919         (compare:CC_NOOV (and:SI (match_dup 4) (const_int 1))
10920                          (const_int 0)))]
10921   "")
10923 (define_split
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" "")
10930                                   (const_int 1)))
10931                          (const_int 0)))
10932    (clobber (match_operand:SI 4 "s_register_operand" ""))]
10933   "TARGET_ARM"
10934   [(set (match_dup 4)
10935         (ior:SI (match_op_dup 1 [(match_dup 2) (match_dup 3)])
10936                 (match_dup 0)))
10937    (set (reg:CC_NOOV CC_REGNUM)
10938         (compare:CC_NOOV (and:SI (match_dup 4) (const_int 1))
10939                          (const_int 0)))]
10940   "")
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))]
10949   "TARGET_ARM"
10950   "#"
10951   "&& reload_completed"
10952   [(const_int 0)]
10953   {
10954     rtx cc_reg = gen_rtx_REG (CCmode, CC_REGNUM);
10956     if (GET_CODE (operands[3]) == LT && operands[2] == const0_rtx)
10957        {
10958          /* Emit mov\\t%0, %1, asr #31 */
10959          emit_insn (gen_rtx_SET (VOIDmode,
10960                                  operands[0],
10961                                  gen_rtx_ASHIFTRT (SImode,
10962                                                    operands[1],
10963                                                    GEN_INT (31))));
10964          DONE;
10965        }
10966      else if (GET_CODE (operands[3]) == NE)
10967        {
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]))));
10972         else
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,
10977                                                   cc_reg,
10978                                                   const0_rtx),
10979                                       gen_rtx_SET (SImode,
10980                                                    operands[0],
10981                                                    GEN_INT (~0))));
10982         DONE;
10983       }
10984     else
10985       {
10986         /* Emit: cmp\\t%1, %2\;mov%D3\\t%0, #0\;mvn%d3\\t%0, #0 */
10987         emit_insn (gen_rtx_SET (VOIDmode,
10988                                 cc_reg,
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,
10995                                                       VOIDmode,
10996                                                       cc_reg,
10997                                                       const0_rtx),
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,
11002                                                       VOIDmode,
11003                                                       cc_reg,
11004                                                       const0_rtx),
11005                                       gen_rtx_SET (VOIDmode,
11006                                                    operands[0],
11007                                                    GEN_INT (~0))));
11008         DONE;
11009       }
11010      FAIL;
11011   }
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")
11019         (if_then_else:SI
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"))
11023             (const_int 0)])
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))]
11027    "TARGET_32BIT"
11028    "#"
11029    "&& reload_completed"
11030   [(set (reg:CC_NOOV CC_REGNUM)
11031         (compare:CC_NOOV
11032          (plus:SI (match_dup 3)
11033                   (match_dup 4))
11034          (const_int 0)))
11035    (set (match_dup 0) (match_dup 1))
11036    (cond_exec (match_dup 6)
11037               (set (match_dup 0) (match_dup 2)))]
11038   "
11039   {
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);
11049   }
11050   "
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")
11058         (if_then_else:SI
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))]
11065   "TARGET_ARM"
11066   "*
11067   if (GET_CODE (operands[5]) == LT
11068       && (operands[4] == const0_rtx))
11069     {
11070       if (which_alternative != 1 && REG_P (operands[1]))
11071         {
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\";
11075         }
11076       else if (which_alternative != 0 && REG_P (operands[2]))
11077         {
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\";
11081         }
11082       /* The only case that falls through to here is when both ops 1 & 2
11083          are constants.  */
11084     }
11086   if (GET_CODE (operands[5]) == GE
11087       && (operands[4] == const0_rtx))
11088     {
11089       if (which_alternative != 1 && REG_P (operands[1]))
11090         {
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\";
11094         }
11095       else if (which_alternative != 0 && REG_P (operands[2]))
11096         {
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\";
11100         }
11101       /* The only case that falls through to here is when both ops 1 & 2
11102          are constants.  */
11103     }
11104   if (CONST_INT_P (operands[4])
11105       && !const_ok_for_arm (INTVAL (operands[4])))
11106     output_asm_insn (\"cmn\\t%3, #%n4\", operands);
11107   else
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);
11113   return \"\";
11114   "
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")])
11127                          (plus:SI
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))]
11132   "TARGET_ARM"
11133   "#"
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")
11141         (if_then_else:SI
11142          (match_operator 4 "arm_comparison_operator"
11143           [(match_operand 5 "cc_register" "") (const_int 0)])
11144          (plus:SI
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")))]
11148   "TARGET_ARM"
11149   "@
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")
11171                          (plus:SI
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))]
11175   "TARGET_ARM"
11176   "#"
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")
11184         (if_then_else:SI
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")
11188          (plus:SI
11189           (match_operand:SI 2 "s_register_operand" "r,r,r,r")
11190           (match_operand:SI 3 "arm_add_operand" "rI,L,rI,L"))))]
11191   "TARGET_ARM"
11192   "@
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))]
11214   "TARGET_ARM"
11215   "#"
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")])))]
11231   "TARGET_ARM"
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))]
11248   "TARGET_ARM"
11249   "*
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]))
11259     {
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\";
11264     }
11265   if (CONST_INT_P (operands[3])
11266       && !const_ok_for_arm (INTVAL (operands[3])))
11267     output_asm_insn (\"cmn\\t%2, #%n3\", operands);
11268   else
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\";
11273   return \"\";
11274   "
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")))]
11288   "TARGET_ARM"
11289   "@
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))]
11307   "TARGET_ARM"
11308   "*
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]))
11318     {
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\";
11323     }
11325   if (CONST_INT_P (operands[5])
11326       && !const_ok_for_arm (INTVAL (operands[5])))
11327     output_asm_insn (\"cmn\\t%4, #%n5\", operands);
11328   else
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\";
11334   "
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")
11342         (if_then_else:SI
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")])))]
11349   "TARGET_ARM"
11350   "@
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")
11360         (if_then_else:SI
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")
11365          (not:SI
11366           (match_operand:SI 2 "s_register_operand" "r,r"))))
11367    (clobber (reg:CC CC_REGNUM))]
11368   "TARGET_ARM"
11369   "#"
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")
11377         (if_then_else:SI
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"))))]
11382   "TARGET_ARM"
11383   "@
11384    mvn%D4\\t%0, %2
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")
11395         (if_then_else:SI 
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")])
11399          (not:SI
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))]
11403   "TARGET_ARM"
11404   "#"
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")
11412         (if_then_else:SI
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")))]
11417   "TARGET_ARM"
11418   "@
11419    mvn%d4\\t%0, %2
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")
11429         (if_then_else:SI
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))]
11438   "TARGET_ARM"
11439   "#"
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")
11447         (if_then_else:SI
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")))]
11454   "TARGET_ARM"
11455   "@
11456    mov%d5\\t%0, %2%S4
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")
11467         (if_then_else:SI
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))]
11476   "TARGET_ARM"
11477   "#"
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")
11485         (if_then_else:SI
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")])))]
11492   "TARGET_ARM"
11493   "@
11494    mov%D5\\t%0, %2%S4
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")
11505         (if_then_else:SI
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))]
11516   "TARGET_ARM"
11517   "#"
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")
11525         (if_then_else:SI
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")])))]
11534   "TARGET_ARM"
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")
11548         (if_then_else:SI
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))]
11557   "TARGET_ARM"
11558   "#"
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")
11566         (if_then_else:SI
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")])))]
11573   "TARGET_ARM"
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")
11582         (if_then_else:SI
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))]
11591   "TARGET_ARM"
11592   "#"
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")
11600         (if_then_else:SI
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"))))]
11607   "TARGET_ARM"
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")
11616         (if_then_else:SI
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))]
11623   "TARGET_ARM"
11624   "#"
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")
11632         (if_then_else:SI
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")))]
11637   "TARGET_ARM"
11638   "@
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")
11649         (if_then_else:SI
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))]
11656   "TARGET_ARM"
11657   "#"
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")
11665         (if_then_else:SI
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"))))]
11670   "TARGET_ARM"
11671   "@
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])"
11687   "*
11688   {
11689     rtx ldm[3];
11690     rtx arith[4];
11691     rtx base_reg;
11692     HOST_WIDE_INT val1 = 0, val2 = 0;
11694     if (REGNO (operands[0]) > REGNO (operands[4]))
11695       {
11696         ldm[1] = operands[4];
11697         ldm[2] = operands[0];
11698       }
11699     else
11700       {
11701         ldm[1] = operands[0];
11702         ldm[2] = operands[4];
11703       }
11705     base_reg = XEXP (operands[2], 0);
11707     if (!REG_P (base_reg))
11708       {
11709         val1 = INTVAL (XEXP (base_reg, 1));
11710         base_reg = XEXP (base_reg, 0);
11711       }
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];
11719     if (val1 < val2)
11720       {
11721         arith[1] = ldm[1];
11722         arith[2] = ldm[2];
11723       }
11724     else
11725       {
11726         arith[1] = ldm[2];
11727         arith[2] = ldm[1];
11728       }
11730     ldm[0] = base_reg;
11731     if (val1 !=0 && val2 != 0)
11732       {
11733         rtx ops[3];
11735         if (val1 == 4 || val2 == 4)
11736           /* Other val must be 8, since we know they are adjacent and neither
11737              is zero.  */
11738           output_asm_insn (\"ldm%(ib%)\\t%0, {%1, %2}\", ldm);
11739         else if (const_ok_for_arm (val1) || const_ok_for_arm (-val1))
11740           {
11741             ldm[0] = ops[0] = operands[4];
11742             ops[1] = base_reg;
11743             ops[2] = GEN_INT (val1);
11744             output_add_immediate (ops);
11745             if (val1 < val2)
11746               output_asm_insn (\"ldm%(ia%)\\t%0, {%1, %2}\", ldm);
11747             else
11748               output_asm_insn (\"ldm%(da%)\\t%0, {%1, %2}\", ldm);
11749           }
11750         else
11751           {
11752             /* Offset is out of range for a single add, so use two ldr.  */
11753             ops[0] = ldm[1];
11754             ops[1] = base_reg;
11755             ops[2] = GEN_INT (val1);
11756             output_asm_insn (\"ldr%?\\t%0, [%1, %2]\", ops);
11757             ops[0] = ldm[2];
11758             ops[2] = GEN_INT (val2);
11759             output_asm_insn (\"ldr%?\\t%0, [%1, %2]\", ops);
11760           }
11761       }
11762     else if (val1 != 0)
11763       {
11764         if (val1 < val2)
11765           output_asm_insn (\"ldm%(da%)\\t%0, {%1, %2}\", ldm);
11766         else
11767           output_asm_insn (\"ldm%(ia%)\\t%0, {%1, %2}\", ldm);
11768       }
11769     else
11770       {
11771         if (val1 < val2)
11772           output_asm_insn (\"ldm%(ia%)\\t%0, {%1, %2}\", ldm);
11773         else
11774           output_asm_insn (\"ldm%(da%)\\t%0, {%1, %2}\", ldm);
11775       }
11776     output_asm_insn (\"%I3%?\\t%0, %1, %2\", arith);
11777     return \"\";
11778   }"
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
11786 (define_peephole2
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)))]
11791   "TARGET_ARM"
11792   [(parallel [(set (reg:CC CC_REGNUM) (compare:CC (match_dup 1) (const_int 0)))
11793               (set (match_dup 0) (match_dup 1))])]
11794   ""
11797 (define_split
11798   [(set (match_operand:SI 0 "s_register_operand" "")
11799         (and:SI (ge:SI (match_operand:SI 1 "s_register_operand" "")
11800                        (const_int 0))
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" ""))]
11805   "TARGET_ARM"
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)])
11808                               (match_dup 5)))]
11809   ""
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.
11816 (define_split
11817   [(set (reg:CC_Z CC_REGNUM)
11818         (compare:CC_Z
11819          (ashift:SI (subreg:SI (match_operand:QI 0 "memory_operand" "") 0)
11820                     (const_int 24))
11821          (match_operand 1 "const_int_operand" "")))
11822    (clobber (match_scratch:SI 2 ""))]
11823   "TARGET_ARM
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)))]
11828   "
11829   operands[1] = GEN_INT (((unsigned long) INTVAL (operands[1])) >> 24);
11830   "
11832 ;; ??? Check the patterns above for Thumb-2 usefulness
11834 (define_expand "prologue"
11835   [(clobber (const_int 0))]
11836   "TARGET_EITHER"
11837   "if (TARGET_32BIT)
11838      arm_expand_prologue ();
11839    else
11840      thumb1_expand_prologue ();
11841   DONE;
11842   "
11845 (define_expand "epilogue"
11846   [(clobber (const_int 0))]
11847   "TARGET_EITHER"
11848   "
11849   if (crtl->calls_eh_return)
11850     emit_insn (gen_force_register_use (gen_rtx_REG (Pmode, 2)));
11851   if (TARGET_THUMB1)
11852    {
11853      thumb1_expand_epilogue ();
11854      emit_jump_insn (gen_rtx_UNSPEC_VOLATILE (VOIDmode,
11855                      gen_rtvec (1, ret_rtx), VUNSPEC_EPILOGUE));
11856    }
11857   else if (HAVE_return)
11858    {
11859      /* HAVE_return is testing for USE_RETURN_INSN (FALSE).  Hence,
11860         no need for explicit testing again.  */
11861      emit_jump_insn (gen_return ());
11862    }
11863   else if (TARGET_32BIT)
11864    {
11865     arm_expand_epilogue (true);
11866    }
11867   DONE;
11868   "
11871 (define_insn "prologue_thumb1_interwork"
11872   [(unspec_volatile [(const_int 0)] VUNSPEC_THUMB1_INTERWORK)]
11873   "TARGET_THUMB1"
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)])]
11887    "TARGET_32BIT"
11888    "
11889    arm_expand_epilogue (false);
11890    DONE;
11891    "
11894 (define_insn "*epilogue_insns"
11895   [(unspec_volatile [(return)] VUNSPEC_EPILOGUE)]
11896   "TARGET_THUMB1"
11897   "*
11898     return thumb1_unexpanded_epilogue ();
11899   "
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" ""))]
11913   "TARGET_EITHER"
11914   "
11915   {
11916     cfun->machine->eh_epilogue_sp_ofs = operands[1];
11917     if (!REG_P (operands[2]) || REGNO (operands[2]) != 2)
11918       {
11919         rtx ra = gen_rtx_REG (Pmode, 2);
11921         emit_move_insn (ra, operands[2]);
11922         operands[2] = ra;
11923       }
11924     /* This is a hack -- we may have crystalized the function type too
11925        early.  */
11926     cfun->machine->func_type = 0;
11927   }"
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
11935 ;; up again here.
11937 ;; ??? Need to audit these splitters for Thumb-2.  Why isn't normal
11938 ;; conditional execution sufficient?
11940 (define_split
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 "" "")])
11944                          (match_dup 0)
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)))]
11951   "
11952   {
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);
11961     else
11962       rc = reverse_condition (rc);
11964     operands[7] = gen_rtx_fmt_ee (rc, VOIDmode, operands[5], const0_rtx);
11965   }"
11968 (define_split
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 "" "")
11973                          (match_dup 0)))
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)))]
11979   "
11980   {
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]);
11986   }"
11989 (define_split
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)))]
12002   "
12003   {
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);
12012     else
12013       rc = reverse_condition (rc);
12015     operands[8] = gen_rtx_fmt_ee (rc, VOIDmode, operands[6], const0_rtx);
12016   }"
12019 (define_split
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" "")
12025                          (not:SI
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))))]
12034   "
12035   {
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);
12044     else
12045       rc = reverse_condition (rc);
12047     operands[8] = gen_rtx_fmt_ee (rc, VOIDmode, operands[6], const0_rtx);
12048   }"
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")
12056                          (not:SI
12057                           (match_operand:SI 2 "s_register_operand" "r,r"))))]
12058   "TARGET_ARM"
12059   "@
12060    mvn%D4\\t%0, %2
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")
12073                          (const_int 1)
12074                          (match_operand:SI 2 "const_int_operand" "n")))
12075     (clobber (reg:CC CC_REGNUM))]
12076   "TARGET_ARM"
12077   "*
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\";
12081   "
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")
12089         (not:SI
12090          (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
12091                           (const_int 1)
12092                           (match_operand:SI 2 "const_int_operand" "n"))))
12093    (clobber (reg:CC CC_REGNUM))]
12094   "TARGET_ARM"
12095   "*
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\";
12100   "
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
12109 ;; part.
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))])]
12117   ""
12118   "*
12119   {
12120     int num_saves = XVECLEN (operands[2], 0);
12121      
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);
12128     else
12129       {
12130         int i;
12131         char pattern[100];
12133         if (TARGET_ARM)
12134             strcpy (pattern, \"stm%(fd%)\\t%m0!, {%1\");
12135         else if (TARGET_THUMB2)
12136             strcpy (pattern, \"push%?\\t{%1\");
12137         else
12138             strcpy (pattern, \"push\\t{%1\");
12140         for (i = 1; i < num_saves; i++)
12141           {
12142             strcat (pattern, \", %|\");
12143             strcat (pattern,
12144                     reg_names[REGNO (XEXP (XVECEXP (operands[2], 0, i), 0))]);
12145           }
12147         strcat (pattern, \"}\");
12148         output_asm_insn (pattern, operands);
12149       }
12151     return \"\";
12152   }"
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")]
12162                     UNSPEC_PRLG_STK))]
12163   ""
12164   ""
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)))
12178         ])]
12179   "TARGET_32BIT && (reload_in_progress || reload_completed)"
12180   "*
12181   {
12182     arm_output_multireg_pop (operands, /*return_pc=*/false,
12183                                        /*cond=*/const_true_rtx,
12184                                        /*reverse=*/false,
12185                                        /*update=*/true);
12186     return \"\";
12187   }
12188   "
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
12198 ;;  with (return).
12199 (define_insn "*pop_multiple_with_writeback_and_return"
12200   [(match_parallel 0 "pop_multiple_return"
12201     [(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)))
12207         ])]
12208   "TARGET_32BIT && (reload_in_progress || reload_completed)"
12209   "*
12210   {
12211     arm_output_multireg_pop (operands, /*return_pc=*/true,
12212                                        /*cond=*/const_true_rtx,
12213                                        /*reverse=*/false,
12214                                        /*update=*/true);
12215     return \"\";
12216   }
12217   "
12218   [(set_attr "type" "load4")
12219    (set_attr "predicable" "yes")]
12222 (define_insn "*pop_multiple_with_return"
12223   [(match_parallel 0 "pop_multiple_return"
12224     [(return)
12225      (set (match_operand:SI 2 "s_register_operand" "=rk")
12226           (mem:SI (match_operand:SI 1 "s_register_operand" "rk")))
12227         ])]
12228   "TARGET_32BIT && (reload_in_progress || reload_completed)"
12229   "*
12230   {
12231     arm_output_multireg_pop (operands, /*return_pc=*/true,
12232                                        /*cond=*/const_true_rtx,
12233                                        /*reverse=*/false,
12234                                        /*update=*/false);
12235     return \"\";
12236   }
12237   "
12238   [(set_attr "type" "load4")
12239    (set_attr "predicable" "yes")]
12242 ;; Load into PC and return
12243 (define_insn "*ldr_with_return"
12244   [(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"
12261   "*
12262   {
12263     int num_regs = XVECLEN (operands[0], 0);
12264     char pattern[100];
12265     rtx op_list[2];
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)
12272       {
12273         strcat (pattern, \"-%P1\");
12274         op_list [1] = XEXP (XVECEXP (operands[0], 0, num_regs - 1), 0);
12275       }
12277     strcat (pattern, \"}\");
12278     output_asm_insn (pattern, op_list);
12279     return \"\";
12280   }
12281   "
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)]
12291   "TARGET_EITHER"
12292   "*
12293   assemble_align (32);
12294   return \"\";
12295   "
12296   [(set_attr "type" "no_insn")]
12299 (define_insn "align_8"
12300   [(unspec_volatile [(const_int 0)] VUNSPEC_ALIGN8)]
12301   "TARGET_EITHER"
12302   "*
12303   assemble_align (64);
12304   return \"\";
12305   "
12306   [(set_attr "type" "no_insn")]
12309 (define_insn "consttable_end"
12310   [(unspec_volatile [(const_int 0)] VUNSPEC_POOL_END)]
12311   "TARGET_EITHER"
12312   "*
12313   making_const_table = FALSE;
12314   return \"\";
12315   "
12316   [(set_attr "type" "no_insn")]
12319 (define_insn "consttable_1"
12320   [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_1)]
12321   "TARGET_THUMB1"
12322   "*
12323   making_const_table = TRUE;
12324   assemble_integer (operands[0], 1, BITS_PER_WORD, 1);
12325   assemble_zeros (3);
12326   return \"\";
12327   "
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)]
12334   "TARGET_THUMB1"
12335   "*
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);
12340   return \"\";
12341   "
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)]
12348   "TARGET_EITHER"
12349   "*
12350   {
12351     rtx x = operands[0];
12352     making_const_table = TRUE;
12353     switch (GET_MODE_CLASS (GET_MODE (x)))
12354       {
12355       case MODE_FLOAT:
12356         if (GET_MODE (x) == HFmode)
12357           arm_emit_fp16_const (x);
12358         else
12359           {
12360             REAL_VALUE_TYPE r;
12361             REAL_VALUE_FROM_CONST_DOUBLE (r, x);
12362             assemble_real (r, GET_MODE (x), BITS_PER_WORD);
12363           }
12364         break;
12365       default:
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)
12372           x = XEXP (x, 0);
12373         assemble_integer (x, 4, BITS_PER_WORD, 1);
12374         mark_symbol_refs_as_used (x);
12375         break;
12376       }
12377     return \"\";
12378   }"
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)]
12385   "TARGET_EITHER"
12386   "*
12387   {
12388     making_const_table = TRUE;
12389     switch (GET_MODE_CLASS (GET_MODE (operands[0])))
12390       {
12391        case MODE_FLOAT:
12392         {
12393           REAL_VALUE_TYPE r;
12394           REAL_VALUE_FROM_CONST_DOUBLE (r, operands[0]);
12395           assemble_real (r, GET_MODE (operands[0]), BITS_PER_WORD);
12396           break;
12397         }
12398       default:
12399         assemble_integer (operands[0], 8, BITS_PER_WORD, 1);
12400         break;
12401       }
12402     return \"\";
12403   }"
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)]
12410   "TARGET_EITHER"
12411   "*
12412   {
12413     making_const_table = TRUE;
12414     switch (GET_MODE_CLASS (GET_MODE (operands[0])))
12415       {
12416        case MODE_FLOAT:
12417         {
12418           REAL_VALUE_TYPE r;
12419           REAL_VALUE_FROM_CONST_DOUBLE (r, operands[0]);
12420           assemble_real (r, GET_MODE (operands[0]), BITS_PER_WORD);
12421           break;
12422         }
12423       default:
12424         assemble_integer (operands[0], 16, BITS_PER_WORD, 1);
12425         break;
12426       }
12427     return \"\";
12428   }"
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 "" "")))])]
12438   "TARGET_THUMB1"
12439   "
12440   if (flag_pic)
12441     {
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;
12448     }
12449   "
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 "" "")))]
12456   "TARGET_THUMB1"
12457   "mov\\t%|pc, %0"
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"
12468   "clz%?\\t%0, %1"
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"
12476   "rbit%?\\t%0, %1"
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"
12484   "
12485    {
12486      rtx tmp = gen_reg_rtx (SImode); 
12487      emit_insn (gen_rbitsi2 (tmp, operands[1]));
12488      emit_insn (gen_clzsi2 (operands[0], tmp));
12489    }
12490    DONE;
12491   "
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"
12501   "pld\\t%a0"
12502   [(set_attr "type" "load1")]
12505 ;; General predication pattern
12507 (define_cond_exec
12508   [(match_operator 0 "arm_comparison_operator"
12509     [(match_operand 1 "cc_register" "")
12510      (const_int 0)])]
12511   "TARGET_32BIT"
12512   ""
12513 [(set_attr "predicated" "yes")]
12516 (define_insn "force_register_use"
12517   [(unspec:SI [(match_operand:SI 0 "register_operand" "")] UNSPEC_REGISTER_USE)]
12518   ""
12519   "%@ %0 needed"
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" ""))]
12529   "TARGET_EITHER"
12530   "
12531   {
12532     if (TARGET_32BIT)
12533       emit_insn (gen_arm_eh_return (operands[0]));
12534     else
12535       emit_insn (gen_thumb_eh_return (operands[0]));
12536     DONE;
12537   }"
12539                                    
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")]
12543                     VUNSPEC_EH_RETURN)
12544    (clobber (match_scratch:SI 1 "=&r"))]
12545   "TARGET_ARM"
12546   "#"
12547   "&& reload_completed"
12548   [(const_int 0)]
12549   "
12550   {
12551     arm_set_return_address (operands[0], operands[1]);
12552     DONE;
12553   }"
12556 (define_insn_and_split "thumb_eh_return"
12557   [(unspec_volatile [(match_operand:SI 0 "s_register_operand" "l")]
12558                     VUNSPEC_EH_RETURN)
12559    (clobber (match_scratch:SI 1 "=&l"))]
12560   "TARGET_THUMB1"
12561   "#"
12562   "&& reload_completed"
12563   [(const_int 0)]
12564   "
12565   {
12566     thumb_set_return_address (operands[0], operands[1]);
12567     DONE;
12568   }"
12569   [(set_attr "type" "mov_reg")]
12573 ;; TLS support
12575 (define_insn "load_tp_hard"
12576   [(set (match_operand:SI 0 "register_operand" "=r")
12577         (unspec:SI [(const_int 0)] UNSPEC_TLS))]
12578   "TARGET_HARD_TP"
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))]
12590   "TARGET_SOFT_TP"
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))]
12605   "TARGET_GNU2_TLS"
12606   {
12607     targetm.asm_out.internal_label (asm_out_file, "LPIC",
12608                                     INTVAL (operands[1]));
12609     return "bl\\t%c0(tlscall)";
12610   }
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")]
12619  ""
12622    arm_load_tp (operands[0]);
12623    DONE;
12624  }")
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")
12632                    (const_int 16)
12633                    (const_int 16))
12634         (match_operand:SI 1 "const_int_operand" ""))]
12635   "arm_arch_thumb2"
12636   "movt%?\t%0, %L1"
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")))]
12646   "arm_arch6"
12647   "@
12648    rev\t%0, %1
12649    rev%?\t%0, %1
12650    rev%?\t%0, %1"
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" "")
12659                              (const_int 16))
12660                 (match_dup 1)))
12661    (set (match_dup 2)
12662         (lshiftrt:SI (match_dup 2)
12663                      (const_int 8)))
12664    (set (match_operand:SI 3 "s_register_operand" "")
12665         (rotatert:SI (match_dup 1)
12666                      (const_int 8)))
12667    (set (match_dup 2)
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)
12672                 (match_dup 2)))]
12673   "TARGET_32BIT"
12674   ""
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" "")
12681                 (const_int 24)))
12682    (set (match_operand:SI 3 "s_register_operand" "")
12683      (lshiftrt:SI (match_dup 1)
12684                   (const_int 24)))
12685    (set (match_dup 3)
12686      (ior:SI (match_dup 3)
12687              (match_dup 2)))
12688    (set (match_operand:SI 4 "s_register_operand" "")
12689      (const_int 16))
12690    (set (match_operand:SI 5 "s_register_operand" "")
12691      (rotatert:SI (match_dup 1)
12692                   (match_dup 4)))
12693    (set (match_dup 2)
12694      (ashift:SI (match_dup 5)
12695                 (const_int 24)))
12696    (set (match_dup 5)
12697      (lshiftrt:SI (match_dup 5)
12698                   (const_int 24)))
12699    (set (match_dup 5)
12700      (ior:SI (match_dup 5)
12701              (match_dup 2)))
12702    (set (match_dup 5)
12703      (rotatert:SI (match_dup 5)
12704                   (match_dup 4)))
12705    (set (match_operand:SI 0 "s_register_operand" "")
12706      (ior:SI (match_dup 5)
12707              (match_dup 3)))]
12708   "TARGET_THUMB"
12709   ""
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)"
12717     if (!arm_arch6)
12718       {
12719         rtx op2 = gen_reg_rtx (SImode);
12720         rtx op3 = gen_reg_rtx (SImode);
12722         if (TARGET_THUMB)
12723           {
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));
12729           }
12730         else
12731           {
12732             emit_insn (gen_arm_legacy_rev (operands[0], operands[1],
12733                                            op2, op3));
12734           }
12736         DONE;
12737       }
12738   "
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"))))]
12747   "arm_arch6"
12748   "@
12749   revsh\t%0, %1
12750   revsh%?\t%0, %1
12751   revsh%?\t%0, %1"
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")))]
12760   "arm_arch6"
12761   "@
12762    rev16\t%0, %1
12763    rev16%?\t%0, %1
12764    rev16%?\t%0, %1"
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")))]
12773 "arm_arch6"
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]),
12791                                   false, true))"
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)
12802                          (const_int 4))))]
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")
12815                          (const_int -4))))
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]),
12839                                   false, false))"
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)
12849                          (const_int 4)))
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")
12862                          (const_int -4)))
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")]
12880          CRC))]
12881   "TARGET_CRC32"
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")))
12899         ])]
12900   "TARGET_32BIT"
12901   "*
12902   {
12903     arm_output_multireg_pop (operands, /*return_pc=*/false,
12904                                        /*cond=*/const_true_rtx,
12905                                        /*reverse=*/false,
12906                                        /*update=*/false);
12907     return \"\";
12908   }
12909   "
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
12918 (include "vfp.md")
12919 ;; Thumb-2 patterns
12920 (include "thumb2.md")
12921 ;; Neon patterns
12922 (include "neon.md")
12923 ;; Crypto patterns
12924 (include "crypto.md")
12925 ;; Synchronization Primitives
12926 (include "sync.md")
12927 ;; Fixed-point patterns
12928 (include "arm-fixed.md")