46fc4422d5ce2268aea898da397ff8d3bc34bf70
[gcc.git] / gcc / config / arm / arm.md
1 ;;- Machine description for ARM for GNU compiler
2 ;; Copyright (C) 1991-2013 Free Software Foundation, Inc.
3 ;; Contributed by Pieter `Tiggr' Schoenmakers (rcpieter@win.tue.nl)
4 ;; and Martin Simmons (@harleqn.co.uk).
5 ;; More major hacks by Richard Earnshaw (rearnsha@arm.com).
6
7 ;; This file is part of GCC.
8
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.
13
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.
18
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/>.
22
23 ;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
24
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.
43
44 \f
45 ;;---------------------------------------------------------------------------
46 ;; Constants
47
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 ]
60 )
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 ]
67 )
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 ]
76 )
77
78 \f
79 ;;---------------------------------------------------------------------------
80 ;; Attributes
81
82 ;; Processor type. This is created automatically from arm-cores.def.
83 (include "arm-tune.md")
84
85 ;; Instruction classification types
86 (include "types.md")
87
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")))
92
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")))
95
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")))
98
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"))
103
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"))
107
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))
111
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")))
117
118 (define_attr "predicated" "yes,no" (const_string "no"))
119
120 ; LENGTH of an instruction (in bytes)
121 (define_attr "length" ""
122 (const_int 4))
123
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"))
132
133 (define_attr "arch_enabled" "no,yes"
134 (cond [(eq_attr "arch" "any")
135 (const_string "yes")
136
137 (and (eq_attr "arch" "a")
138 (match_test "TARGET_ARM"))
139 (const_string "yes")
140
141 (and (eq_attr "arch" "t")
142 (match_test "TARGET_THUMB"))
143 (const_string "yes")
144
145 (and (eq_attr "arch" "t1")
146 (match_test "TARGET_THUMB1"))
147 (const_string "yes")
148
149 (and (eq_attr "arch" "t2")
150 (match_test "TARGET_THUMB2"))
151 (const_string "yes")
152
153 (and (eq_attr "arch" "32")
154 (match_test "TARGET_32BIT"))
155 (const_string "yes")
156
157 (and (eq_attr "arch" "v6")
158 (match_test "TARGET_32BIT && arm_arch6"))
159 (const_string "yes")
160
161 (and (eq_attr "arch" "nov6")
162 (match_test "TARGET_32BIT && !arm_arch6"))
163 (const_string "yes")
164
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")
169
170 (and (eq_attr "arch" "neon_for_64bits")
171 (match_test "TARGET_NEON")
172 (match_test "TARGET_PREFER_NEON_64BITS"))
173 (const_string "yes")
174
175 (and (eq_attr "arch" "iwmmxt2")
176 (match_test "TARGET_REALLY_IWMMXT2"))
177 (const_string "yes")]
178
179 (const_string "no")))
180
181 (define_attr "opt" "any,speed,size"
182 (const_string "any"))
183
184 (define_attr "opt_enabled" "no,yes"
185 (cond [(eq_attr "opt" "any")
186 (const_string "yes")
187
188 (and (eq_attr "opt" "speed")
189 (match_test "optimize_function_for_speed_p (cfun)"))
190 (const_string "yes")
191
192 (and (eq_attr "opt" "size")
193 (match_test "optimize_function_for_size_p (cfun)"))
194 (const_string "yes")]
195 (const_string "no")))
196
197 (define_attr "use_literal_pool" "no,yes"
198 (cond [(and (eq_attr "type" "f_loads,f_loadd")
199 (match_test "CONSTANT_P (operands[1])"))
200 (const_string "yes")]
201 (const_string "no")))
202
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"))
207
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")
212
213 (and (eq_attr "predicable_short_it" "no")
214 (and (eq_attr "predicated" "yes")
215 (match_test "arm_restrict_it")))
216 (const_string "no")
217
218 (and (eq_attr "enabled_for_depr_it" "no")
219 (match_test "arm_restrict_it"))
220 (const_string "no")
221
222 (and (eq_attr "use_literal_pool" "yes")
223 (match_test "arm_disable_literal_pool"))
224 (const_string "no")
225
226 (eq_attr "arch_enabled" "no")
227 (const_string "no")
228
229 (eq_attr "opt_enabled" "no")
230 (const_string "no")]
231 (const_string "yes")))
232
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))
245
246 (define_attr "pool_range" ""
247 (cond [(eq_attr "is_thumb" "yes") (attr "thumb2_pool_range")]
248 (attr "arm_pool_range")))
249 (define_attr "neg_pool_range" ""
250 (cond [(eq_attr "is_thumb" "yes") (attr "thumb2_neg_pool_range")]
251 (attr "arm_neg_pool_range")))
252
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")])
260
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")))
264
265 ; YES if the "type" attribute assigned to the insn denotes an
266 ; Advanced SIMD instruction, NO otherwise.
267 (define_attr "is_neon_type" "yes,no"
268 (if_then_else (eq_attr "type"
269 "neon_add, neon_add_q, neon_add_widen, neon_add_long,\
270 neon_qadd, neon_qadd_q, neon_add_halve, neon_add_halve_q,\
271 neon_add_halve_narrow_q,\
272 neon_sub, neon_sub_q, neon_sub_widen, neon_sub_long, neon_qsub,\
273 neon_qsub_q, neon_sub_halve, neon_sub_halve_q,\
274 neon_sub_halve_narrow_q,\
275 neon_abs, neon_abs_q, neon_neg, neon_neg_q, neon_qneg,\
276 neon_qneg_q, neon_qabs, neon_qabs_q, neon_abd, neon_abd_q,\
277 neon_abd_long, neon_minmax, neon_minmax_q, neon_compare,\
278 neon_compare_q, neon_compare_zero, neon_compare_zero_q,\
279 neon_arith_acc, neon_arith_acc_q, neon_reduc_add,\
280 neon_reduc_add_q, neon_reduc_add_long, neon_reduc_add_acc,\
281 neon_reduc_add_acc_q, neon_reduc_minmax, neon_reduc_minmax_q,\
282 neon_logic, neon_logic_q, neon_tst, neon_tst_q,\
283 neon_shift_imm, neon_shift_imm_q, neon_shift_imm_narrow_q,\
284 neon_shift_imm_long, neon_shift_reg, neon_shift_reg_q,\
285 neon_shift_acc, neon_shift_acc_q, neon_sat_shift_imm,\
286 neon_sat_shift_imm_q, neon_sat_shift_imm_narrow_q,\
287 neon_sat_shift_reg, neon_sat_shift_reg_q,\
288 neon_ins, neon_ins_q, neon_move, neon_move_q, neon_move_narrow_q,\
289 neon_permute, neon_permute_q, neon_zip, neon_zip_q, neon_tbl1,\
290 neon_tbl1_q, neon_tbl2, neon_tbl2_q, neon_tbl3, neon_tbl3_q,\
291 neon_tbl4, neon_tbl4_q, neon_bsl, neon_bsl_q, neon_cls,\
292 neon_cls_q, neon_cnt, neon_cnt_q, neon_dup, neon_dup_q,\
293 neon_ext, neon_ext_q, neon_rbit, neon_rbit_q,\
294 neon_rev, neon_rev_q, neon_mul_b, neon_mul_b_q, neon_mul_h,\
295 neon_mul_h_q, neon_mul_s, neon_mul_s_q, neon_mul_b_long,\
296 neon_mul_h_long, neon_mul_s_long, neon_mul_h_scalar,\
297 neon_mul_h_scalar_q, neon_mul_s_scalar, neon_mul_s_scalar_q,\
298 neon_mul_h_scalar_long, neon_mul_s_scalar_long, neon_sat_mul_b,\
299 neon_sat_mul_b_q, neon_sat_mul_h, neon_sat_mul_h_q,\
300 neon_sat_mul_s, neon_sat_mul_s_q, neon_sat_mul_b_long,\
301 neon_sat_mul_h_long, neon_sat_mul_s_long, neon_sat_mul_h_scalar,\
302 neon_sat_mul_h_scalar_q, neon_sat_mul_s_scalar,\
303 neon_sat_mul_s_scalar_q, neon_sat_mul_h_scalar_long,\
304 neon_sat_mul_s_scalar_long, neon_mla_b, neon_mla_b_q, neon_mla_h,\
305 neon_mla_h_q, neon_mla_s, neon_mla_s_q, neon_mla_b_long,\
306 neon_mla_h_long, neon_mla_s_long, neon_mla_h_scalar,\
307 neon_mla_h_scalar_q, neon_mla_s_scalar, neon_mla_s_scalar_q,\
308 neon_mla_h_scalar_long, neon_mla_s_scalar_long,\
309 neon_sat_mla_b_long, neon_sat_mla_h_long,\
310 neon_sat_mla_s_long, neon_sat_mla_h_scalar_long,\
311 neon_sat_mla_s_scalar_long,\
312 neon_to_gp, neon_to_gp_q, neon_from_gp, neon_from_gp_q,\
313 neon_ldr, neon_load1_1reg, neon_load1_1reg_q, neon_load1_2reg,\
314 neon_load1_2reg_q, neon_load1_3reg, neon_load1_3reg_q,\
315 neon_load1_4reg, neon_load1_4reg_q, neon_load1_all_lanes,\
316 neon_load1_all_lanes_q, neon_load1_one_lane, neon_load1_one_lane_q,\
317 neon_load2_2reg, neon_load2_2reg_q, neon_load2_4reg,\
318 neon_load2_4reg_q, neon_load2_all_lanes, neon_load2_all_lanes_q,\
319 neon_load2_one_lane, neon_load2_one_lane_q,\
320 neon_load3_3reg, neon_load3_3reg_q, neon_load3_all_lanes,\
321 neon_load3_all_lanes_q, neon_load3_one_lane, neon_load3_one_lane_q,\
322 neon_load4_4reg, neon_load4_4reg_q, neon_load4_all_lanes,\
323 neon_load4_all_lanes_q, neon_load4_one_lane, neon_load4_one_lane_q,\
324 neon_str, neon_store1_1reg, neon_store1_1reg_q, neon_store1_2reg,\
325 neon_store1_2reg_q, neon_store1_3reg, neon_store1_3reg_q,\
326 neon_store1_4reg, neon_store1_4reg_q, neon_store1_one_lane,\
327 neon_store1_one_lane_q, neon_store2_2reg, neon_store2_2reg_q,\
328 neon_store2_4reg, neon_store2_4reg_q, neon_store2_one_lane,\
329 neon_store2_one_lane_q, neon_store3_3reg, neon_store3_3reg_q,\
330 neon_store3_one_lane, neon_store3_one_lane_q, neon_store4_4reg,\
331 neon_store4_4reg_q, neon_store4_one_lane, neon_store4_one_lane_q,\
332 neon_fp_abd_s, neon_fp_abd_s_q, neon_fp_abd_d, neon_fp_abd_d_q,\
333 neon_fp_addsub_s, neon_fp_addsub_s_q, neon_fp_addsub_d,\
334 neon_fp_addsub_d_q, neon_fp_compare_s, neon_fp_compare_s_q,\
335 neon_fp_compare_d, neon_fp_compare_d_q, neon_fp_minmax_s,\
336 neon_fp_minmax_s_q, neon_fp_minmax_d, neon_fp_minmax_d_q,\
337 neon_fp_reduc_add_s, neon_fp_reduc_add_s_q, neon_fp_reduc_add_d,\
338 neon_fp_reduc_add_d_q, neon_fp_reduc_minmax_s,
339 neon_fp_reduc_minmax_s_q, neon_fp_reduc_minmax_d,\
340 neon_fp_reduc_minmax_d_q,\
341 neon_fp_cvt_narrow_s_q, neon_fp_cvt_narrow_d_q,\
342 neon_fp_cvt_widen_h, neon_fp_cvt_widen_s, neon_fp_to_int_s,\
343 neon_fp_to_int_s_q, neon_int_to_fp_s, neon_int_to_fp_s_q,\
344 neon_fp_round_s, neon_fp_round_s_q, neon_fp_recpe_s,\
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")
359 (const_string "yes")
360 (const_string "no")))
361
362 ; condition codes: this one is used by final_prescan_insn to speed up
363 ; conditionalizing instructions. It saves having to scan the rtl to see if
364 ; it uses or alters the condition codes.
365 ;
366 ; USE means that the condition codes are used by the insn in the process of
367 ; outputting code, this means (at present) that we can't use the insn in
368 ; inlined branches
369 ;
370 ; SET means that the purpose of the insn is to set the condition codes in a
371 ; well defined manner.
372 ;
373 ; CLOB means that the condition codes are altered in an undefined manner, if
374 ; they are altered at all
375 ;
376 ; UNCONDITIONAL means the instruction can not be conditionally executed and
377 ; that the instruction does not use or alter the condition codes.
378 ;
379 ; NOCOND means that the instruction does not use or alter the condition
380 ; codes but can be converted into a conditionally exectuted instruction.
381
382 (define_attr "conds" "use,set,clob,unconditional,nocond"
383 (if_then_else
384 (ior (eq_attr "is_thumb1" "yes")
385 (eq_attr "type" "call"))
386 (const_string "clob")
387 (if_then_else (eq_attr "is_neon_type" "no")
388 (const_string "nocond")
389 (const_string "unconditional"))))
390
391 ; Predicable means that the insn can be conditionally executed based on
392 ; an automatically added predicate (additional patterns are generated by
393 ; gen...). We default to 'no' because no Thumb patterns match this rule
394 ; and not all ARM patterns do.
395 (define_attr "predicable" "no,yes" (const_string "no"))
396
397 ; Only model the write buffer for ARM6 and ARM7. Earlier processors don't
398 ; have one. Later ones, such as StrongARM, have write-back caches, so don't
399 ; suffer blockages enough to warrant modelling this (and it can adversely
400 ; affect the schedule).
401 (define_attr "model_wbuf" "no,yes" (const (symbol_ref "arm_tune_wbuf")))
402
403 ; WRITE_CONFLICT implies that a read following an unrelated write is likely
404 ; to stall the processor. Used with model_wbuf above.
405 (define_attr "write_conflict" "no,yes"
406 (if_then_else (eq_attr "type"
407 "block,call,load1")
408 (const_string "yes")
409 (const_string "no")))
410
411 ; Classify the insns into those that take one cycle and those that take more
412 ; than one on the main cpu execution unit.
413 (define_attr "core_cycles" "single,multi"
414 (if_then_else (eq_attr "type"
415 "adc_imm, adc_reg, adcs_imm, adcs_reg, adr, alu_ext, alu_imm, alu_reg,\
416 alu_shift_imm, alu_shift_reg, alus_ext, alus_imm, alus_reg,\
417 alus_shift_imm, alus_shift_reg, bfm, csel, rev, logic_imm, logic_reg,\
418 logic_shift_imm, logic_shift_reg, logics_imm, logics_reg,\
419 logics_shift_imm, logics_shift_reg, extend, shift_imm, float, fcsel,\
420 wmmx_wor, wmmx_wxor, wmmx_wand, wmmx_wandn, wmmx_wmov, wmmx_tmcrr,\
421 wmmx_tmrrc, wmmx_wldr, wmmx_wstr, wmmx_tmcr, wmmx_tmrc, wmmx_wadd,\
422 wmmx_wsub, wmmx_wmul, wmmx_wmac, wmmx_wavg2, wmmx_tinsr, wmmx_textrm,\
423 wmmx_wshufh, wmmx_wcmpeq, wmmx_wcmpgt, wmmx_wmax, wmmx_wmin, wmmx_wpack,\
424 wmmx_wunpckih, wmmx_wunpckil, wmmx_wunpckeh, wmmx_wunpckel, wmmx_wror,\
425 wmmx_wsra, wmmx_wsrl, wmmx_wsll, wmmx_wmadd, wmmx_tmia, wmmx_tmiaph,\
426 wmmx_tmiaxy, wmmx_tbcst, wmmx_tmovmsk, wmmx_wacc, wmmx_waligni,\
427 wmmx_walignr, wmmx_tandc, wmmx_textrc, wmmx_torc, wmmx_torvsc, wmmx_wsad,\
428 wmmx_wabs, wmmx_wabsdiff, wmmx_waddsubhx, wmmx_wsubaddhx, wmmx_wavg4,\
429 wmmx_wmulw, wmmx_wqmulm, wmmx_wqmulwm, wmmx_waddbhus, wmmx_wqmiaxy,\
430 wmmx_wmiaxy, wmmx_wmiawxy, wmmx_wmerge")
431 (const_string "single")
432 (const_string "multi")))
433
434 ;; FAR_JUMP is "yes" if a BL instruction is used to generate a branch to a
435 ;; distant label. Only applicable to Thumb code.
436 (define_attr "far_jump" "yes,no" (const_string "no"))
437
438
439 ;; The number of machine instructions this pattern expands to.
440 ;; Used for Thumb-2 conditional execution.
441 (define_attr "ce_count" "" (const_int 1))
442
443 ;;---------------------------------------------------------------------------
444 ;; Unspecs
445
446 (include "unspecs.md")
447
448 ;;---------------------------------------------------------------------------
449 ;; Mode iterators
450
451 (include "iterators.md")
452
453 ;;---------------------------------------------------------------------------
454 ;; Predicates
455
456 (include "predicates.md")
457 (include "constraints.md")
458
459 ;;---------------------------------------------------------------------------
460 ;; Pipeline descriptions
461
462 (define_attr "tune_cortexr4" "yes,no"
463 (const (if_then_else
464 (eq_attr "tune" "cortexr4,cortexr4f,cortexr5")
465 (const_string "yes")
466 (const_string "no"))))
467
468 ;; True if the generic scheduling description should be used.
469
470 (define_attr "generic_sched" "yes,no"
471 (const (if_then_else
472 (ior (eq_attr "tune" "fa526,fa626,fa606te,fa626te,fmp626,fa726te,arm926ejs,arm1020e,arm1026ejs,arm1136js,arm1136jfs,cortexa5,cortexa7,cortexa8,cortexa9,cortexa12,cortexa15,cortexa53,cortexm4,marvell_pj4")
473 (eq_attr "tune_cortexr4" "yes"))
474 (const_string "no")
475 (const_string "yes"))))
476
477 (define_attr "generic_vfp" "yes,no"
478 (const (if_then_else
479 (and (eq_attr "fpu" "vfp")
480 (eq_attr "tune" "!arm1020e,arm1022e,cortexa5,cortexa7,cortexa8,cortexa9,cortexa12,cortexa53,cortexm4,marvell_pj4")
481 (eq_attr "tune_cortexr4" "no"))
482 (const_string "yes")
483 (const_string "no"))))
484
485 (include "marvell-f-iwmmxt.md")
486 (include "arm-generic.md")
487 (include "arm926ejs.md")
488 (include "arm1020e.md")
489 (include "arm1026ejs.md")
490 (include "arm1136jfs.md")
491 (include "fa526.md")
492 (include "fa606te.md")
493 (include "fa626te.md")
494 (include "fmp626.md")
495 (include "fa726te.md")
496 (include "cortex-a5.md")
497 (include "cortex-a7.md")
498 (include "cortex-a8.md")
499 (include "cortex-a9.md")
500 (include "cortex-a15.md")
501 (include "cortex-a53.md")
502 (include "cortex-r4.md")
503 (include "cortex-r4f.md")
504 (include "cortex-m4.md")
505 (include "cortex-m4-fpu.md")
506 (include "vfp11.md")
507 (include "marvell-pj4.md")
508
509 \f
510 ;;---------------------------------------------------------------------------
511 ;; Insn patterns
512 ;;
513 ;; Addition insns.
514
515 ;; Note: For DImode insns, there is normally no reason why operands should
516 ;; not be in the same register, what we don't want is for something being
517 ;; written to partially overlap something that is an input.
518
519 (define_expand "adddi3"
520 [(parallel
521 [(set (match_operand:DI 0 "s_register_operand" "")
522 (plus:DI (match_operand:DI 1 "s_register_operand" "")
523 (match_operand:DI 2 "arm_adddi_operand" "")))
524 (clobber (reg:CC CC_REGNUM))])]
525 "TARGET_EITHER"
526 "
527 if (TARGET_THUMB1)
528 {
529 if (!REG_P (operands[1]))
530 operands[1] = force_reg (DImode, operands[1]);
531 if (!REG_P (operands[2]))
532 operands[2] = force_reg (DImode, operands[2]);
533 }
534 "
535 )
536
537 (define_insn "*thumb1_adddi3"
538 [(set (match_operand:DI 0 "register_operand" "=l")
539 (plus:DI (match_operand:DI 1 "register_operand" "%0")
540 (match_operand:DI 2 "register_operand" "l")))
541 (clobber (reg:CC CC_REGNUM))
542 ]
543 "TARGET_THUMB1"
544 "add\\t%Q0, %Q0, %Q2\;adc\\t%R0, %R0, %R2"
545 [(set_attr "length" "4")
546 (set_attr "type" "multiple")]
547 )
548
549 (define_insn_and_split "*arm_adddi3"
550 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r,&r,&r,&r")
551 (plus:DI (match_operand:DI 1 "s_register_operand" "%0, 0, r, 0, r")
552 (match_operand:DI 2 "arm_adddi_operand" "r, 0, r, Dd, Dd")))
553 (clobber (reg:CC CC_REGNUM))]
554 "TARGET_32BIT && !TARGET_NEON"
555 "#"
556 "TARGET_32BIT && reload_completed
557 && ! (TARGET_NEON && IS_VFP_REGNUM (REGNO (operands[0])))"
558 [(parallel [(set (reg:CC_C CC_REGNUM)
559 (compare:CC_C (plus:SI (match_dup 1) (match_dup 2))
560 (match_dup 1)))
561 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
562 (set (match_dup 3) (plus:SI (plus:SI (match_dup 4) (match_dup 5))
563 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
564 "
565 {
566 operands[3] = gen_highpart (SImode, operands[0]);
567 operands[0] = gen_lowpart (SImode, operands[0]);
568 operands[4] = gen_highpart (SImode, operands[1]);
569 operands[1] = gen_lowpart (SImode, operands[1]);
570 operands[5] = gen_highpart_mode (SImode, DImode, operands[2]);
571 operands[2] = gen_lowpart (SImode, operands[2]);
572 }"
573 [(set_attr "conds" "clob")
574 (set_attr "length" "8")
575 (set_attr "type" "multiple")]
576 )
577
578 (define_insn_and_split "*adddi_sesidi_di"
579 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
580 (plus:DI (sign_extend:DI
581 (match_operand:SI 2 "s_register_operand" "r,r"))
582 (match_operand:DI 1 "s_register_operand" "0,r")))
583 (clobber (reg:CC CC_REGNUM))]
584 "TARGET_32BIT"
585 "#"
586 "TARGET_32BIT && reload_completed"
587 [(parallel [(set (reg:CC_C CC_REGNUM)
588 (compare:CC_C (plus:SI (match_dup 1) (match_dup 2))
589 (match_dup 1)))
590 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
591 (set (match_dup 3) (plus:SI (plus:SI (ashiftrt:SI (match_dup 2)
592 (const_int 31))
593 (match_dup 4))
594 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
595 "
596 {
597 operands[3] = gen_highpart (SImode, operands[0]);
598 operands[0] = gen_lowpart (SImode, operands[0]);
599 operands[4] = gen_highpart (SImode, operands[1]);
600 operands[1] = gen_lowpart (SImode, operands[1]);
601 operands[2] = gen_lowpart (SImode, operands[2]);
602 }"
603 [(set_attr "conds" "clob")
604 (set_attr "length" "8")
605 (set_attr "type" "multiple")]
606 )
607
608 (define_insn_and_split "*adddi_zesidi_di"
609 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
610 (plus:DI (zero_extend:DI
611 (match_operand:SI 2 "s_register_operand" "r,r"))
612 (match_operand:DI 1 "s_register_operand" "0,r")))
613 (clobber (reg:CC CC_REGNUM))]
614 "TARGET_32BIT"
615 "#"
616 "TARGET_32BIT && reload_completed"
617 [(parallel [(set (reg:CC_C CC_REGNUM)
618 (compare:CC_C (plus:SI (match_dup 1) (match_dup 2))
619 (match_dup 1)))
620 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
621 (set (match_dup 3) (plus:SI (plus:SI (match_dup 4) (const_int 0))
622 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
623 "
624 {
625 operands[3] = gen_highpart (SImode, operands[0]);
626 operands[0] = gen_lowpart (SImode, operands[0]);
627 operands[4] = gen_highpart (SImode, operands[1]);
628 operands[1] = gen_lowpart (SImode, operands[1]);
629 operands[2] = gen_lowpart (SImode, operands[2]);
630 }"
631 [(set_attr "conds" "clob")
632 (set_attr "length" "8")
633 (set_attr "type" "multiple")]
634 )
635
636 (define_expand "addsi3"
637 [(set (match_operand:SI 0 "s_register_operand" "")
638 (plus:SI (match_operand:SI 1 "s_register_operand" "")
639 (match_operand:SI 2 "reg_or_int_operand" "")))]
640 "TARGET_EITHER"
641 "
642 if (TARGET_32BIT && CONST_INT_P (operands[2]))
643 {
644 arm_split_constant (PLUS, SImode, NULL_RTX,
645 INTVAL (operands[2]), operands[0], operands[1],
646 optimize && can_create_pseudo_p ());
647 DONE;
648 }
649 "
650 )
651
652 ; If there is a scratch available, this will be faster than synthesizing the
653 ; addition.
654 (define_peephole2
655 [(match_scratch:SI 3 "r")
656 (set (match_operand:SI 0 "arm_general_register_operand" "")
657 (plus:SI (match_operand:SI 1 "arm_general_register_operand" "")
658 (match_operand:SI 2 "const_int_operand" "")))]
659 "TARGET_32BIT &&
660 !(const_ok_for_arm (INTVAL (operands[2]))
661 || const_ok_for_arm (-INTVAL (operands[2])))
662 && const_ok_for_arm (~INTVAL (operands[2]))"
663 [(set (match_dup 3) (match_dup 2))
664 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 3)))]
665 ""
666 )
667
668 ;; The r/r/k alternative is required when reloading the address
669 ;; (plus (reg rN) (reg sp)) into (reg rN). In this case reload will
670 ;; put the duplicated register first, and not try the commutative version.
671 (define_insn_and_split "*arm_addsi3"
672 [(set (match_operand:SI 0 "s_register_operand" "=rk,l,l ,l ,r ,k ,r,r ,k ,r ,k,k,r ,k ,r")
673 (plus:SI (match_operand:SI 1 "s_register_operand" "%0 ,l,0 ,l ,rk,k ,r,rk,k ,rk,k,r,rk,k ,rk")
674 (match_operand:SI 2 "reg_or_int_operand" "rk ,l,Py,Pd,rI,rI,k,Pj,Pj,L ,L,L,PJ,PJ,?n")))]
675 "TARGET_32BIT"
676 "@
677 add%?\\t%0, %0, %2
678 add%?\\t%0, %1, %2
679 add%?\\t%0, %1, %2
680 add%?\\t%0, %1, %2
681 add%?\\t%0, %1, %2
682 add%?\\t%0, %1, %2
683 add%?\\t%0, %2, %1
684 addw%?\\t%0, %1, %2
685 addw%?\\t%0, %1, %2
686 sub%?\\t%0, %1, #%n2
687 sub%?\\t%0, %1, #%n2
688 sub%?\\t%0, %1, #%n2
689 subw%?\\t%0, %1, #%n2
690 subw%?\\t%0, %1, #%n2
691 #"
692 "TARGET_32BIT
693 && CONST_INT_P (operands[2])
694 && !const_ok_for_op (INTVAL (operands[2]), PLUS)
695 && (reload_completed || !arm_eliminable_register (operands[1]))"
696 [(clobber (const_int 0))]
697 "
698 arm_split_constant (PLUS, SImode, curr_insn,
699 INTVAL (operands[2]), operands[0],
700 operands[1], 0);
701 DONE;
702 "
703 [(set_attr "length" "2,4,4,4,4,4,4,4,4,4,4,4,4,4,16")
704 (set_attr "predicable" "yes")
705 (set_attr "predicable_short_it" "yes,yes,yes,yes,no,no,no,no,no,no,no,no,no,no,no")
706 (set_attr "arch" "t2,t2,t2,t2,*,*,*,t2,t2,*,*,a,t2,t2,*")
707 (set (attr "type") (if_then_else (match_operand 2 "const_int_operand" "")
708 (const_string "alu_imm")
709 (const_string "alu_reg")))
710 ]
711 )
712
713 (define_insn_and_split "*thumb1_addsi3"
714 [(set (match_operand:SI 0 "register_operand" "=l,l,l,*rk,*hk,l,k,l,l,l")
715 (plus:SI (match_operand:SI 1 "register_operand" "%0,0,l,*0,*0,k,k,0,l,k")
716 (match_operand:SI 2 "nonmemory_operand" "I,J,lL,*hk,*rk,M,O,Pa,Pb,Pc")))]
717 "TARGET_THUMB1"
718 "*
719 static const char * const asms[] =
720 {
721 \"add\\t%0, %0, %2\",
722 \"sub\\t%0, %0, #%n2\",
723 \"add\\t%0, %1, %2\",
724 \"add\\t%0, %0, %2\",
725 \"add\\t%0, %0, %2\",
726 \"add\\t%0, %1, %2\",
727 \"add\\t%0, %1, %2\",
728 \"#\",
729 \"#\",
730 \"#\"
731 };
732 if ((which_alternative == 2 || which_alternative == 6)
733 && CONST_INT_P (operands[2])
734 && INTVAL (operands[2]) < 0)
735 return \"sub\\t%0, %1, #%n2\";
736 return asms[which_alternative];
737 "
738 "&& reload_completed && CONST_INT_P (operands[2])
739 && ((operands[1] != stack_pointer_rtx
740 && (INTVAL (operands[2]) > 255 || INTVAL (operands[2]) < -255))
741 || (operands[1] == stack_pointer_rtx
742 && INTVAL (operands[2]) > 1020))"
743 [(set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))
744 (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 3)))]
745 {
746 HOST_WIDE_INT offset = INTVAL (operands[2]);
747 if (operands[1] == stack_pointer_rtx)
748 offset -= 1020;
749 else
750 {
751 if (offset > 255)
752 offset = 255;
753 else if (offset < -255)
754 offset = -255;
755 }
756 operands[3] = GEN_INT (offset);
757 operands[2] = GEN_INT (INTVAL (operands[2]) - offset);
758 }
759 [(set_attr "length" "2,2,2,2,2,2,2,4,4,4")
760 (set_attr "type" "alus_imm,alus_imm,alus_reg,alus_reg,alus_reg,
761 alus_reg,alus_reg,multiple,multiple,multiple")]
762 )
763
764 ;; Reloading and elimination of the frame pointer can
765 ;; sometimes cause this optimization to be missed.
766 (define_peephole2
767 [(set (match_operand:SI 0 "arm_general_register_operand" "")
768 (match_operand:SI 1 "const_int_operand" ""))
769 (set (match_dup 0)
770 (plus:SI (match_dup 0) (reg:SI SP_REGNUM)))]
771 "TARGET_THUMB1
772 && (unsigned HOST_WIDE_INT) (INTVAL (operands[1])) < 1024
773 && (INTVAL (operands[1]) & 3) == 0"
774 [(set (match_dup 0) (plus:SI (reg:SI SP_REGNUM) (match_dup 1)))]
775 ""
776 )
777
778 (define_insn "addsi3_compare0"
779 [(set (reg:CC_NOOV CC_REGNUM)
780 (compare:CC_NOOV
781 (plus:SI (match_operand:SI 1 "s_register_operand" "r, r,r")
782 (match_operand:SI 2 "arm_add_operand" "I,L,r"))
783 (const_int 0)))
784 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
785 (plus:SI (match_dup 1) (match_dup 2)))]
786 "TARGET_ARM"
787 "@
788 add%.\\t%0, %1, %2
789 sub%.\\t%0, %1, #%n2
790 add%.\\t%0, %1, %2"
791 [(set_attr "conds" "set")
792 (set_attr "type" "alus_imm,alus_imm,alus_reg")]
793 )
794
795 (define_insn "*addsi3_compare0_scratch"
796 [(set (reg:CC_NOOV CC_REGNUM)
797 (compare:CC_NOOV
798 (plus:SI (match_operand:SI 0 "s_register_operand" "r, r, r")
799 (match_operand:SI 1 "arm_add_operand" "I,L, r"))
800 (const_int 0)))]
801 "TARGET_ARM"
802 "@
803 cmn%?\\t%0, %1
804 cmp%?\\t%0, #%n1
805 cmn%?\\t%0, %1"
806 [(set_attr "conds" "set")
807 (set_attr "predicable" "yes")
808 (set_attr "type" "alus_imm,alus_imm,alus_reg")]
809 )
810
811 (define_insn "*compare_negsi_si"
812 [(set (reg:CC_Z CC_REGNUM)
813 (compare:CC_Z
814 (neg:SI (match_operand:SI 0 "s_register_operand" "l,r"))
815 (match_operand:SI 1 "s_register_operand" "l,r")))]
816 "TARGET_32BIT"
817 "cmn%?\\t%1, %0"
818 [(set_attr "conds" "set")
819 (set_attr "predicable" "yes")
820 (set_attr "arch" "t2,*")
821 (set_attr "length" "2,4")
822 (set_attr "predicable_short_it" "yes,no")
823 (set_attr "type" "alus_reg")]
824 )
825
826 ;; This is the canonicalization of addsi3_compare0_for_combiner when the
827 ;; addend is a constant.
828 (define_insn "cmpsi2_addneg"
829 [(set (reg:CC CC_REGNUM)
830 (compare:CC
831 (match_operand:SI 1 "s_register_operand" "r,r")
832 (match_operand:SI 2 "arm_addimm_operand" "L,I")))
833 (set (match_operand:SI 0 "s_register_operand" "=r,r")
834 (plus:SI (match_dup 1)
835 (match_operand:SI 3 "arm_addimm_operand" "I,L")))]
836 "TARGET_32BIT && INTVAL (operands[2]) == -INTVAL (operands[3])"
837 "@
838 add%.\\t%0, %1, %3
839 sub%.\\t%0, %1, #%n3"
840 [(set_attr "conds" "set")
841 (set_attr "type" "alus_reg")]
842 )
843
844 ;; Convert the sequence
845 ;; sub rd, rn, #1
846 ;; cmn rd, #1 (equivalent to cmp rd, #-1)
847 ;; bne dest
848 ;; into
849 ;; subs rd, rn, #1
850 ;; bcs dest ((unsigned)rn >= 1)
851 ;; similarly for the beq variant using bcc.
852 ;; This is a common looping idiom (while (n--))
853 (define_peephole2
854 [(set (match_operand:SI 0 "arm_general_register_operand" "")
855 (plus:SI (match_operand:SI 1 "arm_general_register_operand" "")
856 (const_int -1)))
857 (set (match_operand 2 "cc_register" "")
858 (compare (match_dup 0) (const_int -1)))
859 (set (pc)
860 (if_then_else (match_operator 3 "equality_operator"
861 [(match_dup 2) (const_int 0)])
862 (match_operand 4 "" "")
863 (match_operand 5 "" "")))]
864 "TARGET_32BIT && peep2_reg_dead_p (3, operands[2])"
865 [(parallel[
866 (set (match_dup 2)
867 (compare:CC
868 (match_dup 1) (const_int 1)))
869 (set (match_dup 0) (plus:SI (match_dup 1) (const_int -1)))])
870 (set (pc)
871 (if_then_else (match_op_dup 3 [(match_dup 2) (const_int 0)])
872 (match_dup 4)
873 (match_dup 5)))]
874 "operands[2] = gen_rtx_REG (CCmode, CC_REGNUM);
875 operands[3] = gen_rtx_fmt_ee ((GET_CODE (operands[3]) == NE
876 ? GEU : LTU),
877 VOIDmode,
878 operands[2], const0_rtx);"
879 )
880
881 ;; The next four insns work because they compare the result with one of
882 ;; the operands, and we know that the use of the condition code is
883 ;; either GEU or LTU, so we can use the carry flag from the addition
884 ;; instead of doing the compare a second time.
885 (define_insn "*addsi3_compare_op1"
886 [(set (reg:CC_C CC_REGNUM)
887 (compare:CC_C
888 (plus:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
889 (match_operand:SI 2 "arm_add_operand" "I,L,r"))
890 (match_dup 1)))
891 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
892 (plus:SI (match_dup 1) (match_dup 2)))]
893 "TARGET_32BIT"
894 "@
895 add%.\\t%0, %1, %2
896 sub%.\\t%0, %1, #%n2
897 add%.\\t%0, %1, %2"
898 [(set_attr "conds" "set")
899 (set_attr "type" "alus_imm,alus_imm,alus_reg")]
900 )
901
902 (define_insn "*addsi3_compare_op2"
903 [(set (reg:CC_C CC_REGNUM)
904 (compare:CC_C
905 (plus:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
906 (match_operand:SI 2 "arm_add_operand" "I,L,r"))
907 (match_dup 2)))
908 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
909 (plus:SI (match_dup 1) (match_dup 2)))]
910 "TARGET_32BIT"
911 "@
912 add%.\\t%0, %1, %2
913 add%.\\t%0, %1, %2
914 sub%.\\t%0, %1, #%n2"
915 [(set_attr "conds" "set")
916 (set_attr "type" "alus_imm,alus_imm,alus_reg")]
917 )
918
919 (define_insn "*compare_addsi2_op0"
920 [(set (reg:CC_C CC_REGNUM)
921 (compare:CC_C
922 (plus:SI (match_operand:SI 0 "s_register_operand" "l,l,r,r,r")
923 (match_operand:SI 1 "arm_add_operand" "Pv,l,I,L,r"))
924 (match_dup 0)))]
925 "TARGET_32BIT"
926 "@
927 cmp%?\\t%0, #%n1
928 cmn%?\\t%0, %1
929 cmn%?\\t%0, %1
930 cmp%?\\t%0, #%n1
931 cmn%?\\t%0, %1"
932 [(set_attr "conds" "set")
933 (set_attr "predicable" "yes")
934 (set_attr "arch" "t2,t2,*,*,*")
935 (set_attr "predicable_short_it" "yes,yes,no,no,no")
936 (set_attr "length" "2,2,4,4,4")
937 (set_attr "type" "alus_imm,alus_reg,alus_imm,alus_imm,alus_reg")]
938 )
939
940 (define_insn "*compare_addsi2_op1"
941 [(set (reg:CC_C CC_REGNUM)
942 (compare:CC_C
943 (plus:SI (match_operand:SI 0 "s_register_operand" "l,l,r,r,r")
944 (match_operand:SI 1 "arm_add_operand" "Pv,l,I,L,r"))
945 (match_dup 1)))]
946 "TARGET_32BIT"
947 "@
948 cmp%?\\t%0, #%n1
949 cmn%?\\t%0, %1
950 cmn%?\\t%0, %1
951 cmp%?\\t%0, #%n1
952 cmn%?\\t%0, %1"
953 [(set_attr "conds" "set")
954 (set_attr "predicable" "yes")
955 (set_attr "arch" "t2,t2,*,*,*")
956 (set_attr "predicable_short_it" "yes,yes,no,no,no")
957 (set_attr "length" "2,2,4,4,4")
958 (set_attr "type" "alus_imm,alus_reg,alus_imm,alus_imm,alus_reg")]
959 )
960
961 (define_insn "*addsi3_carryin_<optab>"
962 [(set (match_operand:SI 0 "s_register_operand" "=l,r,r")
963 (plus:SI (plus:SI (match_operand:SI 1 "s_register_operand" "%l,r,r")
964 (match_operand:SI 2 "arm_not_operand" "0,rI,K"))
965 (LTUGEU:SI (reg:<cnb> CC_REGNUM) (const_int 0))))]
966 "TARGET_32BIT"
967 "@
968 adc%?\\t%0, %1, %2
969 adc%?\\t%0, %1, %2
970 sbc%?\\t%0, %1, #%B2"
971 [(set_attr "conds" "use")
972 (set_attr "predicable" "yes")
973 (set_attr "arch" "t2,*,*")
974 (set_attr "length" "4")
975 (set_attr "predicable_short_it" "yes,no,no")
976 (set_attr "type" "adc_reg,adc_reg,adc_imm")]
977 )
978
979 (define_insn "*addsi3_carryin_alt2_<optab>"
980 [(set (match_operand:SI 0 "s_register_operand" "=l,r,r")
981 (plus:SI (plus:SI (LTUGEU:SI (reg:<cnb> CC_REGNUM) (const_int 0))
982 (match_operand:SI 1 "s_register_operand" "%l,r,r"))
983 (match_operand:SI 2 "arm_rhs_operand" "l,rI,K")))]
984 "TARGET_32BIT"
985 "@
986 adc%?\\t%0, %1, %2
987 adc%?\\t%0, %1, %2
988 sbc%?\\t%0, %1, #%B2"
989 [(set_attr "conds" "use")
990 (set_attr "predicable" "yes")
991 (set_attr "arch" "t2,*,*")
992 (set_attr "length" "4")
993 (set_attr "predicable_short_it" "yes,no,no")
994 (set_attr "type" "adc_reg,adc_reg,adc_imm")]
995 )
996
997 (define_insn "*addsi3_carryin_shift_<optab>"
998 [(set (match_operand:SI 0 "s_register_operand" "=r")
999 (plus:SI (plus:SI
1000 (match_operator:SI 2 "shift_operator"
1001 [(match_operand:SI 3 "s_register_operand" "r")
1002 (match_operand:SI 4 "reg_or_int_operand" "rM")])
1003 (match_operand:SI 1 "s_register_operand" "r"))
1004 (LTUGEU:SI (reg:<cnb> CC_REGNUM) (const_int 0))))]
1005 "TARGET_32BIT"
1006 "adc%?\\t%0, %1, %3%S2"
1007 [(set_attr "conds" "use")
1008 (set_attr "predicable" "yes")
1009 (set_attr "predicable_short_it" "no")
1010 (set (attr "type") (if_then_else (match_operand 4 "const_int_operand" "")
1011 (const_string "alu_shift_imm")
1012 (const_string "alu_shift_reg")))]
1013 )
1014
1015 (define_insn "*addsi3_carryin_clobercc_<optab>"
1016 [(set (match_operand:SI 0 "s_register_operand" "=r")
1017 (plus:SI (plus:SI (match_operand:SI 1 "s_register_operand" "%r")
1018 (match_operand:SI 2 "arm_rhs_operand" "rI"))
1019 (LTUGEU:SI (reg:<cnb> CC_REGNUM) (const_int 0))))
1020 (clobber (reg:CC CC_REGNUM))]
1021 "TARGET_32BIT"
1022 "adc%.\\t%0, %1, %2"
1023 [(set_attr "conds" "set")
1024 (set_attr "type" "adcs_reg")]
1025 )
1026
1027 (define_insn "*subsi3_carryin"
1028 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
1029 (minus:SI (minus:SI (match_operand:SI 1 "reg_or_int_operand" "r,I")
1030 (match_operand:SI 2 "s_register_operand" "r,r"))
1031 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1032 "TARGET_32BIT"
1033 "@
1034 sbc%?\\t%0, %1, %2
1035 rsc%?\\t%0, %2, %1"
1036 [(set_attr "conds" "use")
1037 (set_attr "arch" "*,a")
1038 (set_attr "predicable" "yes")
1039 (set_attr "predicable_short_it" "no")
1040 (set_attr "type" "adc_reg,adc_imm")]
1041 )
1042
1043 (define_insn "*subsi3_carryin_const"
1044 [(set (match_operand:SI 0 "s_register_operand" "=r")
1045 (minus:SI (plus:SI (match_operand:SI 1 "reg_or_int_operand" "r")
1046 (match_operand:SI 2 "arm_not_operand" "K"))
1047 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1048 "TARGET_32BIT"
1049 "sbc\\t%0, %1, #%B2"
1050 [(set_attr "conds" "use")
1051 (set_attr "type" "adc_imm")]
1052 )
1053
1054 (define_insn "*subsi3_carryin_compare"
1055 [(set (reg:CC CC_REGNUM)
1056 (compare:CC (match_operand:SI 1 "s_register_operand" "r")
1057 (match_operand:SI 2 "s_register_operand" "r")))
1058 (set (match_operand:SI 0 "s_register_operand" "=r")
1059 (minus:SI (minus:SI (match_dup 1)
1060 (match_dup 2))
1061 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1062 "TARGET_32BIT"
1063 "sbcs\\t%0, %1, %2"
1064 [(set_attr "conds" "set")
1065 (set_attr "type" "adcs_reg")]
1066 )
1067
1068 (define_insn "*subsi3_carryin_compare_const"
1069 [(set (reg:CC CC_REGNUM)
1070 (compare:CC (match_operand:SI 1 "reg_or_int_operand" "r")
1071 (match_operand:SI 2 "arm_not_operand" "K")))
1072 (set (match_operand:SI 0 "s_register_operand" "=r")
1073 (minus:SI (plus:SI (match_dup 1)
1074 (match_dup 2))
1075 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1076 "TARGET_32BIT"
1077 "sbcs\\t%0, %1, #%B2"
1078 [(set_attr "conds" "set")
1079 (set_attr "type" "adcs_imm")]
1080 )
1081
1082 (define_insn "*subsi3_carryin_shift"
1083 [(set (match_operand:SI 0 "s_register_operand" "=r")
1084 (minus:SI (minus:SI
1085 (match_operand:SI 1 "s_register_operand" "r")
1086 (match_operator:SI 2 "shift_operator"
1087 [(match_operand:SI 3 "s_register_operand" "r")
1088 (match_operand:SI 4 "reg_or_int_operand" "rM")]))
1089 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1090 "TARGET_32BIT"
1091 "sbc%?\\t%0, %1, %3%S2"
1092 [(set_attr "conds" "use")
1093 (set_attr "predicable" "yes")
1094 (set (attr "type") (if_then_else (match_operand 4 "const_int_operand" "")
1095 (const_string "alu_shift_imm")
1096 (const_string "alu_shift_reg")))]
1097 )
1098
1099 (define_insn "*rsbsi3_carryin_shift"
1100 [(set (match_operand:SI 0 "s_register_operand" "=r")
1101 (minus:SI (minus:SI
1102 (match_operator:SI 2 "shift_operator"
1103 [(match_operand:SI 3 "s_register_operand" "r")
1104 (match_operand:SI 4 "reg_or_int_operand" "rM")])
1105 (match_operand:SI 1 "s_register_operand" "r"))
1106 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1107 "TARGET_ARM"
1108 "rsc%?\\t%0, %1, %3%S2"
1109 [(set_attr "conds" "use")
1110 (set_attr "predicable" "yes")
1111 (set (attr "type") (if_then_else (match_operand 4 "const_int_operand" "")
1112 (const_string "alu_shift_imm")
1113 (const_string "alu_shift_reg")))]
1114 )
1115
1116 ; transform ((x << y) - 1) to ~(~(x-1) << y) Where X is a constant.
1117 (define_split
1118 [(set (match_operand:SI 0 "s_register_operand" "")
1119 (plus:SI (ashift:SI (match_operand:SI 1 "const_int_operand" "")
1120 (match_operand:SI 2 "s_register_operand" ""))
1121 (const_int -1)))
1122 (clobber (match_operand:SI 3 "s_register_operand" ""))]
1123 "TARGET_32BIT"
1124 [(set (match_dup 3) (match_dup 1))
1125 (set (match_dup 0) (not:SI (ashift:SI (match_dup 3) (match_dup 2))))]
1126 "
1127 operands[1] = GEN_INT (~(INTVAL (operands[1]) - 1));
1128 ")
1129
1130 (define_expand "addsf3"
1131 [(set (match_operand:SF 0 "s_register_operand" "")
1132 (plus:SF (match_operand:SF 1 "s_register_operand" "")
1133 (match_operand:SF 2 "s_register_operand" "")))]
1134 "TARGET_32BIT && TARGET_HARD_FLOAT"
1135 "
1136 ")
1137
1138 (define_expand "adddf3"
1139 [(set (match_operand:DF 0 "s_register_operand" "")
1140 (plus:DF (match_operand:DF 1 "s_register_operand" "")
1141 (match_operand:DF 2 "s_register_operand" "")))]
1142 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
1143 "
1144 ")
1145
1146 (define_expand "subdi3"
1147 [(parallel
1148 [(set (match_operand:DI 0 "s_register_operand" "")
1149 (minus:DI (match_operand:DI 1 "s_register_operand" "")
1150 (match_operand:DI 2 "s_register_operand" "")))
1151 (clobber (reg:CC CC_REGNUM))])]
1152 "TARGET_EITHER"
1153 "
1154 if (TARGET_THUMB1)
1155 {
1156 if (!REG_P (operands[1]))
1157 operands[1] = force_reg (DImode, operands[1]);
1158 if (!REG_P (operands[2]))
1159 operands[2] = force_reg (DImode, operands[2]);
1160 }
1161 "
1162 )
1163
1164 (define_insn_and_split "*arm_subdi3"
1165 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r,&r")
1166 (minus:DI (match_operand:DI 1 "s_register_operand" "0,r,0")
1167 (match_operand:DI 2 "s_register_operand" "r,0,0")))
1168 (clobber (reg:CC CC_REGNUM))]
1169 "TARGET_32BIT && !TARGET_NEON"
1170 "#" ; "subs\\t%Q0, %Q1, %Q2\;sbc\\t%R0, %R1, %R2"
1171 "&& reload_completed"
1172 [(parallel [(set (reg:CC CC_REGNUM)
1173 (compare:CC (match_dup 1) (match_dup 2)))
1174 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
1175 (set (match_dup 3) (minus:SI (minus:SI (match_dup 4) (match_dup 5))
1176 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1177 {
1178 operands[3] = gen_highpart (SImode, operands[0]);
1179 operands[0] = gen_lowpart (SImode, operands[0]);
1180 operands[4] = gen_highpart (SImode, operands[1]);
1181 operands[1] = gen_lowpart (SImode, operands[1]);
1182 operands[5] = gen_highpart (SImode, operands[2]);
1183 operands[2] = gen_lowpart (SImode, operands[2]);
1184 }
1185 [(set_attr "conds" "clob")
1186 (set_attr "length" "8")
1187 (set_attr "type" "multiple")]
1188 )
1189
1190 (define_insn "*thumb_subdi3"
1191 [(set (match_operand:DI 0 "register_operand" "=l")
1192 (minus:DI (match_operand:DI 1 "register_operand" "0")
1193 (match_operand:DI 2 "register_operand" "l")))
1194 (clobber (reg:CC CC_REGNUM))]
1195 "TARGET_THUMB1"
1196 "sub\\t%Q0, %Q0, %Q2\;sbc\\t%R0, %R0, %R2"
1197 [(set_attr "length" "4")
1198 (set_attr "type" "multiple")]
1199 )
1200
1201 (define_insn_and_split "*subdi_di_zesidi"
1202 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1203 (minus:DI (match_operand:DI 1 "s_register_operand" "0,r")
1204 (zero_extend:DI
1205 (match_operand:SI 2 "s_register_operand" "r,r"))))
1206 (clobber (reg:CC CC_REGNUM))]
1207 "TARGET_32BIT"
1208 "#" ; "subs\\t%Q0, %Q1, %2\;sbc\\t%R0, %R1, #0"
1209 "&& reload_completed"
1210 [(parallel [(set (reg:CC CC_REGNUM)
1211 (compare:CC (match_dup 1) (match_dup 2)))
1212 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
1213 (set (match_dup 3) (minus:SI (plus:SI (match_dup 4) (match_dup 5))
1214 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1215 {
1216 operands[3] = gen_highpart (SImode, operands[0]);
1217 operands[0] = gen_lowpart (SImode, operands[0]);
1218 operands[4] = gen_highpart (SImode, operands[1]);
1219 operands[1] = gen_lowpart (SImode, operands[1]);
1220 operands[5] = GEN_INT (~0);
1221 }
1222 [(set_attr "conds" "clob")
1223 (set_attr "length" "8")
1224 (set_attr "type" "multiple")]
1225 )
1226
1227 (define_insn_and_split "*subdi_di_sesidi"
1228 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1229 (minus:DI (match_operand:DI 1 "s_register_operand" "0,r")
1230 (sign_extend:DI
1231 (match_operand:SI 2 "s_register_operand" "r,r"))))
1232 (clobber (reg:CC CC_REGNUM))]
1233 "TARGET_32BIT"
1234 "#" ; "subs\\t%Q0, %Q1, %2\;sbc\\t%R0, %R1, %2, asr #31"
1235 "&& reload_completed"
1236 [(parallel [(set (reg:CC CC_REGNUM)
1237 (compare:CC (match_dup 1) (match_dup 2)))
1238 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
1239 (set (match_dup 3) (minus:SI (minus:SI (match_dup 4)
1240 (ashiftrt:SI (match_dup 2)
1241 (const_int 31)))
1242 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1243 {
1244 operands[3] = gen_highpart (SImode, operands[0]);
1245 operands[0] = gen_lowpart (SImode, operands[0]);
1246 operands[4] = gen_highpart (SImode, operands[1]);
1247 operands[1] = gen_lowpart (SImode, operands[1]);
1248 }
1249 [(set_attr "conds" "clob")
1250 (set_attr "length" "8")
1251 (set_attr "type" "multiple")]
1252 )
1253
1254 (define_insn_and_split "*subdi_zesidi_di"
1255 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1256 (minus:DI (zero_extend:DI
1257 (match_operand:SI 2 "s_register_operand" "r,r"))
1258 (match_operand:DI 1 "s_register_operand" "0,r")))
1259 (clobber (reg:CC CC_REGNUM))]
1260 "TARGET_ARM"
1261 "#" ; "rsbs\\t%Q0, %Q1, %2\;rsc\\t%R0, %R1, #0"
1262 ; is equivalent to:
1263 ; "subs\\t%Q0, %2, %Q1\;rsc\\t%R0, %R1, #0"
1264 "&& reload_completed"
1265 [(parallel [(set (reg:CC CC_REGNUM)
1266 (compare:CC (match_dup 2) (match_dup 1)))
1267 (set (match_dup 0) (minus:SI (match_dup 2) (match_dup 1)))])
1268 (set (match_dup 3) (minus:SI (minus:SI (const_int 0) (match_dup 4))
1269 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1270 {
1271 operands[3] = gen_highpart (SImode, operands[0]);
1272 operands[0] = gen_lowpart (SImode, operands[0]);
1273 operands[4] = gen_highpart (SImode, operands[1]);
1274 operands[1] = gen_lowpart (SImode, operands[1]);
1275 }
1276 [(set_attr "conds" "clob")
1277 (set_attr "length" "8")
1278 (set_attr "type" "multiple")]
1279 )
1280
1281 (define_insn_and_split "*subdi_sesidi_di"
1282 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1283 (minus:DI (sign_extend:DI
1284 (match_operand:SI 2 "s_register_operand" "r,r"))
1285 (match_operand:DI 1 "s_register_operand" "0,r")))
1286 (clobber (reg:CC CC_REGNUM))]
1287 "TARGET_ARM"
1288 "#" ; "rsbs\\t%Q0, %Q1, %2\;rsc\\t%R0, %R1, %2, asr #31"
1289 ; is equivalent to:
1290 ; "subs\\t%Q0, %2, %Q1\;rsc\\t%R0, %R1, %2, asr #31"
1291 "&& reload_completed"
1292 [(parallel [(set (reg:CC CC_REGNUM)
1293 (compare:CC (match_dup 2) (match_dup 1)))
1294 (set (match_dup 0) (minus:SI (match_dup 2) (match_dup 1)))])
1295 (set (match_dup 3) (minus:SI (minus:SI
1296 (ashiftrt:SI (match_dup 2)
1297 (const_int 31))
1298 (match_dup 4))
1299 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1300 {
1301 operands[3] = gen_highpart (SImode, operands[0]);
1302 operands[0] = gen_lowpart (SImode, operands[0]);
1303 operands[4] = gen_highpart (SImode, operands[1]);
1304 operands[1] = gen_lowpart (SImode, operands[1]);
1305 }
1306 [(set_attr "conds" "clob")
1307 (set_attr "length" "8")
1308 (set_attr "type" "multiple")]
1309 )
1310
1311 (define_insn_and_split "*subdi_zesidi_zesidi"
1312 [(set (match_operand:DI 0 "s_register_operand" "=r")
1313 (minus:DI (zero_extend:DI
1314 (match_operand:SI 1 "s_register_operand" "r"))
1315 (zero_extend:DI
1316 (match_operand:SI 2 "s_register_operand" "r"))))
1317 (clobber (reg:CC CC_REGNUM))]
1318 "TARGET_32BIT"
1319 "#" ; "subs\\t%Q0, %1, %2\;sbc\\t%R0, %1, %1"
1320 "&& reload_completed"
1321 [(parallel [(set (reg:CC CC_REGNUM)
1322 (compare:CC (match_dup 1) (match_dup 2)))
1323 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
1324 (set (match_dup 3) (minus:SI (minus:SI (match_dup 1) (match_dup 1))
1325 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1326 {
1327 operands[3] = gen_highpart (SImode, operands[0]);
1328 operands[0] = gen_lowpart (SImode, operands[0]);
1329 }
1330 [(set_attr "conds" "clob")
1331 (set_attr "length" "8")
1332 (set_attr "type" "multiple")]
1333 )
1334
1335 (define_expand "subsi3"
1336 [(set (match_operand:SI 0 "s_register_operand" "")
1337 (minus:SI (match_operand:SI 1 "reg_or_int_operand" "")
1338 (match_operand:SI 2 "s_register_operand" "")))]
1339 "TARGET_EITHER"
1340 "
1341 if (CONST_INT_P (operands[1]))
1342 {
1343 if (TARGET_32BIT)
1344 {
1345 arm_split_constant (MINUS, SImode, NULL_RTX,
1346 INTVAL (operands[1]), operands[0],
1347 operands[2], optimize && can_create_pseudo_p ());
1348 DONE;
1349 }
1350 else /* TARGET_THUMB1 */
1351 operands[1] = force_reg (SImode, operands[1]);
1352 }
1353 "
1354 )
1355
1356 (define_insn "thumb1_subsi3_insn"
1357 [(set (match_operand:SI 0 "register_operand" "=l")
1358 (minus:SI (match_operand:SI 1 "register_operand" "l")
1359 (match_operand:SI 2 "reg_or_int_operand" "lPd")))]
1360 "TARGET_THUMB1"
1361 "sub\\t%0, %1, %2"
1362 [(set_attr "length" "2")
1363 (set_attr "conds" "set")
1364 (set_attr "type" "alus_reg")]
1365 )
1366
1367 ; ??? Check Thumb-2 split length
1368 (define_insn_and_split "*arm_subsi3_insn"
1369 [(set (match_operand:SI 0 "s_register_operand" "=l,l ,l ,l ,r ,r,r,rk,r")
1370 (minus:SI (match_operand:SI 1 "reg_or_int_operand" "l ,0 ,l ,Pz,rI,r,r,k ,?n")
1371 (match_operand:SI 2 "reg_or_int_operand" "l ,Py,Pd,l ,r ,I,r,r ,r")))]
1372 "TARGET_32BIT"
1373 "@
1374 sub%?\\t%0, %1, %2
1375 sub%?\\t%0, %2
1376 sub%?\\t%0, %1, %2
1377 rsb%?\\t%0, %2, %1
1378 rsb%?\\t%0, %2, %1
1379 sub%?\\t%0, %1, %2
1380 sub%?\\t%0, %1, %2
1381 sub%?\\t%0, %1, %2
1382 #"
1383 "&& (CONST_INT_P (operands[1])
1384 && !const_ok_for_arm (INTVAL (operands[1])))"
1385 [(clobber (const_int 0))]
1386 "
1387 arm_split_constant (MINUS, SImode, curr_insn,
1388 INTVAL (operands[1]), operands[0], operands[2], 0);
1389 DONE;
1390 "
1391 [(set_attr "length" "4,4,4,4,4,4,4,4,16")
1392 (set_attr "arch" "t2,t2,t2,t2,*,*,*,*,*")
1393 (set_attr "predicable" "yes")
1394 (set_attr "predicable_short_it" "yes,yes,yes,yes,no,no,no,no,no")
1395 (set_attr "type" "alu_reg,alu_reg,alu_reg,alu_reg,alu_imm,alu_imm,alu_reg,alu_reg,multiple")]
1396 )
1397
1398 (define_peephole2
1399 [(match_scratch:SI 3 "r")
1400 (set (match_operand:SI 0 "arm_general_register_operand" "")
1401 (minus:SI (match_operand:SI 1 "const_int_operand" "")
1402 (match_operand:SI 2 "arm_general_register_operand" "")))]
1403 "TARGET_32BIT
1404 && !const_ok_for_arm (INTVAL (operands[1]))
1405 && const_ok_for_arm (~INTVAL (operands[1]))"
1406 [(set (match_dup 3) (match_dup 1))
1407 (set (match_dup 0) (minus:SI (match_dup 3) (match_dup 2)))]
1408 ""
1409 )
1410
1411 (define_insn "*subsi3_compare0"
1412 [(set (reg:CC_NOOV CC_REGNUM)
1413 (compare:CC_NOOV
1414 (minus:SI (match_operand:SI 1 "arm_rhs_operand" "r,r,I")
1415 (match_operand:SI 2 "arm_rhs_operand" "I,r,r"))
1416 (const_int 0)))
1417 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
1418 (minus:SI (match_dup 1) (match_dup 2)))]
1419 "TARGET_32BIT"
1420 "@
1421 sub%.\\t%0, %1, %2
1422 sub%.\\t%0, %1, %2
1423 rsb%.\\t%0, %2, %1"
1424 [(set_attr "conds" "set")
1425 (set_attr "type" "alus_imm,alus_reg,alus_reg")]
1426 )
1427
1428 (define_insn "subsi3_compare"
1429 [(set (reg:CC CC_REGNUM)
1430 (compare:CC (match_operand:SI 1 "arm_rhs_operand" "r,r,I")
1431 (match_operand:SI 2 "arm_rhs_operand" "I,r,r")))
1432 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
1433 (minus:SI (match_dup 1) (match_dup 2)))]
1434 "TARGET_32BIT"
1435 "@
1436 sub%.\\t%0, %1, %2
1437 sub%.\\t%0, %1, %2
1438 rsb%.\\t%0, %2, %1"
1439 [(set_attr "conds" "set")
1440 (set_attr "type" "alus_imm,alus_reg,alus_reg")]
1441 )
1442
1443 (define_expand "subsf3"
1444 [(set (match_operand:SF 0 "s_register_operand" "")
1445 (minus:SF (match_operand:SF 1 "s_register_operand" "")
1446 (match_operand:SF 2 "s_register_operand" "")))]
1447 "TARGET_32BIT && TARGET_HARD_FLOAT"
1448 "
1449 ")
1450
1451 (define_expand "subdf3"
1452 [(set (match_operand:DF 0 "s_register_operand" "")
1453 (minus:DF (match_operand:DF 1 "s_register_operand" "")
1454 (match_operand:DF 2 "s_register_operand" "")))]
1455 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
1456 "
1457 ")
1458
1459 \f
1460 ;; Multiplication insns
1461
1462 (define_expand "mulhi3"
1463 [(set (match_operand:HI 0 "s_register_operand" "")
1464 (mult:HI (match_operand:HI 1 "s_register_operand" "")
1465 (match_operand:HI 2 "s_register_operand" "")))]
1466 "TARGET_DSP_MULTIPLY"
1467 "
1468 {
1469 rtx result = gen_reg_rtx (SImode);
1470 emit_insn (gen_mulhisi3 (result, operands[1], operands[2]));
1471 emit_move_insn (operands[0], gen_lowpart (HImode, result));
1472 DONE;
1473 }"
1474 )
1475
1476 (define_expand "mulsi3"
1477 [(set (match_operand:SI 0 "s_register_operand" "")
1478 (mult:SI (match_operand:SI 2 "s_register_operand" "")
1479 (match_operand:SI 1 "s_register_operand" "")))]
1480 "TARGET_EITHER"
1481 ""
1482 )
1483
1484 ;; Use `&' and then `0' to prevent the operands 0 and 1 being the same
1485 (define_insn "*arm_mulsi3"
1486 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r")
1487 (mult:SI (match_operand:SI 2 "s_register_operand" "r,r")
1488 (match_operand:SI 1 "s_register_operand" "%0,r")))]
1489 "TARGET_32BIT && !arm_arch6"
1490 "mul%?\\t%0, %2, %1"
1491 [(set_attr "type" "mul")
1492 (set_attr "predicable" "yes")]
1493 )
1494
1495 (define_insn "*arm_mulsi3_v6"
1496 [(set (match_operand:SI 0 "s_register_operand" "=l,l,r")
1497 (mult:SI (match_operand:SI 1 "s_register_operand" "0,l,r")
1498 (match_operand:SI 2 "s_register_operand" "l,0,r")))]
1499 "TARGET_32BIT && arm_arch6"
1500 "mul%?\\t%0, %1, %2"
1501 [(set_attr "type" "mul")
1502 (set_attr "predicable" "yes")
1503 (set_attr "arch" "t2,t2,*")
1504 (set_attr "length" "4")
1505 (set_attr "predicable_short_it" "yes,yes,no")]
1506 )
1507
1508 ; Unfortunately with the Thumb the '&'/'0' trick can fails when operands
1509 ; 1 and 2; are the same, because reload will make operand 0 match
1510 ; operand 1 without realizing that this conflicts with operand 2. We fix
1511 ; this by adding another alternative to match this case, and then `reload'
1512 ; it ourselves. This alternative must come first.
1513 (define_insn "*thumb_mulsi3"
1514 [(set (match_operand:SI 0 "register_operand" "=&l,&l,&l")
1515 (mult:SI (match_operand:SI 1 "register_operand" "%l,*h,0")
1516 (match_operand:SI 2 "register_operand" "l,l,l")))]
1517 "TARGET_THUMB1 && !arm_arch6"
1518 "*
1519 if (which_alternative < 2)
1520 return \"mov\\t%0, %1\;mul\\t%0, %2\";
1521 else
1522 return \"mul\\t%0, %2\";
1523 "
1524 [(set_attr "length" "4,4,2")
1525 (set_attr "type" "muls")]
1526 )
1527
1528 (define_insn "*thumb_mulsi3_v6"
1529 [(set (match_operand:SI 0 "register_operand" "=l,l,l")
1530 (mult:SI (match_operand:SI 1 "register_operand" "0,l,0")
1531 (match_operand:SI 2 "register_operand" "l,0,0")))]
1532 "TARGET_THUMB1 && arm_arch6"
1533 "@
1534 mul\\t%0, %2
1535 mul\\t%0, %1
1536 mul\\t%0, %1"
1537 [(set_attr "length" "2")
1538 (set_attr "type" "muls")]
1539 )
1540
1541 (define_insn "*mulsi3_compare0"
1542 [(set (reg:CC_NOOV CC_REGNUM)
1543 (compare:CC_NOOV (mult:SI
1544 (match_operand:SI 2 "s_register_operand" "r,r")
1545 (match_operand:SI 1 "s_register_operand" "%0,r"))
1546 (const_int 0)))
1547 (set (match_operand:SI 0 "s_register_operand" "=&r,&r")
1548 (mult:SI (match_dup 2) (match_dup 1)))]
1549 "TARGET_ARM && !arm_arch6"
1550 "mul%.\\t%0, %2, %1"
1551 [(set_attr "conds" "set")
1552 (set_attr "type" "muls")]
1553 )
1554
1555 (define_insn "*mulsi3_compare0_v6"
1556 [(set (reg:CC_NOOV CC_REGNUM)
1557 (compare:CC_NOOV (mult:SI
1558 (match_operand:SI 2 "s_register_operand" "r")
1559 (match_operand:SI 1 "s_register_operand" "r"))
1560 (const_int 0)))
1561 (set (match_operand:SI 0 "s_register_operand" "=r")
1562 (mult:SI (match_dup 2) (match_dup 1)))]
1563 "TARGET_ARM && arm_arch6 && optimize_size"
1564 "mul%.\\t%0, %2, %1"
1565 [(set_attr "conds" "set")
1566 (set_attr "type" "muls")]
1567 )
1568
1569 (define_insn "*mulsi_compare0_scratch"
1570 [(set (reg:CC_NOOV CC_REGNUM)
1571 (compare:CC_NOOV (mult:SI
1572 (match_operand:SI 2 "s_register_operand" "r,r")
1573 (match_operand:SI 1 "s_register_operand" "%0,r"))
1574 (const_int 0)))
1575 (clobber (match_scratch:SI 0 "=&r,&r"))]
1576 "TARGET_ARM && !arm_arch6"
1577 "mul%.\\t%0, %2, %1"
1578 [(set_attr "conds" "set")
1579 (set_attr "type" "muls")]
1580 )
1581
1582 (define_insn "*mulsi_compare0_scratch_v6"
1583 [(set (reg:CC_NOOV CC_REGNUM)
1584 (compare:CC_NOOV (mult:SI
1585 (match_operand:SI 2 "s_register_operand" "r")
1586 (match_operand:SI 1 "s_register_operand" "r"))
1587 (const_int 0)))
1588 (clobber (match_scratch:SI 0 "=r"))]
1589 "TARGET_ARM && arm_arch6 && optimize_size"
1590 "mul%.\\t%0, %2, %1"
1591 [(set_attr "conds" "set")
1592 (set_attr "type" "muls")]
1593 )
1594
1595 ;; Unnamed templates to match MLA instruction.
1596
1597 (define_insn "*mulsi3addsi"
1598 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r,&r")
1599 (plus:SI
1600 (mult:SI (match_operand:SI 2 "s_register_operand" "r,r,r,r")
1601 (match_operand:SI 1 "s_register_operand" "%0,r,0,r"))
1602 (match_operand:SI 3 "s_register_operand" "r,r,0,0")))]
1603 "TARGET_32BIT && !arm_arch6"
1604 "mla%?\\t%0, %2, %1, %3"
1605 [(set_attr "type" "mla")
1606 (set_attr "predicable" "yes")]
1607 )
1608
1609 (define_insn "*mulsi3addsi_v6"
1610 [(set (match_operand:SI 0 "s_register_operand" "=r")
1611 (plus:SI
1612 (mult:SI (match_operand:SI 2 "s_register_operand" "r")
1613 (match_operand:SI 1 "s_register_operand" "r"))
1614 (match_operand:SI 3 "s_register_operand" "r")))]
1615 "TARGET_32BIT && arm_arch6"
1616 "mla%?\\t%0, %2, %1, %3"
1617 [(set_attr "type" "mla")
1618 (set_attr "predicable" "yes")
1619 (set_attr "predicable_short_it" "no")]
1620 )
1621
1622 (define_insn "*mulsi3addsi_compare0"
1623 [(set (reg:CC_NOOV CC_REGNUM)
1624 (compare:CC_NOOV
1625 (plus:SI (mult:SI
1626 (match_operand:SI 2 "s_register_operand" "r,r,r,r")
1627 (match_operand:SI 1 "s_register_operand" "%0,r,0,r"))
1628 (match_operand:SI 3 "s_register_operand" "r,r,0,0"))
1629 (const_int 0)))
1630 (set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r,&r")
1631 (plus:SI (mult:SI (match_dup 2) (match_dup 1))
1632 (match_dup 3)))]
1633 "TARGET_ARM && arm_arch6"
1634 "mla%.\\t%0, %2, %1, %3"
1635 [(set_attr "conds" "set")
1636 (set_attr "type" "mlas")]
1637 )
1638
1639 (define_insn "*mulsi3addsi_compare0_v6"
1640 [(set (reg:CC_NOOV CC_REGNUM)
1641 (compare:CC_NOOV
1642 (plus:SI (mult:SI
1643 (match_operand:SI 2 "s_register_operand" "r")
1644 (match_operand:SI 1 "s_register_operand" "r"))
1645 (match_operand:SI 3 "s_register_operand" "r"))
1646 (const_int 0)))
1647 (set (match_operand:SI 0 "s_register_operand" "=r")
1648 (plus:SI (mult:SI (match_dup 2) (match_dup 1))
1649 (match_dup 3)))]
1650 "TARGET_ARM && arm_arch6 && optimize_size"
1651 "mla%.\\t%0, %2, %1, %3"
1652 [(set_attr "conds" "set")
1653 (set_attr "type" "mlas")]
1654 )
1655
1656 (define_insn "*mulsi3addsi_compare0_scratch"
1657 [(set (reg:CC_NOOV CC_REGNUM)
1658 (compare:CC_NOOV
1659 (plus:SI (mult:SI
1660 (match_operand:SI 2 "s_register_operand" "r,r,r,r")
1661 (match_operand:SI 1 "s_register_operand" "%0,r,0,r"))
1662 (match_operand:SI 3 "s_register_operand" "?r,r,0,0"))
1663 (const_int 0)))
1664 (clobber (match_scratch:SI 0 "=&r,&r,&r,&r"))]
1665 "TARGET_ARM && !arm_arch6"
1666 "mla%.\\t%0, %2, %1, %3"
1667 [(set_attr "conds" "set")
1668 (set_attr "type" "mlas")]
1669 )
1670
1671 (define_insn "*mulsi3addsi_compare0_scratch_v6"
1672 [(set (reg:CC_NOOV CC_REGNUM)
1673 (compare:CC_NOOV
1674 (plus:SI (mult:SI
1675 (match_operand:SI 2 "s_register_operand" "r")
1676 (match_operand:SI 1 "s_register_operand" "r"))
1677 (match_operand:SI 3 "s_register_operand" "r"))
1678 (const_int 0)))
1679 (clobber (match_scratch:SI 0 "=r"))]
1680 "TARGET_ARM && arm_arch6 && optimize_size"
1681 "mla%.\\t%0, %2, %1, %3"
1682 [(set_attr "conds" "set")
1683 (set_attr "type" "mlas")]
1684 )
1685
1686 (define_insn "*mulsi3subsi"
1687 [(set (match_operand:SI 0 "s_register_operand" "=r")
1688 (minus:SI
1689 (match_operand:SI 3 "s_register_operand" "r")
1690 (mult:SI (match_operand:SI 2 "s_register_operand" "r")
1691 (match_operand:SI 1 "s_register_operand" "r"))))]
1692 "TARGET_32BIT && arm_arch_thumb2"
1693 "mls%?\\t%0, %2, %1, %3"
1694 [(set_attr "type" "mla")
1695 (set_attr "predicable" "yes")
1696 (set_attr "predicable_short_it" "no")]
1697 )
1698
1699 (define_expand "maddsidi4"
1700 [(set (match_operand:DI 0 "s_register_operand" "")
1701 (plus:DI
1702 (mult:DI
1703 (sign_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1704 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "")))
1705 (match_operand:DI 3 "s_register_operand" "")))]
1706 "TARGET_32BIT && arm_arch3m"
1707 "")
1708
1709 (define_insn "*mulsidi3adddi"
1710 [(set (match_operand:DI 0 "s_register_operand" "=&r")
1711 (plus:DI
1712 (mult:DI
1713 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "%r"))
1714 (sign_extend:DI (match_operand:SI 3 "s_register_operand" "r")))
1715 (match_operand:DI 1 "s_register_operand" "0")))]
1716 "TARGET_32BIT && arm_arch3m && !arm_arch6"
1717 "smlal%?\\t%Q0, %R0, %3, %2"
1718 [(set_attr "type" "smlal")
1719 (set_attr "predicable" "yes")]
1720 )
1721
1722 (define_insn "*mulsidi3adddi_v6"
1723 [(set (match_operand:DI 0 "s_register_operand" "=r")
1724 (plus:DI
1725 (mult:DI
1726 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r"))
1727 (sign_extend:DI (match_operand:SI 3 "s_register_operand" "r")))
1728 (match_operand:DI 1 "s_register_operand" "0")))]
1729 "TARGET_32BIT && arm_arch6"
1730 "smlal%?\\t%Q0, %R0, %3, %2"
1731 [(set_attr "type" "smlal")
1732 (set_attr "predicable" "yes")
1733 (set_attr "predicable_short_it" "no")]
1734 )
1735
1736 ;; 32x32->64 widening multiply.
1737 ;; As with mulsi3, the only difference between the v3-5 and v6+
1738 ;; versions of these patterns is the requirement that the output not
1739 ;; overlap the inputs, but that still means we have to have a named
1740 ;; expander and two different starred insns.
1741
1742 (define_expand "mulsidi3"
1743 [(set (match_operand:DI 0 "s_register_operand" "")
1744 (mult:DI
1745 (sign_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1746 (sign_extend:DI (match_operand:SI 2 "s_register_operand" ""))))]
1747 "TARGET_32BIT && arm_arch3m"
1748 ""
1749 )
1750
1751 (define_insn "*mulsidi3_nov6"
1752 [(set (match_operand:DI 0 "s_register_operand" "=&r")
1753 (mult:DI
1754 (sign_extend:DI (match_operand:SI 1 "s_register_operand" "%r"))
1755 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))]
1756 "TARGET_32BIT && arm_arch3m && !arm_arch6"
1757 "smull%?\\t%Q0, %R0, %1, %2"
1758 [(set_attr "type" "smull")
1759 (set_attr "predicable" "yes")]
1760 )
1761
1762 (define_insn "*mulsidi3_v6"
1763 [(set (match_operand:DI 0 "s_register_operand" "=r")
1764 (mult:DI
1765 (sign_extend:DI (match_operand:SI 1 "s_register_operand" "r"))
1766 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))]
1767 "TARGET_32BIT && arm_arch6"
1768 "smull%?\\t%Q0, %R0, %1, %2"
1769 [(set_attr "type" "smull")
1770 (set_attr "predicable" "yes")
1771 (set_attr "predicable_short_it" "no")]
1772 )
1773
1774 (define_expand "umulsidi3"
1775 [(set (match_operand:DI 0 "s_register_operand" "")
1776 (mult:DI
1777 (zero_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1778 (zero_extend:DI (match_operand:SI 2 "s_register_operand" ""))))]
1779 "TARGET_32BIT && arm_arch3m"
1780 ""
1781 )
1782
1783 (define_insn "*umulsidi3_nov6"
1784 [(set (match_operand:DI 0 "s_register_operand" "=&r")
1785 (mult:DI
1786 (zero_extend:DI (match_operand:SI 1 "s_register_operand" "%r"))
1787 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))]
1788 "TARGET_32BIT && arm_arch3m && !arm_arch6"
1789 "umull%?\\t%Q0, %R0, %1, %2"
1790 [(set_attr "type" "umull")
1791 (set_attr "predicable" "yes")]
1792 )
1793
1794 (define_insn "*umulsidi3_v6"
1795 [(set (match_operand:DI 0 "s_register_operand" "=r")
1796 (mult:DI
1797 (zero_extend:DI (match_operand:SI 1 "s_register_operand" "r"))
1798 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))]
1799 "TARGET_32BIT && arm_arch6"
1800 "umull%?\\t%Q0, %R0, %1, %2"
1801 [(set_attr "type" "umull")
1802 (set_attr "predicable" "yes")
1803 (set_attr "predicable_short_it" "no")]
1804 )
1805
1806 (define_expand "umaddsidi4"
1807 [(set (match_operand:DI 0 "s_register_operand" "")
1808 (plus:DI
1809 (mult:DI
1810 (zero_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1811 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "")))
1812 (match_operand:DI 3 "s_register_operand" "")))]
1813 "TARGET_32BIT && arm_arch3m"
1814 "")
1815
1816 (define_insn "*umulsidi3adddi"
1817 [(set (match_operand:DI 0 "s_register_operand" "=&r")
1818 (plus:DI
1819 (mult:DI
1820 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "%r"))
1821 (zero_extend:DI (match_operand:SI 3 "s_register_operand" "r")))
1822 (match_operand:DI 1 "s_register_operand" "0")))]
1823 "TARGET_32BIT && arm_arch3m && !arm_arch6"
1824 "umlal%?\\t%Q0, %R0, %3, %2"
1825 [(set_attr "type" "umlal")
1826 (set_attr "predicable" "yes")]
1827 )
1828
1829 (define_insn "*umulsidi3adddi_v6"
1830 [(set (match_operand:DI 0 "s_register_operand" "=r")
1831 (plus:DI
1832 (mult:DI
1833 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r"))
1834 (zero_extend:DI (match_operand:SI 3 "s_register_operand" "r")))
1835 (match_operand:DI 1 "s_register_operand" "0")))]
1836 "TARGET_32BIT && arm_arch6"
1837 "umlal%?\\t%Q0, %R0, %3, %2"
1838 [(set_attr "type" "umlal")
1839 (set_attr "predicable" "yes")
1840 (set_attr "predicable_short_it" "no")]
1841 )
1842
1843 (define_expand "smulsi3_highpart"
1844 [(parallel
1845 [(set (match_operand:SI 0 "s_register_operand" "")
1846 (truncate:SI
1847 (lshiftrt:DI
1848 (mult:DI
1849 (sign_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1850 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "")))
1851 (const_int 32))))
1852 (clobber (match_scratch:SI 3 ""))])]
1853 "TARGET_32BIT && arm_arch3m"
1854 ""
1855 )
1856
1857 (define_insn "*smulsi3_highpart_nov6"
1858 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r")
1859 (truncate:SI
1860 (lshiftrt:DI
1861 (mult:DI
1862 (sign_extend:DI (match_operand:SI 1 "s_register_operand" "%0,r"))
1863 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r,r")))
1864 (const_int 32))))
1865 (clobber (match_scratch:SI 3 "=&r,&r"))]
1866 "TARGET_32BIT && arm_arch3m && !arm_arch6"
1867 "smull%?\\t%3, %0, %2, %1"
1868 [(set_attr "type" "smull")
1869 (set_attr "predicable" "yes")]
1870 )
1871
1872 (define_insn "*smulsi3_highpart_v6"
1873 [(set (match_operand:SI 0 "s_register_operand" "=r")
1874 (truncate:SI
1875 (lshiftrt:DI
1876 (mult:DI
1877 (sign_extend:DI (match_operand:SI 1 "s_register_operand" "r"))
1878 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r")))
1879 (const_int 32))))
1880 (clobber (match_scratch:SI 3 "=r"))]
1881 "TARGET_32BIT && arm_arch6"
1882 "smull%?\\t%3, %0, %2, %1"
1883 [(set_attr "type" "smull")
1884 (set_attr "predicable" "yes")
1885 (set_attr "predicable_short_it" "no")]
1886 )
1887
1888 (define_expand "umulsi3_highpart"
1889 [(parallel
1890 [(set (match_operand:SI 0 "s_register_operand" "")
1891 (truncate:SI
1892 (lshiftrt:DI
1893 (mult:DI
1894 (zero_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1895 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "")))
1896 (const_int 32))))
1897 (clobber (match_scratch:SI 3 ""))])]
1898 "TARGET_32BIT && arm_arch3m"
1899 ""
1900 )
1901
1902 (define_insn "*umulsi3_highpart_nov6"
1903 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r")
1904 (truncate:SI
1905 (lshiftrt:DI
1906 (mult:DI
1907 (zero_extend:DI (match_operand:SI 1 "s_register_operand" "%0,r"))
1908 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r,r")))
1909 (const_int 32))))
1910 (clobber (match_scratch:SI 3 "=&r,&r"))]
1911 "TARGET_32BIT && arm_arch3m && !arm_arch6"
1912 "umull%?\\t%3, %0, %2, %1"
1913 [(set_attr "type" "umull")
1914 (set_attr "predicable" "yes")]
1915 )
1916
1917 (define_insn "*umulsi3_highpart_v6"
1918 [(set (match_operand:SI 0 "s_register_operand" "=r")
1919 (truncate:SI
1920 (lshiftrt:DI
1921 (mult:DI
1922 (zero_extend:DI (match_operand:SI 1 "s_register_operand" "r"))
1923 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r")))
1924 (const_int 32))))
1925 (clobber (match_scratch:SI 3 "=r"))]
1926 "TARGET_32BIT && arm_arch6"
1927 "umull%?\\t%3, %0, %2, %1"
1928 [(set_attr "type" "umull")
1929 (set_attr "predicable" "yes")
1930 (set_attr "predicable_short_it" "no")]
1931 )
1932
1933 (define_insn "mulhisi3"
1934 [(set (match_operand:SI 0 "s_register_operand" "=r")
1935 (mult:SI (sign_extend:SI
1936 (match_operand:HI 1 "s_register_operand" "%r"))
1937 (sign_extend:SI
1938 (match_operand:HI 2 "s_register_operand" "r"))))]
1939 "TARGET_DSP_MULTIPLY"
1940 "smulbb%?\\t%0, %1, %2"
1941 [(set_attr "type" "smulxy")
1942 (set_attr "predicable" "yes")]
1943 )
1944
1945 (define_insn "*mulhisi3tb"
1946 [(set (match_operand:SI 0 "s_register_operand" "=r")
1947 (mult:SI (ashiftrt:SI
1948 (match_operand:SI 1 "s_register_operand" "r")
1949 (const_int 16))
1950 (sign_extend:SI
1951 (match_operand:HI 2 "s_register_operand" "r"))))]
1952 "TARGET_DSP_MULTIPLY"
1953 "smultb%?\\t%0, %1, %2"
1954 [(set_attr "type" "smulxy")
1955 (set_attr "predicable" "yes")
1956 (set_attr "predicable_short_it" "no")]
1957 )
1958
1959 (define_insn "*mulhisi3bt"
1960 [(set (match_operand:SI 0 "s_register_operand" "=r")
1961 (mult:SI (sign_extend:SI
1962 (match_operand:HI 1 "s_register_operand" "r"))
1963 (ashiftrt:SI
1964 (match_operand:SI 2 "s_register_operand" "r")
1965 (const_int 16))))]
1966 "TARGET_DSP_MULTIPLY"
1967 "smulbt%?\\t%0, %1, %2"
1968 [(set_attr "type" "smulxy")
1969 (set_attr "predicable" "yes")
1970 (set_attr "predicable_short_it" "no")]
1971 )
1972
1973 (define_insn "*mulhisi3tt"
1974 [(set (match_operand:SI 0 "s_register_operand" "=r")
1975 (mult:SI (ashiftrt:SI
1976 (match_operand:SI 1 "s_register_operand" "r")
1977 (const_int 16))
1978 (ashiftrt:SI
1979 (match_operand:SI 2 "s_register_operand" "r")
1980 (const_int 16))))]
1981 "TARGET_DSP_MULTIPLY"
1982 "smultt%?\\t%0, %1, %2"
1983 [(set_attr "type" "smulxy")
1984 (set_attr "predicable" "yes")
1985 (set_attr "predicable_short_it" "no")]
1986 )
1987
1988 (define_insn "maddhisi4"
1989 [(set (match_operand:SI 0 "s_register_operand" "=r")
1990 (plus:SI (mult:SI (sign_extend:SI
1991 (match_operand:HI 1 "s_register_operand" "r"))
1992 (sign_extend:SI
1993 (match_operand:HI 2 "s_register_operand" "r")))
1994 (match_operand:SI 3 "s_register_operand" "r")))]
1995 "TARGET_DSP_MULTIPLY"
1996 "smlabb%?\\t%0, %1, %2, %3"
1997 [(set_attr "type" "smlaxy")
1998 (set_attr "predicable" "yes")
1999 (set_attr "predicable_short_it" "no")]
2000 )
2001
2002 ;; Note: there is no maddhisi4ibt because this one is canonical form
2003 (define_insn "*maddhisi4tb"
2004 [(set (match_operand:SI 0 "s_register_operand" "=r")
2005 (plus:SI (mult:SI (ashiftrt:SI
2006 (match_operand:SI 1 "s_register_operand" "r")
2007 (const_int 16))
2008 (sign_extend:SI
2009 (match_operand:HI 2 "s_register_operand" "r")))
2010 (match_operand:SI 3 "s_register_operand" "r")))]
2011 "TARGET_DSP_MULTIPLY"
2012 "smlatb%?\\t%0, %1, %2, %3"
2013 [(set_attr "type" "smlaxy")
2014 (set_attr "predicable" "yes")
2015 (set_attr "predicable_short_it" "no")]
2016 )
2017
2018 (define_insn "*maddhisi4tt"
2019 [(set (match_operand:SI 0 "s_register_operand" "=r")
2020 (plus:SI (mult:SI (ashiftrt:SI
2021 (match_operand:SI 1 "s_register_operand" "r")
2022 (const_int 16))
2023 (ashiftrt:SI
2024 (match_operand:SI 2 "s_register_operand" "r")
2025 (const_int 16)))
2026 (match_operand:SI 3 "s_register_operand" "r")))]
2027 "TARGET_DSP_MULTIPLY"
2028 "smlatt%?\\t%0, %1, %2, %3"
2029 [(set_attr "type" "smlaxy")
2030 (set_attr "predicable" "yes")
2031 (set_attr "predicable_short_it" "no")]
2032 )
2033
2034 (define_insn "maddhidi4"
2035 [(set (match_operand:DI 0 "s_register_operand" "=r")
2036 (plus:DI
2037 (mult:DI (sign_extend:DI
2038 (match_operand:HI 1 "s_register_operand" "r"))
2039 (sign_extend:DI
2040 (match_operand:HI 2 "s_register_operand" "r")))
2041 (match_operand:DI 3 "s_register_operand" "0")))]
2042 "TARGET_DSP_MULTIPLY"
2043 "smlalbb%?\\t%Q0, %R0, %1, %2"
2044 [(set_attr "type" "smlalxy")
2045 (set_attr "predicable" "yes")
2046 (set_attr "predicable_short_it" "no")])
2047
2048 ;; Note: there is no maddhidi4ibt because this one is canonical form
2049 (define_insn "*maddhidi4tb"
2050 [(set (match_operand:DI 0 "s_register_operand" "=r")
2051 (plus:DI
2052 (mult:DI (sign_extend:DI
2053 (ashiftrt:SI
2054 (match_operand:SI 1 "s_register_operand" "r")
2055 (const_int 16)))
2056 (sign_extend:DI
2057 (match_operand:HI 2 "s_register_operand" "r")))
2058 (match_operand:DI 3 "s_register_operand" "0")))]
2059 "TARGET_DSP_MULTIPLY"
2060 "smlaltb%?\\t%Q0, %R0, %1, %2"
2061 [(set_attr "type" "smlalxy")
2062 (set_attr "predicable" "yes")
2063 (set_attr "predicable_short_it" "no")])
2064
2065 (define_insn "*maddhidi4tt"
2066 [(set (match_operand:DI 0 "s_register_operand" "=r")
2067 (plus:DI
2068 (mult:DI (sign_extend:DI
2069 (ashiftrt:SI
2070 (match_operand:SI 1 "s_register_operand" "r")
2071 (const_int 16)))
2072 (sign_extend:DI
2073 (ashiftrt:SI
2074 (match_operand:SI 2 "s_register_operand" "r")
2075 (const_int 16))))
2076 (match_operand:DI 3 "s_register_operand" "0")))]
2077 "TARGET_DSP_MULTIPLY"
2078 "smlaltt%?\\t%Q0, %R0, %1, %2"
2079 [(set_attr "type" "smlalxy")
2080 (set_attr "predicable" "yes")
2081 (set_attr "predicable_short_it" "no")])
2082
2083 (define_expand "mulsf3"
2084 [(set (match_operand:SF 0 "s_register_operand" "")
2085 (mult:SF (match_operand:SF 1 "s_register_operand" "")
2086 (match_operand:SF 2 "s_register_operand" "")))]
2087 "TARGET_32BIT && TARGET_HARD_FLOAT"
2088 "
2089 ")
2090
2091 (define_expand "muldf3"
2092 [(set (match_operand:DF 0 "s_register_operand" "")
2093 (mult:DF (match_operand:DF 1 "s_register_operand" "")
2094 (match_operand:DF 2 "s_register_operand" "")))]
2095 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
2096 "
2097 ")
2098 \f
2099 ;; Division insns
2100
2101 (define_expand "divsf3"
2102 [(set (match_operand:SF 0 "s_register_operand" "")
2103 (div:SF (match_operand:SF 1 "s_register_operand" "")
2104 (match_operand:SF 2 "s_register_operand" "")))]
2105 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
2106 "")
2107
2108 (define_expand "divdf3"
2109 [(set (match_operand:DF 0 "s_register_operand" "")
2110 (div:DF (match_operand:DF 1 "s_register_operand" "")
2111 (match_operand:DF 2 "s_register_operand" "")))]
2112 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
2113 "")
2114 \f
2115 ;; Boolean and,ior,xor insns
2116
2117 ;; Split up double word logical operations
2118
2119 ;; Split up simple DImode logical operations. Simply perform the logical
2120 ;; operation on the upper and lower halves of the registers.
2121 (define_split
2122 [(set (match_operand:DI 0 "s_register_operand" "")
2123 (match_operator:DI 6 "logical_binary_operator"
2124 [(match_operand:DI 1 "s_register_operand" "")
2125 (match_operand:DI 2 "s_register_operand" "")]))]
2126 "TARGET_32BIT && reload_completed
2127 && ! (TARGET_NEON && IS_VFP_REGNUM (REGNO (operands[0])))
2128 && ! IS_IWMMXT_REGNUM (REGNO (operands[0]))"
2129 [(set (match_dup 0) (match_op_dup:SI 6 [(match_dup 1) (match_dup 2)]))
2130 (set (match_dup 3) (match_op_dup:SI 6 [(match_dup 4) (match_dup 5)]))]
2131 "
2132 {
2133 operands[3] = gen_highpart (SImode, operands[0]);
2134 operands[0] = gen_lowpart (SImode, operands[0]);
2135 operands[4] = gen_highpart (SImode, operands[1]);
2136 operands[1] = gen_lowpart (SImode, operands[1]);
2137 operands[5] = gen_highpart (SImode, operands[2]);
2138 operands[2] = gen_lowpart (SImode, operands[2]);
2139 }"
2140 )
2141
2142 (define_split
2143 [(set (match_operand:DI 0 "s_register_operand" "")
2144 (match_operator:DI 6 "logical_binary_operator"
2145 [(sign_extend:DI (match_operand:SI 2 "s_register_operand" ""))
2146 (match_operand:DI 1 "s_register_operand" "")]))]
2147 "TARGET_32BIT && reload_completed"
2148 [(set (match_dup 0) (match_op_dup:SI 6 [(match_dup 1) (match_dup 2)]))
2149 (set (match_dup 3) (match_op_dup:SI 6
2150 [(ashiftrt:SI (match_dup 2) (const_int 31))
2151 (match_dup 4)]))]
2152 "
2153 {
2154 operands[3] = gen_highpart (SImode, operands[0]);
2155 operands[0] = gen_lowpart (SImode, operands[0]);
2156 operands[4] = gen_highpart (SImode, operands[1]);
2157 operands[1] = gen_lowpart (SImode, operands[1]);
2158 operands[5] = gen_highpart (SImode, operands[2]);
2159 operands[2] = gen_lowpart (SImode, operands[2]);
2160 }"
2161 )
2162
2163 ;; The zero extend of operand 2 means we can just copy the high part of
2164 ;; operand1 into operand0.
2165 (define_split
2166 [(set (match_operand:DI 0 "s_register_operand" "")
2167 (ior:DI
2168 (zero_extend:DI (match_operand:SI 2 "s_register_operand" ""))
2169 (match_operand:DI 1 "s_register_operand" "")))]
2170 "TARGET_32BIT && operands[0] != operands[1] && reload_completed"
2171 [(set (match_dup 0) (ior:SI (match_dup 1) (match_dup 2)))
2172 (set (match_dup 3) (match_dup 4))]
2173 "
2174 {
2175 operands[4] = gen_highpart (SImode, operands[1]);
2176 operands[3] = gen_highpart (SImode, operands[0]);
2177 operands[0] = gen_lowpart (SImode, operands[0]);
2178 operands[1] = gen_lowpart (SImode, operands[1]);
2179 }"
2180 )
2181
2182 ;; The zero extend of operand 2 means we can just copy the high part of
2183 ;; operand1 into operand0.
2184 (define_split
2185 [(set (match_operand:DI 0 "s_register_operand" "")
2186 (xor:DI
2187 (zero_extend:DI (match_operand:SI 2 "s_register_operand" ""))
2188 (match_operand:DI 1 "s_register_operand" "")))]
2189 "TARGET_32BIT && operands[0] != operands[1] && reload_completed"
2190 [(set (match_dup 0) (xor:SI (match_dup 1) (match_dup 2)))
2191 (set (match_dup 3) (match_dup 4))]
2192 "
2193 {
2194 operands[4] = gen_highpart (SImode, operands[1]);
2195 operands[3] = gen_highpart (SImode, operands[0]);
2196 operands[0] = gen_lowpart (SImode, operands[0]);
2197 operands[1] = gen_lowpart (SImode, operands[1]);
2198 }"
2199 )
2200
2201 (define_expand "anddi3"
2202 [(set (match_operand:DI 0 "s_register_operand" "")
2203 (and:DI (match_operand:DI 1 "s_register_operand" "")
2204 (match_operand:DI 2 "neon_inv_logic_op2" "")))]
2205 "TARGET_32BIT"
2206 ""
2207 )
2208
2209 (define_insn_and_split "*anddi3_insn"
2210 [(set (match_operand:DI 0 "s_register_operand" "=w,w ,&r,&r,&r,&r,?w,?w")
2211 (and:DI (match_operand:DI 1 "s_register_operand" "%w,0 ,0 ,r ,0 ,r ,w ,0")
2212 (match_operand:DI 2 "arm_anddi_operand_neon" "w ,DL,r ,r ,De,De,w ,DL")))]
2213 "TARGET_32BIT && !TARGET_IWMMXT"
2214 {
2215 switch (which_alternative)
2216 {
2217 case 0: /* fall through */
2218 case 6: return "vand\t%P0, %P1, %P2";
2219 case 1: /* fall through */
2220 case 7: return neon_output_logic_immediate ("vand", &operands[2],
2221 DImode, 1, VALID_NEON_QREG_MODE (DImode));
2222 case 2:
2223 case 3:
2224 case 4:
2225 case 5: /* fall through */
2226 return "#";
2227 default: gcc_unreachable ();
2228 }
2229 }
2230 "TARGET_32BIT && !TARGET_IWMMXT && reload_completed
2231 && !(IS_VFP_REGNUM (REGNO (operands[0])))"
2232 [(set (match_dup 3) (match_dup 4))
2233 (set (match_dup 5) (match_dup 6))]
2234 "
2235 {
2236 operands[3] = gen_lowpart (SImode, operands[0]);
2237 operands[5] = gen_highpart (SImode, operands[0]);
2238
2239 operands[4] = simplify_gen_binary (AND, SImode,
2240 gen_lowpart (SImode, operands[1]),
2241 gen_lowpart (SImode, operands[2]));
2242 operands[6] = simplify_gen_binary (AND, SImode,
2243 gen_highpart (SImode, operands[1]),
2244 gen_highpart_mode (SImode, DImode, operands[2]));
2245
2246 }"
2247 [(set_attr "type" "neon_logic,neon_logic,multiple,multiple,\
2248 multiple,multiple,neon_logic,neon_logic")
2249 (set_attr "arch" "neon_for_64bits,neon_for_64bits,*,*,*,*,
2250 avoid_neon_for_64bits,avoid_neon_for_64bits")
2251 (set_attr "length" "*,*,8,8,8,8,*,*")
2252 ]
2253 )
2254
2255 (define_insn_and_split "*anddi_zesidi_di"
2256 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2257 (and:DI (zero_extend:DI
2258 (match_operand:SI 2 "s_register_operand" "r,r"))
2259 (match_operand:DI 1 "s_register_operand" "0,r")))]
2260 "TARGET_32BIT"
2261 "#"
2262 "TARGET_32BIT && reload_completed"
2263 ; The zero extend of operand 2 clears the high word of the output
2264 ; operand.
2265 [(set (match_dup 0) (and:SI (match_dup 1) (match_dup 2)))
2266 (set (match_dup 3) (const_int 0))]
2267 "
2268 {
2269 operands[3] = gen_highpart (SImode, operands[0]);
2270 operands[0] = gen_lowpart (SImode, operands[0]);
2271 operands[1] = gen_lowpart (SImode, operands[1]);
2272 }"
2273 [(set_attr "length" "8")
2274 (set_attr "type" "multiple")]
2275 )
2276
2277 (define_insn "*anddi_sesdi_di"
2278 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2279 (and:DI (sign_extend:DI
2280 (match_operand:SI 2 "s_register_operand" "r,r"))
2281 (match_operand:DI 1 "s_register_operand" "0,r")))]
2282 "TARGET_32BIT"
2283 "#"
2284 [(set_attr "length" "8")
2285 (set_attr "type" "multiple")]
2286 )
2287
2288 (define_expand "andsi3"
2289 [(set (match_operand:SI 0 "s_register_operand" "")
2290 (and:SI (match_operand:SI 1 "s_register_operand" "")
2291 (match_operand:SI 2 "reg_or_int_operand" "")))]
2292 "TARGET_EITHER"
2293 "
2294 if (TARGET_32BIT)
2295 {
2296 if (CONST_INT_P (operands[2]))
2297 {
2298 if (INTVAL (operands[2]) == 255 && arm_arch6)
2299 {
2300 operands[1] = convert_to_mode (QImode, operands[1], 1);
2301 emit_insn (gen_thumb2_zero_extendqisi2_v6 (operands[0],
2302 operands[1]));
2303 }
2304 else
2305 arm_split_constant (AND, SImode, NULL_RTX,
2306 INTVAL (operands[2]), operands[0],
2307 operands[1],
2308 optimize && can_create_pseudo_p ());
2309
2310 DONE;
2311 }
2312 }
2313 else /* TARGET_THUMB1 */
2314 {
2315 if (!CONST_INT_P (operands[2]))
2316 {
2317 rtx tmp = force_reg (SImode, operands[2]);
2318 if (rtx_equal_p (operands[0], operands[1]))
2319 operands[2] = tmp;
2320 else
2321 {
2322 operands[2] = operands[1];
2323 operands[1] = tmp;
2324 }
2325 }
2326 else
2327 {
2328 int i;
2329
2330 if (((unsigned HOST_WIDE_INT) ~INTVAL (operands[2])) < 256)
2331 {
2332 operands[2] = force_reg (SImode,
2333 GEN_INT (~INTVAL (operands[2])));
2334
2335 emit_insn (gen_thumb1_bicsi3 (operands[0], operands[2], operands[1]));
2336
2337 DONE;
2338 }
2339
2340 for (i = 9; i <= 31; i++)
2341 {
2342 if ((((HOST_WIDE_INT) 1) << i) - 1 == INTVAL (operands[2]))
2343 {
2344 emit_insn (gen_extzv (operands[0], operands[1], GEN_INT (i),
2345 const0_rtx));
2346 DONE;
2347 }
2348 else if ((((HOST_WIDE_INT) 1) << i) - 1
2349 == ~INTVAL (operands[2]))
2350 {
2351 rtx shift = GEN_INT (i);
2352 rtx reg = gen_reg_rtx (SImode);
2353
2354 emit_insn (gen_lshrsi3 (reg, operands[1], shift));
2355 emit_insn (gen_ashlsi3 (operands[0], reg, shift));
2356
2357 DONE;
2358 }
2359 }
2360
2361 operands[2] = force_reg (SImode, operands[2]);
2362 }
2363 }
2364 "
2365 )
2366
2367 ; ??? Check split length for Thumb-2
2368 (define_insn_and_split "*arm_andsi3_insn"
2369 [(set (match_operand:SI 0 "s_register_operand" "=r,l,r,r,r")
2370 (and:SI (match_operand:SI 1 "s_register_operand" "%r,0,r,r,r")
2371 (match_operand:SI 2 "reg_or_int_operand" "I,l,K,r,?n")))]
2372 "TARGET_32BIT"
2373 "@
2374 and%?\\t%0, %1, %2
2375 and%?\\t%0, %1, %2
2376 bic%?\\t%0, %1, #%B2
2377 and%?\\t%0, %1, %2
2378 #"
2379 "TARGET_32BIT
2380 && CONST_INT_P (operands[2])
2381 && !(const_ok_for_arm (INTVAL (operands[2]))
2382 || const_ok_for_arm (~INTVAL (operands[2])))"
2383 [(clobber (const_int 0))]
2384 "
2385 arm_split_constant (AND, SImode, curr_insn,
2386 INTVAL (operands[2]), operands[0], operands[1], 0);
2387 DONE;
2388 "
2389 [(set_attr "length" "4,4,4,4,16")
2390 (set_attr "predicable" "yes")
2391 (set_attr "predicable_short_it" "no,yes,no,no,no")
2392 (set_attr "type" "logic_imm,logic_imm,logic_reg,logic_reg,logic_imm")]
2393 )
2394
2395 (define_insn "*thumb1_andsi3_insn"
2396 [(set (match_operand:SI 0 "register_operand" "=l")
2397 (and:SI (match_operand:SI 1 "register_operand" "%0")
2398 (match_operand:SI 2 "register_operand" "l")))]
2399 "TARGET_THUMB1"
2400 "and\\t%0, %2"
2401 [(set_attr "length" "2")
2402 (set_attr "type" "logic_imm")
2403 (set_attr "conds" "set")])
2404
2405 (define_insn "*andsi3_compare0"
2406 [(set (reg:CC_NOOV CC_REGNUM)
2407 (compare:CC_NOOV
2408 (and:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
2409 (match_operand:SI 2 "arm_not_operand" "I,K,r"))
2410 (const_int 0)))
2411 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
2412 (and:SI (match_dup 1) (match_dup 2)))]
2413 "TARGET_32BIT"
2414 "@
2415 and%.\\t%0, %1, %2
2416 bic%.\\t%0, %1, #%B2
2417 and%.\\t%0, %1, %2"
2418 [(set_attr "conds" "set")
2419 (set_attr "type" "logics_imm,logics_imm,logics_reg")]
2420 )
2421
2422 (define_insn "*andsi3_compare0_scratch"
2423 [(set (reg:CC_NOOV CC_REGNUM)
2424 (compare:CC_NOOV
2425 (and:SI (match_operand:SI 0 "s_register_operand" "r,r,r")
2426 (match_operand:SI 1 "arm_not_operand" "I,K,r"))
2427 (const_int 0)))
2428 (clobber (match_scratch:SI 2 "=X,r,X"))]
2429 "TARGET_32BIT"
2430 "@
2431 tst%?\\t%0, %1
2432 bic%.\\t%2, %0, #%B1
2433 tst%?\\t%0, %1"
2434 [(set_attr "conds" "set")
2435 (set_attr "type" "logics_imm,logics_imm,logics_reg")]
2436 )
2437
2438 (define_insn "*zeroextractsi_compare0_scratch"
2439 [(set (reg:CC_NOOV CC_REGNUM)
2440 (compare:CC_NOOV (zero_extract:SI
2441 (match_operand:SI 0 "s_register_operand" "r")
2442 (match_operand 1 "const_int_operand" "n")
2443 (match_operand 2 "const_int_operand" "n"))
2444 (const_int 0)))]
2445 "TARGET_32BIT
2446 && (INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) < 32
2447 && INTVAL (operands[1]) > 0
2448 && INTVAL (operands[1]) + (INTVAL (operands[2]) & 1) <= 8
2449 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32)"
2450 "*
2451 operands[1] = GEN_INT (((1 << INTVAL (operands[1])) - 1)
2452 << INTVAL (operands[2]));
2453 output_asm_insn (\"tst%?\\t%0, %1\", operands);
2454 return \"\";
2455 "
2456 [(set_attr "conds" "set")
2457 (set_attr "predicable" "yes")
2458 (set_attr "predicable_short_it" "no")
2459 (set_attr "type" "logics_imm")]
2460 )
2461
2462 (define_insn_and_split "*ne_zeroextractsi"
2463 [(set (match_operand:SI 0 "s_register_operand" "=r")
2464 (ne:SI (zero_extract:SI
2465 (match_operand:SI 1 "s_register_operand" "r")
2466 (match_operand:SI 2 "const_int_operand" "n")
2467 (match_operand:SI 3 "const_int_operand" "n"))
2468 (const_int 0)))
2469 (clobber (reg:CC CC_REGNUM))]
2470 "TARGET_32BIT
2471 && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
2472 && INTVAL (operands[2]) > 0
2473 && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
2474 && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)"
2475 "#"
2476 "TARGET_32BIT
2477 && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
2478 && INTVAL (operands[2]) > 0
2479 && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
2480 && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)"
2481 [(parallel [(set (reg:CC_NOOV CC_REGNUM)
2482 (compare:CC_NOOV (and:SI (match_dup 1) (match_dup 2))
2483 (const_int 0)))
2484 (set (match_dup 0) (and:SI (match_dup 1) (match_dup 2)))])
2485 (set (match_dup 0)
2486 (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
2487 (match_dup 0) (const_int 1)))]
2488 "
2489 operands[2] = GEN_INT (((1 << INTVAL (operands[2])) - 1)
2490 << INTVAL (operands[3]));
2491 "
2492 [(set_attr "conds" "clob")
2493 (set (attr "length")
2494 (if_then_else (eq_attr "is_thumb" "yes")
2495 (const_int 12)
2496 (const_int 8)))
2497 (set_attr "type" "multiple")]
2498 )
2499
2500 (define_insn_and_split "*ne_zeroextractsi_shifted"
2501 [(set (match_operand:SI 0 "s_register_operand" "=r")
2502 (ne:SI (zero_extract:SI
2503 (match_operand:SI 1 "s_register_operand" "r")
2504 (match_operand:SI 2 "const_int_operand" "n")
2505 (const_int 0))
2506 (const_int 0)))
2507 (clobber (reg:CC CC_REGNUM))]
2508 "TARGET_ARM"
2509 "#"
2510 "TARGET_ARM"
2511 [(parallel [(set (reg:CC_NOOV CC_REGNUM)
2512 (compare:CC_NOOV (ashift:SI (match_dup 1) (match_dup 2))
2513 (const_int 0)))
2514 (set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 2)))])
2515 (set (match_dup 0)
2516 (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
2517 (match_dup 0) (const_int 1)))]
2518 "
2519 operands[2] = GEN_INT (32 - INTVAL (operands[2]));
2520 "
2521 [(set_attr "conds" "clob")
2522 (set_attr "length" "8")
2523 (set_attr "type" "multiple")]
2524 )
2525
2526 (define_insn_and_split "*ite_ne_zeroextractsi"
2527 [(set (match_operand:SI 0 "s_register_operand" "=r")
2528 (if_then_else:SI (ne (zero_extract:SI
2529 (match_operand:SI 1 "s_register_operand" "r")
2530 (match_operand:SI 2 "const_int_operand" "n")
2531 (match_operand:SI 3 "const_int_operand" "n"))
2532 (const_int 0))
2533 (match_operand:SI 4 "arm_not_operand" "rIK")
2534 (const_int 0)))
2535 (clobber (reg:CC CC_REGNUM))]
2536 "TARGET_ARM
2537 && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
2538 && INTVAL (operands[2]) > 0
2539 && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
2540 && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)
2541 && !reg_overlap_mentioned_p (operands[0], operands[4])"
2542 "#"
2543 "TARGET_ARM
2544 && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
2545 && INTVAL (operands[2]) > 0
2546 && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
2547 && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)
2548 && !reg_overlap_mentioned_p (operands[0], operands[4])"
2549 [(parallel [(set (reg:CC_NOOV CC_REGNUM)
2550 (compare:CC_NOOV (and:SI (match_dup 1) (match_dup 2))
2551 (const_int 0)))
2552 (set (match_dup 0) (and:SI (match_dup 1) (match_dup 2)))])
2553 (set (match_dup 0)
2554 (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
2555 (match_dup 0) (match_dup 4)))]
2556 "
2557 operands[2] = GEN_INT (((1 << INTVAL (operands[2])) - 1)
2558 << INTVAL (operands[3]));
2559 "
2560 [(set_attr "conds" "clob")
2561 (set_attr "length" "8")
2562 (set_attr "type" "multiple")]
2563 )
2564
2565 (define_insn_and_split "*ite_ne_zeroextractsi_shifted"
2566 [(set (match_operand:SI 0 "s_register_operand" "=r")
2567 (if_then_else:SI (ne (zero_extract:SI
2568 (match_operand:SI 1 "s_register_operand" "r")
2569 (match_operand:SI 2 "const_int_operand" "n")
2570 (const_int 0))
2571 (const_int 0))
2572 (match_operand:SI 3 "arm_not_operand" "rIK")
2573 (const_int 0)))
2574 (clobber (reg:CC CC_REGNUM))]
2575 "TARGET_ARM && !reg_overlap_mentioned_p (operands[0], operands[3])"
2576 "#"
2577 "TARGET_ARM && !reg_overlap_mentioned_p (operands[0], operands[3])"
2578 [(parallel [(set (reg:CC_NOOV CC_REGNUM)
2579 (compare:CC_NOOV (ashift:SI (match_dup 1) (match_dup 2))
2580 (const_int 0)))
2581 (set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 2)))])
2582 (set (match_dup 0)
2583 (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
2584 (match_dup 0) (match_dup 3)))]
2585 "
2586 operands[2] = GEN_INT (32 - INTVAL (operands[2]));
2587 "
2588 [(set_attr "conds" "clob")
2589 (set_attr "length" "8")
2590 (set_attr "type" "multiple")]
2591 )
2592
2593 (define_split
2594 [(set (match_operand:SI 0 "s_register_operand" "")
2595 (zero_extract:SI (match_operand:SI 1 "s_register_operand" "")
2596 (match_operand:SI 2 "const_int_operand" "")
2597 (match_operand:SI 3 "const_int_operand" "")))
2598 (clobber (match_operand:SI 4 "s_register_operand" ""))]
2599 "TARGET_THUMB1"
2600 [(set (match_dup 4) (ashift:SI (match_dup 1) (match_dup 2)))
2601 (set (match_dup 0) (lshiftrt:SI (match_dup 4) (match_dup 3)))]
2602 "{
2603 HOST_WIDE_INT temp = INTVAL (operands[2]);
2604
2605 operands[2] = GEN_INT (32 - temp - INTVAL (operands[3]));
2606 operands[3] = GEN_INT (32 - temp);
2607 }"
2608 )
2609
2610 ;; ??? Use Thumb-2 has bitfield insert/extract instructions.
2611 (define_split
2612 [(set (match_operand:SI 0 "s_register_operand" "")
2613 (match_operator:SI 1 "shiftable_operator"
2614 [(zero_extract:SI (match_operand:SI 2 "s_register_operand" "")
2615 (match_operand:SI 3 "const_int_operand" "")
2616 (match_operand:SI 4 "const_int_operand" ""))
2617 (match_operand:SI 5 "s_register_operand" "")]))
2618 (clobber (match_operand:SI 6 "s_register_operand" ""))]
2619 "TARGET_ARM"
2620 [(set (match_dup 6) (ashift:SI (match_dup 2) (match_dup 3)))
2621 (set (match_dup 0)
2622 (match_op_dup 1
2623 [(lshiftrt:SI (match_dup 6) (match_dup 4))
2624 (match_dup 5)]))]
2625 "{
2626 HOST_WIDE_INT temp = INTVAL (operands[3]);
2627
2628 operands[3] = GEN_INT (32 - temp - INTVAL (operands[4]));
2629 operands[4] = GEN_INT (32 - temp);
2630 }"
2631 )
2632
2633 (define_split
2634 [(set (match_operand:SI 0 "s_register_operand" "")
2635 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "")
2636 (match_operand:SI 2 "const_int_operand" "")
2637 (match_operand:SI 3 "const_int_operand" "")))]
2638 "TARGET_THUMB1"
2639 [(set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 2)))
2640 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (match_dup 3)))]
2641 "{
2642 HOST_WIDE_INT temp = INTVAL (operands[2]);
2643
2644 operands[2] = GEN_INT (32 - temp - INTVAL (operands[3]));
2645 operands[3] = GEN_INT (32 - temp);
2646 }"
2647 )
2648
2649 (define_split
2650 [(set (match_operand:SI 0 "s_register_operand" "")
2651 (match_operator:SI 1 "shiftable_operator"
2652 [(sign_extract:SI (match_operand:SI 2 "s_register_operand" "")
2653 (match_operand:SI 3 "const_int_operand" "")
2654 (match_operand:SI 4 "const_int_operand" ""))
2655 (match_operand:SI 5 "s_register_operand" "")]))
2656 (clobber (match_operand:SI 6 "s_register_operand" ""))]
2657 "TARGET_ARM"
2658 [(set (match_dup 6) (ashift:SI (match_dup 2) (match_dup 3)))
2659 (set (match_dup 0)
2660 (match_op_dup 1
2661 [(ashiftrt:SI (match_dup 6) (match_dup 4))
2662 (match_dup 5)]))]
2663 "{
2664 HOST_WIDE_INT temp = INTVAL (operands[3]);
2665
2666 operands[3] = GEN_INT (32 - temp - INTVAL (operands[4]));
2667 operands[4] = GEN_INT (32 - temp);
2668 }"
2669 )
2670
2671 ;;; ??? This pattern is bogus. If operand3 has bits outside the range
2672 ;;; represented by the bitfield, then this will produce incorrect results.
2673 ;;; Somewhere, the value needs to be truncated. On targets like the m68k,
2674 ;;; which have a real bit-field insert instruction, the truncation happens
2675 ;;; in the bit-field insert instruction itself. Since arm does not have a
2676 ;;; bit-field insert instruction, we would have to emit code here to truncate
2677 ;;; the value before we insert. This loses some of the advantage of having
2678 ;;; this insv pattern, so this pattern needs to be reevalutated.
2679
2680 (define_expand "insv"
2681 [(set (zero_extract (match_operand 0 "nonimmediate_operand" "")
2682 (match_operand 1 "general_operand" "")
2683 (match_operand 2 "general_operand" ""))
2684 (match_operand 3 "reg_or_int_operand" ""))]
2685 "TARGET_ARM || arm_arch_thumb2"
2686 "
2687 {
2688 int start_bit = INTVAL (operands[2]);
2689 int width = INTVAL (operands[1]);
2690 HOST_WIDE_INT mask = (((HOST_WIDE_INT)1) << width) - 1;
2691 rtx target, subtarget;
2692
2693 if (arm_arch_thumb2)
2694 {
2695 if (unaligned_access && MEM_P (operands[0])
2696 && s_register_operand (operands[3], GET_MODE (operands[3]))
2697 && (width == 16 || width == 32) && (start_bit % BITS_PER_UNIT) == 0)
2698 {
2699 rtx base_addr;
2700
2701 if (BYTES_BIG_ENDIAN)
2702 start_bit = GET_MODE_BITSIZE (GET_MODE (operands[3])) - width
2703 - start_bit;
2704
2705 if (width == 32)
2706 {
2707 base_addr = adjust_address (operands[0], SImode,
2708 start_bit / BITS_PER_UNIT);
2709 emit_insn (gen_unaligned_storesi (base_addr, operands[3]));
2710 }
2711 else
2712 {
2713 rtx tmp = gen_reg_rtx (HImode);
2714
2715 base_addr = adjust_address (operands[0], HImode,
2716 start_bit / BITS_PER_UNIT);
2717 emit_move_insn (tmp, gen_lowpart (HImode, operands[3]));
2718 emit_insn (gen_unaligned_storehi (base_addr, tmp));
2719 }
2720 DONE;
2721 }
2722 else if (s_register_operand (operands[0], GET_MODE (operands[0])))
2723 {
2724 bool use_bfi = TRUE;
2725
2726 if (CONST_INT_P (operands[3]))
2727 {
2728 HOST_WIDE_INT val = INTVAL (operands[3]) & mask;
2729
2730 if (val == 0)
2731 {
2732 emit_insn (gen_insv_zero (operands[0], operands[1],
2733 operands[2]));
2734 DONE;
2735 }
2736
2737 /* See if the set can be done with a single orr instruction. */
2738 if (val == mask && const_ok_for_arm (val << start_bit))
2739 use_bfi = FALSE;
2740 }
2741
2742 if (use_bfi)
2743 {
2744 if (!REG_P (operands[3]))
2745 operands[3] = force_reg (SImode, operands[3]);
2746
2747 emit_insn (gen_insv_t2 (operands[0], operands[1], operands[2],
2748 operands[3]));
2749 DONE;
2750 }
2751 }
2752 else
2753 FAIL;
2754 }
2755
2756 if (!s_register_operand (operands[0], GET_MODE (operands[0])))
2757 FAIL;
2758
2759 target = copy_rtx (operands[0]);
2760 /* Avoid using a subreg as a subtarget, and avoid writing a paradoxical
2761 subreg as the final target. */
2762 if (GET_CODE (target) == SUBREG)
2763 {
2764 subtarget = gen_reg_rtx (SImode);
2765 if (GET_MODE_SIZE (GET_MODE (SUBREG_REG (target)))
2766 < GET_MODE_SIZE (SImode))
2767 target = SUBREG_REG (target);
2768 }
2769 else
2770 subtarget = target;
2771
2772 if (CONST_INT_P (operands[3]))
2773 {
2774 /* Since we are inserting a known constant, we may be able to
2775 reduce the number of bits that we have to clear so that
2776 the mask becomes simple. */
2777 /* ??? This code does not check to see if the new mask is actually
2778 simpler. It may not be. */
2779 rtx op1 = gen_reg_rtx (SImode);
2780 /* ??? Truncate operand3 to fit in the bitfield. See comment before
2781 start of this pattern. */
2782 HOST_WIDE_INT op3_value = mask & INTVAL (operands[3]);
2783 HOST_WIDE_INT mask2 = ((mask & ~op3_value) << start_bit);
2784
2785 emit_insn (gen_andsi3 (op1, operands[0],
2786 gen_int_mode (~mask2, SImode)));
2787 emit_insn (gen_iorsi3 (subtarget, op1,
2788 gen_int_mode (op3_value << start_bit, SImode)));
2789 }
2790 else if (start_bit == 0
2791 && !(const_ok_for_arm (mask)
2792 || const_ok_for_arm (~mask)))
2793 {
2794 /* A Trick, since we are setting the bottom bits in the word,
2795 we can shift operand[3] up, operand[0] down, OR them together
2796 and rotate the result back again. This takes 3 insns, and
2797 the third might be mergeable into another op. */
2798 /* The shift up copes with the possibility that operand[3] is
2799 wider than the bitfield. */
2800 rtx op0 = gen_reg_rtx (SImode);
2801 rtx op1 = gen_reg_rtx (SImode);
2802
2803 emit_insn (gen_ashlsi3 (op0, operands[3], GEN_INT (32 - width)));
2804 emit_insn (gen_lshrsi3 (op1, operands[0], operands[1]));
2805 emit_insn (gen_iorsi3 (op1, op1, op0));
2806 emit_insn (gen_rotlsi3 (subtarget, op1, operands[1]));
2807 }
2808 else if ((width + start_bit == 32)
2809 && !(const_ok_for_arm (mask)
2810 || const_ok_for_arm (~mask)))
2811 {
2812 /* Similar trick, but slightly less efficient. */
2813
2814 rtx op0 = gen_reg_rtx (SImode);
2815 rtx op1 = gen_reg_rtx (SImode);
2816
2817 emit_insn (gen_ashlsi3 (op0, operands[3], GEN_INT (32 - width)));
2818 emit_insn (gen_ashlsi3 (op1, operands[0], operands[1]));
2819 emit_insn (gen_lshrsi3 (op1, op1, operands[1]));
2820 emit_insn (gen_iorsi3 (subtarget, op1, op0));
2821 }
2822 else
2823 {
2824 rtx op0 = gen_int_mode (mask, SImode);
2825 rtx op1 = gen_reg_rtx (SImode);
2826 rtx op2 = gen_reg_rtx (SImode);
2827
2828 if (!(const_ok_for_arm (mask) || const_ok_for_arm (~mask)))
2829 {
2830 rtx tmp = gen_reg_rtx (SImode);
2831
2832 emit_insn (gen_movsi (tmp, op0));
2833 op0 = tmp;
2834 }
2835
2836 /* Mask out any bits in operand[3] that are not needed. */
2837 emit_insn (gen_andsi3 (op1, operands[3], op0));
2838
2839 if (CONST_INT_P (op0)
2840 && (const_ok_for_arm (mask << start_bit)
2841 || const_ok_for_arm (~(mask << start_bit))))
2842 {
2843 op0 = gen_int_mode (~(mask << start_bit), SImode);
2844 emit_insn (gen_andsi3 (op2, operands[0], op0));
2845 }
2846 else
2847 {
2848 if (CONST_INT_P (op0))
2849 {
2850 rtx tmp = gen_reg_rtx (SImode);
2851
2852 emit_insn (gen_movsi (tmp, op0));
2853 op0 = tmp;
2854 }
2855
2856 if (start_bit != 0)
2857 emit_insn (gen_ashlsi3 (op0, op0, operands[2]));
2858
2859 emit_insn (gen_andsi_notsi_si (op2, operands[0], op0));
2860 }
2861
2862 if (start_bit != 0)
2863 emit_insn (gen_ashlsi3 (op1, op1, operands[2]));
2864
2865 emit_insn (gen_iorsi3 (subtarget, op1, op2));
2866 }
2867
2868 if (subtarget != target)
2869 {
2870 /* If TARGET is still a SUBREG, then it must be wider than a word,
2871 so we must be careful only to set the subword we were asked to. */
2872 if (GET_CODE (target) == SUBREG)
2873 emit_move_insn (target, subtarget);
2874 else
2875 emit_move_insn (target, gen_lowpart (GET_MODE (target), subtarget));
2876 }
2877
2878 DONE;
2879 }"
2880 )
2881
2882 (define_insn "insv_zero"
2883 [(set (zero_extract:SI (match_operand:SI 0 "s_register_operand" "+r")
2884 (match_operand:SI 1 "const_int_operand" "M")
2885 (match_operand:SI 2 "const_int_operand" "M"))
2886 (const_int 0))]
2887 "arm_arch_thumb2"
2888 "bfc%?\t%0, %2, %1"
2889 [(set_attr "length" "4")
2890 (set_attr "predicable" "yes")
2891 (set_attr "predicable_short_it" "no")
2892 (set_attr "type" "bfm")]
2893 )
2894
2895 (define_insn "insv_t2"
2896 [(set (zero_extract:SI (match_operand:SI 0 "s_register_operand" "+r")
2897 (match_operand:SI 1 "const_int_operand" "M")
2898 (match_operand:SI 2 "const_int_operand" "M"))
2899 (match_operand:SI 3 "s_register_operand" "r"))]
2900 "arm_arch_thumb2"
2901 "bfi%?\t%0, %3, %2, %1"
2902 [(set_attr "length" "4")
2903 (set_attr "predicable" "yes")
2904 (set_attr "predicable_short_it" "no")
2905 (set_attr "type" "bfm")]
2906 )
2907
2908 ; constants for op 2 will never be given to these patterns.
2909 (define_insn_and_split "*anddi_notdi_di"
2910 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2911 (and:DI (not:DI (match_operand:DI 1 "s_register_operand" "0,r"))
2912 (match_operand:DI 2 "s_register_operand" "r,0")))]
2913 "TARGET_32BIT"
2914 "#"
2915 "TARGET_32BIT && reload_completed
2916 && ! (TARGET_NEON && IS_VFP_REGNUM (REGNO (operands[0])))
2917 && ! IS_IWMMXT_REGNUM (REGNO (operands[0]))"
2918 [(set (match_dup 0) (and:SI (not:SI (match_dup 1)) (match_dup 2)))
2919 (set (match_dup 3) (and:SI (not:SI (match_dup 4)) (match_dup 5)))]
2920 "
2921 {
2922 operands[3] = gen_highpart (SImode, operands[0]);
2923 operands[0] = gen_lowpart (SImode, operands[0]);
2924 operands[4] = gen_highpart (SImode, operands[1]);
2925 operands[1] = gen_lowpart (SImode, operands[1]);
2926 operands[5] = gen_highpart (SImode, operands[2]);
2927 operands[2] = gen_lowpart (SImode, operands[2]);
2928 }"
2929 [(set_attr "length" "8")
2930 (set_attr "predicable" "yes")
2931 (set_attr "type" "multiple")]
2932 )
2933
2934 (define_insn_and_split "*anddi_notzesidi_di"
2935 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2936 (and:DI (not:DI (zero_extend:DI
2937 (match_operand:SI 2 "s_register_operand" "r,r")))
2938 (match_operand:DI 1 "s_register_operand" "0,?r")))]
2939 "TARGET_32BIT"
2940 "@
2941 bic%?\\t%Q0, %Q1, %2
2942 #"
2943 ; (not (zero_extend ...)) allows us to just copy the high word from
2944 ; operand1 to operand0.
2945 "TARGET_32BIT
2946 && reload_completed
2947 && operands[0] != operands[1]"
2948 [(set (match_dup 0) (and:SI (not:SI (match_dup 2)) (match_dup 1)))
2949 (set (match_dup 3) (match_dup 4))]
2950 "
2951 {
2952 operands[3] = gen_highpart (SImode, operands[0]);
2953 operands[0] = gen_lowpart (SImode, operands[0]);
2954 operands[4] = gen_highpart (SImode, operands[1]);
2955 operands[1] = gen_lowpart (SImode, operands[1]);
2956 }"
2957 [(set_attr "length" "4,8")
2958 (set_attr "predicable" "yes")
2959 (set_attr "predicable_short_it" "no")
2960 (set_attr "type" "multiple")]
2961 )
2962
2963 (define_insn_and_split "*anddi_notsesidi_di"
2964 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2965 (and:DI (not:DI (sign_extend:DI
2966 (match_operand:SI 2 "s_register_operand" "r,r")))
2967 (match_operand:DI 1 "s_register_operand" "0,r")))]
2968 "TARGET_32BIT"
2969 "#"
2970 "TARGET_32BIT && reload_completed"
2971 [(set (match_dup 0) (and:SI (not:SI (match_dup 2)) (match_dup 1)))
2972 (set (match_dup 3) (and:SI (not:SI
2973 (ashiftrt:SI (match_dup 2) (const_int 31)))
2974 (match_dup 4)))]
2975 "
2976 {
2977 operands[3] = gen_highpart (SImode, operands[0]);
2978 operands[0] = gen_lowpart (SImode, operands[0]);
2979 operands[4] = gen_highpart (SImode, operands[1]);
2980 operands[1] = gen_lowpart (SImode, operands[1]);
2981 }"
2982 [(set_attr "length" "8")
2983 (set_attr "predicable" "yes")
2984 (set_attr "predicable_short_it" "no")
2985 (set_attr "type" "multiple")]
2986 )
2987
2988 (define_insn "andsi_notsi_si"
2989 [(set (match_operand:SI 0 "s_register_operand" "=r")
2990 (and:SI (not:SI (match_operand:SI 2 "s_register_operand" "r"))
2991 (match_operand:SI 1 "s_register_operand" "r")))]
2992 "TARGET_32BIT"
2993 "bic%?\\t%0, %1, %2"
2994 [(set_attr "predicable" "yes")
2995 (set_attr "predicable_short_it" "no")
2996 (set_attr "type" "logic_reg")]
2997 )
2998
2999 (define_insn "thumb1_bicsi3"
3000 [(set (match_operand:SI 0 "register_operand" "=l")
3001 (and:SI (not:SI (match_operand:SI 1 "register_operand" "l"))
3002 (match_operand:SI 2 "register_operand" "0")))]
3003 "TARGET_THUMB1"
3004 "bic\\t%0, %1"
3005 [(set_attr "length" "2")
3006 (set_attr "conds" "set")
3007 (set_attr "type" "logics_reg")]
3008 )
3009
3010 (define_insn "andsi_not_shiftsi_si"
3011 [(set (match_operand:SI 0 "s_register_operand" "=r")
3012 (and:SI (not:SI (match_operator:SI 4 "shift_operator"
3013 [(match_operand:SI 2 "s_register_operand" "r")
3014 (match_operand:SI 3 "arm_rhs_operand" "rM")]))
3015 (match_operand:SI 1 "s_register_operand" "r")))]
3016 "TARGET_ARM"
3017 "bic%?\\t%0, %1, %2%S4"
3018 [(set_attr "predicable" "yes")
3019 (set_attr "shift" "2")
3020 (set (attr "type") (if_then_else (match_operand 3 "const_int_operand" "")
3021 (const_string "logic_shift_imm")
3022 (const_string "logic_shift_reg")))]
3023 )
3024
3025 (define_insn "*andsi_notsi_si_compare0"
3026 [(set (reg:CC_NOOV CC_REGNUM)
3027 (compare:CC_NOOV
3028 (and:SI (not:SI (match_operand:SI 2 "s_register_operand" "r"))
3029 (match_operand:SI 1 "s_register_operand" "r"))
3030 (const_int 0)))
3031 (set (match_operand:SI 0 "s_register_operand" "=r")
3032 (and:SI (not:SI (match_dup 2)) (match_dup 1)))]
3033 "TARGET_32BIT"
3034 "bic%.\\t%0, %1, %2"
3035 [(set_attr "conds" "set")
3036 (set_attr "type" "logics_shift_reg")]
3037 )
3038
3039 (define_insn "*andsi_notsi_si_compare0_scratch"
3040 [(set (reg:CC_NOOV CC_REGNUM)
3041 (compare:CC_NOOV
3042 (and:SI (not:SI (match_operand:SI 2 "s_register_operand" "r"))
3043 (match_operand:SI 1 "s_register_operand" "r"))
3044 (const_int 0)))
3045 (clobber (match_scratch:SI 0 "=r"))]
3046 "TARGET_32BIT"
3047 "bic%.\\t%0, %1, %2"
3048 [(set_attr "conds" "set")
3049 (set_attr "type" "logics_shift_reg")]
3050 )
3051
3052 (define_expand "iordi3"
3053 [(set (match_operand:DI 0 "s_register_operand" "")
3054 (ior:DI (match_operand:DI 1 "s_register_operand" "")
3055 (match_operand:DI 2 "neon_logic_op2" "")))]
3056 "TARGET_32BIT"
3057 ""
3058 )
3059
3060 (define_insn_and_split "*iordi3_insn"
3061 [(set (match_operand:DI 0 "s_register_operand" "=w,w ,&r,&r,&r,&r,?w,?w")
3062 (ior:DI (match_operand:DI 1 "s_register_operand" "%w,0 ,0 ,r ,0 ,r ,w ,0")
3063 (match_operand:DI 2 "arm_iordi_operand_neon" "w ,Dl,r ,r ,Df,Df,w ,Dl")))]
3064 "TARGET_32BIT && !TARGET_IWMMXT"
3065 {
3066 switch (which_alternative)
3067 {
3068 case 0: /* fall through */
3069 case 6: return "vorr\t%P0, %P1, %P2";
3070 case 1: /* fall through */
3071 case 7: return neon_output_logic_immediate ("vorr", &operands[2],
3072 DImode, 0, VALID_NEON_QREG_MODE (DImode));
3073 case 2:
3074 case 3:
3075 case 4:
3076 case 5:
3077 return "#";
3078 default: gcc_unreachable ();
3079 }
3080 }
3081 "TARGET_32BIT && !TARGET_IWMMXT && reload_completed
3082 && !(IS_VFP_REGNUM (REGNO (operands[0])))"
3083 [(set (match_dup 3) (match_dup 4))
3084 (set (match_dup 5) (match_dup 6))]
3085 "
3086 {
3087 operands[3] = gen_lowpart (SImode, operands[0]);
3088 operands[5] = gen_highpart (SImode, operands[0]);
3089
3090 operands[4] = simplify_gen_binary (IOR, SImode,
3091 gen_lowpart (SImode, operands[1]),
3092 gen_lowpart (SImode, operands[2]));
3093 operands[6] = simplify_gen_binary (IOR, SImode,
3094 gen_highpart (SImode, operands[1]),
3095 gen_highpart_mode (SImode, DImode, operands[2]));
3096
3097 }"
3098 [(set_attr "type" "neon_logic,neon_logic,multiple,multiple,multiple,\
3099 multiple,neon_logic,neon_logic")
3100 (set_attr "length" "*,*,8,8,8,8,*,*")
3101 (set_attr "arch" "neon_for_64bits,neon_for_64bits,*,*,*,*,avoid_neon_for_64bits,avoid_neon_for_64bits")]
3102 )
3103
3104 (define_insn "*iordi_zesidi_di"
3105 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
3106 (ior:DI (zero_extend:DI
3107 (match_operand:SI 2 "s_register_operand" "r,r"))
3108 (match_operand:DI 1 "s_register_operand" "0,?r")))]
3109 "TARGET_32BIT"
3110 "@
3111 orr%?\\t%Q0, %Q1, %2
3112 #"
3113 [(set_attr "length" "4,8")
3114 (set_attr "predicable" "yes")
3115 (set_attr "predicable_short_it" "no")
3116 (set_attr "type" "logic_reg,multiple")]
3117 )
3118
3119 (define_insn "*iordi_sesidi_di"
3120 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
3121 (ior:DI (sign_extend:DI
3122 (match_operand:SI 2 "s_register_operand" "r,r"))
3123 (match_operand:DI 1 "s_register_operand" "0,r")))]
3124 "TARGET_32BIT"
3125 "#"
3126 [(set_attr "length" "8")
3127 (set_attr "predicable" "yes")
3128 (set_attr "type" "multiple")]
3129 )
3130
3131 (define_expand "iorsi3"
3132 [(set (match_operand:SI 0 "s_register_operand" "")
3133 (ior:SI (match_operand:SI 1 "s_register_operand" "")
3134 (match_operand:SI 2 "reg_or_int_operand" "")))]
3135 "TARGET_EITHER"
3136 "
3137 if (CONST_INT_P (operands[2]))
3138 {
3139 if (TARGET_32BIT)
3140 {
3141 arm_split_constant (IOR, SImode, NULL_RTX,
3142 INTVAL (operands[2]), operands[0], operands[1],
3143 optimize && can_create_pseudo_p ());
3144 DONE;
3145 }
3146 else /* TARGET_THUMB1 */
3147 {
3148 rtx tmp = force_reg (SImode, operands[2]);
3149 if (rtx_equal_p (operands[0], operands[1]))
3150 operands[2] = tmp;
3151 else
3152 {
3153 operands[2] = operands[1];
3154 operands[1] = tmp;
3155 }
3156 }
3157 }
3158 "
3159 )
3160
3161 (define_insn_and_split "*iorsi3_insn"
3162 [(set (match_operand:SI 0 "s_register_operand" "=r,l,r,r,r")
3163 (ior:SI (match_operand:SI 1 "s_register_operand" "%r,0,r,r,r")
3164 (match_operand:SI 2 "reg_or_int_operand" "I,l,K,r,?n")))]
3165 "TARGET_32BIT"
3166 "@
3167 orr%?\\t%0, %1, %2
3168 orr%?\\t%0, %1, %2
3169 orn%?\\t%0, %1, #%B2
3170 orr%?\\t%0, %1, %2
3171 #"
3172 "TARGET_32BIT
3173 && CONST_INT_P (operands[2])
3174 && !(const_ok_for_arm (INTVAL (operands[2]))
3175 || (TARGET_THUMB2 && const_ok_for_arm (~INTVAL (operands[2]))))"
3176 [(clobber (const_int 0))]
3177 {
3178 arm_split_constant (IOR, SImode, curr_insn,
3179 INTVAL (operands[2]), operands[0], operands[1], 0);
3180 DONE;
3181 }
3182 [(set_attr "length" "4,4,4,4,16")
3183 (set_attr "arch" "32,t2,t2,32,32")
3184 (set_attr "predicable" "yes")
3185 (set_attr "predicable_short_it" "no,yes,no,no,no")
3186 (set_attr "type" "logic_imm,logic_reg,logic_imm,logic_reg,logic_reg")]
3187 )
3188
3189 (define_insn "*thumb1_iorsi3_insn"
3190 [(set (match_operand:SI 0 "register_operand" "=l")
3191 (ior:SI (match_operand:SI 1 "register_operand" "%0")
3192 (match_operand:SI 2 "register_operand" "l")))]
3193 "TARGET_THUMB1"
3194 "orr\\t%0, %2"
3195 [(set_attr "length" "2")
3196 (set_attr "conds" "set")
3197 (set_attr "type" "logics_reg")])
3198
3199 (define_peephole2
3200 [(match_scratch:SI 3 "r")
3201 (set (match_operand:SI 0 "arm_general_register_operand" "")
3202 (ior:SI (match_operand:SI 1 "arm_general_register_operand" "")
3203 (match_operand:SI 2 "const_int_operand" "")))]
3204 "TARGET_ARM
3205 && !const_ok_for_arm (INTVAL (operands[2]))
3206 && const_ok_for_arm (~INTVAL (operands[2]))"
3207 [(set (match_dup 3) (match_dup 2))
3208 (set (match_dup 0) (ior:SI (match_dup 1) (match_dup 3)))]
3209 ""
3210 )
3211
3212 (define_insn "*iorsi3_compare0"
3213 [(set (reg:CC_NOOV CC_REGNUM)
3214 (compare:CC_NOOV (ior:SI (match_operand:SI 1 "s_register_operand" "%r,r")
3215 (match_operand:SI 2 "arm_rhs_operand" "I,r"))
3216 (const_int 0)))
3217 (set (match_operand:SI 0 "s_register_operand" "=r,r")
3218 (ior:SI (match_dup 1) (match_dup 2)))]
3219 "TARGET_32BIT"
3220 "orr%.\\t%0, %1, %2"
3221 [(set_attr "conds" "set")
3222 (set_attr "type" "logics_imm,logics_reg")]
3223 )
3224
3225 (define_insn "*iorsi3_compare0_scratch"
3226 [(set (reg:CC_NOOV CC_REGNUM)
3227 (compare:CC_NOOV (ior:SI (match_operand:SI 1 "s_register_operand" "%r,r")
3228 (match_operand:SI 2 "arm_rhs_operand" "I,r"))
3229 (const_int 0)))
3230 (clobber (match_scratch:SI 0 "=r,r"))]
3231 "TARGET_32BIT"
3232 "orr%.\\t%0, %1, %2"
3233 [(set_attr "conds" "set")
3234 (set_attr "type" "logics_imm,logics_reg")]
3235 )
3236
3237 (define_expand "xordi3"
3238 [(set (match_operand:DI 0 "s_register_operand" "")
3239 (xor:DI (match_operand:DI 1 "s_register_operand" "")
3240 (match_operand:DI 2 "arm_xordi_operand" "")))]
3241 "TARGET_32BIT"
3242 ""
3243 )
3244
3245 (define_insn_and_split "*xordi3_insn"
3246 [(set (match_operand:DI 0 "s_register_operand" "=w,&r,&r,&r,&r,?w")
3247 (xor:DI (match_operand:DI 1 "s_register_operand" "w ,%0,r ,0 ,r ,w")
3248 (match_operand:DI 2 "arm_xordi_operand" "w ,r ,r ,Dg,Dg,w")))]
3249 "TARGET_32BIT && !TARGET_IWMMXT"
3250 {
3251 switch (which_alternative)
3252 {
3253 case 1:
3254 case 2:
3255 case 3:
3256 case 4: /* fall through */
3257 return "#";
3258 case 0: /* fall through */
3259 case 5: return "veor\t%P0, %P1, %P2";
3260 default: gcc_unreachable ();
3261 }
3262 }
3263 "TARGET_32BIT && !TARGET_IWMMXT && reload_completed
3264 && !(IS_VFP_REGNUM (REGNO (operands[0])))"
3265 [(set (match_dup 3) (match_dup 4))
3266 (set (match_dup 5) (match_dup 6))]
3267 "
3268 {
3269 operands[3] = gen_lowpart (SImode, operands[0]);
3270 operands[5] = gen_highpart (SImode, operands[0]);
3271
3272 operands[4] = simplify_gen_binary (XOR, SImode,
3273 gen_lowpart (SImode, operands[1]),
3274 gen_lowpart (SImode, operands[2]));
3275 operands[6] = simplify_gen_binary (XOR, SImode,
3276 gen_highpart (SImode, operands[1]),
3277 gen_highpart_mode (SImode, DImode, operands[2]));
3278
3279 }"
3280 [(set_attr "length" "*,8,8,8,8,*")
3281 (set_attr "type" "neon_logic,multiple,multiple,multiple,multiple,neon_logic")
3282 (set_attr "arch" "neon_for_64bits,*,*,*,*,avoid_neon_for_64bits")]
3283 )
3284
3285 (define_insn "*xordi_zesidi_di"
3286 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
3287 (xor:DI (zero_extend:DI
3288 (match_operand:SI 2 "s_register_operand" "r,r"))
3289 (match_operand:DI 1 "s_register_operand" "0,?r")))]
3290 "TARGET_32BIT"
3291 "@
3292 eor%?\\t%Q0, %Q1, %2
3293 #"
3294 [(set_attr "length" "4,8")
3295 (set_attr "predicable" "yes")
3296 (set_attr "predicable_short_it" "no")
3297 (set_attr "type" "logic_reg")]
3298 )
3299
3300 (define_insn "*xordi_sesidi_di"
3301 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
3302 (xor:DI (sign_extend:DI
3303 (match_operand:SI 2 "s_register_operand" "r,r"))
3304 (match_operand:DI 1 "s_register_operand" "0,r")))]
3305 "TARGET_32BIT"
3306 "#"
3307 [(set_attr "length" "8")
3308 (set_attr "predicable" "yes")
3309 (set_attr "type" "multiple")]
3310 )
3311
3312 (define_expand "xorsi3"
3313 [(set (match_operand:SI 0 "s_register_operand" "")
3314 (xor:SI (match_operand:SI 1 "s_register_operand" "")
3315 (match_operand:SI 2 "reg_or_int_operand" "")))]
3316 "TARGET_EITHER"
3317 "if (CONST_INT_P (operands[2]))
3318 {
3319 if (TARGET_32BIT)
3320 {
3321 arm_split_constant (XOR, SImode, NULL_RTX,
3322 INTVAL (operands[2]), operands[0], operands[1],
3323 optimize && can_create_pseudo_p ());
3324 DONE;
3325 }
3326 else /* TARGET_THUMB1 */
3327 {
3328 rtx tmp = force_reg (SImode, operands[2]);
3329 if (rtx_equal_p (operands[0], operands[1]))
3330 operands[2] = tmp;
3331 else
3332 {
3333 operands[2] = operands[1];
3334 operands[1] = tmp;
3335 }
3336 }
3337 }"
3338 )
3339
3340 (define_insn_and_split "*arm_xorsi3"
3341 [(set (match_operand:SI 0 "s_register_operand" "=r,l,r,r")
3342 (xor:SI (match_operand:SI 1 "s_register_operand" "%r,0,r,r")
3343 (match_operand:SI 2 "reg_or_int_operand" "I,l,r,?n")))]
3344 "TARGET_32BIT"
3345 "@
3346 eor%?\\t%0, %1, %2
3347 eor%?\\t%0, %1, %2
3348 eor%?\\t%0, %1, %2
3349 #"
3350 "TARGET_32BIT
3351 && CONST_INT_P (operands[2])
3352 && !const_ok_for_arm (INTVAL (operands[2]))"
3353 [(clobber (const_int 0))]
3354 {
3355 arm_split_constant (XOR, SImode, curr_insn,
3356 INTVAL (operands[2]), operands[0], operands[1], 0);
3357 DONE;
3358 }
3359 [(set_attr "length" "4,4,4,16")
3360 (set_attr "predicable" "yes")
3361 (set_attr "predicable_short_it" "no,yes,no,no")
3362 (set_attr "type" "logic_imm,logic_reg,logic_reg,multiple")]
3363 )
3364
3365 (define_insn "*thumb1_xorsi3_insn"
3366 [(set (match_operand:SI 0 "register_operand" "=l")
3367 (xor:SI (match_operand:SI 1 "register_operand" "%0")
3368 (match_operand:SI 2 "register_operand" "l")))]
3369 "TARGET_THUMB1"
3370 "eor\\t%0, %2"
3371 [(set_attr "length" "2")
3372 (set_attr "conds" "set")
3373 (set_attr "type" "logics_reg")]
3374 )
3375
3376 (define_insn "*xorsi3_compare0"
3377 [(set (reg:CC_NOOV CC_REGNUM)
3378 (compare:CC_NOOV (xor:SI (match_operand:SI 1 "s_register_operand" "r,r")
3379 (match_operand:SI 2 "arm_rhs_operand" "I,r"))
3380 (const_int 0)))
3381 (set (match_operand:SI 0 "s_register_operand" "=r,r")
3382 (xor:SI (match_dup 1) (match_dup 2)))]
3383 "TARGET_32BIT"
3384 "eor%.\\t%0, %1, %2"
3385 [(set_attr "conds" "set")
3386 (set_attr "type" "logics_imm,logics_reg")]
3387 )
3388
3389 (define_insn "*xorsi3_compare0_scratch"
3390 [(set (reg:CC_NOOV CC_REGNUM)
3391 (compare:CC_NOOV (xor:SI (match_operand:SI 0 "s_register_operand" "r,r")
3392 (match_operand:SI 1 "arm_rhs_operand" "I,r"))
3393 (const_int 0)))]
3394 "TARGET_32BIT"
3395 "teq%?\\t%0, %1"
3396 [(set_attr "conds" "set")
3397 (set_attr "type" "logics_imm,logics_reg")]
3398 )
3399
3400 ; By splitting (IOR (AND (NOT A) (NOT B)) C) as D = AND (IOR A B) (NOT C),
3401 ; (NOT D) we can sometimes merge the final NOT into one of the following
3402 ; insns.
3403
3404 (define_split
3405 [(set (match_operand:SI 0 "s_register_operand" "")
3406 (ior:SI (and:SI (not:SI (match_operand:SI 1 "s_register_operand" ""))
3407 (not:SI (match_operand:SI 2 "arm_rhs_operand" "")))
3408 (match_operand:SI 3 "arm_rhs_operand" "")))
3409 (clobber (match_operand:SI 4 "s_register_operand" ""))]
3410 "TARGET_32BIT"
3411 [(set (match_dup 4) (and:SI (ior:SI (match_dup 1) (match_dup 2))
3412 (not:SI (match_dup 3))))
3413 (set (match_dup 0) (not:SI (match_dup 4)))]
3414 ""
3415 )
3416
3417 (define_insn_and_split "*andsi_iorsi3_notsi"
3418 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r")
3419 (and:SI (ior:SI (match_operand:SI 1 "s_register_operand" "%0,r,r")
3420 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI"))
3421 (not:SI (match_operand:SI 3 "arm_rhs_operand" "rI,rI,rI"))))]
3422 "TARGET_32BIT"
3423 "#" ; "orr%?\\t%0, %1, %2\;bic%?\\t%0, %0, %3"
3424 "&& reload_completed"
3425 [(set (match_dup 0) (ior:SI (match_dup 1) (match_dup 2)))
3426 (set (match_dup 0) (and:SI (not:SI (match_dup 3)) (match_dup 0)))]
3427 ""
3428 [(set_attr "length" "8")
3429 (set_attr "ce_count" "2")
3430 (set_attr "predicable" "yes")
3431 (set_attr "predicable_short_it" "no")
3432 (set_attr "type" "multiple")]
3433 )
3434
3435 ; ??? Are these four splitters still beneficial when the Thumb-2 bitfield
3436 ; insns are available?
3437 (define_split
3438 [(set (match_operand:SI 0 "s_register_operand" "")
3439 (match_operator:SI 1 "logical_binary_operator"
3440 [(zero_extract:SI (match_operand:SI 2 "s_register_operand" "")
3441 (match_operand:SI 3 "const_int_operand" "")
3442 (match_operand:SI 4 "const_int_operand" ""))
3443 (match_operator:SI 9 "logical_binary_operator"
3444 [(lshiftrt:SI (match_operand:SI 5 "s_register_operand" "")
3445 (match_operand:SI 6 "const_int_operand" ""))
3446 (match_operand:SI 7 "s_register_operand" "")])]))
3447 (clobber (match_operand:SI 8 "s_register_operand" ""))]
3448 "TARGET_32BIT
3449 && GET_CODE (operands[1]) == GET_CODE (operands[9])
3450 && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
3451 [(set (match_dup 8)
3452 (match_op_dup 1
3453 [(ashift:SI (match_dup 2) (match_dup 4))
3454 (match_dup 5)]))
3455 (set (match_dup 0)
3456 (match_op_dup 1
3457 [(lshiftrt:SI (match_dup 8) (match_dup 6))
3458 (match_dup 7)]))]
3459 "
3460 operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
3461 ")
3462
3463 (define_split
3464 [(set (match_operand:SI 0 "s_register_operand" "")
3465 (match_operator:SI 1 "logical_binary_operator"
3466 [(match_operator:SI 9 "logical_binary_operator"
3467 [(lshiftrt:SI (match_operand:SI 5 "s_register_operand" "")
3468 (match_operand:SI 6 "const_int_operand" ""))
3469 (match_operand:SI 7 "s_register_operand" "")])
3470 (zero_extract:SI (match_operand:SI 2 "s_register_operand" "")
3471 (match_operand:SI 3 "const_int_operand" "")
3472 (match_operand:SI 4 "const_int_operand" ""))]))
3473 (clobber (match_operand:SI 8 "s_register_operand" ""))]
3474 "TARGET_32BIT
3475 && GET_CODE (operands[1]) == GET_CODE (operands[9])
3476 && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
3477 [(set (match_dup 8)
3478 (match_op_dup 1
3479 [(ashift:SI (match_dup 2) (match_dup 4))
3480 (match_dup 5)]))
3481 (set (match_dup 0)
3482 (match_op_dup 1
3483 [(lshiftrt:SI (match_dup 8) (match_dup 6))
3484 (match_dup 7)]))]
3485 "
3486 operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
3487 ")
3488
3489 (define_split
3490 [(set (match_operand:SI 0 "s_register_operand" "")
3491 (match_operator:SI 1 "logical_binary_operator"
3492 [(sign_extract:SI (match_operand:SI 2 "s_register_operand" "")
3493 (match_operand:SI 3 "const_int_operand" "")
3494 (match_operand:SI 4 "const_int_operand" ""))
3495 (match_operator:SI 9 "logical_binary_operator"
3496 [(ashiftrt:SI (match_operand:SI 5 "s_register_operand" "")
3497 (match_operand:SI 6 "const_int_operand" ""))
3498 (match_operand:SI 7 "s_register_operand" "")])]))
3499 (clobber (match_operand:SI 8 "s_register_operand" ""))]
3500 "TARGET_32BIT
3501 && GET_CODE (operands[1]) == GET_CODE (operands[9])
3502 && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
3503 [(set (match_dup 8)
3504 (match_op_dup 1
3505 [(ashift:SI (match_dup 2) (match_dup 4))
3506 (match_dup 5)]))
3507 (set (match_dup 0)
3508 (match_op_dup 1
3509 [(ashiftrt:SI (match_dup 8) (match_dup 6))
3510 (match_dup 7)]))]
3511 "
3512 operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
3513 ")
3514
3515 (define_split
3516 [(set (match_operand:SI 0 "s_register_operand" "")
3517 (match_operator:SI 1 "logical_binary_operator"
3518 [(match_operator:SI 9 "logical_binary_operator"
3519 [(ashiftrt:SI (match_operand:SI 5 "s_register_operand" "")
3520 (match_operand:SI 6 "const_int_operand" ""))
3521 (match_operand:SI 7 "s_register_operand" "")])
3522 (sign_extract:SI (match_operand:SI 2 "s_register_operand" "")
3523 (match_operand:SI 3 "const_int_operand" "")
3524 (match_operand:SI 4 "const_int_operand" ""))]))
3525 (clobber (match_operand:SI 8 "s_register_operand" ""))]
3526 "TARGET_32BIT
3527 && GET_CODE (operands[1]) == GET_CODE (operands[9])
3528 && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
3529 [(set (match_dup 8)
3530 (match_op_dup 1
3531 [(ashift:SI (match_dup 2) (match_dup 4))
3532 (match_dup 5)]))
3533 (set (match_dup 0)
3534 (match_op_dup 1
3535 [(ashiftrt:SI (match_dup 8) (match_dup 6))
3536 (match_dup 7)]))]
3537 "
3538 operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
3539 ")
3540 \f
3541
3542 ;; Minimum and maximum insns
3543
3544 (define_expand "smaxsi3"
3545 [(parallel [
3546 (set (match_operand:SI 0 "s_register_operand" "")
3547 (smax:SI (match_operand:SI 1 "s_register_operand" "")
3548 (match_operand:SI 2 "arm_rhs_operand" "")))
3549 (clobber (reg:CC CC_REGNUM))])]
3550 "TARGET_32BIT"
3551 "
3552 if (operands[2] == const0_rtx || operands[2] == constm1_rtx)
3553 {
3554 /* No need for a clobber of the condition code register here. */
3555 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
3556 gen_rtx_SMAX (SImode, operands[1],
3557 operands[2])));
3558 DONE;
3559 }
3560 ")
3561
3562 (define_insn "*smax_0"
3563 [(set (match_operand:SI 0 "s_register_operand" "=r")
3564 (smax:SI (match_operand:SI 1 "s_register_operand" "r")
3565 (const_int 0)))]
3566 "TARGET_32BIT"
3567 "bic%?\\t%0, %1, %1, asr #31"
3568 [(set_attr "predicable" "yes")
3569 (set_attr "predicable_short_it" "no")
3570 (set_attr "type" "logic_shift_reg")]
3571 )
3572
3573 (define_insn "*smax_m1"
3574 [(set (match_operand:SI 0 "s_register_operand" "=r")
3575 (smax:SI (match_operand:SI 1 "s_register_operand" "r")
3576 (const_int -1)))]
3577 "TARGET_32BIT"
3578 "orr%?\\t%0, %1, %1, asr #31"
3579 [(set_attr "predicable" "yes")
3580 (set_attr "predicable_short_it" "no")
3581 (set_attr "type" "logic_shift_reg")]
3582 )
3583
3584 (define_insn_and_split "*arm_smax_insn"
3585 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
3586 (smax:SI (match_operand:SI 1 "s_register_operand" "%0,?r")
3587 (match_operand:SI 2 "arm_rhs_operand" "rI,rI")))
3588 (clobber (reg:CC CC_REGNUM))]
3589 "TARGET_ARM"
3590 "#"
3591 ; cmp\\t%1, %2\;movlt\\t%0, %2
3592 ; cmp\\t%1, %2\;movge\\t%0, %1\;movlt\\t%0, %2"
3593 "TARGET_ARM"
3594 [(set (reg:CC CC_REGNUM)
3595 (compare:CC (match_dup 1) (match_dup 2)))
3596 (set (match_dup 0)
3597 (if_then_else:SI (ge:SI (reg:CC CC_REGNUM) (const_int 0))
3598 (match_dup 1)
3599 (match_dup 2)))]
3600 ""
3601 [(set_attr "conds" "clob")
3602 (set_attr "length" "8,12")
3603 (set_attr "type" "multiple")]
3604 )
3605
3606 (define_expand "sminsi3"
3607 [(parallel [
3608 (set (match_operand:SI 0 "s_register_operand" "")
3609 (smin:SI (match_operand:SI 1 "s_register_operand" "")
3610 (match_operand:SI 2 "arm_rhs_operand" "")))
3611 (clobber (reg:CC CC_REGNUM))])]
3612 "TARGET_32BIT"
3613 "
3614 if (operands[2] == const0_rtx)
3615 {
3616 /* No need for a clobber of the condition code register here. */
3617 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
3618 gen_rtx_SMIN (SImode, operands[1],
3619 operands[2])));
3620 DONE;
3621 }
3622 ")
3623
3624 (define_insn "*smin_0"
3625 [(set (match_operand:SI 0 "s_register_operand" "=r")
3626 (smin:SI (match_operand:SI 1 "s_register_operand" "r")
3627 (const_int 0)))]
3628 "TARGET_32BIT"
3629 "and%?\\t%0, %1, %1, asr #31"
3630 [(set_attr "predicable" "yes")
3631 (set_attr "predicable_short_it" "no")
3632 (set_attr "type" "logic_shift_reg")]
3633 )
3634
3635 (define_insn_and_split "*arm_smin_insn"
3636 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
3637 (smin:SI (match_operand:SI 1 "s_register_operand" "%0,?r")
3638 (match_operand:SI 2 "arm_rhs_operand" "rI,rI")))
3639 (clobber (reg:CC CC_REGNUM))]
3640 "TARGET_ARM"
3641 "#"
3642 ; cmp\\t%1, %2\;movge\\t%0, %2
3643 ; cmp\\t%1, %2\;movlt\\t%0, %1\;movge\\t%0, %2"
3644 "TARGET_ARM"
3645 [(set (reg:CC CC_REGNUM)
3646 (compare:CC (match_dup 1) (match_dup 2)))
3647 (set (match_dup 0)
3648 (if_then_else:SI (lt:SI (reg:CC CC_REGNUM) (const_int 0))
3649 (match_dup 1)
3650 (match_dup 2)))]
3651 ""
3652 [(set_attr "conds" "clob")
3653 (set_attr "length" "8,12")
3654 (set_attr "type" "multiple,multiple")]
3655 )
3656
3657 (define_expand "umaxsi3"
3658 [(parallel [
3659 (set (match_operand:SI 0 "s_register_operand" "")
3660 (umax:SI (match_operand:SI 1 "s_register_operand" "")
3661 (match_operand:SI 2 "arm_rhs_operand" "")))
3662 (clobber (reg:CC CC_REGNUM))])]
3663 "TARGET_32BIT"
3664 ""
3665 )
3666
3667 (define_insn_and_split "*arm_umaxsi3"
3668 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
3669 (umax:SI (match_operand:SI 1 "s_register_operand" "0,r,?r")
3670 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
3671 (clobber (reg:CC CC_REGNUM))]
3672 "TARGET_ARM"
3673 "#"
3674 ; cmp\\t%1, %2\;movcc\\t%0, %2
3675 ; cmp\\t%1, %2\;movcs\\t%0, %1
3676 ; cmp\\t%1, %2\;movcs\\t%0, %1\;movcc\\t%0, %2"
3677 "TARGET_ARM"
3678 [(set (reg:CC CC_REGNUM)
3679 (compare:CC (match_dup 1) (match_dup 2)))
3680 (set (match_dup 0)
3681 (if_then_else:SI (geu:SI (reg:CC CC_REGNUM) (const_int 0))
3682 (match_dup 1)
3683 (match_dup 2)))]
3684 ""
3685 [(set_attr "conds" "clob")
3686 (set_attr "length" "8,8,12")
3687 (set_attr "type" "store1")]
3688 )
3689
3690 (define_expand "uminsi3"
3691 [(parallel [
3692 (set (match_operand:SI 0 "s_register_operand" "")
3693 (umin:SI (match_operand:SI 1 "s_register_operand" "")
3694 (match_operand:SI 2 "arm_rhs_operand" "")))
3695 (clobber (reg:CC CC_REGNUM))])]
3696 "TARGET_32BIT"
3697 ""
3698 )
3699
3700 (define_insn_and_split "*arm_uminsi3"
3701 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
3702 (umin:SI (match_operand:SI 1 "s_register_operand" "0,r,?r")
3703 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
3704 (clobber (reg:CC CC_REGNUM))]
3705 "TARGET_ARM"
3706 "#"
3707 ; cmp\\t%1, %2\;movcs\\t%0, %2
3708 ; cmp\\t%1, %2\;movcc\\t%0, %1
3709 ; cmp\\t%1, %2\;movcc\\t%0, %1\;movcs\\t%0, %2"
3710 "TARGET_ARM"
3711 [(set (reg:CC CC_REGNUM)
3712 (compare:CC (match_dup 1) (match_dup 2)))
3713 (set (match_dup 0)
3714 (if_then_else:SI (ltu:SI (reg:CC CC_REGNUM) (const_int 0))
3715 (match_dup 1)
3716 (match_dup 2)))]
3717 ""
3718 [(set_attr "conds" "clob")
3719 (set_attr "length" "8,8,12")
3720 (set_attr "type" "store1")]
3721 )
3722
3723 (define_insn "*store_minmaxsi"
3724 [(set (match_operand:SI 0 "memory_operand" "=m")
3725 (match_operator:SI 3 "minmax_operator"
3726 [(match_operand:SI 1 "s_register_operand" "r")
3727 (match_operand:SI 2 "s_register_operand" "r")]))
3728 (clobber (reg:CC CC_REGNUM))]
3729 "TARGET_32BIT && optimize_function_for_size_p (cfun)"
3730 "*
3731 operands[3] = gen_rtx_fmt_ee (minmax_code (operands[3]), SImode,
3732 operands[1], operands[2]);
3733 output_asm_insn (\"cmp\\t%1, %2\", operands);
3734 if (TARGET_THUMB2)
3735 output_asm_insn (\"ite\t%d3\", operands);
3736 output_asm_insn (\"str%d3\\t%1, %0\", operands);
3737 output_asm_insn (\"str%D3\\t%2, %0\", operands);
3738 return \"\";
3739 "
3740 [(set_attr "conds" "clob")
3741 (set (attr "length")
3742 (if_then_else (eq_attr "is_thumb" "yes")
3743 (const_int 14)
3744 (const_int 12)))
3745 (set_attr "type" "store1")]
3746 )
3747
3748 ; Reject the frame pointer in operand[1], since reloading this after
3749 ; it has been eliminated can cause carnage.
3750 (define_insn "*minmax_arithsi"
3751 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
3752 (match_operator:SI 4 "shiftable_operator"
3753 [(match_operator:SI 5 "minmax_operator"
3754 [(match_operand:SI 2 "s_register_operand" "r,r")
3755 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
3756 (match_operand:SI 1 "s_register_operand" "0,?r")]))
3757 (clobber (reg:CC CC_REGNUM))]
3758 "TARGET_32BIT && !arm_eliminable_register (operands[1]) && !arm_restrict_it"
3759 "*
3760 {
3761 enum rtx_code code = GET_CODE (operands[4]);
3762 bool need_else;
3763
3764 if (which_alternative != 0 || operands[3] != const0_rtx
3765 || (code != PLUS && code != IOR && code != XOR))
3766 need_else = true;
3767 else
3768 need_else = false;
3769
3770 operands[5] = gen_rtx_fmt_ee (minmax_code (operands[5]), SImode,
3771 operands[2], operands[3]);
3772 output_asm_insn (\"cmp\\t%2, %3\", operands);
3773 if (TARGET_THUMB2)
3774 {
3775 if (need_else)
3776 output_asm_insn (\"ite\\t%d5\", operands);
3777 else
3778 output_asm_insn (\"it\\t%d5\", operands);
3779 }
3780 output_asm_insn (\"%i4%d5\\t%0, %1, %2\", operands);
3781 if (need_else)
3782 output_asm_insn (\"%i4%D5\\t%0, %1, %3\", operands);
3783 return \"\";
3784 }"
3785 [(set_attr "conds" "clob")
3786 (set (attr "length")
3787 (if_then_else (eq_attr "is_thumb" "yes")
3788 (const_int 14)
3789 (const_int 12)))
3790 (set_attr "type" "multiple")]
3791 )
3792
3793 ; Reject the frame pointer in operand[1], since reloading this after
3794 ; it has been eliminated can cause carnage.
3795 (define_insn_and_split "*minmax_arithsi_non_canon"
3796 [(set (match_operand:SI 0 "s_register_operand" "=Ts,Ts")
3797 (minus:SI
3798 (match_operand:SI 1 "s_register_operand" "0,?Ts")
3799 (match_operator:SI 4 "minmax_operator"
3800 [(match_operand:SI 2 "s_register_operand" "Ts,Ts")
3801 (match_operand:SI 3 "arm_rhs_operand" "TsI,TsI")])))
3802 (clobber (reg:CC CC_REGNUM))]
3803 "TARGET_32BIT && !arm_eliminable_register (operands[1])
3804 && !(arm_restrict_it && CONST_INT_P (operands[3]))"
3805 "#"
3806 "TARGET_32BIT && !arm_eliminable_register (operands[1]) && reload_completed"
3807 [(set (reg:CC CC_REGNUM)
3808 (compare:CC (match_dup 2) (match_dup 3)))
3809
3810 (cond_exec (match_op_dup 4 [(reg:CC CC_REGNUM) (const_int 0)])
3811 (set (match_dup 0)
3812 (minus:SI (match_dup 1)
3813 (match_dup 2))))
3814 (cond_exec (match_op_dup 5 [(reg:CC CC_REGNUM) (const_int 0)])
3815 (set (match_dup 0)
3816 (match_dup 6)))]
3817 {
3818 enum machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
3819 operands[2], operands[3]);
3820 enum rtx_code rc = minmax_code (operands[4]);
3821 operands[4] = gen_rtx_fmt_ee (rc, VOIDmode,
3822 operands[2], operands[3]);
3823
3824 if (mode == CCFPmode || mode == CCFPEmode)
3825 rc = reverse_condition_maybe_unordered (rc);
3826 else
3827 rc = reverse_condition (rc);
3828 operands[5] = gen_rtx_fmt_ee (rc, SImode, operands[2], operands[3]);
3829 if (CONST_INT_P (operands[3]))
3830 operands[6] = plus_constant (SImode, operands[1], -INTVAL (operands[3]));
3831 else
3832 operands[6] = gen_rtx_MINUS (SImode, operands[1], operands[3]);
3833 }
3834 [(set_attr "conds" "clob")
3835 (set (attr "length")
3836 (if_then_else (eq_attr "is_thumb" "yes")
3837 (const_int 14)
3838 (const_int 12)))
3839 (set_attr "type" "multiple")]
3840 )
3841
3842 (define_code_iterator SAT [smin smax])
3843 (define_code_iterator SATrev [smin smax])
3844 (define_code_attr SATlo [(smin "1") (smax "2")])
3845 (define_code_attr SAThi [(smin "2") (smax "1")])
3846
3847 (define_insn "*satsi_<SAT:code>"
3848 [(set (match_operand:SI 0 "s_register_operand" "=r")
3849 (SAT:SI (SATrev:SI (match_operand:SI 3 "s_register_operand" "r")
3850 (match_operand:SI 1 "const_int_operand" "i"))
3851 (match_operand:SI 2 "const_int_operand" "i")))]
3852 "TARGET_32BIT && arm_arch6 && <SAT:CODE> != <SATrev:CODE>
3853 && arm_sat_operator_match (operands[<SAT:SATlo>], operands[<SAT:SAThi>], NULL, NULL)"
3854 {
3855 int mask;
3856 bool signed_sat;
3857 if (!arm_sat_operator_match (operands[<SAT:SATlo>], operands[<SAT:SAThi>],
3858 &mask, &signed_sat))
3859 gcc_unreachable ();
3860
3861 operands[1] = GEN_INT (mask);
3862 if (signed_sat)
3863 return "ssat%?\t%0, %1, %3";
3864 else
3865 return "usat%?\t%0, %1, %3";
3866 }
3867 [(set_attr "predicable" "yes")
3868 (set_attr "predicable_short_it" "no")
3869 (set_attr "type" "alus_imm")]
3870 )
3871
3872 (define_insn "*satsi_<SAT:code>_shift"
3873 [(set (match_operand:SI 0 "s_register_operand" "=r")
3874 (SAT:SI (SATrev:SI (match_operator:SI 3 "sat_shift_operator"
3875 [(match_operand:SI 4 "s_register_operand" "r")
3876 (match_operand:SI 5 "const_int_operand" "i")])
3877 (match_operand:SI 1 "const_int_operand" "i"))
3878 (match_operand:SI 2 "const_int_operand" "i")))]
3879 "TARGET_32BIT && arm_arch6 && <SAT:CODE> != <SATrev:CODE>
3880 && arm_sat_operator_match (operands[<SAT:SATlo>], operands[<SAT:SAThi>], NULL, NULL)"
3881 {
3882 int mask;
3883 bool signed_sat;
3884 if (!arm_sat_operator_match (operands[<SAT:SATlo>], operands[<SAT:SAThi>],
3885 &mask, &signed_sat))
3886 gcc_unreachable ();
3887
3888 operands[1] = GEN_INT (mask);
3889 if (signed_sat)
3890 return "ssat%?\t%0, %1, %4%S3";
3891 else
3892 return "usat%?\t%0, %1, %4%S3";
3893 }
3894 [(set_attr "predicable" "yes")
3895 (set_attr "predicable_short_it" "no")
3896 (set_attr "shift" "3")
3897 (set_attr "type" "logic_shift_reg")])
3898 \f
3899 ;; Shift and rotation insns
3900
3901 (define_expand "ashldi3"
3902 [(set (match_operand:DI 0 "s_register_operand" "")
3903 (ashift:DI (match_operand:DI 1 "s_register_operand" "")
3904 (match_operand:SI 2 "general_operand" "")))]
3905 "TARGET_32BIT"
3906 "
3907 if (TARGET_NEON)
3908 {
3909 /* Delay the decision whether to use NEON or core-regs until
3910 register allocation. */
3911 emit_insn (gen_ashldi3_neon (operands[0], operands[1], operands[2]));
3912 DONE;
3913 }
3914 else
3915 {
3916 /* Only the NEON case can handle in-memory shift counts. */
3917 if (!reg_or_int_operand (operands[2], SImode))
3918 operands[2] = force_reg (SImode, operands[2]);
3919 }
3920
3921 if (!CONST_INT_P (operands[2]) && TARGET_REALLY_IWMMXT)
3922 ; /* No special preparation statements; expand pattern as above. */
3923 else
3924 {
3925 rtx scratch1, scratch2;
3926
3927 if (CONST_INT_P (operands[2])
3928 && (HOST_WIDE_INT) INTVAL (operands[2]) == 1)
3929 {
3930 emit_insn (gen_arm_ashldi3_1bit (operands[0], operands[1]));
3931 DONE;
3932 }
3933
3934 /* Ideally we should use iwmmxt here if we could know that operands[1]
3935 ends up already living in an iwmmxt register. Otherwise it's
3936 cheaper to have the alternate code being generated than moving
3937 values to iwmmxt regs and back. */
3938
3939 /* If we're optimizing for size, we prefer the libgcc calls. */
3940 if (optimize_function_for_size_p (cfun))
3941 FAIL;
3942
3943 /* Expand operation using core-registers.
3944 'FAIL' would achieve the same thing, but this is a bit smarter. */
3945 scratch1 = gen_reg_rtx (SImode);
3946 scratch2 = gen_reg_rtx (SImode);
3947 arm_emit_coreregs_64bit_shift (ASHIFT, operands[0], operands[1],
3948 operands[2], scratch1, scratch2);
3949 DONE;
3950 }
3951 "
3952 )
3953
3954 (define_insn "arm_ashldi3_1bit"
3955 [(set (match_operand:DI 0 "s_register_operand" "=r,&r")
3956 (ashift:DI (match_operand:DI 1 "s_register_operand" "0,r")
3957 (const_int 1)))
3958 (clobber (reg:CC CC_REGNUM))]
3959 "TARGET_32BIT"
3960 "movs\\t%Q0, %Q1, asl #1\;adc\\t%R0, %R1, %R1"
3961 [(set_attr "conds" "clob")
3962 (set_attr "length" "8")
3963 (set_attr "type" "multiple")]
3964 )
3965
3966 (define_expand "ashlsi3"
3967 [(set (match_operand:SI 0 "s_register_operand" "")
3968 (ashift:SI (match_operand:SI 1 "s_register_operand" "")
3969 (match_operand:SI 2 "arm_rhs_operand" "")))]
3970 "TARGET_EITHER"
3971 "
3972 if (CONST_INT_P (operands[2])
3973 && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) > 31)
3974 {
3975 emit_insn (gen_movsi (operands[0], const0_rtx));
3976 DONE;
3977 }
3978 "
3979 )
3980
3981 (define_insn "*thumb1_ashlsi3"
3982 [(set (match_operand:SI 0 "register_operand" "=l,l")
3983 (ashift:SI (match_operand:SI 1 "register_operand" "l,0")
3984 (match_operand:SI 2 "nonmemory_operand" "N,l")))]
3985 "TARGET_THUMB1"
3986 "lsl\\t%0, %1, %2"
3987 [(set_attr "length" "2")
3988 (set_attr "type" "shift_imm,shift_reg")
3989 (set_attr "conds" "set")])
3990
3991 (define_expand "ashrdi3"
3992 [(set (match_operand:DI 0 "s_register_operand" "")
3993 (ashiftrt:DI (match_operand:DI 1 "s_register_operand" "")
3994 (match_operand:SI 2 "reg_or_int_operand" "")))]
3995 "TARGET_32BIT"
3996 "
3997 if (TARGET_NEON)
3998 {
3999 /* Delay the decision whether to use NEON or core-regs until
4000 register allocation. */
4001 emit_insn (gen_ashrdi3_neon (operands[0], operands[1], operands[2]));
4002 DONE;
4003 }
4004
4005 if (!CONST_INT_P (operands[2]) && TARGET_REALLY_IWMMXT)
4006 ; /* No special preparation statements; expand pattern as above. */
4007 else
4008 {
4009 rtx scratch1, scratch2;
4010
4011 if (CONST_INT_P (operands[2])
4012 && (HOST_WIDE_INT) INTVAL (operands[2]) == 1)
4013 {
4014 emit_insn (gen_arm_ashrdi3_1bit (operands[0], operands[1]));
4015 DONE;
4016 }
4017
4018 /* Ideally we should use iwmmxt here if we could know that operands[1]
4019 ends up already living in an iwmmxt register. Otherwise it's
4020 cheaper to have the alternate code being generated than moving
4021 values to iwmmxt regs and back. */
4022
4023 /* If we're optimizing for size, we prefer the libgcc calls. */
4024 if (optimize_function_for_size_p (cfun))
4025 FAIL;
4026
4027 /* Expand operation using core-registers.
4028 'FAIL' would achieve the same thing, but this is a bit smarter. */
4029 scratch1 = gen_reg_rtx (SImode);
4030 scratch2 = gen_reg_rtx (SImode);
4031 arm_emit_coreregs_64bit_shift (ASHIFTRT, operands[0], operands[1],
4032 operands[2], scratch1, scratch2);
4033 DONE;
4034 }
4035 "
4036 )
4037
4038 (define_insn "arm_ashrdi3_1bit"
4039 [(set (match_operand:DI 0 "s_register_operand" "=r,&r")
4040 (ashiftrt:DI (match_operand:DI 1 "s_register_operand" "0,r")
4041 (const_int 1)))
4042 (clobber (reg:CC CC_REGNUM))]
4043 "TARGET_32BIT"
4044 "movs\\t%R0, %R1, asr #1\;mov\\t%Q0, %Q1, rrx"
4045 [(set_attr "conds" "clob")
4046 (set_attr "length" "8")
4047 (set_attr "type" "multiple")]
4048 )
4049
4050 (define_expand "ashrsi3"
4051 [(set (match_operand:SI 0 "s_register_operand" "")
4052 (ashiftrt:SI (match_operand:SI 1 "s_register_operand" "")
4053 (match_operand:SI 2 "arm_rhs_operand" "")))]
4054 "TARGET_EITHER"
4055 "
4056 if (CONST_INT_P (operands[2])
4057 && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) > 31)
4058 operands[2] = GEN_INT (31);
4059 "
4060 )
4061
4062 (define_insn "*thumb1_ashrsi3"
4063 [(set (match_operand:SI 0 "register_operand" "=l,l")
4064 (ashiftrt:SI (match_operand:SI 1 "register_operand" "l,0")
4065 (match_operand:SI 2 "nonmemory_operand" "N,l")))]
4066 "TARGET_THUMB1"
4067 "asr\\t%0, %1, %2"
4068 [(set_attr "length" "2")
4069 (set_attr "type" "shift_imm,shift_reg")
4070 (set_attr "conds" "set")])
4071
4072 (define_expand "lshrdi3"
4073 [(set (match_operand:DI 0 "s_register_operand" "")
4074 (lshiftrt:DI (match_operand:DI 1 "s_register_operand" "")
4075 (match_operand:SI 2 "reg_or_int_operand" "")))]
4076 "TARGET_32BIT"
4077 "
4078 if (TARGET_NEON)
4079 {
4080 /* Delay the decision whether to use NEON or core-regs until
4081 register allocation. */
4082 emit_insn (gen_lshrdi3_neon (operands[0], operands[1], operands[2]));
4083 DONE;
4084 }
4085
4086 if (!CONST_INT_P (operands[2]) && TARGET_REALLY_IWMMXT)
4087 ; /* No special preparation statements; expand pattern as above. */
4088 else
4089 {
4090 rtx scratch1, scratch2;
4091
4092 if (CONST_INT_P (operands[2])
4093 && (HOST_WIDE_INT) INTVAL (operands[2]) == 1)
4094 {
4095 emit_insn (gen_arm_lshrdi3_1bit (operands[0], operands[1]));
4096 DONE;
4097 }
4098
4099 /* Ideally we should use iwmmxt here if we could know that operands[1]
4100 ends up already living in an iwmmxt register. Otherwise it's
4101 cheaper to have the alternate code being generated than moving
4102 values to iwmmxt regs and back. */
4103
4104 /* If we're optimizing for size, we prefer the libgcc calls. */
4105 if (optimize_function_for_size_p (cfun))
4106 FAIL;
4107
4108 /* Expand operation using core-registers.
4109 'FAIL' would achieve the same thing, but this is a bit smarter. */
4110 scratch1 = gen_reg_rtx (SImode);
4111 scratch2 = gen_reg_rtx (SImode);
4112 arm_emit_coreregs_64bit_shift (LSHIFTRT, operands[0], operands[1],
4113 operands[2], scratch1, scratch2);
4114 DONE;
4115 }
4116 "
4117 )
4118
4119 (define_insn "arm_lshrdi3_1bit"
4120 [(set (match_operand:DI 0 "s_register_operand" "=r,&r")
4121 (lshiftrt:DI (match_operand:DI 1 "s_register_operand" "0,r")
4122 (const_int 1)))
4123 (clobber (reg:CC CC_REGNUM))]
4124 "TARGET_32BIT"
4125 "movs\\t%R0, %R1, lsr #1\;mov\\t%Q0, %Q1, rrx"
4126 [(set_attr "conds" "clob")
4127 (set_attr "length" "8")
4128 (set_attr "type" "multiple")]
4129 )
4130
4131 (define_expand "lshrsi3"
4132 [(set (match_operand:SI 0 "s_register_operand" "")
4133 (lshiftrt:SI (match_operand:SI 1 "s_register_operand" "")
4134 (match_operand:SI 2 "arm_rhs_operand" "")))]
4135 "TARGET_EITHER"
4136 "
4137 if (CONST_INT_P (operands[2])
4138 && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) > 31)
4139 {
4140 emit_insn (gen_movsi (operands[0], const0_rtx));
4141 DONE;
4142 }
4143 "
4144 )
4145
4146 (define_insn "*thumb1_lshrsi3"
4147 [(set (match_operand:SI 0 "register_operand" "=l,l")
4148 (lshiftrt:SI (match_operand:SI 1 "register_operand" "l,0")
4149 (match_operand:SI 2 "nonmemory_operand" "N,l")))]
4150 "TARGET_THUMB1"
4151 "lsr\\t%0, %1, %2"
4152 [(set_attr "length" "2")
4153 (set_attr "type" "shift_imm,shift_reg")
4154 (set_attr "conds" "set")])
4155
4156 (define_expand "rotlsi3"
4157 [(set (match_operand:SI 0 "s_register_operand" "")
4158 (rotatert:SI (match_operand:SI 1 "s_register_operand" "")
4159 (match_operand:SI 2 "reg_or_int_operand" "")))]
4160 "TARGET_32BIT"
4161 "
4162 if (CONST_INT_P (operands[2]))
4163 operands[2] = GEN_INT ((32 - INTVAL (operands[2])) % 32);
4164 else
4165 {
4166 rtx reg = gen_reg_rtx (SImode);
4167 emit_insn (gen_subsi3 (reg, GEN_INT (32), operands[2]));
4168 operands[2] = reg;
4169 }
4170 "
4171 )
4172
4173 (define_expand "rotrsi3"
4174 [(set (match_operand:SI 0 "s_register_operand" "")
4175 (rotatert:SI (match_operand:SI 1 "s_register_operand" "")
4176 (match_operand:SI 2 "arm_rhs_operand" "")))]
4177 "TARGET_EITHER"
4178 "
4179 if (TARGET_32BIT)
4180 {
4181 if (CONST_INT_P (operands[2])
4182 && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) > 31)
4183 operands[2] = GEN_INT (INTVAL (operands[2]) % 32);
4184 }
4185 else /* TARGET_THUMB1 */
4186 {
4187 if (CONST_INT_P (operands [2]))
4188 operands [2] = force_reg (SImode, operands[2]);
4189 }
4190 "
4191 )
4192
4193 (define_insn "*thumb1_rotrsi3"
4194 [(set (match_operand:SI 0 "register_operand" "=l")
4195 (rotatert:SI (match_operand:SI 1 "register_operand" "0")
4196 (match_operand:SI 2 "register_operand" "l")))]
4197 "TARGET_THUMB1"
4198 "ror\\t%0, %0, %2"
4199 [(set_attr "type" "shift_reg")
4200 (set_attr "length" "2")]
4201 )
4202
4203 (define_insn "*arm_shiftsi3"
4204 [(set (match_operand:SI 0 "s_register_operand" "=l,l,r,r")
4205 (match_operator:SI 3 "shift_operator"
4206 [(match_operand:SI 1 "s_register_operand" "0,l,r,r")
4207 (match_operand:SI 2 "reg_or_int_operand" "l,M,M,r")]))]
4208 "TARGET_32BIT"
4209 "* return arm_output_shift(operands, 0);"
4210 [(set_attr "predicable" "yes")
4211 (set_attr "arch" "t2,t2,*,*")
4212 (set_attr "predicable_short_it" "yes,yes,no,no")
4213 (set_attr "length" "4")
4214 (set_attr "shift" "1")
4215 (set_attr "type" "alu_shift_reg,alu_shift_imm,alu_shift_imm,alu_shift_reg")]
4216 )
4217
4218 (define_insn "*shiftsi3_compare0"
4219 [(set (reg:CC_NOOV CC_REGNUM)
4220 (compare:CC_NOOV (match_operator:SI 3 "shift_operator"
4221 [(match_operand:SI 1 "s_register_operand" "r,r")
4222 (match_operand:SI 2 "arm_rhs_operand" "M,r")])
4223 (const_int 0)))
4224 (set (match_operand:SI 0 "s_register_operand" "=r,r")
4225 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))]
4226 "TARGET_32BIT"
4227 "* return arm_output_shift(operands, 1);"
4228 [(set_attr "conds" "set")
4229 (set_attr "shift" "1")
4230 (set_attr "type" "alus_shift_imm,alus_shift_reg")]
4231 )
4232
4233 (define_insn "*shiftsi3_compare0_scratch"
4234 [(set (reg:CC_NOOV CC_REGNUM)
4235 (compare:CC_NOOV (match_operator:SI 3 "shift_operator"
4236 [(match_operand:SI 1 "s_register_operand" "r,r")
4237 (match_operand:SI 2 "arm_rhs_operand" "M,r")])
4238 (const_int 0)))
4239 (clobber (match_scratch:SI 0 "=r,r"))]
4240 "TARGET_32BIT"
4241 "* return arm_output_shift(operands, 1);"
4242 [(set_attr "conds" "set")
4243 (set_attr "shift" "1")
4244 (set_attr "type" "shift_imm,shift_reg")]
4245 )
4246
4247 (define_insn "*not_shiftsi"
4248 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4249 (not:SI (match_operator:SI 3 "shift_operator"
4250 [(match_operand:SI 1 "s_register_operand" "r,r")
4251 (match_operand:SI 2 "shift_amount_operand" "M,rM")])))]
4252 "TARGET_32BIT"
4253 "mvn%?\\t%0, %1%S3"
4254 [(set_attr "predicable" "yes")
4255 (set_attr "predicable_short_it" "no")
4256 (set_attr "shift" "1")
4257 (set_attr "arch" "32,a")
4258 (set_attr "type" "mvn_shift,mvn_shift_reg")])
4259
4260 (define_insn "*not_shiftsi_compare0"
4261 [(set (reg:CC_NOOV CC_REGNUM)
4262 (compare:CC_NOOV
4263 (not:SI (match_operator:SI 3 "shift_operator"
4264 [(match_operand:SI 1 "s_register_operand" "r,r")
4265 (match_operand:SI 2 "shift_amount_operand" "M,rM")]))
4266 (const_int 0)))
4267 (set (match_operand:SI 0 "s_register_operand" "=r,r")
4268 (not:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)])))]
4269 "TARGET_32BIT"
4270 "mvn%.\\t%0, %1%S3"
4271 [(set_attr "conds" "set")
4272 (set_attr "shift" "1")
4273 (set_attr "arch" "32,a")
4274 (set_attr "type" "mvn_shift,mvn_shift_reg")])
4275
4276 (define_insn "*not_shiftsi_compare0_scratch"
4277 [(set (reg:CC_NOOV CC_REGNUM)
4278 (compare:CC_NOOV
4279 (not:SI (match_operator:SI 3 "shift_operator"
4280 [(match_operand:SI 1 "s_register_operand" "r,r")
4281 (match_operand:SI 2 "shift_amount_operand" "M,rM")]))
4282 (const_int 0)))
4283 (clobber (match_scratch:SI 0 "=r,r"))]
4284 "TARGET_32BIT"
4285 "mvn%.\\t%0, %1%S3"
4286 [(set_attr "conds" "set")
4287 (set_attr "shift" "1")
4288 (set_attr "arch" "32,a")
4289 (set_attr "type" "mvn_shift,mvn_shift_reg")])
4290
4291 ;; We don't really have extzv, but defining this using shifts helps
4292 ;; to reduce register pressure later on.
4293
4294 (define_expand "extzv"
4295 [(set (match_operand 0 "s_register_operand" "")
4296 (zero_extract (match_operand 1 "nonimmediate_operand" "")
4297 (match_operand 2 "const_int_operand" "")
4298 (match_operand 3 "const_int_operand" "")))]
4299 "TARGET_THUMB1 || arm_arch_thumb2"
4300 "
4301 {
4302 HOST_WIDE_INT lshift = 32 - INTVAL (operands[2]) - INTVAL (operands[3]);
4303 HOST_WIDE_INT rshift = 32 - INTVAL (operands[2]);
4304
4305 if (arm_arch_thumb2)
4306 {
4307 HOST_WIDE_INT width = INTVAL (operands[2]);
4308 HOST_WIDE_INT bitpos = INTVAL (operands[3]);
4309
4310 if (unaligned_access && MEM_P (operands[1])
4311 && (width == 16 || width == 32) && (bitpos % BITS_PER_UNIT) == 0)
4312 {
4313 rtx base_addr;
4314
4315 if (BYTES_BIG_ENDIAN)
4316 bitpos = GET_MODE_BITSIZE (GET_MODE (operands[0])) - width
4317 - bitpos;
4318
4319 if (width == 32)
4320 {
4321 base_addr = adjust_address (operands[1], SImode,
4322 bitpos / BITS_PER_UNIT);
4323 emit_insn (gen_unaligned_loadsi (operands[0], base_addr));
4324 }
4325 else
4326 {
4327 rtx dest = operands[0];
4328 rtx tmp = gen_reg_rtx (SImode);
4329
4330 /* We may get a paradoxical subreg here. Strip it off. */
4331 if (GET_CODE (dest) == SUBREG
4332 && GET_MODE (dest) == SImode
4333 && GET_MODE (SUBREG_REG (dest)) == HImode)
4334 dest = SUBREG_REG (dest);
4335
4336 if (GET_MODE_BITSIZE (GET_MODE (dest)) != width)
4337 FAIL;
4338
4339 base_addr = adjust_address (operands[1], HImode,
4340 bitpos / BITS_PER_UNIT);
4341 emit_insn (gen_unaligned_loadhiu (tmp, base_addr));
4342 emit_move_insn (gen_lowpart (SImode, dest), tmp);
4343 }
4344 DONE;
4345 }
4346 else if (s_register_operand (operands[1], GET_MODE (operands[1])))
4347 {
4348 emit_insn (gen_extzv_t2 (operands[0], operands[1], operands[2],
4349 operands[3]));
4350 DONE;
4351 }
4352 else
4353 FAIL;
4354 }
4355
4356 if (!s_register_operand (operands[1], GET_MODE (operands[1])))
4357 FAIL;
4358
4359 operands[3] = GEN_INT (rshift);
4360
4361 if (lshift == 0)
4362 {
4363 emit_insn (gen_lshrsi3 (operands[0], operands[1], operands[3]));
4364 DONE;
4365 }
4366
4367 emit_insn (gen_extzv_t1 (operands[0], operands[1], GEN_INT (lshift),
4368 operands[3], gen_reg_rtx (SImode)));
4369 DONE;
4370 }"
4371 )
4372
4373 ;; Helper for extzv, for the Thumb-1 register-shifts case.
4374
4375 (define_expand "extzv_t1"
4376 [(set (match_operand:SI 4 "s_register_operand" "")
4377 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
4378 (match_operand:SI 2 "const_int_operand" "")))
4379 (set (match_operand:SI 0 "s_register_operand" "")
4380 (lshiftrt:SI (match_dup 4)
4381 (match_operand:SI 3 "const_int_operand" "")))]
4382 "TARGET_THUMB1"
4383 "")
4384
4385 (define_expand "extv"
4386 [(set (match_operand 0 "s_register_operand" "")
4387 (sign_extract (match_operand 1 "nonimmediate_operand" "")
4388 (match_operand 2 "const_int_operand" "")
4389 (match_operand 3 "const_int_operand" "")))]
4390 "arm_arch_thumb2"
4391 {
4392 HOST_WIDE_INT width = INTVAL (operands[2]);
4393 HOST_WIDE_INT bitpos = INTVAL (operands[3]);
4394
4395 if (unaligned_access && MEM_P (operands[1]) && (width == 16 || width == 32)
4396 && (bitpos % BITS_PER_UNIT) == 0)
4397 {
4398 rtx base_addr;
4399
4400 if (BYTES_BIG_ENDIAN)
4401 bitpos = GET_MODE_BITSIZE (GET_MODE (operands[0])) - width - bitpos;
4402
4403 if (width == 32)
4404 {
4405 base_addr = adjust_address (operands[1], SImode,
4406 bitpos / BITS_PER_UNIT);
4407 emit_insn (gen_unaligned_loadsi (operands[0], base_addr));
4408 }
4409 else
4410 {
4411 rtx dest = operands[0];
4412 rtx tmp = gen_reg_rtx (SImode);
4413
4414 /* We may get a paradoxical subreg here. Strip it off. */
4415 if (GET_CODE (dest) == SUBREG
4416 && GET_MODE (dest) == SImode
4417 && GET_MODE (SUBREG_REG (dest)) == HImode)
4418 dest = SUBREG_REG (dest);
4419
4420 if (GET_MODE_BITSIZE (GET_MODE (dest)) != width)
4421 FAIL;
4422
4423 base_addr = adjust_address (operands[1], HImode,
4424 bitpos / BITS_PER_UNIT);
4425 emit_insn (gen_unaligned_loadhis (tmp, base_addr));
4426 emit_move_insn (gen_lowpart (SImode, dest), tmp);
4427 }
4428
4429 DONE;
4430 }
4431 else if (!s_register_operand (operands[1], GET_MODE (operands[1])))
4432 FAIL;
4433 else if (GET_MODE (operands[0]) == SImode
4434 && GET_MODE (operands[1]) == SImode)
4435 {
4436 emit_insn (gen_extv_regsi (operands[0], operands[1], operands[2],
4437 operands[3]));
4438 DONE;
4439 }
4440
4441 FAIL;
4442 })
4443
4444 ; Helper to expand register forms of extv with the proper modes.
4445
4446 (define_expand "extv_regsi"
4447 [(set (match_operand:SI 0 "s_register_operand" "")
4448 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "")
4449 (match_operand 2 "const_int_operand" "")
4450 (match_operand 3 "const_int_operand" "")))]
4451 ""
4452 {
4453 })
4454
4455 ; ARMv6+ unaligned load/store instructions (used for packed structure accesses).
4456
4457 (define_insn "unaligned_loadsi"
4458 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
4459 (unspec:SI [(match_operand:SI 1 "memory_operand" "Uw,m")]
4460 UNSPEC_UNALIGNED_LOAD))]
4461 "unaligned_access && TARGET_32BIT"
4462 "ldr%?\t%0, %1\t@ unaligned"
4463 [(set_attr "arch" "t2,any")
4464 (set_attr "length" "2,4")
4465 (set_attr "predicable" "yes")
4466 (set_attr "predicable_short_it" "yes,no")
4467 (set_attr "type" "load1")])
4468
4469 (define_insn "unaligned_loadhis"
4470 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
4471 (sign_extend:SI
4472 (unspec:HI [(match_operand:HI 1 "memory_operand" "Uw,m")]
4473 UNSPEC_UNALIGNED_LOAD)))]
4474 "unaligned_access && TARGET_32BIT"
4475 "ldr%(sh%)\t%0, %1\t@ unaligned"
4476 [(set_attr "arch" "t2,any")
4477 (set_attr "length" "2,4")
4478 (set_attr "predicable" "yes")
4479 (set_attr "predicable_short_it" "yes,no")
4480 (set_attr "type" "load_byte")])
4481
4482 (define_insn "unaligned_loadhiu"
4483 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
4484 (zero_extend:SI
4485 (unspec:HI [(match_operand:HI 1 "memory_operand" "Uw,m")]
4486 UNSPEC_UNALIGNED_LOAD)))]
4487 "unaligned_access && TARGET_32BIT"
4488 "ldr%(h%)\t%0, %1\t@ unaligned"
4489 [(set_attr "arch" "t2,any")
4490 (set_attr "length" "2,4")
4491 (set_attr "predicable" "yes")
4492 (set_attr "predicable_short_it" "yes,no")
4493 (set_attr "type" "load_byte")])
4494
4495 (define_insn "unaligned_storesi"
4496 [(set (match_operand:SI 0 "memory_operand" "=Uw,m")
4497 (unspec:SI [(match_operand:SI 1 "s_register_operand" "l,r")]
4498 UNSPEC_UNALIGNED_STORE))]
4499 "unaligned_access && TARGET_32BIT"
4500 "str%?\t%1, %0\t@ unaligned"
4501 [(set_attr "arch" "t2,any")
4502 (set_attr "length" "2,4")
4503 (set_attr "predicable" "yes")
4504 (set_attr "predicable_short_it" "yes,no")
4505 (set_attr "type" "store1")])
4506
4507 (define_insn "unaligned_storehi"
4508 [(set (match_operand:HI 0 "memory_operand" "=Uw,m")
4509 (unspec:HI [(match_operand:HI 1 "s_register_operand" "l,r")]
4510 UNSPEC_UNALIGNED_STORE))]
4511 "unaligned_access && TARGET_32BIT"
4512 "str%(h%)\t%1, %0\t@ unaligned"
4513 [(set_attr "arch" "t2,any")
4514 (set_attr "length" "2,4")
4515 (set_attr "predicable" "yes")
4516 (set_attr "predicable_short_it" "yes,no")
4517 (set_attr "type" "store1")])
4518
4519 ;; Unaligned double-word load and store.
4520 ;; Split after reload into two unaligned single-word accesses.
4521 ;; It prevents lower_subreg from splitting some other aligned
4522 ;; double-word accesses too early. Used for internal memcpy.
4523
4524 (define_insn_and_split "unaligned_loaddi"
4525 [(set (match_operand:DI 0 "s_register_operand" "=l,r")
4526 (unspec:DI [(match_operand:DI 1 "memory_operand" "o,o")]
4527 UNSPEC_UNALIGNED_LOAD))]
4528 "unaligned_access && TARGET_32BIT"
4529 "#"
4530 "&& reload_completed"
4531 [(set (match_dup 0) (unspec:SI [(match_dup 1)] UNSPEC_UNALIGNED_LOAD))
4532 (set (match_dup 2) (unspec:SI [(match_dup 3)] UNSPEC_UNALIGNED_LOAD))]
4533 {
4534 operands[2] = gen_highpart (SImode, operands[0]);
4535 operands[0] = gen_lowpart (SImode, operands[0]);
4536 operands[3] = gen_highpart (SImode, operands[1]);
4537 operands[1] = gen_lowpart (SImode, operands[1]);
4538
4539 /* If the first destination register overlaps with the base address,
4540 swap the order in which the loads are emitted. */
4541 if (reg_overlap_mentioned_p (operands[0], operands[1]))
4542 {
4543 rtx tmp = operands[1];
4544 operands[1] = operands[3];
4545 operands[3] = tmp;
4546 tmp = operands[0];
4547 operands[0] = operands[2];
4548 operands[2] = tmp;
4549 }
4550 }
4551 [(set_attr "arch" "t2,any")
4552 (set_attr "length" "4,8")
4553 (set_attr "predicable" "yes")
4554 (set_attr "type" "load2")])
4555
4556 (define_insn_and_split "unaligned_storedi"
4557 [(set (match_operand:DI 0 "memory_operand" "=o,o")
4558 (unspec:DI [(match_operand:DI 1 "s_register_operand" "l,r")]
4559 UNSPEC_UNALIGNED_STORE))]
4560 "unaligned_access && TARGET_32BIT"
4561 "#"
4562 "&& reload_completed"
4563 [(set (match_dup 0) (unspec:SI [(match_dup 1)] UNSPEC_UNALIGNED_STORE))
4564 (set (match_dup 2) (unspec:SI [(match_dup 3)] UNSPEC_UNALIGNED_STORE))]
4565 {
4566 operands[2] = gen_highpart (SImode, operands[0]);
4567 operands[0] = gen_lowpart (SImode, operands[0]);
4568 operands[3] = gen_highpart (SImode, operands[1]);
4569 operands[1] = gen_lowpart (SImode, operands[1]);
4570 }
4571 [(set_attr "arch" "t2,any")
4572 (set_attr "length" "4,8")
4573 (set_attr "predicable" "yes")
4574 (set_attr "type" "store2")])
4575
4576
4577 (define_insn "*extv_reg"
4578 [(set (match_operand:SI 0 "s_register_operand" "=r")
4579 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
4580 (match_operand:SI 2 "const_int_operand" "M")
4581 (match_operand:SI 3 "const_int_operand" "M")))]
4582 "arm_arch_thumb2"
4583 "sbfx%?\t%0, %1, %3, %2"
4584 [(set_attr "length" "4")
4585 (set_attr "predicable" "yes")
4586 (set_attr "predicable_short_it" "no")
4587 (set_attr "type" "bfm")]
4588 )
4589
4590 (define_insn "extzv_t2"
4591 [(set (match_operand:SI 0 "s_register_operand" "=r")
4592 (zero_extract:SI (match_operand:SI 1 "s_register_operand" "r")
4593 (match_operand:SI 2 "const_int_operand" "M")
4594 (match_operand:SI 3 "const_int_operand" "M")))]
4595 "arm_arch_thumb2"
4596 "ubfx%?\t%0, %1, %3, %2"
4597 [(set_attr "length" "4")
4598 (set_attr "predicable" "yes")
4599 (set_attr "predicable_short_it" "no")
4600 (set_attr "type" "bfm")]
4601 )
4602
4603
4604 ;; Division instructions
4605 (define_insn "divsi3"
4606 [(set (match_operand:SI 0 "s_register_operand" "=r")
4607 (div:SI (match_operand:SI 1 "s_register_operand" "r")
4608 (match_operand:SI 2 "s_register_operand" "r")))]
4609 "TARGET_IDIV"
4610 "sdiv%?\t%0, %1, %2"
4611 [(set_attr "predicable" "yes")
4612 (set_attr "predicable_short_it" "no")
4613 (set_attr "type" "sdiv")]
4614 )
4615
4616 (define_insn "udivsi3"
4617 [(set (match_operand:SI 0 "s_register_operand" "=r")
4618 (udiv:SI (match_operand:SI 1 "s_register_operand" "r")
4619 (match_operand:SI 2 "s_register_operand" "r")))]
4620 "TARGET_IDIV"
4621 "udiv%?\t%0, %1, %2"
4622 [(set_attr "predicable" "yes")
4623 (set_attr "predicable_short_it" "no")
4624 (set_attr "type" "udiv")]
4625 )
4626
4627 \f
4628 ;; Unary arithmetic insns
4629
4630 (define_expand "negdi2"
4631 [(parallel
4632 [(set (match_operand:DI 0 "s_register_operand" "")
4633 (neg:DI (match_operand:DI 1 "s_register_operand" "")))
4634 (clobber (reg:CC CC_REGNUM))])]
4635 "TARGET_EITHER"
4636 {
4637 if (TARGET_NEON)
4638 {
4639 emit_insn (gen_negdi2_neon (operands[0], operands[1]));
4640 DONE;
4641 }
4642 }
4643 )
4644
4645 ;; The constraints here are to prevent a *partial* overlap (where %Q0 == %R1).
4646 ;; The first alternative allows the common case of a *full* overlap.
4647 (define_insn_and_split "*arm_negdi2"
4648 [(set (match_operand:DI 0 "s_register_operand" "=r,&r")
4649 (neg:DI (match_operand:DI 1 "s_register_operand" "0,r")))
4650 (clobber (reg:CC CC_REGNUM))]
4651 "TARGET_ARM"
4652 "#" ; "rsbs\\t%Q0, %Q1, #0\;rsc\\t%R0, %R1, #0"
4653 "&& reload_completed"
4654 [(parallel [(set (reg:CC CC_REGNUM)
4655 (compare:CC (const_int 0) (match_dup 1)))
4656 (set (match_dup 0) (minus:SI (const_int 0) (match_dup 1)))])
4657 (set (match_dup 2) (minus:SI (minus:SI (const_int 0) (match_dup 3))
4658 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
4659 {
4660 operands[2] = gen_highpart (SImode, operands[0]);
4661 operands[0] = gen_lowpart (SImode, operands[0]);
4662 operands[3] = gen_highpart (SImode, operands[1]);
4663 operands[1] = gen_lowpart (SImode, operands[1]);
4664 }
4665 [(set_attr "conds" "clob")
4666 (set_attr "length" "8")
4667 (set_attr "type" "multiple")]
4668 )
4669
4670 (define_insn "*thumb1_negdi2"
4671 [(set (match_operand:DI 0 "register_operand" "=&l")
4672 (neg:DI (match_operand:DI 1 "register_operand" "l")))
4673 (clobber (reg:CC CC_REGNUM))]
4674 "TARGET_THUMB1"
4675 "mov\\t%R0, #0\;neg\\t%Q0, %Q1\;sbc\\t%R0, %R1"
4676 [(set_attr "length" "6")
4677 (set_attr "type" "multiple")]
4678 )
4679
4680 (define_expand "negsi2"
4681 [(set (match_operand:SI 0 "s_register_operand" "")
4682 (neg:SI (match_operand:SI 1 "s_register_operand" "")))]
4683 "TARGET_EITHER"
4684 ""
4685 )
4686
4687 (define_insn "*arm_negsi2"
4688 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
4689 (neg:SI (match_operand:SI 1 "s_register_operand" "l,r")))]
4690 "TARGET_32BIT"
4691 "rsb%?\\t%0, %1, #0"
4692 [(set_attr "predicable" "yes")
4693 (set_attr "predicable_short_it" "yes,no")
4694 (set_attr "arch" "t2,*")
4695 (set_attr "length" "4")
4696 (set_attr "type" "alu_reg")]
4697 )
4698
4699 (define_insn "*thumb1_negsi2"
4700 [(set (match_operand:SI 0 "register_operand" "=l")
4701 (neg:SI (match_operand:SI 1 "register_operand" "l")))]
4702 "TARGET_THUMB1"
4703 "neg\\t%0, %1"
4704 [(set_attr "length" "2")
4705 (set_attr "type" "alu_imm")]
4706 )
4707
4708 (define_expand "negsf2"
4709 [(set (match_operand:SF 0 "s_register_operand" "")
4710 (neg:SF (match_operand:SF 1 "s_register_operand" "")))]
4711 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
4712 ""
4713 )
4714
4715 (define_expand "negdf2"
4716 [(set (match_operand:DF 0 "s_register_operand" "")
4717 (neg:DF (match_operand:DF 1 "s_register_operand" "")))]
4718 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
4719 "")
4720
4721 (define_insn_and_split "*zextendsidi_negsi"
4722 [(set (match_operand:DI 0 "s_register_operand" "=r")
4723 (zero_extend:DI (neg:SI (match_operand:SI 1 "s_register_operand" "r"))))]
4724 "TARGET_32BIT"
4725 "#"
4726 ""
4727 [(set (match_dup 2)
4728 (neg:SI (match_dup 1)))
4729 (set (match_dup 3)
4730 (const_int 0))]
4731 {
4732 operands[2] = gen_lowpart (SImode, operands[0]);
4733 operands[3] = gen_highpart (SImode, operands[0]);
4734 }
4735 [(set_attr "length" "8")
4736 (set_attr "type" "multiple")]
4737 )
4738
4739 ;; Negate an extended 32-bit value.
4740 (define_insn_and_split "*negdi_extendsidi"
4741 [(set (match_operand:DI 0 "s_register_operand" "=l,r")
4742 (neg:DI (sign_extend:DI
4743 (match_operand:SI 1 "s_register_operand" "l,r"))))
4744 (clobber (reg:CC CC_REGNUM))]
4745 "TARGET_32BIT"
4746 "#"
4747 "&& reload_completed"
4748 [(const_int 0)]
4749 {
4750 rtx low = gen_lowpart (SImode, operands[0]);
4751 rtx high = gen_highpart (SImode, operands[0]);
4752
4753 if (reg_overlap_mentioned_p (low, operands[1]))
4754 {
4755 /* Input overlaps the low word of the output. Use:
4756 asr Rhi, Rin, #31
4757 rsbs Rlo, Rin, #0
4758 rsc Rhi, Rhi, #0 (thumb2: sbc Rhi, Rhi, Rhi, lsl #1). */
4759 rtx cc_reg = gen_rtx_REG (CC_Cmode, CC_REGNUM);
4760
4761 emit_insn (gen_rtx_SET (VOIDmode, high,
4762 gen_rtx_ASHIFTRT (SImode, operands[1],
4763 GEN_INT (31))));
4764
4765 emit_insn (gen_subsi3_compare (low, const0_rtx, operands[1]));
4766 if (TARGET_ARM)
4767 emit_insn (gen_rtx_SET (VOIDmode, high,
4768 gen_rtx_MINUS (SImode,
4769 gen_rtx_MINUS (SImode,
4770 const0_rtx,
4771 high),
4772 gen_rtx_LTU (SImode,
4773 cc_reg,
4774 const0_rtx))));
4775 else
4776 {
4777 rtx two_x = gen_rtx_ASHIFT (SImode, high, GEN_INT (1));
4778 emit_insn (gen_rtx_SET (VOIDmode, high,
4779 gen_rtx_MINUS (SImode,
4780 gen_rtx_MINUS (SImode,
4781 high,
4782 two_x),
4783 gen_rtx_LTU (SImode,
4784 cc_reg,
4785 const0_rtx))));
4786 }
4787 }
4788 else
4789 {
4790 /* No overlap, or overlap on high word. Use:
4791 rsb Rlo, Rin, #0
4792 bic Rhi, Rlo, Rin
4793 asr Rhi, Rhi, #31
4794 Flags not needed for this sequence. */
4795 emit_insn (gen_rtx_SET (VOIDmode, low,
4796 gen_rtx_NEG (SImode, operands[1])));
4797 emit_insn (gen_rtx_SET (VOIDmode, high,
4798 gen_rtx_AND (SImode,
4799 gen_rtx_NOT (SImode, operands[1]),
4800 low)));
4801 emit_insn (gen_rtx_SET (VOIDmode, high,
4802 gen_rtx_ASHIFTRT (SImode, high,
4803 GEN_INT (31))));
4804 }
4805 DONE;
4806 }
4807 [(set_attr "length" "12")
4808 (set_attr "arch" "t2,*")
4809 (set_attr "type" "multiple")]
4810 )
4811
4812 (define_insn_and_split "*negdi_zero_extendsidi"
4813 [(set (match_operand:DI 0 "s_register_operand" "=r,&r")
4814 (neg:DI (zero_extend:DI (match_operand:SI 1 "s_register_operand" "0,r"))))
4815 (clobber (reg:CC CC_REGNUM))]
4816 "TARGET_32BIT"
4817 "#" ; "rsbs\\t%Q0, %1, #0\;sbc\\t%R0,%R0,%R0"
4818 ;; Don't care what register is input to sbc,
4819 ;; since we just just need to propagate the carry.
4820 "&& reload_completed"
4821 [(parallel [(set (reg:CC CC_REGNUM)
4822 (compare:CC (const_int 0) (match_dup 1)))
4823 (set (match_dup 0) (minus:SI (const_int 0) (match_dup 1)))])
4824 (set (match_dup 2) (minus:SI (minus:SI (match_dup 2) (match_dup 2))
4825 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
4826 {
4827 operands[2] = gen_highpart (SImode, operands[0]);
4828 operands[0] = gen_lowpart (SImode, operands[0]);
4829 }
4830 [(set_attr "conds" "clob")
4831 (set_attr "length" "8")
4832 (set_attr "type" "multiple")] ;; length in thumb is 4
4833 )
4834
4835 ;; abssi2 doesn't really clobber the condition codes if a different register
4836 ;; is being set. To keep things simple, assume during rtl manipulations that
4837 ;; it does, but tell the final scan operator the truth. Similarly for
4838 ;; (neg (abs...))
4839
4840 (define_expand "abssi2"
4841 [(parallel
4842 [(set (match_operand:SI 0 "s_register_operand" "")
4843 (abs:SI (match_operand:SI 1 "s_register_operand" "")))
4844 (clobber (match_dup 2))])]
4845 "TARGET_EITHER"
4846 "
4847 if (TARGET_THUMB1)
4848 operands[2] = gen_rtx_SCRATCH (SImode);
4849 else
4850 operands[2] = gen_rtx_REG (CCmode, CC_REGNUM);
4851 ")
4852
4853 (define_insn_and_split "*arm_abssi2"
4854 [(set (match_operand:SI 0 "s_register_operand" "=r,&r")
4855 (abs:SI (match_operand:SI 1 "s_register_operand" "0,r")))
4856 (clobber (reg:CC CC_REGNUM))]
4857 "TARGET_ARM"
4858 "#"
4859 "&& reload_completed"
4860 [(const_int 0)]
4861 {
4862 /* if (which_alternative == 0) */
4863 if (REGNO(operands[0]) == REGNO(operands[1]))
4864 {
4865 /* Emit the pattern:
4866 cmp\\t%0, #0\;rsblt\\t%0, %0, #0
4867 [(set (reg:CC CC_REGNUM)
4868 (compare:CC (match_dup 0) (const_int 0)))
4869 (cond_exec (lt:CC (reg:CC CC_REGNUM) (const_int 0))
4870 (set (match_dup 0) (minus:SI (const_int 0) (match_dup 1))))]
4871 */
4872 emit_insn (gen_rtx_SET (VOIDmode,
4873 gen_rtx_REG (CCmode, CC_REGNUM),
4874 gen_rtx_COMPARE (CCmode, operands[0], const0_rtx)));
4875 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
4876 (gen_rtx_LT (SImode,
4877 gen_rtx_REG (CCmode, CC_REGNUM),
4878 const0_rtx)),
4879 (gen_rtx_SET (VOIDmode,
4880 operands[0],
4881 (gen_rtx_MINUS (SImode,
4882 const0_rtx,
4883 operands[1]))))));
4884 DONE;
4885 }
4886 else
4887 {
4888 /* Emit the pattern:
4889 alt1: eor%?\\t%0, %1, %1, asr #31\;sub%?\\t%0, %0, %1, asr #31
4890 [(set (match_dup 0)
4891 (xor:SI (match_dup 1)
4892 (ashiftrt:SI (match_dup 1) (const_int 31))))
4893 (set (match_dup 0)
4894 (minus:SI (match_dup 0)
4895 (ashiftrt:SI (match_dup 1) (const_int 31))))]
4896 */
4897 emit_insn (gen_rtx_SET (VOIDmode,
4898 operands[0],
4899 gen_rtx_XOR (SImode,
4900 gen_rtx_ASHIFTRT (SImode,
4901 operands[1],
4902 GEN_INT (31)),
4903 operands[1])));
4904 emit_insn (gen_rtx_SET (VOIDmode,
4905 operands[0],
4906 gen_rtx_MINUS (SImode,
4907 operands[0],
4908 gen_rtx_ASHIFTRT (SImode,
4909 operands[1],
4910 GEN_INT (31)))));
4911 DONE;
4912 }
4913 }
4914 [(set_attr "conds" "clob,*")
4915 (set_attr "shift" "1")
4916 (set_attr "predicable" "no, yes")
4917 (set_attr "length" "8")
4918 (set_attr "type" "multiple")]
4919 )
4920
4921 (define_insn_and_split "*thumb1_abssi2"
4922 [(set (match_operand:SI 0 "s_register_operand" "=l")
4923 (abs:SI (match_operand:SI 1 "s_register_operand" "l")))
4924 (clobber (match_scratch:SI 2 "=&l"))]
4925 "TARGET_THUMB1"
4926 "#"
4927 "TARGET_THUMB1 && reload_completed"
4928 [(set (match_dup 2) (ashiftrt:SI (match_dup 1) (const_int 31)))
4929 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))
4930 (set (match_dup 0) (xor:SI (match_dup 0) (match_dup 2)))]
4931 ""
4932 [(set_attr "length" "6")
4933 (set_attr "type" "multiple")]
4934 )
4935
4936 (define_insn_and_split "*arm_neg_abssi2"
4937 [(set (match_operand:SI 0 "s_register_operand" "=r,&r")
4938 (neg:SI (abs:SI (match_operand:SI 1 "s_register_operand" "0,r"))))
4939 (clobber (reg:CC CC_REGNUM))]
4940 "TARGET_ARM"
4941 "#"
4942 "&& reload_completed"
4943 [(const_int 0)]
4944 {
4945 /* if (which_alternative == 0) */
4946 if (REGNO (operands[0]) == REGNO (operands[1]))
4947 {
4948 /* Emit the pattern:
4949 cmp\\t%0, #0\;rsbgt\\t%0, %0, #0
4950 */
4951 emit_insn (gen_rtx_SET (VOIDmode,
4952 gen_rtx_REG (CCmode, CC_REGNUM),
4953 gen_rtx_COMPARE (CCmode, operands[0], const0_rtx)));
4954 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
4955 gen_rtx_GT (SImode,
4956 gen_rtx_REG (CCmode, CC_REGNUM),
4957 const0_rtx),
4958 gen_rtx_SET (VOIDmode,
4959 operands[0],
4960 (gen_rtx_MINUS (SImode,
4961 const0_rtx,
4962 operands[1])))));
4963 }
4964 else
4965 {
4966 /* Emit the pattern:
4967 eor%?\\t%0, %1, %1, asr #31\;rsb%?\\t%0, %0, %1, asr #31
4968 */
4969 emit_insn (gen_rtx_SET (VOIDmode,
4970 operands[0],
4971 gen_rtx_XOR (SImode,
4972 gen_rtx_ASHIFTRT (SImode,
4973 operands[1],
4974 GEN_INT (31)),
4975 operands[1])));
4976 emit_insn (gen_rtx_SET (VOIDmode,
4977 operands[0],
4978 gen_rtx_MINUS (SImode,
4979 gen_rtx_ASHIFTRT (SImode,
4980 operands[1],
4981 GEN_INT (31)),
4982 operands[0])));
4983 }
4984 DONE;
4985 }
4986 [(set_attr "conds" "clob,*")
4987 (set_attr "shift" "1")
4988 (set_attr "predicable" "no, yes")
4989 (set_attr "length" "8")
4990 (set_attr "type" "multiple")]
4991 )
4992
4993 (define_insn_and_split "*thumb1_neg_abssi2"
4994 [(set (match_operand:SI 0 "s_register_operand" "=l")
4995 (neg:SI (abs:SI (match_operand:SI 1 "s_register_operand" "l"))))
4996 (clobber (match_scratch:SI 2 "=&l"))]
4997 "TARGET_THUMB1"
4998 "#"
4999 "TARGET_THUMB1 && reload_completed"
5000 [(set (match_dup 2) (ashiftrt:SI (match_dup 1) (const_int 31)))
5001 (set (match_dup 0) (minus:SI (match_dup 2) (match_dup 1)))
5002 (set (match_dup 0) (xor:SI (match_dup 0) (match_dup 2)))]
5003 ""
5004 [(set_attr "length" "6")
5005 (set_attr "type" "multiple")]
5006 )
5007
5008 (define_expand "abssf2"
5009 [(set (match_operand:SF 0 "s_register_operand" "")
5010 (abs:SF (match_operand:SF 1 "s_register_operand" "")))]
5011 "TARGET_32BIT && TARGET_HARD_FLOAT"
5012 "")
5013
5014 (define_expand "absdf2"
5015 [(set (match_operand:DF 0 "s_register_operand" "")
5016 (abs:DF (match_operand:DF 1 "s_register_operand" "")))]
5017 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
5018 "")
5019
5020 (define_expand "sqrtsf2"
5021 [(set (match_operand:SF 0 "s_register_operand" "")
5022 (sqrt:SF (match_operand:SF 1 "s_register_operand" "")))]
5023 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
5024 "")
5025
5026 (define_expand "sqrtdf2"
5027 [(set (match_operand:DF 0 "s_register_operand" "")
5028 (sqrt:DF (match_operand:DF 1 "s_register_operand" "")))]
5029 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
5030 "")
5031
5032 (define_insn_and_split "one_cmpldi2"
5033 [(set (match_operand:DI 0 "s_register_operand" "=w,&r,&r,?w")
5034 (not:DI (match_operand:DI 1 "s_register_operand" " w, 0, r, w")))]
5035 "TARGET_32BIT"
5036 "@
5037 vmvn\t%P0, %P1
5038 #
5039 #
5040 vmvn\t%P0, %P1"
5041 "TARGET_32BIT && reload_completed
5042 && arm_general_register_operand (operands[0], DImode)"
5043 [(set (match_dup 0) (not:SI (match_dup 1)))
5044 (set (match_dup 2) (not:SI (match_dup 3)))]
5045 "
5046 {
5047 operands[2] = gen_highpart (SImode, operands[0]);
5048 operands[0] = gen_lowpart (SImode, operands[0]);
5049 operands[3] = gen_highpart (SImode, operands[1]);
5050 operands[1] = gen_lowpart (SImode, operands[1]);
5051 }"
5052 [(set_attr "length" "*,8,8,*")
5053 (set_attr "predicable" "no,yes,yes,no")
5054 (set_attr "type" "neon_move,multiple,multiple,neon_move")
5055 (set_attr "arch" "neon_for_64bits,*,*,avoid_neon_for_64bits")]
5056 )
5057
5058 (define_expand "one_cmplsi2"
5059 [(set (match_operand:SI 0 "s_register_operand" "")
5060 (not:SI (match_operand:SI 1 "s_register_operand" "")))]
5061 "TARGET_EITHER"
5062 ""
5063 )
5064
5065 (define_insn "*arm_one_cmplsi2"
5066 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
5067 (not:SI (match_operand:SI 1 "s_register_operand" "l,r")))]
5068 "TARGET_32BIT"
5069 "mvn%?\\t%0, %1"
5070 [(set_attr "predicable" "yes")
5071 (set_attr "predicable_short_it" "yes,no")
5072 (set_attr "arch" "t2,*")
5073 (set_attr "length" "4")
5074 (set_attr "type" "mvn_reg")]
5075 )
5076
5077 (define_insn "*thumb1_one_cmplsi2"
5078 [(set (match_operand:SI 0 "register_operand" "=l")
5079 (not:SI (match_operand:SI 1 "register_operand" "l")))]
5080 "TARGET_THUMB1"
5081 "mvn\\t%0, %1"
5082 [(set_attr "length" "2")
5083 (set_attr "type" "mvn_reg")]
5084 )
5085
5086 (define_insn "*notsi_compare0"
5087 [(set (reg:CC_NOOV CC_REGNUM)
5088 (compare:CC_NOOV (not:SI (match_operand:SI 1 "s_register_operand" "r"))
5089 (const_int 0)))
5090 (set (match_operand:SI 0 "s_register_operand" "=r")
5091 (not:SI (match_dup 1)))]
5092 "TARGET_32BIT"
5093 "mvn%.\\t%0, %1"
5094 [(set_attr "conds" "set")
5095 (set_attr "type" "mvn_reg")]
5096 )
5097
5098 (define_insn "*notsi_compare0_scratch"
5099 [(set (reg:CC_NOOV CC_REGNUM)
5100 (compare:CC_NOOV (not:SI (match_operand:SI 1 "s_register_operand" "r"))
5101 (const_int 0)))
5102 (clobber (match_scratch:SI 0 "=r"))]
5103 "TARGET_32BIT"
5104 "mvn%.\\t%0, %1"
5105 [(set_attr "conds" "set")
5106 (set_attr "type" "mvn_reg")]
5107 )
5108 \f
5109 ;; Fixed <--> Floating conversion insns
5110
5111 (define_expand "floatsihf2"
5112 [(set (match_operand:HF 0 "general_operand" "")
5113 (float:HF (match_operand:SI 1 "general_operand" "")))]
5114 "TARGET_EITHER"
5115 "
5116 {
5117 rtx op1 = gen_reg_rtx (SFmode);
5118 expand_float (op1, operands[1], 0);
5119 op1 = convert_to_mode (HFmode, op1, 0);
5120 emit_move_insn (operands[0], op1);
5121 DONE;
5122 }"
5123 )
5124
5125 (define_expand "floatdihf2"
5126 [(set (match_operand:HF 0 "general_operand" "")
5127 (float:HF (match_operand:DI 1 "general_operand" "")))]
5128 "TARGET_EITHER"
5129 "
5130 {
5131 rtx op1 = gen_reg_rtx (SFmode);
5132 expand_float (op1, operands[1], 0);
5133 op1 = convert_to_mode (HFmode, op1, 0);
5134 emit_move_insn (operands[0], op1);
5135 DONE;
5136 }"
5137 )
5138
5139 (define_expand "floatsisf2"
5140 [(set (match_operand:SF 0 "s_register_operand" "")
5141 (float:SF (match_operand:SI 1 "s_register_operand" "")))]
5142 "TARGET_32BIT && TARGET_HARD_FLOAT"
5143 "
5144 ")
5145
5146 (define_expand "floatsidf2"
5147 [(set (match_operand:DF 0 "s_register_operand" "")
5148 (float:DF (match_operand:SI 1 "s_register_operand" "")))]
5149 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
5150 "
5151 ")
5152
5153 (define_expand "fix_trunchfsi2"
5154 [(set (match_operand:SI 0 "general_operand" "")
5155 (fix:SI (fix:HF (match_operand:HF 1 "general_operand" ""))))]
5156 "TARGET_EITHER"
5157 "
5158 {
5159 rtx op1 = convert_to_mode (SFmode, operands[1], 0);
5160 expand_fix (operands[0], op1, 0);
5161 DONE;
5162 }"
5163 )
5164
5165 (define_expand "fix_trunchfdi2"
5166 [(set (match_operand:DI 0 "general_operand" "")
5167 (fix:DI (fix:HF (match_operand:HF 1 "general_operand" ""))))]
5168 "TARGET_EITHER"
5169 "
5170 {
5171 rtx op1 = convert_to_mode (SFmode, operands[1], 0);
5172 expand_fix (operands[0], op1, 0);
5173 DONE;
5174 }"
5175 )
5176
5177 (define_expand "fix_truncsfsi2"
5178 [(set (match_operand:SI 0 "s_register_operand" "")
5179 (fix:SI (fix:SF (match_operand:SF 1 "s_register_operand" ""))))]
5180 "TARGET_32BIT && TARGET_HARD_FLOAT"
5181 "
5182 ")
5183
5184 (define_expand "fix_truncdfsi2"
5185 [(set (match_operand:SI 0 "s_register_operand" "")
5186 (fix:SI (fix:DF (match_operand:DF 1 "s_register_operand" ""))))]
5187 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
5188 "
5189 ")
5190
5191 ;; Truncation insns
5192
5193 (define_expand "truncdfsf2"
5194 [(set (match_operand:SF 0 "s_register_operand" "")
5195 (float_truncate:SF
5196 (match_operand:DF 1 "s_register_operand" "")))]
5197 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
5198 ""
5199 )
5200
5201 /* DFmode -> HFmode conversions have to go through SFmode. */
5202 (define_expand "truncdfhf2"
5203 [(set (match_operand:HF 0 "general_operand" "")
5204 (float_truncate:HF
5205 (match_operand:DF 1 "general_operand" "")))]
5206 "TARGET_EITHER"
5207 "
5208 {
5209 rtx op1;
5210 op1 = convert_to_mode (SFmode, operands[1], 0);
5211 op1 = convert_to_mode (HFmode, op1, 0);
5212 emit_move_insn (operands[0], op1);
5213 DONE;
5214 }"
5215 )
5216 \f
5217 ;; Zero and sign extension instructions.
5218
5219 (define_insn "zero_extend<mode>di2"
5220 [(set (match_operand:DI 0 "s_register_operand" "=w,r,?r,w")
5221 (zero_extend:DI (match_operand:QHSI 1 "<qhs_zextenddi_op>"
5222 "<qhs_zextenddi_cstr>")))]
5223 "TARGET_32BIT <qhs_zextenddi_cond>"
5224 "#"
5225 [(set_attr "length" "8,4,8,8")
5226 (set_attr "arch" "neon_for_64bits,*,*,avoid_neon_for_64bits")
5227 (set_attr "ce_count" "2")
5228 (set_attr "predicable" "yes")
5229 (set_attr "type" "multiple,mov_reg,multiple,multiple")]
5230 )
5231
5232 (define_insn "extend<mode>di2"
5233 [(set (match_operand:DI 0 "s_register_operand" "=w,r,?r,?r,w")
5234 (sign_extend:DI (match_operand:QHSI 1 "<qhs_extenddi_op>"
5235 "<qhs_extenddi_cstr>")))]
5236 "TARGET_32BIT <qhs_sextenddi_cond>"
5237 "#"
5238 [(set_attr "length" "8,4,8,8,8")
5239 (set_attr "ce_count" "2")
5240 (set_attr "shift" "1")
5241 (set_attr "predicable" "yes")
5242 (set_attr "arch" "neon_for_64bits,*,a,t,avoid_neon_for_64bits")
5243 (set_attr "type" "multiple,mov_reg,multiple,multiple,multiple")]
5244 )
5245
5246 ;; Splits for all extensions to DImode
5247 (define_split
5248 [(set (match_operand:DI 0 "s_register_operand" "")
5249 (zero_extend:DI (match_operand 1 "nonimmediate_operand" "")))]
5250 "TARGET_32BIT && reload_completed && !IS_VFP_REGNUM (REGNO (operands[0]))"
5251 [(set (match_dup 0) (match_dup 1))]
5252 {
5253 rtx lo_part = gen_lowpart (SImode, operands[0]);
5254 enum machine_mode src_mode = GET_MODE (operands[1]);
5255
5256 if (REG_P (operands[0])
5257 && !reg_overlap_mentioned_p (operands[0], operands[1]))
5258 emit_clobber (operands[0]);
5259 if (!REG_P (lo_part) || src_mode != SImode
5260 || !rtx_equal_p (lo_part, operands[1]))
5261 {
5262 if (src_mode == SImode)
5263 emit_move_insn (lo_part, operands[1]);
5264 else
5265 emit_insn (gen_rtx_SET (VOIDmode, lo_part,
5266 gen_rtx_ZERO_EXTEND (SImode, operands[1])));
5267 operands[1] = lo_part;
5268 }
5269 operands[0] = gen_highpart (SImode, operands[0]);
5270 operands[1] = const0_rtx;
5271 })
5272
5273 (define_split
5274 [(set (match_operand:DI 0 "s_register_operand" "")
5275 (sign_extend:DI (match_operand 1 "nonimmediate_operand" "")))]
5276 "TARGET_32BIT && reload_completed && !IS_VFP_REGNUM (REGNO (operands[0]))"
5277 [(set (match_dup 0) (ashiftrt:SI (match_dup 1) (const_int 31)))]
5278 {
5279 rtx lo_part = gen_lowpart (SImode, operands[0]);
5280 enum machine_mode src_mode = GET_MODE (operands[1]);
5281
5282 if (REG_P (operands[0])
5283 && !reg_overlap_mentioned_p (operands[0], operands[1]))
5284 emit_clobber (operands[0]);
5285
5286 if (!REG_P (lo_part) || src_mode != SImode
5287 || !rtx_equal_p (lo_part, operands[1]))
5288 {
5289 if (src_mode == SImode)
5290 emit_move_insn (lo_part, operands[1]);
5291 else
5292 emit_insn (gen_rtx_SET (VOIDmode, lo_part,
5293 gen_rtx_SIGN_EXTEND (SImode, operands[1])));
5294 operands[1] = lo_part;
5295 }
5296 operands[0] = gen_highpart (SImode, operands[0]);
5297 })
5298
5299 (define_expand "zero_extendhisi2"
5300 [(set (match_operand:SI 0 "s_register_operand" "")
5301 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
5302 "TARGET_EITHER"
5303 {
5304 if (TARGET_ARM && !arm_arch4 && MEM_P (operands[1]))
5305 {
5306 emit_insn (gen_movhi_bytes (operands[0], operands[1]));
5307 DONE;
5308 }
5309 if (!arm_arch6 && !MEM_P (operands[1]))
5310 {
5311 rtx t = gen_lowpart (SImode, operands[1]);
5312 rtx tmp = gen_reg_rtx (SImode);
5313 emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (16)));
5314 emit_insn (gen_lshrsi3 (operands[0], tmp, GEN_INT (16)));
5315 DONE;
5316 }
5317 })
5318
5319 (define_split
5320 [(set (match_operand:SI 0 "s_register_operand" "")
5321 (zero_extend:SI (match_operand:HI 1 "s_register_operand" "")))]
5322 "!TARGET_THUMB2 && !arm_arch6"
5323 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
5324 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 16)))]
5325 {
5326 operands[2] = gen_lowpart (SImode, operands[1]);
5327 })
5328
5329 (define_insn "*thumb1_zero_extendhisi2"
5330 [(set (match_operand:SI 0 "register_operand" "=l,l")
5331 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "l,m")))]
5332 "TARGET_THUMB1"
5333 {
5334 rtx mem;
5335
5336 if (which_alternative == 0 && arm_arch6)
5337 return "uxth\t%0, %1";
5338 if (which_alternative == 0)
5339 return "#";
5340
5341 mem = XEXP (operands[1], 0);
5342
5343 if (GET_CODE (mem) == CONST)
5344 mem = XEXP (mem, 0);
5345
5346 if (GET_CODE (mem) == PLUS)
5347 {
5348 rtx a = XEXP (mem, 0);
5349
5350 /* This can happen due to bugs in reload. */
5351 if (REG_P (a) && REGNO (a) == SP_REGNUM)
5352 {
5353 rtx ops[2];
5354 ops[0] = operands[0];
5355 ops[1] = a;
5356
5357 output_asm_insn ("mov\t%0, %1", ops);
5358
5359 XEXP (mem, 0) = operands[0];
5360 }
5361 }
5362
5363 return "ldrh\t%0, %1";
5364 }
5365 [(set_attr_alternative "length"
5366 [(if_then_else (eq_attr "is_arch6" "yes")
5367 (const_int 2) (const_int 4))
5368 (const_int 4)])
5369 (set_attr "type" "extend,load_byte")]
5370 )
5371
5372 (define_insn "*arm_zero_extendhisi2"
5373 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5374 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
5375 "TARGET_ARM && arm_arch4 && !arm_arch6"
5376 "@
5377 #
5378 ldr%(h%)\\t%0, %1"
5379 [(set_attr "type" "alu_shift_reg,load_byte")
5380 (set_attr "predicable" "yes")]
5381 )
5382
5383 (define_insn "*arm_zero_extendhisi2_v6"
5384 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5385 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
5386 "TARGET_ARM && arm_arch6"
5387 "@
5388 uxth%?\\t%0, %1
5389 ldr%(h%)\\t%0, %1"
5390 [(set_attr "predicable" "yes")
5391 (set_attr "type" "extend,load_byte")]
5392 )
5393
5394 (define_insn "*arm_zero_extendhisi2addsi"
5395 [(set (match_operand:SI 0 "s_register_operand" "=r")
5396 (plus:SI (zero_extend:SI (match_operand:HI 1 "s_register_operand" "r"))
5397 (match_operand:SI 2 "s_register_operand" "r")))]
5398 "TARGET_INT_SIMD"
5399 "uxtah%?\\t%0, %2, %1"
5400 [(set_attr "type" "alu_shift_reg")
5401 (set_attr "predicable" "yes")
5402 (set_attr "predicable_short_it" "no")]
5403 )
5404
5405 (define_expand "zero_extendqisi2"
5406 [(set (match_operand:SI 0 "s_register_operand" "")
5407 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))]
5408 "TARGET_EITHER"
5409 {
5410 if (TARGET_ARM && !arm_arch6 && !MEM_P (operands[1]))
5411 {
5412 emit_insn (gen_andsi3 (operands[0],
5413 gen_lowpart (SImode, operands[1]),
5414 GEN_INT (255)));
5415 DONE;
5416 }
5417 if (!arm_arch6 && !MEM_P (operands[1]))
5418 {
5419 rtx t = gen_lowpart (SImode, operands[1]);
5420 rtx tmp = gen_reg_rtx (SImode);
5421 emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (24)));
5422 emit_insn (gen_lshrsi3 (operands[0], tmp, GEN_INT (24)));
5423 DONE;
5424 }
5425 })
5426
5427 (define_split
5428 [(set (match_operand:SI 0 "s_register_operand" "")
5429 (zero_extend:SI (match_operand:QI 1 "s_register_operand" "")))]
5430 "!arm_arch6"
5431 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 24)))
5432 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 24)))]
5433 {
5434 operands[2] = simplify_gen_subreg (SImode, operands[1], QImode, 0);
5435 if (TARGET_ARM)
5436 {
5437 emit_insn (gen_andsi3 (operands[0], operands[2], GEN_INT (255)));
5438 DONE;
5439 }
5440 })
5441
5442 (define_insn "*thumb1_zero_extendqisi2"
5443 [(set (match_operand:SI 0 "register_operand" "=l,l")
5444 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "l,m")))]
5445 "TARGET_THUMB1 && !arm_arch6"
5446 "@
5447 #
5448 ldrb\\t%0, %1"
5449 [(set_attr "length" "4,2")
5450 (set_attr "type" "alu_shift_reg,load_byte")
5451 (set_attr "pool_range" "*,32")]
5452 )
5453
5454 (define_insn "*thumb1_zero_extendqisi2_v6"
5455 [(set (match_operand:SI 0 "register_operand" "=l,l")
5456 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "l,m")))]
5457 "TARGET_THUMB1 && arm_arch6"
5458 "@
5459 uxtb\\t%0, %1
5460 ldrb\\t%0, %1"
5461 [(set_attr "length" "2")
5462 (set_attr "type" "extend,load_byte")]
5463 )
5464
5465 (define_insn "*arm_zero_extendqisi2"
5466 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5467 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
5468 "TARGET_ARM && !arm_arch6"
5469 "@
5470 #
5471 ldr%(b%)\\t%0, %1\\t%@ zero_extendqisi2"
5472 [(set_attr "length" "8,4")
5473 (set_attr "type" "alu_shift_reg,load_byte")
5474 (set_attr "predicable" "yes")]
5475 )
5476
5477 (define_insn "*arm_zero_extendqisi2_v6"
5478 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5479 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
5480 "TARGET_ARM && arm_arch6"
5481 "@
5482 uxtb%(%)\\t%0, %1
5483 ldr%(b%)\\t%0, %1\\t%@ zero_extendqisi2"
5484 [(set_attr "type" "extend,load_byte")
5485 (set_attr "predicable" "yes")]
5486 )
5487
5488 (define_insn "*arm_zero_extendqisi2addsi"
5489 [(set (match_operand:SI 0 "s_register_operand" "=r")
5490 (plus:SI (zero_extend:SI (match_operand:QI 1 "s_register_operand" "r"))
5491 (match_operand:SI 2 "s_register_operand" "r")))]
5492 "TARGET_INT_SIMD"
5493 "uxtab%?\\t%0, %2, %1"
5494 [(set_attr "predicable" "yes")
5495 (set_attr "predicable_short_it" "no")
5496 (set_attr "type" "alu_shift_reg")]
5497 )
5498
5499 (define_split
5500 [(set (match_operand:SI 0 "s_register_operand" "")
5501 (zero_extend:SI (subreg:QI (match_operand:SI 1 "" "") 0)))
5502 (clobber (match_operand:SI 2 "s_register_operand" ""))]
5503 "TARGET_32BIT && (!MEM_P (operands[1])) && ! BYTES_BIG_ENDIAN"
5504 [(set (match_dup 2) (match_dup 1))
5505 (set (match_dup 0) (and:SI (match_dup 2) (const_int 255)))]
5506 ""
5507 )
5508
5509 (define_split
5510 [(set (match_operand:SI 0 "s_register_operand" "")
5511 (zero_extend:SI (subreg:QI (match_operand:SI 1 "" "") 3)))
5512 (clobber (match_operand:SI 2 "s_register_operand" ""))]
5513 "TARGET_32BIT && (!MEM_P (operands[1])) && BYTES_BIG_ENDIAN"
5514 [(set (match_dup 2) (match_dup 1))
5515 (set (match_dup 0) (and:SI (match_dup 2) (const_int 255)))]
5516 ""
5517 )
5518
5519
5520 (define_split
5521 [(set (match_operand:SI 0 "s_register_operand" "")
5522 (ior_xor:SI (and:SI (ashift:SI
5523 (match_operand:SI 1 "s_register_operand" "")
5524 (match_operand:SI 2 "const_int_operand" ""))
5525 (match_operand:SI 3 "const_int_operand" ""))
5526 (zero_extend:SI
5527 (match_operator 5 "subreg_lowpart_operator"
5528 [(match_operand:SI 4 "s_register_operand" "")]))))]
5529 "TARGET_32BIT
5530 && ((unsigned HOST_WIDE_INT) INTVAL (operands[3])
5531 == (GET_MODE_MASK (GET_MODE (operands[5]))
5532 & (GET_MODE_MASK (GET_MODE (operands[5]))
5533 << (INTVAL (operands[2])))))"
5534 [(set (match_dup 0) (ior_xor:SI (ashift:SI (match_dup 1) (match_dup 2))
5535 (match_dup 4)))
5536 (set (match_dup 0) (zero_extend:SI (match_dup 5)))]
5537 "operands[5] = gen_lowpart (GET_MODE (operands[5]), operands[0]);"
5538 )
5539
5540 (define_insn "*compareqi_eq0"
5541 [(set (reg:CC_Z CC_REGNUM)
5542 (compare:CC_Z (match_operand:QI 0 "s_register_operand" "r")
5543 (const_int 0)))]
5544 "TARGET_32BIT"
5545 "tst%?\\t%0, #255"
5546 [(set_attr "conds" "set")
5547 (set_attr "predicable" "yes")
5548 (set_attr "predicable_short_it" "no")
5549 (set_attr "type" "logic_imm")]
5550 )
5551
5552 (define_expand "extendhisi2"
5553 [(set (match_operand:SI 0 "s_register_operand" "")
5554 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
5555 "TARGET_EITHER"
5556 {
5557 if (TARGET_THUMB1)
5558 {
5559 emit_insn (gen_thumb1_extendhisi2 (operands[0], operands[1]));
5560 DONE;
5561 }
5562 if (MEM_P (operands[1]) && TARGET_ARM && !arm_arch4)
5563 {
5564 emit_insn (gen_extendhisi2_mem (operands[0], operands[1]));
5565 DONE;
5566 }
5567
5568 if (!arm_arch6 && !MEM_P (operands[1]))
5569 {
5570 rtx t = gen_lowpart (SImode, operands[1]);
5571 rtx tmp = gen_reg_rtx (SImode);
5572 emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (16)));
5573 emit_insn (gen_ashrsi3 (operands[0], tmp, GEN_INT (16)));
5574 DONE;
5575 }
5576 })
5577
5578 (define_split
5579 [(parallel
5580 [(set (match_operand:SI 0 "register_operand" "")
5581 (sign_extend:SI (match_operand:HI 1 "register_operand" "")))
5582 (clobber (match_scratch:SI 2 ""))])]
5583 "!arm_arch6"
5584 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
5585 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 16)))]
5586 {
5587 operands[2] = simplify_gen_subreg (SImode, operands[1], HImode, 0);
5588 })
5589
5590 ;; We used to have an early-clobber on the scratch register here.
5591 ;; However, there's a bug somewhere in reload which means that this
5592 ;; can be partially ignored during spill allocation if the memory
5593 ;; address also needs reloading; this causes us to die later on when
5594 ;; we try to verify the operands. Fortunately, we don't really need
5595 ;; the early-clobber: we can always use operand 0 if operand 2
5596 ;; overlaps the address.
5597 (define_insn "thumb1_extendhisi2"
5598 [(set (match_operand:SI 0 "register_operand" "=l,l")
5599 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "l,m")))
5600 (clobber (match_scratch:SI 2 "=X,l"))]
5601 "TARGET_THUMB1"
5602 "*
5603 {
5604 rtx ops[4];
5605 rtx mem;
5606
5607 if (which_alternative == 0 && !arm_arch6)
5608 return \"#\";
5609 if (which_alternative == 0)
5610 return \"sxth\\t%0, %1\";
5611
5612 mem = XEXP (operands[1], 0);
5613
5614 /* This code used to try to use 'V', and fix the address only if it was
5615 offsettable, but this fails for e.g. REG+48 because 48 is outside the
5616 range of QImode offsets, and offsettable_address_p does a QImode
5617 address check. */
5618
5619 if (GET_CODE (mem) == CONST)
5620 mem = XEXP (mem, 0);
5621
5622 if (GET_CODE (mem) == LABEL_REF)
5623 return \"ldr\\t%0, %1\";
5624
5625 if (GET_CODE (mem) == PLUS)
5626 {
5627 rtx a = XEXP (mem, 0);
5628 rtx b = XEXP (mem, 1);
5629
5630 if (GET_CODE (a) == LABEL_REF
5631 && CONST_INT_P (b))
5632 return \"ldr\\t%0, %1\";
5633
5634 if (REG_P (b))
5635 return \"ldrsh\\t%0, %1\";
5636
5637 ops[1] = a;
5638 ops[2] = b;
5639 }
5640 else
5641 {
5642 ops[1] = mem;
5643 ops[2] = const0_rtx;
5644 }
5645
5646 gcc_assert (REG_P (ops[1]));
5647
5648 ops[0] = operands[0];
5649 if (reg_mentioned_p (operands[2], ops[1]))
5650 ops[3] = ops[0];
5651 else
5652 ops[3] = operands[2];
5653 output_asm_insn (\"mov\\t%3, %2\;ldrsh\\t%0, [%1, %3]\", ops);
5654 return \"\";
5655 }"
5656 [(set_attr_alternative "length"
5657 [(if_then_else (eq_attr "is_arch6" "yes")
5658 (const_int 2) (const_int 4))
5659 (const_int 4)])
5660 (set_attr "type" "extend,load_byte")
5661 (set_attr "pool_range" "*,1018")]
5662 )
5663
5664 ;; This pattern will only be used when ldsh is not available
5665 (define_expand "extendhisi2_mem"
5666 [(set (match_dup 2) (zero_extend:SI (match_operand:HI 1 "" "")))
5667 (set (match_dup 3)
5668 (zero_extend:SI (match_dup 7)))
5669 (set (match_dup 6) (ashift:SI (match_dup 4) (const_int 24)))
5670 (set (match_operand:SI 0 "" "")
5671 (ior:SI (ashiftrt:SI (match_dup 6) (const_int 16)) (match_dup 5)))]
5672 "TARGET_ARM"
5673 "
5674 {
5675 rtx mem1, mem2;
5676 rtx addr = copy_to_mode_reg (SImode, XEXP (operands[1], 0));
5677
5678 mem1 = change_address (operands[1], QImode, addr);
5679 mem2 = change_address (operands[1], QImode,
5680 plus_constant (Pmode, addr, 1));
5681 operands[0] = gen_lowpart (SImode, operands[0]);
5682 operands[1] = mem1;
5683 operands[2] = gen_reg_rtx (SImode);
5684 operands[3] = gen_reg_rtx (SImode);
5685 operands[6] = gen_reg_rtx (SImode);
5686 operands[7] = mem2;
5687
5688 if (BYTES_BIG_ENDIAN)
5689 {
5690 operands[4] = operands[2];
5691 operands[5] = operands[3];
5692 }
5693 else
5694 {
5695 operands[4] = operands[3];
5696 operands[5] = operands[2];
5697 }
5698 }"
5699 )
5700
5701 (define_split
5702 [(set (match_operand:SI 0 "register_operand" "")
5703 (sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
5704 "!arm_arch6"
5705 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
5706 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 16)))]
5707 {
5708 operands[2] = simplify_gen_subreg (SImode, operands[1], HImode, 0);
5709 })
5710
5711 (define_insn "*arm_extendhisi2"
5712 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5713 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
5714 "TARGET_ARM && arm_arch4 && !arm_arch6"
5715 "@
5716 #
5717 ldr%(sh%)\\t%0, %1"
5718 [(set_attr "length" "8,4")
5719 (set_attr "type" "alu_shift_reg,load_byte")
5720 (set_attr "predicable" "yes")
5721 (set_attr "pool_range" "*,256")
5722 (set_attr "neg_pool_range" "*,244")]
5723 )
5724
5725 ;; ??? Check Thumb-2 pool range
5726 (define_insn "*arm_extendhisi2_v6"
5727 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5728 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
5729 "TARGET_32BIT && arm_arch6"
5730 "@
5731 sxth%?\\t%0, %1
5732 ldr%(sh%)\\t%0, %1"
5733 [(set_attr "type" "extend,load_byte")
5734 (set_attr "predicable" "yes")
5735 (set_attr "predicable_short_it" "no")
5736 (set_attr "pool_range" "*,256")
5737 (set_attr "neg_pool_range" "*,244")]
5738 )
5739
5740 (define_insn "*arm_extendhisi2addsi"
5741 [(set (match_operand:SI 0 "s_register_operand" "=r")
5742 (plus:SI (sign_extend:SI (match_operand:HI 1 "s_register_operand" "r"))
5743 (match_operand:SI 2 "s_register_operand" "r")))]
5744 "TARGET_INT_SIMD"
5745 "sxtah%?\\t%0, %2, %1"
5746 [(set_attr "type" "alu_shift_reg")]
5747 )
5748
5749 (define_expand "extendqihi2"
5750 [(set (match_dup 2)
5751 (ashift:SI (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "")
5752 (const_int 24)))
5753 (set (match_operand:HI 0 "s_register_operand" "")
5754 (ashiftrt:SI (match_dup 2)
5755 (const_int 24)))]
5756 "TARGET_ARM"
5757 "
5758 {
5759 if (arm_arch4 && MEM_P (operands[1]))
5760 {
5761 emit_insn (gen_rtx_SET (VOIDmode,
5762 operands[0],
5763 gen_rtx_SIGN_EXTEND (HImode, operands[1])));
5764 DONE;
5765 }
5766 if (!s_register_operand (operands[1], QImode))
5767 operands[1] = copy_to_mode_reg (QImode, operands[1]);
5768 operands[0] = gen_lowpart (SImode, operands[0]);
5769 operands[1] = gen_lowpart (SImode, operands[1]);
5770 operands[2] = gen_reg_rtx (SImode);
5771 }"
5772 )
5773
5774 (define_insn "*arm_extendqihi_insn"
5775 [(set (match_operand:HI 0 "s_register_operand" "=r")
5776 (sign_extend:HI (match_operand:QI 1 "arm_extendqisi_mem_op" "Uq")))]
5777 "TARGET_ARM && arm_arch4"
5778 "ldr%(sb%)\\t%0, %1"
5779 [(set_attr "type" "load_byte")
5780 (set_attr "predicable" "yes")
5781 (set_attr "pool_range" "256")
5782 (set_attr "neg_pool_range" "244")]
5783 )
5784
5785 (define_expand "extendqisi2"
5786 [(set (match_operand:SI 0 "s_register_operand" "")
5787 (sign_extend:SI (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "")))]
5788 "TARGET_EITHER"
5789 {
5790 if (!arm_arch4 && MEM_P (operands[1]))
5791 operands[1] = copy_to_mode_reg (QImode, operands[1]);
5792
5793 if (!arm_arch6 && !MEM_P (operands[1]))
5794 {
5795 rtx t = gen_lowpart (SImode, operands[1]);
5796 rtx tmp = gen_reg_rtx (SImode);
5797 emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (24)));
5798 emit_insn (gen_ashrsi3 (operands[0], tmp, GEN_INT (24)));
5799 DONE;
5800 }
5801 })
5802
5803 (define_split
5804 [(set (match_operand:SI 0 "register_operand" "")
5805 (sign_extend:SI (match_operand:QI 1 "register_operand" "")))]
5806 "!arm_arch6"
5807 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 24)))
5808 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 24)))]
5809 {
5810 operands[2] = simplify_gen_subreg (SImode, operands[1], QImode, 0);
5811 })
5812
5813 (define_insn "*arm_extendqisi"
5814 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5815 (sign_extend:SI (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "r,Uq")))]
5816 "TARGET_ARM && arm_arch4 && !arm_arch6"
5817 "@
5818 #
5819 ldr%(sb%)\\t%0, %1"
5820 [(set_attr "length" "8,4")
5821 (set_attr "type" "alu_shift_reg,load_byte")
5822 (set_attr "predicable" "yes")
5823 (set_attr "pool_range" "*,256")
5824 (set_attr "neg_pool_range" "*,244")]
5825 )
5826
5827 (define_insn "*arm_extendqisi_v6"
5828 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5829 (sign_extend:SI
5830 (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "r,Uq")))]
5831 "TARGET_ARM && arm_arch6"
5832 "@
5833 sxtb%?\\t%0, %1
5834 ldr%(sb%)\\t%0, %1"
5835 [(set_attr "type" "extend,load_byte")
5836 (set_attr "predicable" "yes")
5837 (set_attr "pool_range" "*,256")
5838 (set_attr "neg_pool_range" "*,244")]
5839 )
5840
5841 (define_insn "*arm_extendqisi2addsi"
5842 [(set (match_operand:SI 0 "s_register_operand" "=r")
5843 (plus:SI (sign_extend:SI (match_operand:QI 1 "s_register_operand" "r"))
5844 (match_operand:SI 2 "s_register_operand" "r")))]
5845 "TARGET_INT_SIMD"
5846 "sxtab%?\\t%0, %2, %1"
5847 [(set_attr "type" "alu_shift_reg")
5848 (set_attr "predicable" "yes")
5849 (set_attr "predicable_short_it" "no")]
5850 )
5851
5852 (define_split
5853 [(set (match_operand:SI 0 "register_operand" "")
5854 (sign_extend:SI (match_operand:QI 1 "memory_operand" "")))]
5855 "TARGET_THUMB1 && reload_completed"
5856 [(set (match_dup 0) (match_dup 2))
5857 (set (match_dup 0) (sign_extend:SI (match_dup 3)))]
5858 {
5859 rtx addr = XEXP (operands[1], 0);
5860
5861 if (GET_CODE (addr) == CONST)
5862 addr = XEXP (addr, 0);
5863
5864 if (GET_CODE (addr) == PLUS
5865 && REG_P (XEXP (addr, 0)) && REG_P (XEXP (addr, 1)))
5866 /* No split necessary. */
5867 FAIL;
5868
5869 if (GET_CODE (addr) == PLUS
5870 && !REG_P (XEXP (addr, 0)) && !REG_P (XEXP (addr, 1)))
5871 FAIL;
5872
5873 if (reg_overlap_mentioned_p (operands[0], addr))
5874 {
5875 rtx t = gen_lowpart (QImode, operands[0]);
5876 emit_move_insn (t, operands[1]);
5877 emit_insn (gen_thumb1_extendqisi2 (operands[0], t));
5878 DONE;
5879 }
5880
5881 if (REG_P (addr))
5882 {
5883 addr = gen_rtx_PLUS (Pmode, addr, operands[0]);
5884 operands[2] = const0_rtx;
5885 }
5886 else if (GET_CODE (addr) != PLUS)
5887 FAIL;
5888 else if (REG_P (XEXP (addr, 0)))
5889 {
5890 operands[2] = XEXP (addr, 1);
5891 addr = gen_rtx_PLUS (Pmode, XEXP (addr, 0), operands[0]);
5892 }
5893 else
5894 {
5895 operands[2] = XEXP (addr, 0);
5896 addr = gen_rtx_PLUS (Pmode, XEXP (addr, 1), operands[0]);
5897 }
5898
5899 operands[3] = change_address (operands[1], QImode, addr);
5900 })
5901
5902 (define_peephole2
5903 [(set (match_operand:SI 0 "register_operand" "")
5904 (plus:SI (match_dup 0) (match_operand 1 "const_int_operand")))
5905 (set (match_operand:SI 2 "register_operand" "") (const_int 0))
5906 (set (match_operand:SI 3 "register_operand" "")
5907 (sign_extend:SI (match_operand:QI 4 "memory_operand" "")))]
5908 "TARGET_THUMB1
5909 && GET_CODE (XEXP (operands[4], 0)) == PLUS
5910 && rtx_equal_p (operands[0], XEXP (XEXP (operands[4], 0), 0))
5911 && rtx_equal_p (operands[2], XEXP (XEXP (operands[4], 0), 1))
5912 && (peep2_reg_dead_p (3, operands[0])
5913 || rtx_equal_p (operands[0], operands[3]))
5914 && (peep2_reg_dead_p (3, operands[2])
5915 || rtx_equal_p (operands[2], operands[3]))"
5916 [(set (match_dup 2) (match_dup 1))
5917 (set (match_dup 3) (sign_extend:SI (match_dup 4)))]
5918 {
5919 rtx addr = gen_rtx_PLUS (Pmode, operands[0], operands[2]);
5920 operands[4] = change_address (operands[4], QImode, addr);
5921 })
5922
5923 (define_insn "thumb1_extendqisi2"
5924 [(set (match_operand:SI 0 "register_operand" "=l,l,l")
5925 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "l,V,m")))]
5926 "TARGET_THUMB1"
5927 {
5928 rtx addr;
5929
5930 if (which_alternative == 0 && arm_arch6)
5931 return "sxtb\\t%0, %1";
5932 if (which_alternative == 0)
5933 return "#";
5934
5935 addr = XEXP (operands[1], 0);
5936 if (GET_CODE (addr) == PLUS
5937 && REG_P (XEXP (addr, 0)) && REG_P (XEXP (addr, 1)))
5938 return "ldrsb\\t%0, %1";
5939
5940 return "#";
5941 }
5942 [(set_attr_alternative "length"
5943 [(if_then_else (eq_attr "is_arch6" "yes")
5944 (const_int 2) (const_int 4))
5945 (const_int 2)
5946 (if_then_else (eq_attr "is_arch6" "yes")
5947 (const_int 4) (const_int 6))])
5948 (set_attr "type" "extend,load_byte,load_byte")]
5949 )
5950
5951 (define_expand "extendsfdf2"
5952 [(set (match_operand:DF 0 "s_register_operand" "")
5953 (float_extend:DF (match_operand:SF 1 "s_register_operand" "")))]
5954 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
5955 ""
5956 )
5957
5958 /* HFmode -> DFmode conversions have to go through SFmode. */
5959 (define_expand "extendhfdf2"
5960 [(set (match_operand:DF 0 "general_operand" "")
5961 (float_extend:DF (match_operand:HF 1 "general_operand" "")))]
5962 "TARGET_EITHER"
5963 "
5964 {
5965 rtx op1;
5966 op1 = convert_to_mode (SFmode, operands[1], 0);
5967 op1 = convert_to_mode (DFmode, op1, 0);
5968 emit_insn (gen_movdf (operands[0], op1));
5969 DONE;
5970 }"
5971 )
5972 \f
5973 ;; Move insns (including loads and stores)
5974
5975 ;; XXX Just some ideas about movti.
5976 ;; I don't think these are a good idea on the arm, there just aren't enough
5977 ;; registers
5978 ;;(define_expand "loadti"
5979 ;; [(set (match_operand:TI 0 "s_register_operand" "")
5980 ;; (mem:TI (match_operand:SI 1 "address_operand" "")))]
5981 ;; "" "")
5982
5983 ;;(define_expand "storeti"
5984 ;; [(set (mem:TI (match_operand:TI 0 "address_operand" ""))
5985 ;; (match_operand:TI 1 "s_register_operand" ""))]
5986 ;; "" "")
5987
5988 ;;(define_expand "movti"
5989 ;; [(set (match_operand:TI 0 "general_operand" "")
5990 ;; (match_operand:TI 1 "general_operand" ""))]
5991 ;; ""
5992 ;; "
5993 ;;{
5994 ;; rtx insn;
5995 ;;
5996 ;; if (MEM_P (operands[0]) && MEM_P (operands[1]))
5997 ;; operands[1] = copy_to_reg (operands[1]);
5998 ;; if (MEM_P (operands[0]))
5999 ;; insn = gen_storeti (XEXP (operands[0], 0), operands[1]);
6000 ;; else if (MEM_P (operands[1]))
6001 ;; insn = gen_loadti (operands[0], XEXP (operands[1], 0));
6002 ;; else
6003 ;; FAIL;
6004 ;;
6005 ;; emit_insn (insn);
6006 ;; DONE;
6007 ;;}")
6008
6009 ;; Recognize garbage generated above.
6010
6011 ;;(define_insn ""
6012 ;; [(set (match_operand:TI 0 "general_operand" "=r,r,r,<,>,m")
6013 ;; (match_operand:TI 1 "general_operand" "<,>,m,r,r,r"))]
6014 ;; ""
6015 ;; "*
6016 ;; {
6017 ;; register mem = (which_alternative < 3);
6018 ;; register const char *template;
6019 ;;
6020 ;; operands[mem] = XEXP (operands[mem], 0);
6021 ;; switch (which_alternative)
6022 ;; {
6023 ;; case 0: template = \"ldmdb\\t%1!, %M0\"; break;
6024 ;; case 1: template = \"ldmia\\t%1!, %M0\"; break;
6025 ;; case 2: template = \"ldmia\\t%1, %M0\"; break;
6026 ;; case 3: template = \"stmdb\\t%0!, %M1\"; break;
6027 ;; case 4: template = \"stmia\\t%0!, %M1\"; break;
6028 ;; case 5: template = \"stmia\\t%0, %M1\"; break;
6029 ;; }
6030 ;; output_asm_insn (template, operands);
6031 ;; return \"\";
6032 ;; }")
6033
6034 (define_expand "movdi"
6035 [(set (match_operand:DI 0 "general_operand" "")
6036 (match_operand:DI 1 "general_operand" ""))]
6037 "TARGET_EITHER"
6038 "
6039 if (can_create_pseudo_p ())
6040 {
6041 if (!REG_P (operands[0]))
6042 operands[1] = force_reg (DImode, operands[1]);
6043 }
6044 "
6045 )
6046
6047 (define_insn "*arm_movdi"
6048 [(set (match_operand:DI 0 "nonimmediate_di_operand" "=r, r, r, q, m")
6049 (match_operand:DI 1 "di_operand" "rDa,Db,Dc,mi,q"))]
6050 "TARGET_32BIT
6051 && !(TARGET_HARD_FLOAT && TARGET_VFP)
6052 && !TARGET_IWMMXT
6053 && ( register_operand (operands[0], DImode)
6054 || register_operand (operands[1], DImode))"
6055 "*
6056 switch (which_alternative)
6057 {
6058 case 0:
6059 case 1:
6060 case 2:
6061 return \"#\";
6062 default:
6063 return output_move_double (operands, true, NULL);
6064 }
6065 "
6066 [(set_attr "length" "8,12,16,8,8")
6067 (set_attr "type" "multiple,multiple,multiple,load2,store2")
6068 (set_attr "arm_pool_range" "*,*,*,1020,*")
6069 (set_attr "arm_neg_pool_range" "*,*,*,1004,*")
6070 (set_attr "thumb2_pool_range" "*,*,*,4094,*")
6071 (set_attr "thumb2_neg_pool_range" "*,*,*,0,*")]
6072 )
6073
6074 (define_split
6075 [(set (match_operand:ANY64 0 "arm_general_register_operand" "")
6076 (match_operand:ANY64 1 "const_double_operand" ""))]
6077 "TARGET_32BIT
6078 && reload_completed
6079 && (arm_const_double_inline_cost (operands[1])
6080 <= arm_max_const_double_inline_cost ())"
6081 [(const_int 0)]
6082 "
6083 arm_split_constant (SET, SImode, curr_insn,
6084 INTVAL (gen_lowpart (SImode, operands[1])),
6085 gen_lowpart (SImode, operands[0]), NULL_RTX, 0);
6086 arm_split_constant (SET, SImode, curr_insn,
6087 INTVAL (gen_highpart_mode (SImode,
6088 GET_MODE (operands[0]),
6089 operands[1])),
6090 gen_highpart (SImode, operands[0]), NULL_RTX, 0);
6091 DONE;
6092 "
6093 )
6094
6095 ; If optimizing for size, or if we have load delay slots, then
6096 ; we want to split the constant into two separate operations.
6097 ; In both cases this may split a trivial part into a single data op
6098 ; leaving a single complex constant to load. We can also get longer
6099 ; offsets in a LDR which means we get better chances of sharing the pool
6100 ; entries. Finally, we can normally do a better job of scheduling
6101 ; LDR instructions than we can with LDM.
6102 ; This pattern will only match if the one above did not.
6103 (define_split
6104 [(set (match_operand:ANY64 0 "arm_general_register_operand" "")
6105 (match_operand:ANY64 1 "const_double_operand" ""))]
6106 "TARGET_ARM && reload_completed
6107 && arm_const_double_by_parts (operands[1])"
6108 [(set (match_dup 0) (match_dup 1))
6109 (set (match_dup 2) (match_dup 3))]
6110 "
6111 operands[2] = gen_highpart (SImode, operands[0]);
6112 operands[3] = gen_highpart_mode (SImode, GET_MODE (operands[0]),
6113 operands[1]);
6114 operands[0] = gen_lowpart (SImode, operands[0]);
6115 operands[1] = gen_lowpart (SImode, operands[1]);
6116 "
6117 )
6118
6119 (define_split
6120 [(set (match_operand:ANY64 0 "arm_general_register_operand" "")
6121 (match_operand:ANY64 1 "arm_general_register_operand" ""))]
6122 "TARGET_EITHER && reload_completed"
6123 [(set (match_dup 0) (match_dup 1))
6124 (set (match_dup 2) (match_dup 3))]
6125 "
6126 operands[2] = gen_highpart (SImode, operands[0]);
6127 operands[3] = gen_highpart (SImode, operands[1]);
6128 operands[0] = gen_lowpart (SImode, operands[0]);
6129 operands[1] = gen_lowpart (SImode, operands[1]);
6130
6131 /* Handle a partial overlap. */
6132 if (rtx_equal_p (operands[0], operands[3]))
6133 {
6134 rtx tmp0 = operands[0];
6135 rtx tmp1 = operands[1];
6136
6137 operands[0] = operands[2];
6138 operands[1] = operands[3];
6139 operands[2] = tmp0;
6140 operands[3] = tmp1;
6141 }
6142 "
6143 )
6144
6145 ;; We can't actually do base+index doubleword loads if the index and
6146 ;; destination overlap. Split here so that we at least have chance to
6147 ;; schedule.
6148 (define_split
6149 [(set (match_operand:DI 0 "s_register_operand" "")
6150 (mem:DI (plus:SI (match_operand:SI 1 "s_register_operand" "")
6151 (match_operand:SI 2 "s_register_operand" ""))))]
6152 "TARGET_LDRD
6153 && reg_overlap_mentioned_p (operands[0], operands[1])
6154 && reg_overlap_mentioned_p (operands[0], operands[2])"
6155 [(set (match_dup 4)
6156 (plus:SI (match_dup 1)
6157 (match_dup 2)))
6158 (set (match_dup 0)
6159 (mem:DI (match_dup 4)))]
6160 "
6161 operands[4] = gen_rtx_REG (SImode, REGNO(operands[0]));
6162 "
6163 )
6164
6165 ;;; ??? This should have alternatives for constants.
6166 ;;; ??? This was originally identical to the movdf_insn pattern.
6167 ;;; ??? The 'i' constraint looks funny, but it should always be replaced by
6168 ;;; thumb_reorg with a memory reference.
6169 (define_insn "*thumb1_movdi_insn"
6170 [(set (match_operand:DI 0 "nonimmediate_operand" "=l,l,l,l,>,l, m,*r")
6171 (match_operand:DI 1 "general_operand" "l, I,J,>,l,mi,l,*r"))]
6172 "TARGET_THUMB1
6173 && ( register_operand (operands[0], DImode)
6174 || register_operand (operands[1], DImode))"
6175 "*
6176 {
6177 switch (which_alternative)
6178 {
6179 default:
6180 case 0:
6181 if (REGNO (operands[1]) == REGNO (operands[0]) + 1)
6182 return \"add\\t%0, %1, #0\;add\\t%H0, %H1, #0\";
6183 return \"add\\t%H0, %H1, #0\;add\\t%0, %1, #0\";
6184 case 1:
6185 return \"mov\\t%Q0, %1\;mov\\t%R0, #0\";
6186 case 2:
6187 operands[1] = GEN_INT (- INTVAL (operands[1]));
6188 return \"mov\\t%Q0, %1\;neg\\t%Q0, %Q0\;asr\\t%R0, %Q0, #31\";
6189 case 3:
6190 return \"ldmia\\t%1, {%0, %H0}\";
6191 case 4:
6192 return \"stmia\\t%0, {%1, %H1}\";
6193 case 5:
6194 return thumb_load_double_from_address (operands);
6195 case 6:
6196 operands[2] = gen_rtx_MEM (SImode,
6197 plus_constant (Pmode, XEXP (operands[0], 0), 4));
6198 output_asm_insn (\"str\\t%1, %0\;str\\t%H1, %2\", operands);
6199 return \"\";
6200 case 7:
6201 if (REGNO (operands[1]) == REGNO (operands[0]) + 1)
6202 return \"mov\\t%0, %1\;mov\\t%H0, %H1\";
6203 return \"mov\\t%H0, %H1\;mov\\t%0, %1\";
6204 }
6205 }"
6206 [(set_attr "length" "4,4,6,2,2,6,4,4")
6207 (set_attr "type" "multiple,multiple,multiple,load2,store2,load2,store2,multiple")
6208 (set_attr "pool_range" "*,*,*,*,*,1018,*,*")]
6209 )
6210
6211 (define_expand "movsi"
6212 [(set (match_operand:SI 0 "general_operand" "")
6213 (match_operand:SI 1 "general_operand" ""))]
6214 "TARGET_EITHER"
6215 "
6216 {
6217 rtx base, offset, tmp;
6218
6219 if (TARGET_32BIT)
6220 {
6221 /* Everything except mem = const or mem = mem can be done easily. */
6222 if (MEM_P (operands[0]))
6223 operands[1] = force_reg (SImode, operands[1]);
6224 if (arm_general_register_operand (operands[0], SImode)
6225 && CONST_INT_P (operands[1])
6226 && !(const_ok_for_arm (INTVAL (operands[1]))
6227 || const_ok_for_arm (~INTVAL (operands[1]))))
6228 {
6229 arm_split_constant (SET, SImode, NULL_RTX,
6230 INTVAL (operands[1]), operands[0], NULL_RTX,
6231 optimize && can_create_pseudo_p ());
6232 DONE;
6233 }
6234 }
6235 else /* TARGET_THUMB1... */
6236 {
6237 if (can_create_pseudo_p ())
6238 {
6239 if (!REG_P (operands[0]))
6240 operands[1] = force_reg (SImode, operands[1]);
6241 }
6242 }
6243
6244 if (ARM_OFFSETS_MUST_BE_WITHIN_SECTIONS_P)
6245 {
6246 split_const (operands[1], &base, &offset);
6247 if (GET_CODE (base) == SYMBOL_REF
6248 && !offset_within_block_p (base, INTVAL (offset)))
6249 {
6250 tmp = can_create_pseudo_p () ? gen_reg_rtx (SImode) : operands[0];
6251 emit_move_insn (tmp, base);
6252 emit_insn (gen_addsi3 (operands[0], tmp, offset));
6253 DONE;
6254 }
6255 }
6256
6257 /* Recognize the case where operand[1] is a reference to thread-local
6258 data and load its address to a register. */
6259 if (arm_tls_referenced_p (operands[1]))
6260 {
6261 rtx tmp = operands[1];
6262 rtx addend = NULL;
6263
6264 if (GET_CODE (tmp) == CONST && GET_CODE (XEXP (tmp, 0)) == PLUS)
6265 {
6266 addend = XEXP (XEXP (tmp, 0), 1);
6267 tmp = XEXP (XEXP (tmp, 0), 0);
6268 }
6269
6270 gcc_assert (GET_CODE (tmp) == SYMBOL_REF);
6271 gcc_assert (SYMBOL_REF_TLS_MODEL (tmp) != 0);
6272
6273 tmp = legitimize_tls_address (tmp,
6274 !can_create_pseudo_p () ? operands[0] : 0);
6275 if (addend)
6276 {
6277 tmp = gen_rtx_PLUS (SImode, tmp, addend);
6278 tmp = force_operand (tmp, operands[0]);
6279 }
6280 operands[1] = tmp;
6281 }
6282 else if (flag_pic
6283 && (CONSTANT_P (operands[1])
6284 || symbol_mentioned_p (operands[1])
6285 || label_mentioned_p (operands[1])))
6286 operands[1] = legitimize_pic_address (operands[1], SImode,
6287 (!can_create_pseudo_p ()
6288 ? operands[0]
6289 : 0));
6290 }
6291 "
6292 )
6293
6294 ;; The ARM LO_SUM and HIGH are backwards - HIGH sets the low bits, and
6295 ;; LO_SUM adds in the high bits. Fortunately these are opaque operations
6296 ;; so this does not matter.
6297 (define_insn "*arm_movt"
6298 [(set (match_operand:SI 0 "nonimmediate_operand" "=r")
6299 (lo_sum:SI (match_operand:SI 1 "nonimmediate_operand" "0")
6300 (match_operand:SI 2 "general_operand" "i")))]
6301 "arm_arch_thumb2"
6302 "movt%?\t%0, #:upper16:%c2"
6303 [(set_attr "predicable" "yes")
6304 (set_attr "predicable_short_it" "no")
6305 (set_attr "length" "4")
6306 (set_attr "type" "mov_imm")]
6307 )
6308
6309 (define_insn "*arm_movsi_insn"
6310 [(set (match_operand:SI 0 "nonimmediate_operand" "=rk,r,r,r,rk,m")
6311 (match_operand:SI 1 "general_operand" "rk, I,K,j,mi,rk"))]
6312 "TARGET_ARM && ! TARGET_IWMMXT
6313 && !(TARGET_HARD_FLOAT && TARGET_VFP)
6314 && ( register_operand (operands[0], SImode)
6315 || register_operand (operands[1], SImode))"
6316 "@
6317 mov%?\\t%0, %1
6318 mov%?\\t%0, %1
6319 mvn%?\\t%0, #%B1
6320 movw%?\\t%0, %1
6321 ldr%?\\t%0, %1
6322 str%?\\t%1, %0"
6323 [(set_attr "type" "mov_reg,mov_imm,mvn_imm,mov_imm,load1,store1")
6324 (set_attr "predicable" "yes")
6325 (set_attr "pool_range" "*,*,*,*,4096,*")
6326 (set_attr "neg_pool_range" "*,*,*,*,4084,*")]
6327 )
6328
6329 (define_split
6330 [(set (match_operand:SI 0 "arm_general_register_operand" "")
6331 (match_operand:SI 1 "const_int_operand" ""))]
6332 "TARGET_32BIT
6333 && (!(const_ok_for_arm (INTVAL (operands[1]))
6334 || const_ok_for_arm (~INTVAL (operands[1]))))"
6335 [(clobber (const_int 0))]
6336 "
6337 arm_split_constant (SET, SImode, NULL_RTX,
6338 INTVAL (operands[1]), operands[0], NULL_RTX, 0);
6339 DONE;
6340 "
6341 )
6342
6343 ;; A normal way to do (symbol + offset) requires three instructions at least
6344 ;; (depends on how big the offset is) as below:
6345 ;; movw r0, #:lower16:g
6346 ;; movw r0, #:upper16:g
6347 ;; adds r0, #4
6348 ;;
6349 ;; A better way would be:
6350 ;; movw r0, #:lower16:g+4
6351 ;; movw r0, #:upper16:g+4
6352 ;;
6353 ;; The limitation of this way is that the length of offset should be a 16-bit
6354 ;; signed value, because current assembler only supports REL type relocation for
6355 ;; such case. If the more powerful RELA type is supported in future, we should
6356 ;; update this pattern to go with better way.
6357 (define_split
6358 [(set (match_operand:SI 0 "arm_general_register_operand" "")
6359 (const:SI (plus:SI (match_operand:SI 1 "general_operand" "")
6360 (match_operand:SI 2 "const_int_operand" ""))))]
6361 "TARGET_THUMB2
6362 && arm_disable_literal_pool
6363 && reload_completed
6364 && GET_CODE (operands[1]) == SYMBOL_REF"
6365 [(clobber (const_int 0))]
6366 "
6367 int offset = INTVAL (operands[2]);
6368
6369 if (offset < -0x8000 || offset > 0x7fff)
6370 {
6371 arm_emit_movpair (operands[0], operands[1]);
6372 emit_insn (gen_rtx_SET (SImode, operands[0],
6373 gen_rtx_PLUS (SImode, operands[0], operands[2])));
6374 }
6375 else
6376 {
6377 rtx op = gen_rtx_CONST (SImode,
6378 gen_rtx_PLUS (SImode, operands[1], operands[2]));
6379 arm_emit_movpair (operands[0], op);
6380 }
6381 "
6382 )
6383
6384 ;; Split symbol_refs at the later stage (after cprop), instead of generating
6385 ;; movt/movw pair directly at expand. Otherwise corresponding high_sum
6386 ;; and lo_sum would be merged back into memory load at cprop. However,
6387 ;; if the default is to prefer movt/movw rather than a load from the constant
6388 ;; pool, the performance is better.
6389 (define_split
6390 [(set (match_operand:SI 0 "arm_general_register_operand" "")
6391 (match_operand:SI 1 "general_operand" ""))]
6392 "TARGET_32BIT
6393 && TARGET_USE_MOVT && GET_CODE (operands[1]) == SYMBOL_REF
6394 && !flag_pic && !target_word_relocations
6395 && !arm_tls_referenced_p (operands[1])"
6396 [(clobber (const_int 0))]
6397 {
6398 arm_emit_movpair (operands[0], operands[1]);
6399 DONE;
6400 })
6401
6402 (define_insn "*thumb1_movsi_insn"
6403 [(set (match_operand:SI 0 "nonimmediate_operand" "=l,l,l,l,l,>,l, m,*l*h*k")
6404 (match_operand:SI 1 "general_operand" "l, I,J,K,>,l,mi,l,*l*h*k"))]
6405 "TARGET_THUMB1
6406 && ( register_operand (operands[0], SImode)
6407 || register_operand (operands[1], SImode))"
6408 "@
6409 mov %0, %1
6410 mov %0, %1
6411 #
6412 #
6413 ldmia\\t%1, {%0}
6414 stmia\\t%0, {%1}
6415 ldr\\t%0, %1
6416 str\\t%1, %0
6417 mov\\t%0, %1"
6418 [(set_attr "length" "2,2,4,4,2,2,2,2,2")
6419 (set_attr "type" "mov_reg,mov_imm,multiple,multiple,load1,store1,load1,store1,mov_reg")
6420 (set_attr "pool_range" "*,*,*,*,*,*,1018,*,*")
6421 (set_attr "conds" "set,clob,*,*,nocond,nocond,nocond,nocond,nocond")])
6422
6423 (define_split
6424 [(set (match_operand:SI 0 "register_operand" "")
6425 (match_operand:SI 1 "const_int_operand" ""))]
6426 "TARGET_THUMB1 && satisfies_constraint_J (operands[1])"
6427 [(set (match_dup 2) (match_dup 1))
6428 (set (match_dup 0) (neg:SI (match_dup 2)))]
6429 "
6430 {
6431 operands[1] = GEN_INT (- INTVAL (operands[1]));
6432 operands[2] = can_create_pseudo_p () ? gen_reg_rtx (SImode) : operands[0];
6433 }"
6434 )
6435
6436 (define_split
6437 [(set (match_operand:SI 0 "register_operand" "")
6438 (match_operand:SI 1 "const_int_operand" ""))]
6439 "TARGET_THUMB1 && satisfies_constraint_K (operands[1])"
6440 [(set (match_dup 2) (match_dup 1))
6441 (set (match_dup 0) (ashift:SI (match_dup 2) (match_dup 3)))]
6442 "
6443 {
6444 unsigned HOST_WIDE_INT val = INTVAL (operands[1]) & 0xffffffffu;
6445 unsigned HOST_WIDE_INT mask = 0xff;
6446 int i;
6447
6448 for (i = 0; i < 25; i++)
6449 if ((val & (mask << i)) == val)
6450 break;
6451
6452 /* Don't split if the shift is zero. */
6453 if (i == 0)
6454 FAIL;
6455
6456 operands[1] = GEN_INT (val >> i);
6457 operands[2] = can_create_pseudo_p () ? gen_reg_rtx (SImode) : operands[0];
6458 operands[3] = GEN_INT (i);
6459 }"
6460 )
6461
6462 ;; For thumb1 split imm move [256-510] into mov [1-255] and add #255
6463 (define_split
6464 [(set (match_operand:SI 0 "register_operand" "")
6465 (match_operand:SI 1 "const_int_operand" ""))]
6466 "TARGET_THUMB1 && satisfies_constraint_Pe (operands[1])"
6467 [(set (match_dup 2) (match_dup 1))
6468 (set (match_dup 0) (plus:SI (match_dup 2) (match_dup 3)))]
6469 "
6470 {
6471 operands[1] = GEN_INT (INTVAL (operands[1]) - 255);
6472 operands[2] = can_create_pseudo_p () ? gen_reg_rtx (SImode) : operands[0];
6473 operands[3] = GEN_INT (255);
6474 }"
6475 )
6476
6477 ;; When generating pic, we need to load the symbol offset into a register.
6478 ;; So that the optimizer does not confuse this with a normal symbol load
6479 ;; we use an unspec. The offset will be loaded from a constant pool entry,
6480 ;; since that is the only type of relocation we can use.
6481
6482 ;; Wrap calculation of the whole PIC address in a single pattern for the
6483 ;; benefit of optimizers, particularly, PRE and HOIST. Calculation of
6484 ;; a PIC address involves two loads from memory, so we want to CSE it
6485 ;; as often as possible.
6486 ;; This pattern will be split into one of the pic_load_addr_* patterns
6487 ;; and a move after GCSE optimizations.
6488 ;;
6489 ;; Note: Update arm.c: legitimize_pic_address() when changing this pattern.
6490 (define_expand "calculate_pic_address"
6491 [(set (match_operand:SI 0 "register_operand" "")
6492 (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "")
6493 (unspec:SI [(match_operand:SI 2 "" "")]
6494 UNSPEC_PIC_SYM))))]
6495 "flag_pic"
6496 )
6497
6498 ;; Split calculate_pic_address into pic_load_addr_* and a move.
6499 (define_split
6500 [(set (match_operand:SI 0 "register_operand" "")
6501 (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "")
6502 (unspec:SI [(match_operand:SI 2 "" "")]
6503 UNSPEC_PIC_SYM))))]
6504 "flag_pic"
6505 [(set (match_dup 3) (unspec:SI [(match_dup 2)] UNSPEC_PIC_SYM))
6506 (set (match_dup 0) (mem:SI (plus:SI (match_dup 1) (match_dup 3))))]
6507 "operands[3] = can_create_pseudo_p () ? gen_reg_rtx (SImode) : operands[0];"
6508 )
6509
6510 ;; operand1 is the memory address to go into
6511 ;; pic_load_addr_32bit.
6512 ;; operand2 is the PIC label to be emitted
6513 ;; from pic_add_dot_plus_eight.
6514 ;; We do this to allow hoisting of the entire insn.
6515 (define_insn_and_split "pic_load_addr_unified"
6516 [(set (match_operand:SI 0 "s_register_operand" "=r,r,l")
6517 (unspec:SI [(match_operand:SI 1 "" "mX,mX,mX")
6518 (match_operand:SI 2 "" "")]
6519 UNSPEC_PIC_UNIFIED))]
6520 "flag_pic"
6521 "#"
6522 "&& reload_completed"
6523 [(set (match_dup 0) (unspec:SI [(match_dup 1)] UNSPEC_PIC_SYM))
6524 (set (match_dup 0) (unspec:SI [(match_dup 0) (match_dup 3)
6525 (match_dup 2)] UNSPEC_PIC_BASE))]
6526 "operands[3] = TARGET_THUMB ? GEN_INT (4) : GEN_INT (8);"
6527 [(set_attr "type" "load1,load1,load1")
6528 (set_attr "pool_range" "4096,4094,1022")
6529 (set_attr "neg_pool_range" "4084,0,0")
6530 (set_attr "arch" "a,t2,t1")
6531 (set_attr "length" "8,6,4")]
6532 )
6533
6534 ;; The rather odd constraints on the following are to force reload to leave
6535 ;; the insn alone, and to force the minipool generation pass to then move
6536 ;; the GOT symbol to memory.
6537
6538 (define_insn "pic_load_addr_32bit"
6539 [(set (match_operand:SI 0 "s_register_operand" "=r")
6540 (unspec:SI [(match_operand:SI 1 "" "mX")] UNSPEC_PIC_SYM))]
6541 "TARGET_32BIT && flag_pic"
6542 "ldr%?\\t%0, %1"
6543 [(set_attr "type" "load1")
6544 (set (attr "pool_range")
6545 (if_then_else (eq_attr "is_thumb" "no")
6546 (const_int 4096)
6547 (const_int 4094)))
6548 (set (attr "neg_pool_range")
6549 (if_then_else (eq_attr "is_thumb" "no")
6550 (const_int 4084)
6551 (const_int 0)))]
6552 )
6553
6554 (define_insn "pic_load_addr_thumb1"
6555 [(set (match_operand:SI 0 "s_register_operand" "=l")
6556 (unspec:SI [(match_operand:SI 1 "" "mX")] UNSPEC_PIC_SYM))]
6557 "TARGET_THUMB1 && flag_pic"
6558 "ldr\\t%0, %1"
6559 [(set_attr "type" "load1")
6560 (set (attr "pool_range") (const_int 1018))]
6561 )
6562
6563 (define_insn "pic_add_dot_plus_four"
6564 [(set (match_operand:SI 0 "register_operand" "=r")
6565 (unspec:SI [(match_operand:SI 1 "register_operand" "0")
6566 (const_int 4)
6567 (match_operand 2 "" "")]
6568 UNSPEC_PIC_BASE))]
6569 "TARGET_THUMB"
6570 "*
6571 (*targetm.asm_out.internal_label) (asm_out_file, \"LPIC\",
6572 INTVAL (operands[2]));
6573 return \"add\\t%0, %|pc\";
6574 "
6575 [(set_attr "length" "2")
6576 (set_attr "type" "alu_reg")]
6577 )
6578
6579 (define_insn "pic_add_dot_plus_eight"
6580 [(set (match_operand:SI 0 "register_operand" "=r")
6581 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
6582 (const_int 8)
6583 (match_operand 2 "" "")]
6584 UNSPEC_PIC_BASE))]
6585 "TARGET_ARM"
6586 "*
6587 (*targetm.asm_out.internal_label) (asm_out_file, \"LPIC\",
6588 INTVAL (operands[2]));
6589 return \"add%?\\t%0, %|pc, %1\";
6590 "
6591 [(set_attr "predicable" "yes")
6592 (set_attr "type" "alu_reg")]
6593 )
6594
6595 (define_insn "tls_load_dot_plus_eight"
6596 [(set (match_operand:SI 0 "register_operand" "=r")
6597 (mem:SI (unspec:SI [(match_operand:SI 1 "register_operand" "r")
6598 (const_int 8)
6599 (match_operand 2 "" "")]
6600 UNSPEC_PIC_BASE)))]
6601 "TARGET_ARM"
6602 "*
6603 (*targetm.asm_out.internal_label) (asm_out_file, \"LPIC\",
6604 INTVAL (operands[2]));
6605 return \"ldr%?\\t%0, [%|pc, %1]\t\t@ tls_load_dot_plus_eight\";
6606 "
6607 [(set_attr "predicable" "yes")
6608 (set_attr "type" "load1")]
6609 )
6610
6611 ;; PIC references to local variables can generate pic_add_dot_plus_eight
6612 ;; followed by a load. These sequences can be crunched down to
6613 ;; tls_load_dot_plus_eight by a peephole.
6614
6615 (define_peephole2
6616 [(set (match_operand:SI 0 "register_operand" "")
6617 (unspec:SI [(match_operand:SI 3 "register_operand" "")
6618 (const_int 8)
6619 (match_operand 1 "" "")]
6620 UNSPEC_PIC_BASE))
6621 (set (match_operand:SI 2 "arm_general_register_operand" "")
6622 (mem:SI (match_dup 0)))]
6623 "TARGET_ARM && peep2_reg_dead_p (2, operands[0])"
6624 [(set (match_dup 2)
6625 (mem:SI (unspec:SI [(match_dup 3)
6626 (const_int 8)
6627 (match_dup 1)]
6628 UNSPEC_PIC_BASE)))]
6629 ""
6630 )
6631
6632 (define_insn "pic_offset_arm"
6633 [(set (match_operand:SI 0 "register_operand" "=r")
6634 (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
6635 (unspec:SI [(match_operand:SI 2 "" "X")]
6636 UNSPEC_PIC_OFFSET))))]
6637 "TARGET_VXWORKS_RTP && TARGET_ARM && flag_pic"
6638 "ldr%?\\t%0, [%1,%2]"
6639 [(set_attr "type" "load1")]
6640 )
6641
6642 (define_expand "builtin_setjmp_receiver"
6643 [(label_ref (match_operand 0 "" ""))]
6644 "flag_pic"
6645 "
6646 {
6647 /* r3 is clobbered by set/longjmp, so we can use it as a scratch
6648 register. */
6649 if (arm_pic_register != INVALID_REGNUM)
6650 arm_load_pic_register (1UL << 3);
6651 DONE;
6652 }")
6653
6654 ;; If copying one reg to another we can set the condition codes according to
6655 ;; its value. Such a move is common after a return from subroutine and the
6656 ;; result is being tested against zero.
6657
6658 (define_insn "*movsi_compare0"
6659 [(set (reg:CC CC_REGNUM)
6660 (compare:CC (match_operand:SI 1 "s_register_operand" "0,r")
6661 (const_int 0)))
6662 (set (match_operand:SI 0 "s_register_operand" "=r,r")
6663 (match_dup 1))]
6664 "TARGET_32BIT"
6665 "@
6666 cmp%?\\t%0, #0
6667 sub%.\\t%0, %1, #0"
6668 [(set_attr "conds" "set")
6669 (set_attr "type" "alus_imm,alus_imm")]
6670 )
6671
6672 ;; Subroutine to store a half word from a register into memory.
6673 ;; Operand 0 is the source register (HImode)
6674 ;; Operand 1 is the destination address in a register (SImode)
6675
6676 ;; In both this routine and the next, we must be careful not to spill
6677 ;; a memory address of reg+large_const into a separate PLUS insn, since this
6678 ;; can generate unrecognizable rtl.
6679
6680 (define_expand "storehi"
6681 [;; store the low byte
6682 (set (match_operand 1 "" "") (match_dup 3))
6683 ;; extract the high byte
6684 (set (match_dup 2)
6685 (ashiftrt:SI (match_operand 0 "" "") (const_int 8)))
6686 ;; store the high byte
6687 (set (match_dup 4) (match_dup 5))]
6688 "TARGET_ARM"
6689 "
6690 {
6691 rtx op1 = operands[1];
6692 rtx addr = XEXP (op1, 0);
6693 enum rtx_code code = GET_CODE (addr);
6694
6695 if ((code == PLUS && !CONST_INT_P (XEXP (addr, 1)))
6696 || code == MINUS)
6697 op1 = replace_equiv_address (operands[1], force_reg (SImode, addr));
6698
6699 operands[4] = adjust_address (op1, QImode, 1);
6700 operands[1] = adjust_address (operands[1], QImode, 0);
6701 operands[3] = gen_lowpart (QImode, operands[0]);
6702 operands[0] = gen_lowpart (SImode, operands[0]);
6703 operands[2] = gen_reg_rtx (SImode);
6704 operands[5] = gen_lowpart (QImode, operands[2]);
6705 }"
6706 )
6707
6708 (define_expand "storehi_bigend"
6709 [(set (match_dup 4) (match_dup 3))
6710 (set (match_dup 2)
6711 (ashiftrt:SI (match_operand 0 "" "") (const_int 8)))
6712 (set (match_operand 1 "" "") (match_dup 5))]
6713 "TARGET_ARM"
6714 "
6715 {
6716 rtx op1 = operands[1];
6717 rtx addr = XEXP (op1, 0);
6718 enum rtx_code code = GET_CODE (addr);
6719
6720 if ((code == PLUS && !CONST_INT_P (XEXP (addr, 1)))
6721 || code == MINUS)
6722 op1 = replace_equiv_address (op1, force_reg (SImode, addr));
6723
6724 operands[4] = adjust_address (op1, QImode, 1);
6725 operands[1] = adjust_address (operands[1], QImode, 0);
6726 operands[3] = gen_lowpart (QImode, operands[0]);
6727 operands[0] = gen_lowpart (SImode, operands[0]);
6728 operands[2] = gen_reg_rtx (SImode);
6729 operands[5] = gen_lowpart (QImode, operands[2]);
6730 }"
6731 )
6732
6733 ;; Subroutine to store a half word integer constant into memory.
6734 (define_expand "storeinthi"
6735 [(set (match_operand 0 "" "")
6736 (match_operand 1 "" ""))
6737 (set (match_dup 3) (match_dup 2))]
6738 "TARGET_ARM"
6739 "
6740 {
6741 HOST_WIDE_INT value = INTVAL (operands[1]);
6742 rtx addr = XEXP (operands[0], 0);
6743 rtx op0 = operands[0];
6744 enum rtx_code code = GET_CODE (addr);
6745
6746 if ((code == PLUS && !CONST_INT_P (XEXP (addr, 1)))
6747 || code == MINUS)
6748 op0 = replace_equiv_address (op0, force_reg (SImode, addr));
6749
6750 operands[1] = gen_reg_rtx (SImode);
6751 if (BYTES_BIG_ENDIAN)
6752 {
6753 emit_insn (gen_movsi (operands[1], GEN_INT ((value >> 8) & 255)));
6754 if ((value & 255) == ((value >> 8) & 255))
6755 operands[2] = operands[1];
6756 else
6757 {
6758 operands[2] = gen_reg_rtx (SImode);
6759 emit_insn (gen_movsi (operands[2], GEN_INT (value & 255)));
6760 }
6761 }
6762 else
6763 {
6764 emit_insn (gen_movsi (operands[1], GEN_INT (value & 255)));
6765 if ((value & 255) == ((value >> 8) & 255))
6766 operands[2] = operands[1];
6767 else
6768 {
6769 operands[2] = gen_reg_rtx (SImode);
6770 emit_insn (gen_movsi (operands[2], GEN_INT ((value >> 8) & 255)));
6771 }
6772 }
6773
6774 operands[3] = adjust_address (op0, QImode, 1);
6775 operands[0] = adjust_address (operands[0], QImode, 0);
6776 operands[2] = gen_lowpart (QImode, operands[2]);
6777 operands[1] = gen_lowpart (QImode, operands[1]);
6778 }"
6779 )
6780
6781 (define_expand "storehi_single_op"
6782 [(set (match_operand:HI 0 "memory_operand" "")
6783 (match_operand:HI 1 "general_operand" ""))]
6784 "TARGET_32BIT && arm_arch4"
6785 "
6786 if (!s_register_operand (operands[1], HImode))
6787 operands[1] = copy_to_mode_reg (HImode, operands[1]);
6788 "
6789 )
6790
6791 (define_expand "movhi"
6792 [(set (match_operand:HI 0 "general_operand" "")
6793 (match_operand:HI 1 "general_operand" ""))]
6794 "TARGET_EITHER"
6795 "
6796 if (TARGET_ARM)
6797 {
6798 if (can_create_pseudo_p ())
6799 {
6800 if (MEM_P (operands[0]))
6801 {
6802 if (arm_arch4)
6803 {
6804 emit_insn (gen_storehi_single_op (operands[0], operands[1]));
6805 DONE;
6806 }
6807 if (CONST_INT_P (operands[1]))
6808 emit_insn (gen_storeinthi (operands[0], operands[1]));
6809 else
6810 {
6811 if (MEM_P (operands[1]))
6812 operands[1] = force_reg (HImode, operands[1]);
6813 if (BYTES_BIG_ENDIAN)
6814 emit_insn (gen_storehi_bigend (operands[1], operands[0]));
6815 else
6816 emit_insn (gen_storehi (operands[1], operands[0]));
6817 }
6818 DONE;
6819 }
6820 /* Sign extend a constant, and keep it in an SImode reg. */
6821 else if (CONST_INT_P (operands[1]))
6822 {
6823 rtx reg = gen_reg_rtx (SImode);
6824 HOST_WIDE_INT val = INTVAL (operands[1]) & 0xffff;
6825
6826 /* If the constant is already valid, leave it alone. */
6827 if (!const_ok_for_arm (val))
6828 {
6829 /* If setting all the top bits will make the constant
6830 loadable in a single instruction, then set them.
6831 Otherwise, sign extend the number. */
6832
6833 if (const_ok_for_arm (~(val | ~0xffff)))
6834 val |= ~0xffff;
6835 else if (val & 0x8000)
6836 val |= ~0xffff;
6837 }
6838
6839 emit_insn (gen_movsi (reg, GEN_INT (val)));
6840 operands[1] = gen_lowpart (HImode, reg);
6841 }
6842 else if (arm_arch4 && optimize && can_create_pseudo_p ()
6843 && MEM_P (operands[1]))
6844 {
6845 rtx reg = gen_reg_rtx (SImode);
6846
6847 emit_insn (gen_zero_extendhisi2 (reg, operands[1]));
6848 operands[1] = gen_lowpart (HImode, reg);
6849 }
6850 else if (!arm_arch4)
6851 {
6852 if (MEM_P (operands[1]))
6853 {
6854 rtx base;
6855 rtx offset = const0_rtx;
6856 rtx reg = gen_reg_rtx (SImode);
6857
6858 if ((REG_P (base = XEXP (operands[1], 0))
6859 || (GET_CODE (base) == PLUS
6860 && (CONST_INT_P (offset = XEXP (base, 1)))
6861 && ((INTVAL(offset) & 1) != 1)
6862 && REG_P (base = XEXP (base, 0))))
6863 && REGNO_POINTER_ALIGN (REGNO (base)) >= 32)
6864 {
6865 rtx new_rtx;
6866
6867 new_rtx = widen_memory_access (operands[1], SImode,
6868 ((INTVAL (offset) & ~3)
6869 - INTVAL (offset)));
6870 emit_insn (gen_movsi (reg, new_rtx));
6871 if (((INTVAL (offset) & 2) != 0)
6872 ^ (BYTES_BIG_ENDIAN ? 1 : 0))
6873 {
6874 rtx reg2 = gen_reg_rtx (SImode);
6875
6876 emit_insn (gen_lshrsi3 (reg2, reg, GEN_INT (16)));
6877 reg = reg2;
6878 }
6879 }
6880 else
6881 emit_insn (gen_movhi_bytes (reg, operands[1]));
6882
6883 operands[1] = gen_lowpart (HImode, reg);
6884 }
6885 }
6886 }
6887 /* Handle loading a large integer during reload. */
6888 else if (CONST_INT_P (operands[1])
6889 && !const_ok_for_arm (INTVAL (operands[1]))
6890 && !const_ok_for_arm (~INTVAL (operands[1])))
6891 {
6892 /* Writing a constant to memory needs a scratch, which should
6893 be handled with SECONDARY_RELOADs. */
6894 gcc_assert (REG_P (operands[0]));
6895
6896 operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
6897 emit_insn (gen_movsi (operands[0], operands[1]));
6898 DONE;
6899 }
6900 }
6901 else if (TARGET_THUMB2)
6902 {
6903 /* Thumb-2 can do everything except mem=mem and mem=const easily. */
6904 if (can_create_pseudo_p ())
6905 {
6906 if (!REG_P (operands[0]))
6907 operands[1] = force_reg (HImode, operands[1]);
6908 /* Zero extend a constant, and keep it in an SImode reg. */
6909 else if (CONST_INT_P (operands[1]))
6910 {
6911 rtx reg = gen_reg_rtx (SImode);
6912 HOST_WIDE_INT val = INTVAL (operands[1]) & 0xffff;
6913
6914 emit_insn (gen_movsi (reg, GEN_INT (val)));
6915 operands[1] = gen_lowpart (HImode, reg);
6916 }
6917 }
6918 }
6919 else /* TARGET_THUMB1 */
6920 {
6921 if (can_create_pseudo_p ())
6922 {
6923 if (CONST_INT_P (operands[1]))
6924 {
6925 rtx reg = gen_reg_rtx (SImode);
6926
6927 emit_insn (gen_movsi (reg, operands[1]));
6928 operands[1] = gen_lowpart (HImode, reg);
6929 }
6930
6931 /* ??? We shouldn't really get invalid addresses here, but this can
6932 happen if we are passed a SP (never OK for HImode/QImode) or
6933 virtual register (also rejected as illegitimate for HImode/QImode)
6934 relative address. */
6935 /* ??? This should perhaps be fixed elsewhere, for instance, in
6936 fixup_stack_1, by checking for other kinds of invalid addresses,
6937 e.g. a bare reference to a virtual register. This may confuse the
6938 alpha though, which must handle this case differently. */
6939 if (MEM_P (operands[0])
6940 && !memory_address_p (GET_MODE (operands[0]),
6941 XEXP (operands[0], 0)))
6942 operands[0]
6943 = replace_equiv_address (operands[0],
6944 copy_to_reg (XEXP (operands[0], 0)));
6945
6946 if (MEM_P (operands[1])
6947 && !memory_address_p (GET_MODE (operands[1]),
6948 XEXP (operands[1], 0)))
6949 operands[1]
6950 = replace_equiv_address (operands[1],
6951 copy_to_reg (XEXP (operands[1], 0)));
6952
6953 if (MEM_P (operands[1]) && optimize > 0)
6954 {
6955 rtx reg = gen_reg_rtx (SImode);
6956
6957 emit_insn (gen_zero_extendhisi2 (reg, operands[1]));
6958 operands[1] = gen_lowpart (HImode, reg);
6959 }
6960
6961 if (MEM_P (operands[0]))
6962 operands[1] = force_reg (HImode, operands[1]);
6963 }
6964 else if (CONST_INT_P (operands[1])
6965 && !satisfies_constraint_I (operands[1]))
6966 {
6967 /* Handle loading a large integer during reload. */
6968
6969 /* Writing a constant to memory needs a scratch, which should
6970 be handled with SECONDARY_RELOADs. */
6971 gcc_assert (REG_P (operands[0]));
6972
6973 operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
6974 emit_insn (gen_movsi (operands[0], operands[1]));
6975 DONE;
6976 }
6977 }
6978 "
6979 )
6980
6981 (define_insn "*thumb1_movhi_insn"
6982 [(set (match_operand:HI 0 "nonimmediate_operand" "=l,l,m,*r,*h,l")
6983 (match_operand:HI 1 "general_operand" "l,m,l,*h,*r,I"))]
6984 "TARGET_THUMB1
6985 && ( register_operand (operands[0], HImode)
6986 || register_operand (operands[1], HImode))"
6987 "*
6988 switch (which_alternative)
6989 {
6990 case 0: return \"add %0, %1, #0\";
6991 case 2: return \"strh %1, %0\";
6992 case 3: return \"mov %0, %1\";
6993 case 4: return \"mov %0, %1\";
6994 case 5: return \"mov %0, %1\";
6995 default: gcc_unreachable ();
6996 case 1:
6997 /* The stack pointer can end up being taken as an index register.
6998 Catch this case here and deal with it. */
6999 if (GET_CODE (XEXP (operands[1], 0)) == PLUS
7000 && REG_P (XEXP (XEXP (operands[1], 0), 0))
7001 && REGNO (XEXP (XEXP (operands[1], 0), 0)) == SP_REGNUM)
7002 {
7003 rtx ops[2];
7004 ops[0] = operands[0];
7005 ops[1] = XEXP (XEXP (operands[1], 0), 0);
7006
7007 output_asm_insn (\"mov %0, %1\", ops);
7008
7009 XEXP (XEXP (operands[1], 0), 0) = operands[0];
7010
7011 }
7012 return \"ldrh %0, %1\";
7013 }"
7014 [(set_attr "length" "2,4,2,2,2,2")
7015 (set_attr "type" "alus_imm,load1,store1,mov_reg,mov_reg,mov_imm")
7016 (set_attr "conds" "clob,nocond,nocond,nocond,nocond,clob")])
7017
7018
7019 (define_expand "movhi_bytes"
7020 [(set (match_dup 2) (zero_extend:SI (match_operand:HI 1 "" "")))
7021 (set (match_dup 3)
7022 (zero_extend:SI (match_dup 6)))
7023 (set (match_operand:SI 0 "" "")
7024 (ior:SI (ashift:SI (match_dup 4) (const_int 8)) (match_dup 5)))]
7025 "TARGET_ARM"
7026 "
7027 {
7028 rtx mem1, mem2;
7029 rtx addr = copy_to_mode_reg (SImode, XEXP (operands[1], 0));
7030
7031 mem1 = change_address (operands[1], QImode, addr);
7032 mem2 = change_address (operands[1], QImode,
7033 plus_constant (Pmode, addr, 1));
7034 operands[0] = gen_lowpart (SImode, operands[0]);
7035 operands[1] = mem1;
7036 operands[2] = gen_reg_rtx (SImode);
7037 operands[3] = gen_reg_rtx (SImode);
7038 operands[6] = mem2;
7039
7040 if (BYTES_BIG_ENDIAN)
7041 {
7042 operands[4] = operands[2];
7043 operands[5] = operands[3];
7044 }
7045 else
7046 {
7047 operands[4] = operands[3];
7048 operands[5] = operands[2];
7049 }
7050 }"
7051 )
7052
7053 (define_expand "movhi_bigend"
7054 [(set (match_dup 2)
7055 (rotate:SI (subreg:SI (match_operand:HI 1 "memory_operand" "") 0)
7056 (const_int 16)))
7057 (set (match_dup 3)
7058 (ashiftrt:SI (match_dup 2) (const_int 16)))
7059 (set (match_operand:HI 0 "s_register_operand" "")
7060 (match_dup 4))]
7061 "TARGET_ARM"
7062 "
7063 operands[2] = gen_reg_rtx (SImode);
7064 operands[3] = gen_reg_rtx (SImode);
7065 operands[4] = gen_lowpart (HImode, operands[3]);
7066 "
7067 )
7068
7069 ;; Pattern to recognize insn generated default case above
7070 (define_insn "*movhi_insn_arch4"
7071 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,m,r")
7072 (match_operand:HI 1 "general_operand" "rI,K,r,mi"))]
7073 "TARGET_ARM
7074 && arm_arch4
7075 && (register_operand (operands[0], HImode)
7076 || register_operand (operands[1], HImode))"
7077 "@
7078 mov%?\\t%0, %1\\t%@ movhi
7079 mvn%?\\t%0, #%B1\\t%@ movhi
7080 str%(h%)\\t%1, %0\\t%@ movhi
7081 ldr%(h%)\\t%0, %1\\t%@ movhi"
7082 [(set_attr "predicable" "yes")
7083 (set_attr "pool_range" "*,*,*,256")
7084 (set_attr "neg_pool_range" "*,*,*,244")
7085 (set_attr_alternative "type"
7086 [(if_then_else (match_operand 1 "const_int_operand" "")
7087 (const_string "mov_imm" )
7088 (const_string "mov_reg"))
7089 (const_string "mvn_imm")
7090 (const_string "store1")
7091 (const_string "load1")])]
7092 )
7093
7094 (define_insn "*movhi_bytes"
7095 [(set (match_operand:HI 0 "s_register_operand" "=r,r,r")
7096 (match_operand:HI 1 "arm_rhs_operand" "I,r,K"))]
7097 "TARGET_ARM"
7098 "@
7099 mov%?\\t%0, %1\\t%@ movhi
7100 mov%?\\t%0, %1\\t%@ movhi
7101 mvn%?\\t%0, #%B1\\t%@ movhi"
7102 [(set_attr "predicable" "yes")
7103 (set_attr "type" "mov_imm,mov_reg,mvn_imm")]
7104 )
7105
7106 (define_expand "thumb_movhi_clobber"
7107 [(set (match_operand:HI 0 "memory_operand" "")
7108 (match_operand:HI 1 "register_operand" ""))
7109 (clobber (match_operand:DI 2 "register_operand" ""))]
7110 "TARGET_THUMB1"
7111 "
7112 if (strict_memory_address_p (HImode, XEXP (operands[0], 0))
7113 && REGNO (operands[1]) <= LAST_LO_REGNUM)
7114 {
7115 emit_insn (gen_movhi (operands[0], operands[1]));
7116 DONE;
7117 }
7118 /* XXX Fixme, need to handle other cases here as well. */
7119 gcc_unreachable ();
7120 "
7121 )
7122
7123 ;; We use a DImode scratch because we may occasionally need an additional
7124 ;; temporary if the address isn't offsettable -- push_reload doesn't seem
7125 ;; to take any notice of the "o" constraints on reload_memory_operand operand.
7126 (define_expand "reload_outhi"
7127 [(parallel [(match_operand:HI 0 "arm_reload_memory_operand" "=o")
7128 (match_operand:HI 1 "s_register_operand" "r")
7129 (match_operand:DI 2 "s_register_operand" "=&l")])]
7130 "TARGET_EITHER"
7131 "if (TARGET_ARM)
7132 arm_reload_out_hi (operands);
7133 else
7134 thumb_reload_out_hi (operands);
7135 DONE;
7136 "
7137 )
7138
7139 (define_expand "reload_inhi"
7140 [(parallel [(match_operand:HI 0 "s_register_operand" "=r")
7141 (match_operand:HI 1 "arm_reload_memory_operand" "o")
7142 (match_operand:DI 2 "s_register_operand" "=&r")])]
7143 "TARGET_EITHER"
7144 "
7145 if (TARGET_ARM)
7146 arm_reload_in_hi (operands);
7147 else
7148 thumb_reload_out_hi (operands);
7149 DONE;
7150 ")
7151
7152 (define_expand "movqi"
7153 [(set (match_operand:QI 0 "general_operand" "")
7154 (match_operand:QI 1 "general_operand" ""))]
7155 "TARGET_EITHER"
7156 "
7157 /* Everything except mem = const or mem = mem can be done easily */
7158
7159 if (can_create_pseudo_p ())
7160 {
7161 if (CONST_INT_P (operands[1]))
7162 {
7163 rtx reg = gen_reg_rtx (SImode);
7164
7165 /* For thumb we want an unsigned immediate, then we are more likely
7166 to be able to use a movs insn. */
7167 if (TARGET_THUMB)
7168 operands[1] = GEN_INT (INTVAL (operands[1]) & 255);
7169
7170 emit_insn (gen_movsi (reg, operands[1]));
7171 operands[1] = gen_lowpart (QImode, reg);
7172 }
7173
7174 if (TARGET_THUMB)
7175 {
7176 /* ??? We shouldn't really get invalid addresses here, but this can
7177 happen if we are passed a SP (never OK for HImode/QImode) or
7178 virtual register (also rejected as illegitimate for HImode/QImode)
7179 relative address. */
7180 /* ??? This should perhaps be fixed elsewhere, for instance, in
7181 fixup_stack_1, by checking for other kinds of invalid addresses,
7182 e.g. a bare reference to a virtual register. This may confuse the
7183 alpha though, which must handle this case differently. */
7184 if (MEM_P (operands[0])
7185 && !memory_address_p (GET_MODE (operands[0]),
7186 XEXP (operands[0], 0)))
7187 operands[0]
7188 = replace_equiv_address (operands[0],
7189 copy_to_reg (XEXP (operands[0], 0)));
7190 if (MEM_P (operands[1])
7191 && !memory_address_p (GET_MODE (operands[1]),
7192 XEXP (operands[1], 0)))
7193 operands[1]
7194 = replace_equiv_address (operands[1],
7195 copy_to_reg (XEXP (operands[1], 0)));
7196 }
7197
7198 if (MEM_P (operands[1]) && optimize > 0)
7199 {
7200 rtx reg = gen_reg_rtx (SImode);
7201
7202 emit_insn (gen_zero_extendqisi2 (reg, operands[1]));
7203 operands[1] = gen_lowpart (QImode, reg);
7204 }
7205
7206 if (MEM_P (operands[0]))
7207 operands[1] = force_reg (QImode, operands[1]);
7208 }
7209 else if (TARGET_THUMB
7210 && CONST_INT_P (operands[1])
7211 && !satisfies_constraint_I (operands[1]))
7212 {
7213 /* Handle loading a large integer during reload. */
7214
7215 /* Writing a constant to memory needs a scratch, which should
7216 be handled with SECONDARY_RELOADs. */
7217 gcc_assert (REG_P (operands[0]));
7218
7219 operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
7220 emit_insn (gen_movsi (operands[0], operands[1]));
7221 DONE;
7222 }
7223 "
7224 )
7225
7226 (define_insn "*arm_movqi_insn"
7227 [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,r,l,r,l,Uu,r,m")
7228 (match_operand:QI 1 "general_operand" "r,r,I,Py,K,Uu,l,m,r"))]
7229 "TARGET_32BIT
7230 && ( register_operand (operands[0], QImode)
7231 || register_operand (operands[1], QImode))"
7232 "@
7233 mov%?\\t%0, %1
7234 mov%?\\t%0, %1
7235 mov%?\\t%0, %1
7236 mov%?\\t%0, %1
7237 mvn%?\\t%0, #%B1
7238 ldr%(b%)\\t%0, %1
7239 str%(b%)\\t%1, %0
7240 ldr%(b%)\\t%0, %1
7241 str%(b%)\\t%1, %0"
7242 [(set_attr "type" "mov_reg,mov_reg,mov_imm,mov_imm,mvn_imm,load1,store1,load1,store1")
7243 (set_attr "predicable" "yes")
7244 (set_attr "predicable_short_it" "yes,yes,yes,no,no,no,no,no,no")
7245 (set_attr "arch" "t2,any,any,t2,any,t2,t2,any,any")
7246 (set_attr "length" "2,4,4,2,4,2,2,4,4")]
7247 )
7248
7249 (define_insn "*thumb1_movqi_insn"
7250 [(set (match_operand:QI 0 "nonimmediate_operand" "=l,l,m,*r,*h,l")
7251 (match_operand:QI 1 "general_operand" "l, m,l,*h,*r,I"))]
7252 "TARGET_THUMB1
7253 && ( register_operand (operands[0], QImode)
7254 || register_operand (operands[1], QImode))"
7255 "@
7256 add\\t%0, %1, #0
7257 ldrb\\t%0, %1
7258 strb\\t%1, %0
7259 mov\\t%0, %1
7260 mov\\t%0, %1
7261 mov\\t%0, %1"
7262 [(set_attr "length" "2")
7263 (set_attr "type" "alu_imm,load1,store1,mov_reg,mov_imm,mov_imm")
7264 (set_attr "pool_range" "*,32,*,*,*,*")
7265 (set_attr "conds" "clob,nocond,nocond,nocond,nocond,clob")])
7266
7267 ;; HFmode moves
7268 (define_expand "movhf"
7269 [(set (match_operand:HF 0 "general_operand" "")
7270 (match_operand:HF 1 "general_operand" ""))]
7271 "TARGET_EITHER"
7272 "
7273 if (TARGET_32BIT)
7274 {
7275 if (MEM_P (operands[0]))
7276 operands[1] = force_reg (HFmode, operands[1]);
7277 }
7278 else /* TARGET_THUMB1 */
7279 {
7280 if (can_create_pseudo_p ())
7281 {
7282 if (!REG_P (operands[0]))
7283 operands[1] = force_reg (HFmode, operands[1]);
7284 }
7285 }
7286 "
7287 )
7288
7289 (define_insn "*arm32_movhf"
7290 [(set (match_operand:HF 0 "nonimmediate_operand" "=r,m,r,r")
7291 (match_operand:HF 1 "general_operand" " m,r,r,F"))]
7292 "TARGET_32BIT && !(TARGET_HARD_FLOAT && TARGET_FP16) && !arm_restrict_it
7293 && ( s_register_operand (operands[0], HFmode)
7294 || s_register_operand (operands[1], HFmode))"
7295 "*
7296 switch (which_alternative)
7297 {
7298 case 0: /* ARM register from memory */
7299 return \"ldr%(h%)\\t%0, %1\\t%@ __fp16\";
7300 case 1: /* memory from ARM register */
7301 return \"str%(h%)\\t%1, %0\\t%@ __fp16\";
7302 case 2: /* ARM register from ARM register */
7303 return \"mov%?\\t%0, %1\\t%@ __fp16\";
7304 case 3: /* ARM register from constant */
7305 {
7306 REAL_VALUE_TYPE r;
7307 long bits;
7308 rtx ops[4];
7309
7310 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
7311 bits = real_to_target (NULL, &r, HFmode);
7312 ops[0] = operands[0];
7313 ops[1] = GEN_INT (bits);
7314 ops[2] = GEN_INT (bits & 0xff00);
7315 ops[3] = GEN_INT (bits & 0x00ff);
7316
7317 if (arm_arch_thumb2)
7318 output_asm_insn (\"movw%?\\t%0, %1\", ops);
7319 else
7320 output_asm_insn (\"mov%?\\t%0, %2\;orr%?\\t%0, %0, %3\", ops);
7321 return \"\";
7322 }
7323 default:
7324 gcc_unreachable ();
7325 }
7326 "
7327 [(set_attr "conds" "unconditional")
7328 (set_attr "type" "load1,store1,mov_reg,multiple")
7329 (set_attr "length" "4,4,4,8")
7330 (set_attr "predicable" "yes")]
7331 )
7332
7333 (define_insn "*thumb1_movhf"
7334 [(set (match_operand:HF 0 "nonimmediate_operand" "=l,l,m,*r,*h")
7335 (match_operand:HF 1 "general_operand" "l,mF,l,*h,*r"))]
7336 "TARGET_THUMB1
7337 && ( s_register_operand (operands[0], HFmode)
7338 || s_register_operand (operands[1], HFmode))"
7339 "*
7340 switch (which_alternative)
7341 {
7342 case 1:
7343 {
7344 rtx addr;
7345 gcc_assert (MEM_P (operands[1]));
7346 addr = XEXP (operands[1], 0);
7347 if (GET_CODE (addr) == LABEL_REF
7348 || (GET_CODE (addr) == CONST
7349 && GET_CODE (XEXP (addr, 0)) == PLUS
7350 && GET_CODE (XEXP (XEXP (addr, 0), 0)) == LABEL_REF
7351 && CONST_INT_P (XEXP (XEXP (addr, 0), 1))))
7352 {
7353 /* Constant pool entry. */
7354 return \"ldr\\t%0, %1\";
7355 }
7356 return \"ldrh\\t%0, %1\";
7357 }
7358 case 2: return \"strh\\t%1, %0\";
7359 default: return \"mov\\t%0, %1\";
7360 }
7361 "
7362 [(set_attr "length" "2")
7363 (set_attr "type" "mov_reg,load1,store1,mov_reg,mov_reg")
7364 (set_attr "pool_range" "*,1018,*,*,*")
7365 (set_attr "conds" "clob,nocond,nocond,nocond,nocond")])
7366
7367 (define_expand "movsf"
7368 [(set (match_operand:SF 0 "general_operand" "")
7369 (match_operand:SF 1 "general_operand" ""))]
7370 "TARGET_EITHER"
7371 "
7372 if (TARGET_32BIT)
7373 {
7374 if (MEM_P (operands[0]))
7375 operands[1] = force_reg (SFmode, operands[1]);
7376 }
7377 else /* TARGET_THUMB1 */
7378 {
7379 if (can_create_pseudo_p ())
7380 {
7381 if (!REG_P (operands[0]))
7382 operands[1] = force_reg (SFmode, operands[1]);
7383 }
7384 }
7385 "
7386 )
7387
7388 ;; Transform a floating-point move of a constant into a core register into
7389 ;; an SImode operation.
7390 (define_split
7391 [(set (match_operand:SF 0 "arm_general_register_operand" "")
7392 (match_operand:SF 1 "immediate_operand" ""))]
7393 "TARGET_EITHER
7394 && reload_completed
7395 && CONST_DOUBLE_P (operands[1])"
7396 [(set (match_dup 2) (match_dup 3))]
7397 "
7398 operands[2] = gen_lowpart (SImode, operands[0]);
7399 operands[3] = gen_lowpart (SImode, operands[1]);
7400 if (operands[2] == 0 || operands[3] == 0)
7401 FAIL;
7402 "
7403 )
7404
7405 (define_insn "*arm_movsf_soft_insn"
7406 [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,m")
7407 (match_operand:SF 1 "general_operand" "r,mE,r"))]
7408 "TARGET_32BIT
7409 && TARGET_SOFT_FLOAT
7410 && (!MEM_P (operands[0])
7411 || register_operand (operands[1], SFmode))"
7412 "@
7413 mov%?\\t%0, %1
7414 ldr%?\\t%0, %1\\t%@ float
7415 str%?\\t%1, %0\\t%@ float"
7416 [(set_attr "predicable" "yes")
7417 (set_attr "predicable_short_it" "no")
7418 (set_attr "type" "mov_reg,load1,store1")
7419 (set_attr "arm_pool_range" "*,4096,*")
7420 (set_attr "thumb2_pool_range" "*,4094,*")
7421 (set_attr "arm_neg_pool_range" "*,4084,*")
7422 (set_attr "thumb2_neg_pool_range" "*,0,*")]
7423 )
7424
7425 ;;; ??? This should have alternatives for constants.
7426 (define_insn "*thumb1_movsf_insn"
7427 [(set (match_operand:SF 0 "nonimmediate_operand" "=l,l,>,l, m,*r,*h")
7428 (match_operand:SF 1 "general_operand" "l, >,l,mF,l,*h,*r"))]
7429 "TARGET_THUMB1
7430 && ( register_operand (operands[0], SFmode)
7431 || register_operand (operands[1], SFmode))"
7432 "@
7433 add\\t%0, %1, #0
7434 ldmia\\t%1, {%0}
7435 stmia\\t%0, {%1}
7436 ldr\\t%0, %1
7437 str\\t%1, %0
7438 mov\\t%0, %1
7439 mov\\t%0, %1"
7440 [(set_attr "length" "2")
7441 (set_attr "type" "alus_imm,load1,store1,load1,store1,mov_reg,mov_reg")
7442 (set_attr "pool_range" "*,*,*,1018,*,*,*")
7443 (set_attr "conds" "clob,nocond,nocond,nocond,nocond,nocond,nocond")]
7444 )
7445
7446 (define_expand "movdf"
7447 [(set (match_operand:DF 0 "general_operand" "")
7448 (match_operand:DF 1 "general_operand" ""))]
7449 "TARGET_EITHER"
7450 "
7451 if (TARGET_32BIT)
7452 {
7453 if (MEM_P (operands[0]))
7454 operands[1] = force_reg (DFmode, operands[1]);
7455 }
7456 else /* TARGET_THUMB */
7457 {
7458 if (can_create_pseudo_p ())
7459 {
7460 if (!REG_P (operands[0]))
7461 operands[1] = force_reg (DFmode, operands[1]);
7462 }
7463 }
7464 "
7465 )
7466
7467 ;; Reloading a df mode value stored in integer regs to memory can require a
7468 ;; scratch reg.
7469 (define_expand "reload_outdf"
7470 [(match_operand:DF 0 "arm_reload_memory_operand" "=o")
7471 (match_operand:DF 1 "s_register_operand" "r")
7472 (match_operand:SI 2 "s_register_operand" "=&r")]
7473 "TARGET_THUMB2"
7474 "
7475 {
7476 enum rtx_code code = GET_CODE (XEXP (operands[0], 0));
7477
7478 if (code == REG)
7479 operands[2] = XEXP (operands[0], 0);
7480 else if (code == POST_INC || code == PRE_DEC)
7481 {
7482 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7483 operands[1] = gen_rtx_SUBREG (DImode, operands[1], 0);
7484 emit_insn (gen_movdi (operands[0], operands[1]));
7485 DONE;
7486 }
7487 else if (code == PRE_INC)
7488 {
7489 rtx reg = XEXP (XEXP (operands[0], 0), 0);
7490
7491 emit_insn (gen_addsi3 (reg, reg, GEN_INT (8)));
7492 operands[2] = reg;
7493 }
7494 else if (code == POST_DEC)
7495 operands[2] = XEXP (XEXP (operands[0], 0), 0);
7496 else
7497 emit_insn (gen_addsi3 (operands[2], XEXP (XEXP (operands[0], 0), 0),
7498 XEXP (XEXP (operands[0], 0), 1)));
7499
7500 emit_insn (gen_rtx_SET (VOIDmode,
7501 replace_equiv_address (operands[0], operands[2]),
7502 operands[1]));
7503
7504 if (code == POST_DEC)
7505 emit_insn (gen_addsi3 (operands[2], operands[2], GEN_INT (-8)));
7506
7507 DONE;
7508 }"
7509 )
7510
7511 (define_insn "*movdf_soft_insn"
7512 [(set (match_operand:DF 0 "nonimmediate_soft_df_operand" "=r,r,r,q,m")
7513 (match_operand:DF 1 "soft_df_operand" "rDa,Db,Dc,mF,q"))]
7514 "TARGET_32BIT && TARGET_SOFT_FLOAT
7515 && ( register_operand (operands[0], DFmode)
7516 || register_operand (operands[1], DFmode))"
7517 "*
7518 switch (which_alternative)
7519 {
7520 case 0:
7521 case 1:
7522 case 2:
7523 return \"#\";
7524 default:
7525 return output_move_double (operands, true, NULL);
7526 }
7527 "
7528 [(set_attr "length" "8,12,16,8,8")
7529 (set_attr "type" "multiple,multiple,multiple,load2,store2")
7530 (set_attr "arm_pool_range" "*,*,*,1020,*")
7531 (set_attr "thumb2_pool_range" "*,*,*,1018,*")
7532 (set_attr "arm_neg_pool_range" "*,*,*,1004,*")
7533 (set_attr "thumb2_neg_pool_range" "*,*,*,0,*")]
7534 )
7535
7536 ;;; ??? This should have alternatives for constants.
7537 ;;; ??? This was originally identical to the movdi_insn pattern.
7538 ;;; ??? The 'F' constraint looks funny, but it should always be replaced by
7539 ;;; thumb_reorg with a memory reference.
7540 (define_insn "*thumb_movdf_insn"
7541 [(set (match_operand:DF 0 "nonimmediate_operand" "=l,l,>,l, m,*r")
7542 (match_operand:DF 1 "general_operand" "l, >,l,mF,l,*r"))]
7543 "TARGET_THUMB1
7544 && ( register_operand (operands[0], DFmode)
7545 || register_operand (operands[1], DFmode))"
7546 "*
7547 switch (which_alternative)
7548 {
7549 default:
7550 case 0:
7551 if (REGNO (operands[1]) == REGNO (operands[0]) + 1)
7552 return \"add\\t%0, %1, #0\;add\\t%H0, %H1, #0\";
7553 return \"add\\t%H0, %H1, #0\;add\\t%0, %1, #0\";
7554 case 1:
7555 return \"ldmia\\t%1, {%0, %H0}\";
7556 case 2:
7557 return \"stmia\\t%0, {%1, %H1}\";
7558 case 3:
7559 return thumb_load_double_from_address (operands);
7560 case 4:
7561 operands[2] = gen_rtx_MEM (SImode,
7562 plus_constant (Pmode,
7563 XEXP (operands[0], 0), 4));
7564 output_asm_insn (\"str\\t%1, %0\;str\\t%H1, %2\", operands);
7565 return \"\";
7566 case 5:
7567 if (REGNO (operands[1]) == REGNO (operands[0]) + 1)
7568 return \"mov\\t%0, %1\;mov\\t%H0, %H1\";
7569 return \"mov\\t%H0, %H1\;mov\\t%0, %1\";
7570 }
7571 "
7572 [(set_attr "length" "4,2,2,6,4,4")
7573 (set_attr "type" "multiple,load2,store2,load2,store2,multiple")
7574 (set_attr "pool_range" "*,*,*,1018,*,*")]
7575 )
7576 \f
7577
7578 ;; load- and store-multiple insns
7579 ;; The arm can load/store any set of registers, provided that they are in
7580 ;; ascending order, but these expanders assume a contiguous set.
7581
7582 (define_expand "load_multiple"
7583 [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
7584 (match_operand:SI 1 "" ""))
7585 (use (match_operand:SI 2 "" ""))])]
7586 "TARGET_32BIT"
7587 {
7588 HOST_WIDE_INT offset = 0;
7589
7590 /* Support only fixed point registers. */
7591 if (!CONST_INT_P (operands[2])
7592 || INTVAL (operands[2]) > 14
7593 || INTVAL (operands[2]) < 2
7594 || !MEM_P (operands[1])
7595 || !REG_P (operands[0])
7596 || REGNO (operands[0]) > (LAST_ARM_REGNUM - 1)
7597 || REGNO (operands[0]) + INTVAL (operands[2]) > LAST_ARM_REGNUM)
7598 FAIL;
7599
7600 operands[3]
7601 = arm_gen_load_multiple (arm_regs_in_sequence + REGNO (operands[0]),
7602 INTVAL (operands[2]),
7603 force_reg (SImode, XEXP (operands[1], 0)),
7604 FALSE, operands[1], &offset);
7605 })
7606
7607 (define_expand "store_multiple"
7608 [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
7609 (match_operand:SI 1 "" ""))
7610 (use (match_operand:SI 2 "" ""))])]
7611 "TARGET_32BIT"
7612 {
7613 HOST_WIDE_INT offset = 0;
7614
7615 /* Support only fixed point registers. */
7616 if (!CONST_INT_P (operands[2])
7617 || INTVAL (operands[2]) > 14
7618 || INTVAL (operands[2]) < 2
7619 || !REG_P (operands[1])
7620 || !MEM_P (operands[0])
7621 || REGNO (operands[1]) > (LAST_ARM_REGNUM - 1)
7622 || REGNO (operands[1]) + INTVAL (operands[2]) > LAST_ARM_REGNUM)
7623 FAIL;
7624
7625 operands[3]
7626 = arm_gen_store_multiple (arm_regs_in_sequence + REGNO (operands[1]),
7627 INTVAL (operands[2]),
7628 force_reg (SImode, XEXP (operands[0], 0)),
7629 FALSE, operands[0], &offset);
7630 })
7631
7632
7633 ;; Move a block of memory if it is word aligned and MORE than 2 words long.
7634 ;; We could let this apply for blocks of less than this, but it clobbers so
7635 ;; many registers that there is then probably a better way.
7636
7637 (define_expand "movmemqi"
7638 [(match_operand:BLK 0 "general_operand" "")
7639 (match_operand:BLK 1 "general_operand" "")
7640 (match_operand:SI 2 "const_int_operand" "")
7641 (match_operand:SI 3 "const_int_operand" "")]
7642 ""
7643 "
7644 if (TARGET_32BIT)
7645 {
7646 if (TARGET_LDRD && current_tune->prefer_ldrd_strd
7647 && !optimize_function_for_size_p (cfun))
7648 {
7649 if (gen_movmem_ldrd_strd (operands))
7650 DONE;
7651 FAIL;
7652 }
7653
7654 if (arm_gen_movmemqi (operands))
7655 DONE;
7656 FAIL;
7657 }
7658 else /* TARGET_THUMB1 */
7659 {
7660 if ( INTVAL (operands[3]) != 4
7661 || INTVAL (operands[2]) > 48)
7662 FAIL;
7663
7664 thumb_expand_movmemqi (operands);
7665 DONE;
7666 }
7667 "
7668 )
7669
7670 ;; Thumb block-move insns
7671
7672 (define_insn "movmem12b"
7673 [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
7674 (mem:SI (match_operand:SI 3 "register_operand" "1")))
7675 (set (mem:SI (plus:SI (match_dup 2) (const_int 4)))
7676 (mem:SI (plus:SI (match_dup 3) (const_int 4))))
7677 (set (mem:SI (plus:SI (match_dup 2) (const_int 8)))
7678 (mem:SI (plus:SI (match_dup 3) (const_int 8))))
7679 (set (match_operand:SI 0 "register_operand" "=l")
7680 (plus:SI (match_dup 2) (const_int 12)))
7681 (set (match_operand:SI 1 "register_operand" "=l")
7682 (plus:SI (match_dup 3) (const_int 12)))
7683 (clobber (match_scratch:SI 4 "=&l"))
7684 (clobber (match_scratch:SI 5 "=&l"))
7685 (clobber (match_scratch:SI 6 "=&l"))]
7686 "TARGET_THUMB1"
7687 "* return thumb_output_move_mem_multiple (3, operands);"
7688 [(set_attr "length" "4")
7689 ; This isn't entirely accurate... It loads as well, but in terms of
7690 ; scheduling the following insn it is better to consider it as a store
7691 (set_attr "type" "store3")]
7692 )
7693
7694 (define_insn "movmem8b"
7695 [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
7696 (mem:SI (match_operand:SI 3 "register_operand" "1")))
7697 (set (mem:SI (plus:SI (match_dup 2) (const_int 4)))
7698 (mem:SI (plus:SI (match_dup 3) (const_int 4))))
7699 (set (match_operand:SI 0 "register_operand" "=l")
7700 (plus:SI (match_dup 2) (const_int 8)))
7701 (set (match_operand:SI 1 "register_operand" "=l")
7702 (plus:SI (match_dup 3) (const_int 8)))
7703 (clobber (match_scratch:SI 4 "=&l"))
7704 (clobber (match_scratch:SI 5 "=&l"))]
7705 "TARGET_THUMB1"
7706 "* return thumb_output_move_mem_multiple (2, operands);"
7707 [(set_attr "length" "4")
7708 ; This isn't entirely accurate... It loads as well, but in terms of
7709 ; scheduling the following insn it is better to consider it as a store
7710 (set_attr "type" "store2")]
7711 )
7712
7713 \f
7714
7715 ;; Compare & branch insns
7716 ;; The range calculations are based as follows:
7717 ;; For forward branches, the address calculation returns the address of
7718 ;; the next instruction. This is 2 beyond the branch instruction.
7719 ;; For backward branches, the address calculation returns the address of
7720 ;; the first instruction in this pattern (cmp). This is 2 before the branch
7721 ;; instruction for the shortest sequence, and 4 before the branch instruction
7722 ;; if we have to jump around an unconditional branch.
7723 ;; To the basic branch range the PC offset must be added (this is +4).
7724 ;; So for forward branches we have
7725 ;; (pos_range - pos_base_offs + pc_offs) = (pos_range - 2 + 4).
7726 ;; And for backward branches we have
7727 ;; (neg_range - neg_base_offs + pc_offs) = (neg_range - (-2 or -4) + 4).
7728 ;;
7729 ;; For a 'b' pos_range = 2046, neg_range = -2048 giving (-2040->2048).
7730 ;; For a 'b<cond>' pos_range = 254, neg_range = -256 giving (-250 ->256).
7731
7732 (define_expand "cbranchsi4"
7733 [(set (pc) (if_then_else
7734 (match_operator 0 "expandable_comparison_operator"
7735 [(match_operand:SI 1 "s_register_operand" "")
7736 (match_operand:SI 2 "nonmemory_operand" "")])
7737 (label_ref (match_operand 3 "" ""))
7738 (pc)))]
7739 "TARGET_EITHER"
7740 "
7741 if (!TARGET_THUMB1)
7742 {
7743 if (!arm_validize_comparison (&operands[0], &operands[1], &operands[2]))
7744 FAIL;
7745 emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
7746 operands[3]));
7747 DONE;
7748 }
7749 if (thumb1_cmpneg_operand (operands[2], SImode))
7750 {
7751 emit_jump_insn (gen_cbranchsi4_scratch (NULL, operands[1], operands[2],
7752 operands[3], operands[0]));
7753 DONE;
7754 }
7755 if (!thumb1_cmp_operand (operands[2], SImode))
7756 operands[2] = force_reg (SImode, operands[2]);
7757 ")
7758
7759 ;; A pattern to recognize a special situation and optimize for it.
7760 ;; On the thumb, zero-extension from memory is preferrable to sign-extension
7761 ;; due to the available addressing modes. Hence, convert a signed comparison
7762 ;; with zero into an unsigned comparison with 127 if possible.
7763 (define_expand "cbranchqi4"
7764 [(set (pc) (if_then_else
7765 (match_operator 0 "lt_ge_comparison_operator"
7766 [(match_operand:QI 1 "memory_operand" "")
7767 (match_operand:QI 2 "const0_operand" "")])
7768 (label_ref (match_operand 3 "" ""))
7769 (pc)))]
7770 "TARGET_THUMB1"
7771 {
7772 rtx xops[4];
7773 xops[1] = gen_reg_rtx (SImode);
7774 emit_insn (gen_zero_extendqisi2 (xops[1], operands[1]));
7775 xops[2] = GEN_INT (127);
7776 xops[0] = gen_rtx_fmt_ee (GET_CODE (operands[0]) == GE ? LEU : GTU,
7777 VOIDmode, xops[1], xops[2]);
7778 xops[3] = operands[3];
7779 emit_insn (gen_cbranchsi4 (xops[0], xops[1], xops[2], xops[3]));
7780 DONE;
7781 })
7782
7783 (define_expand "cbranchsf4"
7784 [(set (pc) (if_then_else
7785 (match_operator 0 "expandable_comparison_operator"
7786 [(match_operand:SF 1 "s_register_operand" "")
7787 (match_operand:SF 2 "arm_float_compare_operand" "")])
7788 (label_ref (match_operand 3 "" ""))
7789 (pc)))]
7790 "TARGET_32BIT && TARGET_HARD_FLOAT"
7791 "emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
7792 operands[3])); DONE;"
7793 )
7794
7795 (define_expand "cbranchdf4"
7796 [(set (pc) (if_then_else
7797 (match_operator 0 "expandable_comparison_operator"
7798 [(match_operand:DF 1 "s_register_operand" "")
7799 (match_operand:DF 2 "arm_float_compare_operand" "")])
7800 (label_ref (match_operand 3 "" ""))
7801 (pc)))]
7802 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
7803 "emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
7804 operands[3])); DONE;"
7805 )
7806
7807 (define_expand "cbranchdi4"
7808 [(set (pc) (if_then_else
7809 (match_operator 0 "expandable_comparison_operator"
7810 [(match_operand:DI 1 "s_register_operand" "")
7811 (match_operand:DI 2 "cmpdi_operand" "")])
7812 (label_ref (match_operand 3 "" ""))
7813 (pc)))]
7814 "TARGET_32BIT"
7815 "{
7816 if (!arm_validize_comparison (&operands[0], &operands[1], &operands[2]))
7817 FAIL;
7818 emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
7819 operands[3]));
7820 DONE;
7821 }"
7822 )
7823
7824 (define_insn "cbranchsi4_insn"
7825 [(set (pc) (if_then_else
7826 (match_operator 0 "arm_comparison_operator"
7827 [(match_operand:SI 1 "s_register_operand" "l,l*h")
7828 (match_operand:SI 2 "thumb1_cmp_operand" "lI*h,*r")])
7829 (label_ref (match_operand 3 "" ""))
7830 (pc)))]
7831 "TARGET_THUMB1"
7832 {
7833 rtx t = cfun->machine->thumb1_cc_insn;
7834 if (t != NULL_RTX)
7835 {
7836 if (!rtx_equal_p (cfun->machine->thumb1_cc_op0, operands[1])
7837 || !rtx_equal_p (cfun->machine->thumb1_cc_op1, operands[2]))
7838 t = NULL_RTX;
7839 if (cfun->machine->thumb1_cc_mode == CC_NOOVmode)
7840 {
7841 if (!noov_comparison_operator (operands[0], VOIDmode))
7842 t = NULL_RTX;
7843 }
7844 else if (cfun->machine->thumb1_cc_mode != CCmode)
7845 t = NULL_RTX;
7846 }
7847 if (t == NULL_RTX)
7848 {
7849 output_asm_insn ("cmp\t%1, %2", operands);
7850 cfun->machine->thumb1_cc_insn = insn;
7851 cfun->machine->thumb1_cc_op0 = operands[1];
7852 cfun->machine->thumb1_cc_op1 = operands[2];
7853 cfun->machine->thumb1_cc_mode = CCmode;
7854 }
7855 else
7856 /* Ensure we emit the right type of condition code on the jump. */
7857 XEXP (operands[0], 0) = gen_rtx_REG (cfun->machine->thumb1_cc_mode,
7858 CC_REGNUM);
7859
7860 switch (get_attr_length (insn))
7861 {
7862 case 4: return \"b%d0\\t%l3\";
7863 case 6: return \"b%D0\\t.LCB%=\;b\\t%l3\\t%@long jump\\n.LCB%=:\";
7864 default: return \"b%D0\\t.LCB%=\;bl\\t%l3\\t%@far jump\\n.LCB%=:\";
7865 }
7866 }
7867 [(set (attr "far_jump")
7868 (if_then_else
7869 (eq_attr "length" "8")
7870 (const_string "yes")
7871 (const_string "no")))
7872 (set (attr "length")
7873 (if_then_else
7874 (and (ge (minus (match_dup 3) (pc)) (const_int -250))
7875 (le (minus (match_dup 3) (pc)) (const_int 256)))
7876 (const_int 4)
7877 (if_then_else
7878 (and (ge (minus (match_dup 3) (pc)) (const_int -2040))
7879 (le (minus (match_dup 3) (pc)) (const_int 2048)))
7880 (const_int 6)
7881 (const_int 8))))
7882 (set_attr "type" "multiple")]
7883 )
7884
7885 (define_insn "cbranchsi4_scratch"
7886 [(set (pc) (if_then_else
7887 (match_operator 4 "arm_comparison_operator"
7888 [(match_operand:SI 1 "s_register_operand" "l,0")
7889 (match_operand:SI 2 "thumb1_cmpneg_operand" "L,J")])
7890 (label_ref (match_operand 3 "" ""))
7891 (pc)))
7892 (clobber (match_scratch:SI 0 "=l,l"))]
7893 "TARGET_THUMB1"
7894 "*
7895 output_asm_insn (\"add\\t%0, %1, #%n2\", operands);
7896
7897 switch (get_attr_length (insn))
7898 {
7899 case 4: return \"b%d4\\t%l3\";
7900 case 6: return \"b%D4\\t.LCB%=\;b\\t%l3\\t%@long jump\\n.LCB%=:\";
7901 default: return \"b%D4\\t.LCB%=\;bl\\t%l3\\t%@far jump\\n.LCB%=:\";
7902 }
7903 "
7904 [(set (attr "far_jump")
7905 (if_then_else
7906 (eq_attr "length" "8")
7907 (const_string "yes")
7908 (const_string "no")))
7909 (set (attr "length")
7910 (if_then_else
7911 (and (ge (minus (match_dup 3) (pc)) (const_int -250))
7912 (le (minus (match_dup 3) (pc)) (const_int 256)))
7913 (const_int 4)
7914 (if_then_else
7915 (and (ge (minus (match_dup 3) (pc)) (const_int -2040))
7916 (le (minus (match_dup 3) (pc)) (const_int 2048)))
7917 (const_int 6)
7918 (const_int 8))))
7919 (set_attr "type" "multiple")]
7920 )
7921
7922 (define_insn "*negated_cbranchsi4"
7923 [(set (pc)
7924 (if_then_else
7925 (match_operator 0 "equality_operator"
7926 [(match_operand:SI 1 "s_register_operand" "l")
7927 (neg:SI (match_operand:SI 2 "s_register_operand" "l"))])
7928 (label_ref (match_operand 3 "" ""))
7929 (pc)))]
7930 "TARGET_THUMB1"
7931 "*
7932 output_asm_insn (\"cmn\\t%1, %2\", operands);
7933 switch (get_attr_length (insn))
7934 {
7935 case 4: return \"b%d0\\t%l3\";
7936 case 6: return \"b%D0\\t.LCB%=\;b\\t%l3\\t%@long jump\\n.LCB%=:\";
7937 default: return \"b%D0\\t.LCB%=\;bl\\t%l3\\t%@far jump\\n.LCB%=:\";
7938 }
7939 "
7940 [(set (attr "far_jump")
7941 (if_then_else
7942 (eq_attr "length" "8")
7943 (const_string "yes")
7944 (const_string "no")))
7945 (set (attr "length")
7946 (if_then_else
7947 (and (ge (minus (match_dup 3) (pc)) (const_int -250))
7948 (le (minus (match_dup 3) (pc)) (const_int 256)))
7949 (const_int 4)
7950 (if_then_else
7951 (and (ge (minus (match_dup 3) (pc)) (const_int -2040))
7952 (le (minus (match_dup 3) (pc)) (const_int 2048)))
7953 (const_int 6)
7954 (const_int 8))))
7955 (set_attr "type" "multiple")]
7956 )
7957
7958 (define_insn "*tbit_cbranch"
7959 [(set (pc)
7960 (if_then_else
7961 (match_operator 0 "equality_operator"
7962 [(zero_extract:SI (match_operand:SI 1 "s_register_operand" "l")
7963 (const_int 1)
7964 (match_operand:SI 2 "const_int_operand" "i"))
7965 (const_int 0)])
7966 (label_ref (match_operand 3 "" ""))
7967 (pc)))
7968 (clobber (match_scratch:SI 4 "=l"))]
7969 "TARGET_THUMB1"
7970 "*
7971 {
7972 rtx op[3];
7973 op[0] = operands[4];
7974 op[1] = operands[1];
7975 op[2] = GEN_INT (32 - 1 - INTVAL (operands[2]));
7976
7977 output_asm_insn (\"lsl\\t%0, %1, %2\", op);
7978 switch (get_attr_length (insn))
7979 {
7980 case 4: return \"b%d0\\t%l3\";
7981 case 6: return \"b%D0\\t.LCB%=\;b\\t%l3\\t%@long jump\\n.LCB%=:\";
7982 default: return \"b%D0\\t.LCB%=\;bl\\t%l3\\t%@far jump\\n.LCB%=:\";
7983 }
7984 }"
7985 [(set (attr "far_jump")
7986 (if_then_else
7987 (eq_attr "length" "8")
7988 (const_string "yes")
7989 (const_string "no")))
7990 (set (attr "length")
7991 (if_then_else
7992 (and (ge (minus (match_dup 3) (pc)) (const_int -250))
7993 (le (minus (match_dup 3) (pc)) (const_int 256)))
7994 (const_int 4)
7995 (if_then_else
7996 (and (ge (minus (match_dup 3) (pc)) (const_int -2040))
7997 (le (minus (match_dup 3) (pc)) (const_int 2048)))
7998 (const_int 6)
7999 (const_int 8))))
8000 (set_attr "type" "multiple")]
8001 )
8002
8003 (define_insn "*tlobits_cbranch"
8004 [(set (pc)
8005 (if_then_else
8006 (match_operator 0 "equality_operator"
8007 [(zero_extract:SI (match_operand:SI 1 "s_register_operand" "l")
8008 (match_operand:SI 2 "const_int_operand" "i")
8009 (const_int 0))
8010 (const_int 0)])
8011 (label_ref (match_operand 3 "" ""))
8012 (pc)))
8013 (clobber (match_scratch:SI 4 "=l"))]
8014 "TARGET_THUMB1"
8015 "*
8016 {
8017 rtx op[3];
8018 op[0] = operands[4];
8019 op[1] = operands[1];
8020 op[2] = GEN_INT (32 - INTVAL (operands[2]));
8021
8022 output_asm_insn (\"lsl\\t%0, %1, %2\", op);
8023 switch (get_attr_length (insn))
8024 {
8025 case 4: return \"b%d0\\t%l3\";
8026 case 6: return \"b%D0\\t.LCB%=\;b\\t%l3\\t%@long jump\\n.LCB%=:\";
8027 default: return \"b%D0\\t.LCB%=\;bl\\t%l3\\t%@far jump\\n.LCB%=:\";
8028 }
8029 }"
8030 [(set (attr "far_jump")
8031 (if_then_else
8032 (eq_attr "length" "8")
8033 (const_string "yes")
8034 (const_string "no")))
8035 (set (attr "length")
8036 (if_then_else
8037 (and (ge (minus (match_dup 3) (pc)) (const_int -250))
8038 (le (minus (match_dup 3) (pc)) (const_int 256)))
8039 (const_int 4)
8040 (if_then_else
8041 (and (ge (minus (match_dup 3) (pc)) (const_int -2040))
8042 (le (minus (match_dup 3) (pc)) (const_int 2048)))
8043 (const_int 6)
8044 (const_int 8))))
8045 (set_attr "type" "multiple")]
8046 )
8047
8048 (define_insn "*tstsi3_cbranch"
8049 [(set (pc)
8050 (if_then_else
8051 (match_operator 3 "equality_operator"
8052 [(and:SI (match_operand:SI 0 "s_register_operand" "%l")
8053 (match_operand:SI 1 "s_register_operand" "l"))
8054 (const_int 0)])
8055 (label_ref (match_operand 2 "" ""))
8056 (pc)))]
8057 "TARGET_THUMB1"
8058 "*
8059 {
8060 output_asm_insn (\"tst\\t%0, %1\", operands);
8061 switch (get_attr_length (insn))
8062 {
8063 case 4: return \"b%d3\\t%l2\";
8064 case 6: return \"b%D3\\t.LCB%=\;b\\t%l2\\t%@long jump\\n.LCB%=:\";
8065 default: return \"b%D3\\t.LCB%=\;bl\\t%l2\\t%@far jump\\n.LCB%=:\";
8066 }
8067 }"
8068 [(set (attr "far_jump")
8069 (if_then_else
8070 (eq_attr "length" "8")
8071 (const_string "yes")
8072 (const_string "no")))
8073 (set (attr "length")
8074 (if_then_else
8075 (and (ge (minus (match_dup 2) (pc)) (const_int -250))
8076 (le (minus (match_dup 2) (pc)) (const_int 256)))
8077 (const_int 4)
8078 (if_then_else
8079 (and (ge (minus (match_dup 2) (pc)) (const_int -2040))
8080 (le (minus (match_dup 2) (pc)) (const_int 2048)))
8081 (const_int 6)
8082 (const_int 8))))
8083 (set_attr "type" "multiple")]
8084 )
8085
8086 (define_insn "*cbranchne_decr1"
8087 [(set (pc)
8088 (if_then_else (match_operator 3 "equality_operator"
8089 [(match_operand:SI 2 "s_register_operand" "l,l,1,l")
8090 (const_int 0)])
8091 (label_ref (match_operand 4 "" ""))
8092 (pc)))
8093 (set (match_operand:SI 0 "thumb_cbrch_target_operand" "=l,*?h,*?m,*?m")
8094 (plus:SI (match_dup 2) (const_int -1)))
8095 (clobber (match_scratch:SI 1 "=X,l,&l,&l"))]
8096 "TARGET_THUMB1"
8097 "*
8098 {
8099 rtx cond[2];
8100 cond[0] = gen_rtx_fmt_ee ((GET_CODE (operands[3]) == NE
8101 ? GEU : LTU),
8102 VOIDmode, operands[2], const1_rtx);
8103 cond[1] = operands[4];
8104
8105 if (which_alternative == 0)
8106 output_asm_insn (\"sub\\t%0, %2, #1\", operands);
8107 else if (which_alternative == 1)
8108 {
8109 /* We must provide an alternative for a hi reg because reload
8110 cannot handle output reloads on a jump instruction, but we
8111 can't subtract into that. Fortunately a mov from lo to hi
8112 does not clobber the condition codes. */
8113 output_asm_insn (\"sub\\t%1, %2, #1\", operands);
8114 output_asm_insn (\"mov\\t%0, %1\", operands);
8115 }
8116 else
8117 {
8118 /* Similarly, but the target is memory. */
8119 output_asm_insn (\"sub\\t%1, %2, #1\", operands);
8120 output_asm_insn (\"str\\t%1, %0\", operands);
8121 }
8122
8123 switch (get_attr_length (insn) - (which_alternative ? 2 : 0))
8124 {
8125 case 4:
8126 output_asm_insn (\"b%d0\\t%l1\", cond);
8127 return \"\";
8128 case 6:
8129 output_asm_insn (\"b%D0\\t.LCB%=\", cond);
8130 return \"b\\t%l4\\t%@long jump\\n.LCB%=:\";
8131 default:
8132 output_asm_insn (\"b%D0\\t.LCB%=\", cond);
8133 return \"bl\\t%l4\\t%@far jump\\n.LCB%=:\";
8134 }
8135 }
8136 "
8137 [(set (attr "far_jump")
8138 (if_then_else
8139 (ior (and (eq (symbol_ref ("which_alternative"))
8140 (const_int 0))
8141 (eq_attr "length" "8"))
8142 (eq_attr "length" "10"))
8143 (const_string "yes")
8144 (const_string "no")))
8145 (set_attr_alternative "length"
8146 [
8147 ;; Alternative 0
8148 (if_then_else
8149 (and (ge (minus (match_dup 4) (pc)) (const_int -250))
8150 (le (minus (match_dup 4) (pc)) (const_int 256)))
8151 (const_int 4)
8152 (if_then_else
8153 (and (ge (minus (match_dup 4) (pc)) (const_int -2040))
8154 (le (minus (match_dup 4) (pc)) (const_int 2048)))
8155 (const_int 6)
8156 (const_int 8)))
8157 ;; Alternative 1
8158 (if_then_else
8159 (and (ge (minus (match_dup 4) (pc)) (const_int -248))
8160 (le (minus (match_dup 4) (pc)) (const_int 256)))
8161 (const_int 6)
8162 (if_then_else
8163 (and (ge (minus (match_dup 4) (pc)) (const_int -2038))
8164 (le (minus (match_dup 4) (pc)) (const_int 2048)))
8165 (const_int 8)
8166 (const_int 10)))
8167 ;; Alternative 2
8168 (if_then_else
8169 (and (ge (minus (match_dup 4) (pc)) (const_int -248))
8170 (le (minus (match_dup 4) (pc)) (const_int 256)))
8171 (const_int 6)
8172 (if_then_else
8173 (and (ge (minus (match_dup 4) (pc)) (const_int -2038))
8174 (le (minus (match_dup 4) (pc)) (const_int 2048)))
8175 (const_int 8)
8176 (const_int 10)))
8177 ;; Alternative 3
8178 (if_then_else
8179 (and (ge (minus (match_dup 4) (pc)) (const_int -248))
8180 (le (minus (match_dup 4) (pc)) (const_int 256)))
8181 (const_int 6)
8182 (if_then_else
8183 (and (ge (minus (match_dup 4) (pc)) (const_int -2038))
8184 (le (minus (match_dup 4) (pc)) (const_int 2048)))
8185 (const_int 8)
8186 (const_int 10)))])
8187 (set_attr "type" "multiple")]
8188 )
8189
8190 (define_insn "*addsi3_cbranch"
8191 [(set (pc)
8192 (if_then_else
8193 (match_operator 4 "arm_comparison_operator"
8194 [(plus:SI
8195 (match_operand:SI 2 "s_register_operand" "%0,l,*l,1,1,1")
8196 (match_operand:SI 3 "reg_or_int_operand" "IJ,lL,*l,lIJ,lIJ,lIJ"))
8197 (const_int 0)])
8198 (label_ref (match_operand 5 "" ""))
8199 (pc)))
8200 (set
8201 (match_operand:SI 0 "thumb_cbrch_target_operand" "=l,l,*!h,*?h,*?m,*?m")
8202 (plus:SI (match_dup 2) (match_dup 3)))
8203 (clobber (match_scratch:SI 1 "=X,X,l,l,&l,&l"))]
8204 "TARGET_THUMB1
8205 && (GET_CODE (operands[4]) == EQ
8206 || GET_CODE (operands[4]) == NE
8207 || GET_CODE (operands[4]) == GE
8208 || GET_CODE (operands[4]) == LT)"
8209 "*
8210 {
8211 rtx cond[3];
8212
8213 cond[0] = (which_alternative < 2) ? operands[0] : operands[1];
8214 cond[1] = operands[2];
8215 cond[2] = operands[3];
8216
8217 if (CONST_INT_P (cond[2]) && INTVAL (cond[2]) < 0)
8218 output_asm_insn (\"sub\\t%0, %1, #%n2\", cond);
8219 else
8220 output_asm_insn (\"add\\t%0, %1, %2\", cond);
8221
8222 if (which_alternative >= 2
8223 && which_alternative < 4)
8224 output_asm_insn (\"mov\\t%0, %1\", operands);
8225 else if (which_alternative >= 4)
8226 output_asm_insn (\"str\\t%1, %0\", operands);
8227
8228 switch (get_attr_length (insn) - ((which_alternative >= 2) ? 2 : 0))
8229 {
8230 case 4:
8231 return \"b%d4\\t%l5\";
8232 case 6:
8233 return \"b%D4\\t.LCB%=\;b\\t%l5\\t%@long jump\\n.LCB%=:\";
8234 default:
8235 return \"b%D4\\t.LCB%=\;bl\\t%l5\\t%@far jump\\n.LCB%=:\";
8236 }
8237 }
8238 "
8239 [(set (attr "far_jump")
8240 (if_then_else
8241 (ior (and (lt (symbol_ref ("which_alternative"))
8242 (const_int 2))
8243 (eq_attr "length" "8"))
8244 (eq_attr "length" "10"))
8245 (const_string "yes")
8246 (const_string "no")))
8247 (set (attr "length")
8248 (if_then_else
8249 (lt (symbol_ref ("which_alternative"))
8250 (const_int 2))
8251 (if_then_else
8252 (and (ge (minus (match_dup 5) (pc)) (const_int -250))
8253 (le (minus (match_dup 5) (pc)) (const_int 256)))
8254 (const_int 4)
8255 (if_then_else
8256 (and (ge (minus (match_dup 5) (pc)) (const_int -2040))
8257 (le (minus (match_dup 5) (pc)) (const_int 2048)))
8258 (const_int 6)
8259 (const_int 8)))
8260 (if_then_else
8261 (and (ge (minus (match_dup 5) (pc)) (const_int -248))
8262 (le (minus (match_dup 5) (pc)) (const_int 256)))
8263 (const_int 6)
8264 (if_then_else
8265 (and (ge (minus (match_dup 5) (pc)) (const_int -2038))
8266 (le (minus (match_dup 5) (pc)) (const_int 2048)))
8267 (const_int 8)
8268 (const_int 10)))))
8269 (set_attr "type" "multiple")]
8270 )
8271
8272 (define_insn "*addsi3_cbranch_scratch"
8273 [(set (pc)
8274 (if_then_else
8275 (match_operator 3 "arm_comparison_operator"
8276 [(plus:SI
8277 (match_operand:SI 1 "s_register_operand" "%l,l,l,0")
8278 (match_operand:SI 2 "reg_or_int_operand" "J,l,L,IJ"))
8279 (const_int 0)])
8280 (label_ref (match_operand 4 "" ""))
8281 (pc)))
8282 (clobber (match_scratch:SI 0 "=X,X,l,l"))]
8283 "TARGET_THUMB1
8284 && (GET_CODE (operands[3]) == EQ
8285 || GET_CODE (operands[3]) == NE
8286 || GET_CODE (operands[3]) == GE
8287 || GET_CODE (operands[3]) == LT)"
8288 "*
8289 {
8290 switch (which_alternative)
8291 {
8292 case 0:
8293 output_asm_insn (\"cmp\t%1, #%n2\", operands);
8294 break;
8295 case 1:
8296 output_asm_insn (\"cmn\t%1, %2\", operands);
8297 break;
8298 case 2:
8299 if (INTVAL (operands[2]) < 0)
8300 output_asm_insn (\"sub\t%0, %1, %2\", operands);
8301 else
8302 output_asm_insn (\"add\t%0, %1, %2\", operands);
8303 break;
8304 case 3:
8305 if (INTVAL (operands[2]) < 0)
8306 output_asm_insn (\"sub\t%0, %0, %2\", operands);
8307 else
8308 output_asm_insn (\"add\t%0, %0, %2\", operands);
8309 break;
8310 }
8311
8312 switch (get_attr_length (insn))
8313 {
8314 case 4:
8315 return \"b%d3\\t%l4\";
8316 case 6:
8317 return \"b%D3\\t.LCB%=\;b\\t%l4\\t%@long jump\\n.LCB%=:\";
8318 default:
8319 return \"b%D3\\t.LCB%=\;bl\\t%l4\\t%@far jump\\n.LCB%=:\";
8320 }
8321 }
8322 "
8323 [(set (attr "far_jump")
8324 (if_then_else
8325 (eq_attr "length" "8")
8326 (const_string "yes")
8327 (const_string "no")))
8328 (set (attr "length")
8329 (if_then_else
8330 (and (ge (minus (match_dup 4) (pc)) (const_int -250))
8331 (le (minus (match_dup 4) (pc)) (const_int 256)))
8332 (const_int 4)
8333 (if_then_else
8334 (and (ge (minus (match_dup 4) (pc)) (const_int -2040))
8335 (le (minus (match_dup 4) (pc)) (const_int 2048)))
8336 (const_int 6)
8337 (const_int 8))))
8338 (set_attr "type" "multiple")]
8339 )
8340
8341
8342 ;; Comparison and test insns
8343
8344 (define_insn "*arm_cmpsi_insn"
8345 [(set (reg:CC CC_REGNUM)
8346 (compare:CC (match_operand:SI 0 "s_register_operand" "l,r,r,r,r")
8347 (match_operand:SI 1 "arm_add_operand" "Py,r,r,I,L")))]
8348 "TARGET_32BIT"
8349 "@
8350 cmp%?\\t%0, %1
8351 cmp%?\\t%0, %1
8352 cmp%?\\t%0, %1
8353 cmp%?\\t%0, %1
8354 cmn%?\\t%0, #%n1"
8355 [(set_attr "conds" "set")
8356 (set_attr "arch" "t2,t2,any,any,any")
8357 (set_attr "length" "2,2,4,4,4")
8358 (set_attr "predicable" "yes")
8359 (set_attr "predicable_short_it" "yes,yes,yes,no,no")
8360 (set_attr "type" "alus_imm,alus_reg,alus_reg,alus_imm,alus_imm")]
8361 )
8362
8363 (define_insn "*cmpsi_shiftsi"
8364 [(set (reg:CC CC_REGNUM)
8365 (compare:CC (match_operand:SI 0 "s_register_operand" "r,r,r")
8366 (match_operator:SI 3 "shift_operator"
8367 [(match_operand:SI 1 "s_register_operand" "r,r,r")
8368 (match_operand:SI 2 "shift_amount_operand" "M,r,M")])))]
8369 "TARGET_32BIT"
8370 "cmp\\t%0, %1%S3"
8371 [(set_attr "conds" "set")
8372 (set_attr "shift" "1")
8373 (set_attr "arch" "32,a,a")
8374 (set_attr "type" "alus_shift_imm,alu_shift_reg,alus_shift_imm")])
8375
8376 (define_insn "*cmpsi_shiftsi_swp"
8377 [(set (reg:CC_SWP CC_REGNUM)
8378 (compare:CC_SWP (match_operator:SI 3 "shift_operator"
8379 [(match_operand:SI 1 "s_register_operand" "r,r,r")
8380 (match_operand:SI 2 "shift_amount_operand" "M,r,M")])
8381 (match_operand:SI 0 "s_register_operand" "r,r,r")))]
8382 "TARGET_32BIT"
8383 "cmp%?\\t%0, %1%S3"
8384 [(set_attr "conds" "set")
8385 (set_attr "shift" "1")
8386 (set_attr "arch" "32,a,a")
8387 (set_attr "type" "alus_shift_imm,alu_shift_reg,alus_shift_imm")])
8388
8389 (define_insn "*arm_cmpsi_negshiftsi_si"
8390 [(set (reg:CC_Z CC_REGNUM)
8391 (compare:CC_Z
8392 (neg:SI (match_operator:SI 1 "shift_operator"
8393 [(match_operand:SI 2 "s_register_operand" "r")
8394 (match_operand:SI 3 "reg_or_int_operand" "rM")]))
8395 (match_operand:SI 0 "s_register_operand" "r")))]
8396 "TARGET_ARM"
8397 "cmn%?\\t%0, %2%S1"
8398 [(set_attr "conds" "set")
8399 (set (attr "type") (if_then_else (match_operand 3 "const_int_operand" "")
8400 (const_string "alus_shift_imm")
8401 (const_string "alus_shift_reg")))
8402 (set_attr "predicable" "yes")]
8403 )
8404
8405 ;; DImode comparisons. The generic code generates branches that
8406 ;; if-conversion can not reduce to a conditional compare, so we do
8407 ;; that directly.
8408
8409 (define_insn_and_split "*arm_cmpdi_insn"
8410 [(set (reg:CC_NCV CC_REGNUM)
8411 (compare:CC_NCV (match_operand:DI 0 "s_register_operand" "r")
8412 (match_operand:DI 1 "arm_di_operand" "rDi")))
8413 (clobber (match_scratch:SI 2 "=r"))]
8414 "TARGET_32BIT"
8415 "#" ; "cmp\\t%Q0, %Q1\;sbcs\\t%2, %R0, %R1"
8416 "&& reload_completed"
8417 [(set (reg:CC CC_REGNUM)
8418 (compare:CC (match_dup 0) (match_dup 1)))
8419 (parallel [(set (reg:CC CC_REGNUM)
8420 (compare:CC (match_dup 3) (match_dup 4)))
8421 (set (match_dup 2)
8422 (minus:SI (match_dup 5)
8423 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))])]
8424 {
8425 operands[3] = gen_highpart (SImode, operands[0]);
8426 operands[0] = gen_lowpart (SImode, operands[0]);
8427 if (CONST_INT_P (operands[1]))
8428 {
8429 operands[4] = GEN_INT (~INTVAL (gen_highpart_mode (SImode,
8430 DImode,
8431 operands[1])));
8432 operands[5] = gen_rtx_PLUS (SImode, operands[3], operands[4]);
8433 }
8434 else
8435 {
8436 operands[4] = gen_highpart (SImode, operands[1]);
8437 operands[5] = gen_rtx_MINUS (SImode, operands[3], operands[4]);
8438 }
8439 operands[1] = gen_lowpart (SImode, operands[1]);
8440 operands[2] = gen_lowpart (SImode, operands[2]);
8441 }
8442 [(set_attr "conds" "set")
8443 (set_attr "length" "8")
8444 (set_attr "type" "multiple")]
8445 )
8446
8447 (define_insn_and_split "*arm_cmpdi_unsigned"
8448 [(set (reg:CC_CZ CC_REGNUM)
8449 (compare:CC_CZ (match_operand:DI 0 "s_register_operand" "l,r,r")
8450 (match_operand:DI 1 "arm_di_operand" "Py,r,rDi")))]
8451
8452 "TARGET_32BIT"
8453 "#" ; "cmp\\t%R0, %R1\;it eq\;cmpeq\\t%Q0, %Q1"
8454 "&& reload_completed"
8455 [(set (reg:CC CC_REGNUM)
8456 (compare:CC (match_dup 2) (match_dup 3)))
8457 (cond_exec (eq:SI (reg:CC CC_REGNUM) (const_int 0))
8458 (set (reg:CC CC_REGNUM)
8459 (compare:CC (match_dup 0) (match_dup 1))))]
8460 {
8461 operands[2] = gen_highpart (SImode, operands[0]);
8462 operands[0] = gen_lowpart (SImode, operands[0]);
8463 if (CONST_INT_P (operands[1]))
8464 operands[3] = gen_highpart_mode (SImode, DImode, operands[1]);
8465 else
8466 operands[3] = gen_highpart (SImode, operands[1]);
8467 operands[1] = gen_lowpart (SImode, operands[1]);
8468 }
8469 [(set_attr "conds" "set")
8470 (set_attr "enabled_for_depr_it" "yes,yes,no")
8471 (set_attr "arch" "t2,t2,*")
8472 (set_attr "length" "6,6,8")
8473 (set_attr "type" "multiple")]
8474 )
8475
8476 (define_insn "*arm_cmpdi_zero"
8477 [(set (reg:CC_Z CC_REGNUM)
8478 (compare:CC_Z (match_operand:DI 0 "s_register_operand" "r")
8479 (const_int 0)))
8480 (clobber (match_scratch:SI 1 "=r"))]
8481 "TARGET_32BIT"
8482 "orr%.\\t%1, %Q0, %R0"
8483 [(set_attr "conds" "set")
8484 (set_attr "type" "logics_reg")]
8485 )
8486
8487 (define_insn "*thumb_cmpdi_zero"
8488 [(set (reg:CC_Z CC_REGNUM)
8489 (compare:CC_Z (match_operand:DI 0 "s_register_operand" "l")
8490 (const_int 0)))
8491 (clobber (match_scratch:SI 1 "=l"))]
8492 "TARGET_THUMB1"
8493 "orr\\t%1, %Q0, %R0"
8494 [(set_attr "conds" "set")
8495 (set_attr "length" "2")
8496 (set_attr "type" "logics_reg")]
8497 )
8498
8499 ; This insn allows redundant compares to be removed by cse, nothing should
8500 ; ever appear in the output file since (set (reg x) (reg x)) is a no-op that
8501 ; is deleted later on. The match_dup will match the mode here, so that
8502 ; mode changes of the condition codes aren't lost by this even though we don't
8503 ; specify what they are.
8504
8505 (define_insn "*deleted_compare"
8506 [(set (match_operand 0 "cc_register" "") (match_dup 0))]
8507 "TARGET_32BIT"
8508 "\\t%@ deleted compare"
8509 [(set_attr "conds" "set")
8510 (set_attr "length" "0")
8511 (set_attr "type" "no_insn")]
8512 )
8513
8514 \f
8515 ;; Conditional branch insns
8516
8517 (define_expand "cbranch_cc"
8518 [(set (pc)
8519 (if_then_else (match_operator 0 "" [(match_operand 1 "" "")
8520 (match_operand 2 "" "")])
8521 (label_ref (match_operand 3 "" ""))
8522 (pc)))]
8523 "TARGET_32BIT"
8524 "operands[1] = arm_gen_compare_reg (GET_CODE (operands[0]),
8525 operands[1], operands[2], NULL_RTX);
8526 operands[2] = const0_rtx;"
8527 )
8528
8529 ;;
8530 ;; Patterns to match conditional branch insns.
8531 ;;
8532
8533 (define_insn "arm_cond_branch"
8534 [(set (pc)
8535 (if_then_else (match_operator 1 "arm_comparison_operator"
8536 [(match_operand 2 "cc_register" "") (const_int 0)])
8537 (label_ref (match_operand 0 "" ""))
8538 (pc)))]
8539 "TARGET_32BIT"
8540 "*
8541 if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
8542 {
8543 arm_ccfsm_state += 2;
8544 return \"\";
8545 }
8546 return \"b%d1\\t%l0\";
8547 "
8548 [(set_attr "conds" "use")
8549 (set_attr "type" "branch")
8550 (set (attr "length")
8551 (if_then_else
8552 (and (match_test "TARGET_THUMB2")
8553 (and (ge (minus (match_dup 0) (pc)) (const_int -250))
8554 (le (minus (match_dup 0) (pc)) (const_int 256))))
8555 (const_int 2)
8556 (const_int 4)))]
8557 )
8558
8559 (define_insn "*arm_cond_branch_reversed"
8560 [(set (pc)
8561 (if_then_else (match_operator 1 "arm_comparison_operator"
8562 [(match_operand 2 "cc_register" "") (const_int 0)])
8563 (pc)
8564 (label_ref (match_operand 0 "" ""))))]
8565 "TARGET_32BIT"
8566 "*
8567 if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
8568 {
8569 arm_ccfsm_state += 2;
8570 return \"\";
8571 }
8572 return \"b%D1\\t%l0\";
8573 "
8574 [(set_attr "conds" "use")
8575 (set_attr "type" "branch")
8576 (set (attr "length")
8577 (if_then_else
8578 (and (match_test "TARGET_THUMB2")
8579 (and (ge (minus (match_dup 0) (pc)) (const_int -250))
8580 (le (minus (match_dup 0) (pc)) (const_int 256))))
8581 (const_int 2)
8582 (const_int 4)))]
8583 )
8584
8585 \f
8586
8587 ; scc insns
8588
8589 (define_expand "cstore_cc"
8590 [(set (match_operand:SI 0 "s_register_operand" "")
8591 (match_operator:SI 1 "" [(match_operand 2 "" "")
8592 (match_operand 3 "" "")]))]
8593 "TARGET_32BIT"
8594 "operands[2] = arm_gen_compare_reg (GET_CODE (operands[1]),
8595 operands[2], operands[3], NULL_RTX);
8596 operands[3] = const0_rtx;"
8597 )
8598
8599 (define_insn_and_split "*mov_scc"
8600 [(set (match_operand:SI 0 "s_register_operand" "=r")
8601 (match_operator:SI 1 "arm_comparison_operator"
8602 [(match_operand 2 "cc_register" "") (const_int 0)]))]
8603 "TARGET_ARM"
8604 "#" ; "mov%D1\\t%0, #0\;mov%d1\\t%0, #1"
8605 "TARGET_ARM"
8606 [(set (match_dup 0)
8607 (if_then_else:SI (match_dup 1)
8608 (const_int 1)
8609 (const_int 0)))]
8610 ""
8611 [(set_attr "conds" "use")
8612 (set_attr "length" "8")
8613 (set_attr "type" "multiple")]
8614 )
8615
8616 (define_insn_and_split "*mov_negscc"
8617 [(set (match_operand:SI 0 "s_register_operand" "=r")
8618 (neg:SI (match_operator:SI 1 "arm_comparison_operator"
8619 [(match_operand 2 "cc_register" "") (const_int 0)])))]
8620 "TARGET_ARM"
8621 "#" ; "mov%D1\\t%0, #0\;mvn%d1\\t%0, #0"
8622 "TARGET_ARM"
8623 [(set (match_dup 0)
8624 (if_then_else:SI (match_dup 1)
8625 (match_dup 3)
8626 (const_int 0)))]
8627 {
8628 operands[3] = GEN_INT (~0);
8629 }
8630 [(set_attr "conds" "use")
8631 (set_attr "length" "8")
8632 (set_attr "type" "multiple")]
8633 )
8634
8635 (define_insn_and_split "*mov_notscc"
8636 [(set (match_operand:SI 0 "s_register_operand" "=r")
8637 (not:SI (match_operator:SI 1 "arm_comparison_operator"
8638 [(match_operand 2 "cc_register" "") (const_int 0)])))]
8639 "TARGET_ARM"
8640 "#" ; "mvn%D1\\t%0, #0\;mvn%d1\\t%0, #1"
8641 "TARGET_ARM"
8642 [(set (match_dup 0)
8643 (if_then_else:SI (match_dup 1)
8644 (match_dup 3)
8645 (match_dup 4)))]
8646 {
8647 operands[3] = GEN_INT (~1);
8648 operands[4] = GEN_INT (~0);
8649 }
8650 [(set_attr "conds" "use")
8651 (set_attr "length" "8")
8652 (set_attr "type" "multiple")]
8653 )
8654
8655 (define_expand "cstoresi4"
8656 [(set (match_operand:SI 0 "s_register_operand" "")
8657 (match_operator:SI 1 "expandable_comparison_operator"
8658 [(match_operand:SI 2 "s_register_operand" "")
8659 (match_operand:SI 3 "reg_or_int_operand" "")]))]
8660 "TARGET_32BIT || TARGET_THUMB1"
8661 "{
8662 rtx op3, scratch, scratch2;
8663
8664 if (!TARGET_THUMB1)
8665 {
8666 if (!arm_add_operand (operands[3], SImode))
8667 operands[3] = force_reg (SImode, operands[3]);
8668 emit_insn (gen_cstore_cc (operands[0], operands[1],
8669 operands[2], operands[3]));
8670 DONE;
8671 }
8672
8673 if (operands[3] == const0_rtx)
8674 {
8675 switch (GET_CODE (operands[1]))
8676 {
8677 case EQ:
8678 emit_insn (gen_cstoresi_eq0_thumb1 (operands[0], operands[2]));
8679 break;
8680
8681 case NE:
8682 emit_insn (gen_cstoresi_ne0_thumb1 (operands[0], operands[2]));
8683 break;
8684
8685 case LE:
8686 scratch = expand_binop (SImode, add_optab, operands[2], constm1_rtx,
8687 NULL_RTX, 0, OPTAB_WIDEN);
8688 scratch = expand_binop (SImode, ior_optab, operands[2], scratch,
8689 NULL_RTX, 0, OPTAB_WIDEN);
8690 expand_binop (SImode, lshr_optab, scratch, GEN_INT (31),
8691 operands[0], 1, OPTAB_WIDEN);
8692 break;
8693
8694 case GE:
8695 scratch = expand_unop (SImode, one_cmpl_optab, operands[2],
8696 NULL_RTX, 1);
8697 expand_binop (SImode, lshr_optab, scratch, GEN_INT (31),
8698 NULL_RTX, 1, OPTAB_WIDEN);
8699 break;
8700
8701 case GT:
8702 scratch = expand_binop (SImode, ashr_optab, operands[2],
8703 GEN_INT (31), NULL_RTX, 0, OPTAB_WIDEN);
8704 scratch = expand_binop (SImode, sub_optab, scratch, operands[2],
8705 NULL_RTX, 0, OPTAB_WIDEN);
8706 expand_binop (SImode, lshr_optab, scratch, GEN_INT (31), operands[0],
8707 0, OPTAB_WIDEN);
8708 break;
8709
8710 /* LT is handled by generic code. No need for unsigned with 0. */
8711 default:
8712 FAIL;
8713 }
8714 DONE;
8715 }
8716
8717 switch (GET_CODE (operands[1]))
8718 {
8719 case EQ:
8720 scratch = expand_binop (SImode, sub_optab, operands[2], operands[3],
8721 NULL_RTX, 0, OPTAB_WIDEN);
8722 emit_insn (gen_cstoresi_eq0_thumb1 (operands[0], scratch));
8723 break;
8724
8725 case NE:
8726 scratch = expand_binop (SImode, sub_optab, operands[2], operands[3],
8727 NULL_RTX, 0, OPTAB_WIDEN);
8728 emit_insn (gen_cstoresi_ne0_thumb1 (operands[0], scratch));
8729 break;
8730
8731 case LE:
8732 op3 = force_reg (SImode, operands[3]);
8733
8734 scratch = expand_binop (SImode, lshr_optab, operands[2], GEN_INT (31),
8735 NULL_RTX, 1, OPTAB_WIDEN);
8736 scratch2 = expand_binop (SImode, ashr_optab, op3, GEN_INT (31),
8737 NULL_RTX, 0, OPTAB_WIDEN);
8738 emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch2,
8739 op3, operands[2]));
8740 break;
8741
8742 case GE:
8743 op3 = operands[3];
8744 if (!thumb1_cmp_operand (op3, SImode))
8745 op3 = force_reg (SImode, op3);
8746 scratch = expand_binop (SImode, ashr_optab, operands[2], GEN_INT (31),
8747 NULL_RTX, 0, OPTAB_WIDEN);
8748 scratch2 = expand_binop (SImode, lshr_optab, op3, GEN_INT (31),
8749 NULL_RTX, 1, OPTAB_WIDEN);
8750 emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch2,
8751 operands[2], op3));
8752 break;
8753
8754 case LEU:
8755 op3 = force_reg (SImode, operands[3]);
8756 scratch = force_reg (SImode, const0_rtx);
8757 emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch,
8758 op3, operands[2]));
8759 break;
8760
8761 case GEU:
8762 op3 = operands[3];
8763 if (!thumb1_cmp_operand (op3, SImode))
8764 op3 = force_reg (SImode, op3);
8765 scratch = force_reg (SImode, const0_rtx);
8766 emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch,
8767 operands[2], op3));
8768 break;
8769
8770 case LTU:
8771 op3 = operands[3];
8772 if (!thumb1_cmp_operand (op3, SImode))
8773 op3 = force_reg (SImode, op3);
8774 scratch = gen_reg_rtx (SImode);
8775 emit_insn (gen_cstoresi_ltu_thumb1 (operands[0], operands[2], op3));
8776 break;
8777
8778 case GTU:
8779 op3 = force_reg (SImode, operands[3]);
8780 scratch = gen_reg_rtx (SImode);
8781 emit_insn (gen_cstoresi_ltu_thumb1 (operands[0], op3, operands[2]));
8782 break;
8783
8784 /* No good sequences for GT, LT. */
8785 default:
8786 FAIL;
8787 }
8788 DONE;
8789 }")
8790
8791 (define_expand "cstoresf4"
8792 [(set (match_operand:SI 0 "s_register_operand" "")
8793 (match_operator:SI 1 "expandable_comparison_operator"
8794 [(match_operand:SF 2 "s_register_operand" "")
8795 (match_operand:SF 3 "arm_float_compare_operand" "")]))]
8796 "TARGET_32BIT && TARGET_HARD_FLOAT"
8797 "emit_insn (gen_cstore_cc (operands[0], operands[1],
8798 operands[2], operands[3])); DONE;"
8799 )
8800
8801 (define_expand "cstoredf4"
8802 [(set (match_operand:SI 0 "s_register_operand" "")
8803 (match_operator:SI 1 "expandable_comparison_operator"
8804 [(match_operand:DF 2 "s_register_operand" "")
8805 (match_operand:DF 3 "arm_float_compare_operand" "")]))]
8806 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
8807 "emit_insn (gen_cstore_cc (operands[0], operands[1],
8808 operands[2], operands[3])); DONE;"
8809 )
8810
8811 (define_expand "cstoredi4"
8812 [(set (match_operand:SI 0 "s_register_operand" "")
8813 (match_operator:SI 1 "expandable_comparison_operator"
8814 [(match_operand:DI 2 "s_register_operand" "")
8815 (match_operand:DI 3 "cmpdi_operand" "")]))]
8816 "TARGET_32BIT"
8817 "{
8818 if (!arm_validize_comparison (&operands[1],
8819 &operands[2],
8820 &operands[3]))
8821 FAIL;
8822 emit_insn (gen_cstore_cc (operands[0], operands[1], operands[2],
8823 operands[3]));
8824 DONE;
8825 }"
8826 )
8827
8828 (define_expand "cstoresi_eq0_thumb1"
8829 [(parallel
8830 [(set (match_operand:SI 0 "s_register_operand" "")
8831 (eq:SI (match_operand:SI 1 "s_register_operand" "")
8832 (const_int 0)))
8833 (clobber (match_dup:SI 2))])]
8834 "TARGET_THUMB1"
8835 "operands[2] = gen_reg_rtx (SImode);"
8836 )
8837
8838 (define_expand "cstoresi_ne0_thumb1"
8839 [(parallel
8840 [(set (match_operand:SI 0 "s_register_operand" "")
8841 (ne:SI (match_operand:SI 1 "s_register_operand" "")
8842 (const_int 0)))
8843 (clobber (match_dup:SI 2))])]
8844 "TARGET_THUMB1"
8845 "operands[2] = gen_reg_rtx (SImode);"
8846 )
8847
8848 (define_insn "*cstoresi_eq0_thumb1_insn"
8849 [(set (match_operand:SI 0 "s_register_operand" "=&l,l")
8850 (eq:SI (match_operand:SI 1 "s_register_operand" "l,0")
8851 (const_int 0)))
8852 (clobber (match_operand:SI 2 "s_register_operand" "=X,l"))]
8853 "TARGET_THUMB1"
8854 "@
8855 neg\\t%0, %1\;adc\\t%0, %0, %1
8856 neg\\t%2, %1\;adc\\t%0, %1, %2"
8857 [(set_attr "length" "4")
8858 (set_attr "type" "multiple")]
8859 )
8860
8861 (define_insn "*cstoresi_ne0_thumb1_insn"
8862 [(set (match_operand:SI 0 "s_register_operand" "=l")
8863 (ne:SI (match_operand:SI 1 "s_register_operand" "0")
8864 (const_int 0)))
8865 (clobber (match_operand:SI 2 "s_register_operand" "=l"))]
8866 "TARGET_THUMB1"
8867 "sub\\t%2, %1, #1\;sbc\\t%0, %1, %2"
8868 [(set_attr "length" "4")]
8869 )
8870
8871 ;; Used as part of the expansion of thumb ltu and gtu sequences
8872 (define_insn "cstoresi_nltu_thumb1"
8873 [(set (match_operand:SI 0 "s_register_operand" "=l,l")
8874 (neg:SI (ltu:SI (match_operand:SI 1 "s_register_operand" "l,*h")
8875 (match_operand:SI 2 "thumb1_cmp_operand" "lI*h,*r"))))]
8876 "TARGET_THUMB1"
8877 "cmp\\t%1, %2\;sbc\\t%0, %0, %0"
8878 [(set_attr "length" "4")
8879 (set_attr "type" "multiple")]
8880 )
8881
8882 (define_insn_and_split "cstoresi_ltu_thumb1"
8883 [(set (match_operand:SI 0 "s_register_operand" "=l,l")
8884 (ltu:SI (match_operand:SI 1 "s_register_operand" "l,*h")
8885 (match_operand:SI 2 "thumb1_cmp_operand" "lI*h,*r")))]
8886 "TARGET_THUMB1"
8887 "#"
8888 "TARGET_THUMB1"
8889 [(set (match_dup 3)
8890 (neg:SI (ltu:SI (match_dup 1) (match_dup 2))))
8891 (set (match_dup 0) (neg:SI (match_dup 3)))]
8892 "operands[3] = gen_reg_rtx (SImode);"
8893 [(set_attr "length" "4")
8894 (set_attr "type" "multiple")]
8895 )
8896
8897 ;; Used as part of the expansion of thumb les sequence.
8898 (define_insn "thumb1_addsi3_addgeu"
8899 [(set (match_operand:SI 0 "s_register_operand" "=l")
8900 (plus:SI (plus:SI (match_operand:SI 1 "s_register_operand" "%0")
8901 (match_operand:SI 2 "s_register_operand" "l"))
8902 (geu:SI (match_operand:SI 3 "s_register_operand" "l")
8903 (match_operand:SI 4 "thumb1_cmp_operand" "lI"))))]
8904 "TARGET_THUMB1"
8905 "cmp\\t%3, %4\;adc\\t%0, %1, %2"
8906 [(set_attr "length" "4")
8907 (set_attr "type" "multiple")]
8908 )
8909
8910 \f
8911 ;; Conditional move insns
8912
8913 (define_expand "movsicc"
8914 [(set (match_operand:SI 0 "s_register_operand" "")
8915 (if_then_else:SI (match_operand 1 "expandable_comparison_operator" "")
8916 (match_operand:SI 2 "arm_not_operand" "")
8917 (match_operand:SI 3 "arm_not_operand" "")))]
8918 "TARGET_32BIT"
8919 "
8920 {
8921 enum rtx_code code;
8922 rtx ccreg;
8923
8924 if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0),
8925 &XEXP (operands[1], 1)))
8926 FAIL;
8927
8928 code = GET_CODE (operands[1]);
8929 ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
8930 XEXP (operands[1], 1), NULL_RTX);
8931 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
8932 }"
8933 )
8934
8935 (define_expand "movsfcc"
8936 [(set (match_operand:SF 0 "s_register_operand" "")
8937 (if_then_else:SF (match_operand 1 "arm_cond_move_operator" "")
8938 (match_operand:SF 2 "s_register_operand" "")
8939 (match_operand:SF 3 "s_register_operand" "")))]
8940 "TARGET_32BIT && TARGET_HARD_FLOAT"
8941 "
8942 {
8943 enum rtx_code code = GET_CODE (operands[1]);
8944 rtx ccreg;
8945
8946 if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0),
8947 &XEXP (operands[1], 1)))
8948 FAIL;
8949
8950 code = GET_CODE (operands[1]);
8951 ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
8952 XEXP (operands[1], 1), NULL_RTX);
8953 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
8954 }"
8955 )
8956
8957 (define_expand "movdfcc"
8958 [(set (match_operand:DF 0 "s_register_operand" "")
8959 (if_then_else:DF (match_operand 1 "arm_cond_move_operator" "")
8960 (match_operand:DF 2 "s_register_operand" "")
8961 (match_operand:DF 3 "s_register_operand" "")))]
8962 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
8963 "
8964 {
8965 enum rtx_code code = GET_CODE (operands[1]);
8966 rtx ccreg;
8967
8968 if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0),
8969 &XEXP (operands[1], 1)))
8970 FAIL;
8971 code = GET_CODE (operands[1]);
8972 ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
8973 XEXP (operands[1], 1), NULL_RTX);
8974 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
8975 }"
8976 )
8977
8978 (define_insn "*cmov<mode>"
8979 [(set (match_operand:SDF 0 "s_register_operand" "=<F_constraint>")
8980 (if_then_else:SDF (match_operator 1 "arm_vsel_comparison_operator"
8981 [(match_operand 2 "cc_register" "") (const_int 0)])
8982 (match_operand:SDF 3 "s_register_operand"
8983 "<F_constraint>")
8984 (match_operand:SDF 4 "s_register_operand"
8985 "<F_constraint>")))]
8986 "TARGET_HARD_FLOAT && TARGET_FPU_ARMV8 <vfp_double_cond>"
8987 "*
8988 {
8989 enum arm_cond_code code = maybe_get_arm_condition_code (operands[1]);
8990 switch (code)
8991 {
8992 case ARM_GE:
8993 case ARM_GT:
8994 case ARM_EQ:
8995 case ARM_VS:
8996 return \"vsel%d1.<V_if_elem>\\t%<V_reg>0, %<V_reg>3, %<V_reg>4\";
8997 case ARM_LT:
8998 case ARM_LE:
8999 case ARM_NE:
9000 case ARM_VC:
9001 return \"vsel%D1.<V_if_elem>\\t%<V_reg>0, %<V_reg>4, %<V_reg>3\";
9002 default:
9003 gcc_unreachable ();
9004 }
9005 return \"\";
9006 }"
9007 [(set_attr "conds" "use")
9008 (set_attr "type" "f_sel<vfp_type>")]
9009 )
9010
9011 (define_insn_and_split "*movsicc_insn"
9012 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r,r,r,r,r")
9013 (if_then_else:SI
9014 (match_operator 3 "arm_comparison_operator"
9015 [(match_operand 4 "cc_register" "") (const_int 0)])
9016 (match_operand:SI 1 "arm_not_operand" "0,0,rI,K,rI,rI,K,K")
9017 (match_operand:SI 2 "arm_not_operand" "rI,K,0,0,rI,K,rI,K")))]
9018 "TARGET_ARM"
9019 "@
9020 mov%D3\\t%0, %2
9021 mvn%D3\\t%0, #%B2
9022 mov%d3\\t%0, %1
9023 mvn%d3\\t%0, #%B1
9024 #
9025 #
9026 #
9027 #"
9028 ; alt4: mov%d3\\t%0, %1\;mov%D3\\t%0, %2
9029 ; alt5: mov%d3\\t%0, %1\;mvn%D3\\t%0, #%B2
9030 ; alt6: mvn%d3\\t%0, #%B1\;mov%D3\\t%0, %2
9031 ; alt7: mvn%d3\\t%0, #%B1\;mvn%D3\\t%0, #%B2"
9032 "&& reload_completed"
9033 [(const_int 0)]
9034 {
9035 enum rtx_code rev_code;
9036 enum machine_mode mode;
9037 rtx rev_cond;
9038
9039 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
9040 operands[3],
9041 gen_rtx_SET (VOIDmode,
9042 operands[0],
9043 operands[1])));
9044
9045 rev_code = GET_CODE (operands[3]);
9046 mode = GET_MODE (operands[4]);
9047 if (mode == CCFPmode || mode == CCFPEmode)
9048 rev_code = reverse_condition_maybe_unordered (rev_code);
9049 else
9050 rev_code = reverse_condition (rev_code);
9051
9052 rev_cond = gen_rtx_fmt_ee (rev_code,
9053 VOIDmode,
9054 operands[4],
9055 const0_rtx);
9056 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
9057 rev_cond,
9058 gen_rtx_SET (VOIDmode,
9059 operands[0],
9060 operands[2])));
9061 DONE;
9062 }
9063 [(set_attr "length" "4,4,4,4,8,8,8,8")
9064 (set_attr "conds" "use")
9065 (set_attr_alternative "type"
9066 [(if_then_else (match_operand 2 "const_int_operand" "")
9067 (const_string "mov_imm")
9068 (const_string "mov_reg"))
9069 (const_string "mvn_imm")
9070 (if_then_else (match_operand 1 "const_int_operand" "")
9071 (const_string "mov_imm")
9072 (const_string "mov_reg"))
9073 (const_string "mvn_imm")
9074 (const_string "mov_reg")
9075 (const_string "mov_reg")
9076 (const_string "mov_reg")
9077 (const_string "mov_reg")])]
9078 )
9079
9080 (define_insn "*movsfcc_soft_insn"
9081 [(set (match_operand:SF 0 "s_register_operand" "=r,r")
9082 (if_then_else:SF (match_operator 3 "arm_comparison_operator"
9083 [(match_operand 4 "cc_register" "") (const_int 0)])
9084 (match_operand:SF 1 "s_register_operand" "0,r")
9085 (match_operand:SF 2 "s_register_operand" "r,0")))]
9086 "TARGET_ARM && TARGET_SOFT_FLOAT"
9087 "@
9088 mov%D3\\t%0, %2
9089 mov%d3\\t%0, %1"
9090 [(set_attr "conds" "use")
9091 (set_attr "type" "mov_reg")]
9092 )
9093
9094 \f
9095 ;; Jump and linkage insns
9096
9097 (define_expand "jump"
9098 [(set (pc)
9099 (label_ref (match_operand 0 "" "")))]
9100 "TARGET_EITHER"
9101 ""
9102 )
9103
9104 (define_insn "*arm_jump"
9105 [(set (pc)
9106 (label_ref (match_operand 0 "" "")))]
9107 "TARGET_32BIT"
9108 "*
9109 {
9110 if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
9111 {
9112 arm_ccfsm_state += 2;
9113 return \"\";
9114 }
9115 return \"b%?\\t%l0\";
9116 }
9117 "
9118 [(set_attr "predicable" "yes")
9119 (set (attr "length")
9120 (if_then_else
9121 (and (match_test "TARGET_THUMB2")
9122 (and (ge (minus (match_dup 0) (pc)) (const_int -2044))
9123 (le (minus (match_dup 0) (pc)) (const_int 2048))))
9124 (const_int 2)
9125 (const_int 4)))
9126 (set_attr "type" "branch")]
9127 )
9128
9129 (define_insn "*thumb_jump"
9130 [(set (pc)
9131 (label_ref (match_operand 0 "" "")))]
9132 "TARGET_THUMB1"
9133 "*
9134 if (get_attr_length (insn) == 2)
9135 return \"b\\t%l0\";
9136 return \"bl\\t%l0\\t%@ far jump\";
9137 "
9138 [(set (attr "far_jump")
9139 (if_then_else
9140 (eq_attr "length" "4")
9141 (const_string "yes")
9142 (const_string "no")))
9143 (set (attr "length")
9144 (if_then_else
9145 (and (ge (minus (match_dup 0) (pc)) (const_int -2044))
9146 (le (minus (match_dup 0) (pc)) (const_int 2048)))
9147 (const_int 2)
9148 (const_int 4)))
9149 (set_attr "type" "branch")]
9150 )
9151
9152 (define_expand "call"
9153 [(parallel [(call (match_operand 0 "memory_operand" "")
9154 (match_operand 1 "general_operand" ""))
9155 (use (match_operand 2 "" ""))
9156 (clobber (reg:SI LR_REGNUM))])]
9157 "TARGET_EITHER"
9158 "
9159 {
9160 rtx callee, pat;
9161
9162 /* In an untyped call, we can get NULL for operand 2. */
9163 if (operands[2] == NULL_RTX)
9164 operands[2] = const0_rtx;
9165
9166 /* Decide if we should generate indirect calls by loading the
9167 32-bit address of the callee into a register before performing the
9168 branch and link. */
9169 callee = XEXP (operands[0], 0);
9170 if (GET_CODE (callee) == SYMBOL_REF
9171 ? arm_is_long_call_p (SYMBOL_REF_DECL (callee))
9172 : !REG_P (callee))
9173 XEXP (operands[0], 0) = force_reg (Pmode, callee);
9174
9175 pat = gen_call_internal (operands[0], operands[1], operands[2]);
9176 arm_emit_call_insn (pat, XEXP (operands[0], 0));
9177 DONE;
9178 }"
9179 )
9180
9181 (define_expand "call_internal"
9182 [(parallel [(call (match_operand 0 "memory_operand" "")
9183 (match_operand 1 "general_operand" ""))
9184 (use (match_operand 2 "" ""))
9185 (clobber (reg:SI LR_REGNUM))])])
9186
9187 (define_insn "*call_reg_armv5"
9188 [(call (mem:SI (match_operand:SI 0 "s_register_operand" "r"))
9189 (match_operand 1 "" ""))
9190 (use (match_operand 2 "" ""))
9191 (clobber (reg:SI LR_REGNUM))]
9192 "TARGET_ARM && arm_arch5 && !SIBLING_CALL_P (insn)"
9193 "blx%?\\t%0"
9194 [(set_attr "type" "call")]
9195 )
9196
9197 (define_insn "*call_reg_arm"
9198 [(call (mem:SI (match_operand:SI 0 "s_register_operand" "r"))
9199 (match_operand 1 "" ""))
9200 (use (match_operand 2 "" ""))
9201 (clobber (reg:SI LR_REGNUM))]
9202 "TARGET_ARM && !arm_arch5 && !SIBLING_CALL_P (insn)"
9203 "*
9204 return output_call (operands);
9205 "
9206 ;; length is worst case, normally it is only two
9207 [(set_attr "length" "12")
9208 (set_attr "type" "call")]
9209 )
9210
9211
9212 ;; Note: not used for armv5+ because the sequence used (ldr pc, ...) is not
9213 ;; considered a function call by the branch predictor of some cores (PR40887).
9214 ;; Falls back to blx rN (*call_reg_armv5).
9215
9216 (define_insn "*call_mem"
9217 [(call (mem:SI (match_operand:SI 0 "call_memory_operand" "m"))
9218 (match_operand 1 "" ""))
9219 (use (match_operand 2 "" ""))
9220 (clobber (reg:SI LR_REGNUM))]
9221 "TARGET_ARM && !arm_arch5 && !SIBLING_CALL_P (insn)"
9222 "*
9223 return output_call_mem (operands);
9224 "
9225 [(set_attr "length" "12")
9226 (set_attr "type" "call")]
9227 )
9228
9229 (define_insn "*call_reg_thumb1_v5"
9230 [(call (mem:SI (match_operand:SI 0 "register_operand" "l*r"))
9231 (match_operand 1 "" ""))
9232 (use (match_operand 2 "" ""))
9233 (clobber (reg:SI LR_REGNUM))]
9234 "TARGET_THUMB1 && arm_arch5 && !SIBLING_CALL_P (insn)"
9235 "blx\\t%0"
9236 [(set_attr "length" "2")
9237 (set_attr "type" "call")]
9238 )
9239
9240 (define_insn "*call_reg_thumb1"
9241 [(call (mem:SI (match_operand:SI 0 "register_operand" "l*r"))
9242 (match_operand 1 "" ""))
9243 (use (match_operand 2 "" ""))
9244 (clobber (reg:SI LR_REGNUM))]
9245 "TARGET_THUMB1 && !arm_arch5 && !SIBLING_CALL_P (insn)"
9246 "*
9247 {
9248 if (!TARGET_CALLER_INTERWORKING)
9249 return thumb_call_via_reg (operands[0]);
9250 else if (operands[1] == const0_rtx)
9251 return \"bl\\t%__interwork_call_via_%0\";
9252 else if (frame_pointer_needed)
9253 return \"bl\\t%__interwork_r7_call_via_%0\";
9254 else
9255 return \"bl\\t%__interwork_r11_call_via_%0\";
9256 }"
9257 [(set_attr "type" "call")]
9258 )
9259
9260 (define_expand "call_value"
9261 [(parallel [(set (match_operand 0 "" "")
9262 (call (match_operand 1 "memory_operand" "")
9263 (match_operand 2 "general_operand" "")))
9264 (use (match_operand 3 "" ""))
9265 (clobber (reg:SI LR_REGNUM))])]
9266 "TARGET_EITHER"
9267 "
9268 {
9269 rtx pat, callee;
9270
9271 /* In an untyped call, we can get NULL for operand 2. */
9272 if (operands[3] == 0)
9273 operands[3] = const0_rtx;
9274
9275 /* Decide if we should generate indirect calls by loading the
9276 32-bit address of the callee into a register before performing the
9277 branch and link. */
9278 callee = XEXP (operands[1], 0);
9279 if (GET_CODE (callee) == SYMBOL_REF
9280 ? arm_is_long_call_p (SYMBOL_REF_DECL (callee))
9281 : !REG_P (callee))
9282 XEXP (operands[1], 0) = force_reg (Pmode, callee);
9283
9284 pat = gen_call_value_internal (operands[0], operands[1],
9285 operands[2], operands[3]);
9286 arm_emit_call_insn (pat, XEXP (operands[1], 0));
9287 DONE;
9288 }"
9289 )
9290
9291 (define_expand "call_value_internal"
9292 [(parallel [(set (match_operand 0 "" "")
9293 (call (match_operand 1 "memory_operand" "")
9294 (match_operand 2 "general_operand" "")))
9295 (use (match_operand 3 "" ""))
9296 (clobber (reg:SI LR_REGNUM))])])
9297
9298 (define_insn "*call_value_reg_armv5"
9299 [(set (match_operand 0 "" "")
9300 (call (mem:SI (match_operand:SI 1 "s_register_operand" "r"))
9301 (match_operand 2 "" "")))
9302 (use (match_operand 3 "" ""))
9303 (clobber (reg:SI LR_REGNUM))]
9304 "TARGET_ARM && arm_arch5 && !SIBLING_CALL_P (insn)"
9305 "blx%?\\t%1"
9306 [(set_attr "type" "call")]
9307 )
9308
9309 (define_insn "*call_value_reg_arm"
9310 [(set (match_operand 0 "" "")
9311 (call (mem:SI (match_operand:SI 1 "s_register_operand" "r"))
9312 (match_operand 2 "" "")))
9313 (use (match_operand 3 "" ""))
9314 (clobber (reg:SI LR_REGNUM))]
9315 "TARGET_ARM && !arm_arch5 && !SIBLING_CALL_P (insn)"
9316 "*
9317 return output_call (&operands[1]);
9318 "
9319 [(set_attr "length" "12")
9320 (set_attr "type" "call")]
9321 )
9322
9323 ;; Note: see *call_mem
9324
9325 (define_insn "*call_value_mem"
9326 [(set (match_operand 0 "" "")
9327 (call (mem:SI (match_operand:SI 1 "call_memory_operand" "m"))
9328 (match_operand 2 "" "")))
9329 (use (match_operand 3 "" ""))
9330 (clobber (reg:SI LR_REGNUM))]
9331 "TARGET_ARM && !arm_arch5 && (!CONSTANT_ADDRESS_P (XEXP (operands[1], 0)))
9332 && !SIBLING_CALL_P (insn)"
9333 "*
9334 return output_call_mem (&operands[1]);
9335 "
9336 [(set_attr "length" "12")
9337 (set_attr "type" "call")]
9338 )
9339
9340 (define_insn "*call_value_reg_thumb1_v5"
9341 [(set (match_operand 0 "" "")
9342 (call (mem:SI (match_operand:SI 1 "register_operand" "l*r"))
9343 (match_operand 2 "" "")))
9344 (use (match_operand 3 "" ""))
9345 (clobber (reg:SI LR_REGNUM))]
9346 "TARGET_THUMB1 && arm_arch5"
9347 "blx\\t%1"
9348 [(set_attr "length" "2")
9349 (set_attr "type" "call")]
9350 )
9351
9352 (define_insn "*call_value_reg_thumb1"
9353 [(set (match_operand 0 "" "")
9354 (call (mem:SI (match_operand:SI 1 "register_operand" "l*r"))
9355 (match_operand 2 "" "")))
9356 (use (match_operand 3 "" ""))
9357 (clobber (reg:SI LR_REGNUM))]
9358 "TARGET_THUMB1 && !arm_arch5"
9359 "*
9360 {
9361 if (!TARGET_CALLER_INTERWORKING)
9362 return thumb_call_via_reg (operands[1]);
9363 else if (operands[2] == const0_rtx)
9364 return \"bl\\t%__interwork_call_via_%1\";
9365 else if (frame_pointer_needed)
9366 return \"bl\\t%__interwork_r7_call_via_%1\";
9367 else
9368 return \"bl\\t%__interwork_r11_call_via_%1\";
9369 }"
9370 [(set_attr "type" "call")]
9371 )
9372
9373 ;; Allow calls to SYMBOL_REFs specially as they are not valid general addresses
9374 ;; The 'a' causes the operand to be treated as an address, i.e. no '#' output.
9375
9376 (define_insn "*call_symbol"
9377 [(call (mem:SI (match_operand:SI 0 "" ""))
9378 (match_operand 1 "" ""))
9379 (use (match_operand 2 "" ""))
9380 (clobber (reg:SI LR_REGNUM))]
9381 "TARGET_32BIT
9382 && !SIBLING_CALL_P (insn)
9383 && (GET_CODE (operands[0]) == SYMBOL_REF)
9384 && !arm_is_long_call_p (SYMBOL_REF_DECL (operands[0]))"
9385 "*
9386 {
9387 return NEED_PLT_RELOC ? \"bl%?\\t%a0(PLT)\" : \"bl%?\\t%a0\";
9388 }"
9389 [(set_attr "type" "call")]
9390 )
9391
9392 (define_insn "*call_value_symbol"
9393 [(set (match_operand 0 "" "")
9394 (call (mem:SI (match_operand:SI 1 "" ""))
9395 (match_operand:SI 2 "" "")))
9396 (use (match_operand 3 "" ""))
9397 (clobber (reg:SI LR_REGNUM))]
9398 "TARGET_32BIT
9399 && !SIBLING_CALL_P (insn)
9400 && (GET_CODE (operands[1]) == SYMBOL_REF)
9401 && !arm_is_long_call_p (SYMBOL_REF_DECL (operands[1]))"
9402 "*
9403 {
9404 return NEED_PLT_RELOC ? \"bl%?\\t%a1(PLT)\" : \"bl%?\\t%a1\";
9405 }"
9406 [(set_attr "type" "call")]
9407 )
9408
9409 (define_insn "*call_insn"
9410 [(call (mem:SI (match_operand:SI 0 "" ""))
9411 (match_operand:SI 1 "" ""))
9412 (use (match_operand 2 "" ""))
9413 (clobber (reg:SI LR_REGNUM))]
9414 "TARGET_THUMB1
9415 && GET_CODE (operands[0]) == SYMBOL_REF
9416 && !arm_is_long_call_p (SYMBOL_REF_DECL (operands[0]))"
9417 "bl\\t%a0"
9418 [(set_attr "length" "4")
9419 (set_attr "type" "call")]
9420 )
9421
9422 (define_insn "*call_value_insn"
9423 [(set (match_operand 0 "" "")
9424 (call (mem:SI (match_operand 1 "" ""))
9425 (match_operand 2 "" "")))
9426 (use (match_operand 3 "" ""))
9427 (clobber (reg:SI LR_REGNUM))]
9428 "TARGET_THUMB1
9429 && GET_CODE (operands[1]) == SYMBOL_REF
9430 && !arm_is_long_call_p (SYMBOL_REF_DECL (operands[1]))"
9431 "bl\\t%a1"
9432 [(set_attr "length" "4")
9433 (set_attr "type" "call")]
9434 )
9435
9436 ;; We may also be able to do sibcalls for Thumb, but it's much harder...
9437 (define_expand "sibcall"
9438 [(parallel [(call (match_operand 0 "memory_operand" "")
9439 (match_operand 1 "general_operand" ""))
9440 (return)
9441 (use (match_operand 2 "" ""))])]
9442 "TARGET_32BIT"
9443 "
9444 {
9445 if (!REG_P (XEXP (operands[0], 0))
9446 && (GET_CODE (XEXP (operands[0], 0)) != SYMBOL_REF))
9447 XEXP (operands[0], 0) = force_reg (SImode, XEXP (operands[0], 0));
9448
9449 if (operands[2] == NULL_RTX)
9450 operands[2] = const0_rtx;
9451 }"
9452 )
9453
9454 (define_expand "sibcall_value"
9455 [(parallel [(set (match_operand 0 "" "")
9456 (call (match_operand 1 "memory_operand" "")
9457 (match_operand 2 "general_operand" "")))
9458 (return)
9459 (use (match_operand 3 "" ""))])]
9460 "TARGET_32BIT"
9461 "
9462 {
9463 if (!REG_P (XEXP (operands[1], 0)) &&
9464 (GET_CODE (XEXP (operands[1],0)) != SYMBOL_REF))
9465 XEXP (operands[1], 0) = force_reg (SImode, XEXP (operands[1], 0));
9466
9467 if (operands[3] == NULL_RTX)
9468 operands[3] = const0_rtx;
9469 }"
9470 )
9471
9472 (define_insn "*sibcall_insn"
9473 [(call (mem:SI (match_operand:SI 0 "call_insn_operand" "Cs, US"))
9474 (match_operand 1 "" ""))
9475 (return)
9476 (use (match_operand 2 "" ""))]
9477 "TARGET_32BIT && SIBLING_CALL_P (insn)"
9478 "*
9479 if (which_alternative == 1)
9480 return NEED_PLT_RELOC ? \"b%?\\t%a0(PLT)\" : \"b%?\\t%a0\";
9481 else
9482 {
9483 if (arm_arch5 || arm_arch4t)
9484 return \"bx%?\\t%0\\t%@ indirect register sibling call\";
9485 else
9486 return \"mov%?\\t%|pc, %0\\t%@ indirect register sibling call\";
9487 }
9488 "
9489 [(set_attr "type" "call")]
9490 )
9491
9492 (define_insn "*sibcall_value_insn"
9493 [(set (match_operand 0 "" "")
9494 (call (mem:SI (match_operand:SI 1 "call_insn_operand" "Cs,US"))
9495 (match_operand 2 "" "")))
9496 (return)
9497 (use (match_operand 3 "" ""))]
9498 "TARGET_32BIT && SIBLING_CALL_P (insn)"
9499 "*
9500 if (which_alternative == 1)
9501 return NEED_PLT_RELOC ? \"b%?\\t%a1(PLT)\" : \"b%?\\t%a1\";
9502 else
9503 {
9504 if (arm_arch5 || arm_arch4t)
9505 return \"bx%?\\t%1\";
9506 else
9507 return \"mov%?\\t%|pc, %1\\t@ indirect sibling call \";
9508 }
9509 "
9510 [(set_attr "type" "call")]
9511 )
9512
9513 (define_expand "<return_str>return"
9514 [(returns)]
9515 "(TARGET_ARM || (TARGET_THUMB2
9516 && ARM_FUNC_TYPE (arm_current_func_type ()) == ARM_FT_NORMAL
9517 && !IS_STACKALIGN (arm_current_func_type ())))
9518 <return_cond_false>"
9519 "
9520 {
9521 if (TARGET_THUMB2)
9522 {
9523 thumb2_expand_return (<return_simple_p>);
9524 DONE;
9525 }
9526 }
9527 "
9528 )
9529
9530 ;; Often the return insn will be the same as loading from memory, so set attr
9531 (define_insn "*arm_return"
9532 [(return)]
9533 "TARGET_ARM && USE_RETURN_INSN (FALSE)"
9534 "*
9535 {
9536 if (arm_ccfsm_state == 2)
9537 {
9538 arm_ccfsm_state += 2;
9539 return \"\";
9540 }
9541 return output_return_instruction (const_true_rtx, true, false, false);
9542 }"
9543 [(set_attr "type" "load1")
9544 (set_attr "length" "12")
9545 (set_attr "predicable" "yes")]
9546 )
9547
9548 (define_insn "*cond_<return_str>return"
9549 [(set (pc)
9550 (if_then_else (match_operator 0 "arm_comparison_operator"
9551 [(match_operand 1 "cc_register" "") (const_int 0)])
9552 (returns)
9553 (pc)))]
9554 "TARGET_ARM <return_cond_true>"
9555 "*
9556 {
9557 if (arm_ccfsm_state == 2)
9558 {
9559 arm_ccfsm_state += 2;
9560 return \"\";
9561 }
9562 return output_return_instruction (operands[0], true, false,
9563 <return_simple_p>);
9564 }"
9565 [(set_attr "conds" "use")
9566 (set_attr "length" "12")
9567 (set_attr "type" "load1")]
9568 )
9569
9570 (define_insn "*cond_<return_str>return_inverted"
9571 [(set (pc)
9572 (if_then_else (match_operator 0 "arm_comparison_operator"
9573 [(match_operand 1 "cc_register" "") (const_int 0)])
9574 (pc)
9575 (returns)))]
9576 "TARGET_ARM <return_cond_true>"
9577 "*
9578 {
9579 if (arm_ccfsm_state == 2)
9580 {
9581 arm_ccfsm_state += 2;
9582 return \"\";
9583 }
9584 return output_return_instruction (operands[0], true, true,
9585 <return_simple_p>);
9586 }"
9587 [(set_attr "conds" "use")
9588 (set_attr "length" "12")
9589 (set_attr "type" "load1")]
9590 )
9591
9592 (define_insn "*arm_simple_return"
9593 [(simple_return)]
9594 "TARGET_ARM"
9595 "*
9596 {
9597 if (arm_ccfsm_state == 2)
9598 {
9599 arm_ccfsm_state += 2;
9600 return \"\";
9601 }
9602 return output_return_instruction (const_true_rtx, true, false, true);
9603 }"
9604 [(set_attr "type" "branch")
9605 (set_attr "length" "4")
9606 (set_attr "predicable" "yes")]
9607 )
9608
9609 ;; Generate a sequence of instructions to determine if the processor is
9610 ;; in 26-bit or 32-bit mode, and return the appropriate return address
9611 ;; mask.
9612
9613 (define_expand "return_addr_mask"
9614 [(set (match_dup 1)
9615 (compare:CC_NOOV (unspec [(const_int 0)] UNSPEC_CHECK_ARCH)
9616 (const_int 0)))
9617 (set (match_operand:SI 0 "s_register_operand" "")
9618 (if_then_else:SI (eq (match_dup 1) (const_int 0))
9619 (const_int -1)
9620 (const_int 67108860)))] ; 0x03fffffc
9621 "TARGET_ARM"
9622 "
9623 operands[1] = gen_rtx_REG (CC_NOOVmode, CC_REGNUM);
9624 ")
9625
9626 (define_insn "*check_arch2"
9627 [(set (match_operand:CC_NOOV 0 "cc_register" "")
9628 (compare:CC_NOOV (unspec [(const_int 0)] UNSPEC_CHECK_ARCH)
9629 (const_int 0)))]
9630 "TARGET_ARM"
9631 "teq\\t%|r0, %|r0\;teq\\t%|pc, %|pc"
9632 [(set_attr "length" "8")
9633 (set_attr "conds" "set")
9634 (set_attr "type" "multiple")]
9635 )
9636
9637 ;; Call subroutine returning any type.
9638
9639 (define_expand "untyped_call"
9640 [(parallel [(call (match_operand 0 "" "")
9641 (const_int 0))
9642 (match_operand 1 "" "")
9643 (match_operand 2 "" "")])]
9644 "TARGET_EITHER"
9645 "
9646 {
9647 int i;
9648 rtx par = gen_rtx_PARALLEL (VOIDmode,
9649 rtvec_alloc (XVECLEN (operands[2], 0)));
9650 rtx addr = gen_reg_rtx (Pmode);
9651 rtx mem;
9652 int size = 0;
9653
9654 emit_move_insn (addr, XEXP (operands[1], 0));
9655 mem = change_address (operands[1], BLKmode, addr);
9656
9657 for (i = 0; i < XVECLEN (operands[2], 0); i++)
9658 {
9659 rtx src = SET_SRC (XVECEXP (operands[2], 0, i));
9660
9661 /* Default code only uses r0 as a return value, but we could
9662 be using anything up to 4 registers. */
9663 if (REGNO (src) == R0_REGNUM)
9664 src = gen_rtx_REG (TImode, R0_REGNUM);
9665
9666 XVECEXP (par, 0, i) = gen_rtx_EXPR_LIST (VOIDmode, src,
9667 GEN_INT (size));
9668 size += GET_MODE_SIZE (GET_MODE (src));
9669 }
9670
9671 emit_call_insn (GEN_CALL_VALUE (par, operands[0], const0_rtx, NULL,
9672 const0_rtx));
9673
9674 size = 0;
9675
9676 for (i = 0; i < XVECLEN (par, 0); i++)
9677 {
9678 HOST_WIDE_INT offset = 0;
9679 rtx reg = XEXP (XVECEXP (par, 0, i), 0);
9680
9681 if (size != 0)
9682 emit_move_insn (addr, plus_constant (Pmode, addr, size));
9683
9684 mem = change_address (mem, GET_MODE (reg), NULL);
9685 if (REGNO (reg) == R0_REGNUM)
9686 {
9687 /* On thumb we have to use a write-back instruction. */
9688 emit_insn (arm_gen_store_multiple (arm_regs_in_sequence, 4, addr,
9689 TARGET_THUMB ? TRUE : FALSE, mem, &offset));
9690 size = TARGET_ARM ? 16 : 0;
9691 }
9692 else
9693 {
9694 emit_move_insn (mem, reg);
9695 size = GET_MODE_SIZE (GET_MODE (reg));
9696 }
9697 }
9698
9699 /* The optimizer does not know that the call sets the function value
9700 registers we stored in the result block. We avoid problems by
9701 claiming that all hard registers are used and clobbered at this
9702 point. */
9703 emit_insn (gen_blockage ());
9704
9705 DONE;
9706 }"
9707 )
9708
9709 (define_expand "untyped_return"
9710 [(match_operand:BLK 0 "memory_operand" "")
9711 (match_operand 1 "" "")]
9712 "TARGET_EITHER"
9713 "
9714 {
9715 int i;
9716 rtx addr = gen_reg_rtx (Pmode);
9717 rtx mem;
9718 int size = 0;
9719
9720 emit_move_insn (addr, XEXP (operands[0], 0));
9721 mem = change_address (operands[0], BLKmode, addr);
9722
9723 for (i = 0; i < XVECLEN (operands[1], 0); i++)
9724 {
9725 HOST_WIDE_INT offset = 0;
9726 rtx reg = SET_DEST (XVECEXP (operands[1], 0, i));
9727
9728 if (size != 0)
9729 emit_move_insn (addr, plus_constant (Pmode, addr, size));
9730
9731 mem = change_address (mem, GET_MODE (reg), NULL);
9732 if (REGNO (reg) == R0_REGNUM)
9733 {
9734 /* On thumb we have to use a write-back instruction. */
9735 emit_insn (arm_gen_load_multiple (arm_regs_in_sequence, 4, addr,
9736 TARGET_THUMB ? TRUE : FALSE, mem, &offset));
9737 size = TARGET_ARM ? 16 : 0;
9738 }
9739 else
9740 {
9741 emit_move_insn (reg, mem);
9742 size = GET_MODE_SIZE (GET_MODE (reg));
9743 }
9744 }
9745
9746 /* Emit USE insns before the return. */
9747 for (i = 0; i < XVECLEN (operands[1], 0); i++)
9748 emit_use (SET_DEST (XVECEXP (operands[1], 0, i)));
9749
9750 /* Construct the return. */
9751 expand_naked_return ();
9752
9753 DONE;
9754 }"
9755 )
9756
9757 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
9758 ;; all of memory. This blocks insns from being moved across this point.
9759
9760 (define_insn "blockage"
9761 [(unspec_volatile [(const_int 0)] VUNSPEC_BLOCKAGE)]
9762 "TARGET_EITHER"
9763 ""
9764 [(set_attr "length" "0")
9765 (set_attr "type" "block")]
9766 )
9767
9768 (define_expand "casesi"
9769 [(match_operand:SI 0 "s_register_operand" "") ; index to jump on
9770 (match_operand:SI 1 "const_int_operand" "") ; lower bound
9771 (match_operand:SI 2 "const_int_operand" "") ; total range
9772 (match_operand:SI 3 "" "") ; table label
9773 (match_operand:SI 4 "" "")] ; Out of range label
9774 "TARGET_32BIT || optimize_size || flag_pic"
9775 "
9776 {
9777 enum insn_code code;
9778 if (operands[1] != const0_rtx)
9779 {
9780 rtx reg = gen_reg_rtx (SImode);
9781
9782 emit_insn (gen_addsi3 (reg, operands[0],
9783 gen_int_mode (-INTVAL (operands[1]),
9784 SImode)));
9785 operands[0] = reg;
9786 }
9787
9788 if (TARGET_ARM)
9789 code = CODE_FOR_arm_casesi_internal;
9790 else if (TARGET_THUMB1)
9791 code = CODE_FOR_thumb1_casesi_internal_pic;
9792 else if (flag_pic)
9793 code = CODE_FOR_thumb2_casesi_internal_pic;
9794 else
9795 code = CODE_FOR_thumb2_casesi_internal;
9796
9797 if (!insn_data[(int) code].operand[1].predicate(operands[2], SImode))
9798 operands[2] = force_reg (SImode, operands[2]);
9799
9800 emit_jump_insn (GEN_FCN ((int) code) (operands[0], operands[2],
9801 operands[3], operands[4]));
9802 DONE;
9803 }"
9804 )
9805
9806 ;; The USE in this pattern is needed to tell flow analysis that this is
9807 ;; a CASESI insn. It has no other purpose.
9808 (define_insn "arm_casesi_internal"
9809 [(parallel [(set (pc)
9810 (if_then_else
9811 (leu (match_operand:SI 0 "s_register_operand" "r")
9812 (match_operand:SI 1 "arm_rhs_operand" "rI"))
9813 (mem:SI (plus:SI (mult:SI (match_dup 0) (const_int 4))
9814 (label_ref (match_operand 2 "" ""))))
9815 (label_ref (match_operand 3 "" ""))))
9816 (clobber (reg:CC CC_REGNUM))
9817 (use (label_ref (match_dup 2)))])]
9818 "TARGET_ARM"
9819 "*
9820 if (flag_pic)
9821 return \"cmp\\t%0, %1\;addls\\t%|pc, %|pc, %0, asl #2\;b\\t%l3\";
9822 return \"cmp\\t%0, %1\;ldrls\\t%|pc, [%|pc, %0, asl #2]\;b\\t%l3\";
9823 "
9824 [(set_attr "conds" "clob")
9825 (set_attr "length" "12")
9826 (set_attr "type" "multiple")]
9827 )
9828
9829 (define_expand "thumb1_casesi_internal_pic"
9830 [(match_operand:SI 0 "s_register_operand" "")
9831 (match_operand:SI 1 "thumb1_cmp_operand" "")
9832 (match_operand 2 "" "")
9833 (match_operand 3 "" "")]
9834 "TARGET_THUMB1"
9835 {
9836 rtx reg0;
9837 rtx test = gen_rtx_GTU (VOIDmode, operands[0], operands[1]);
9838 emit_jump_insn (gen_cbranchsi4 (test, operands[0], operands[1],
9839 operands[3]));
9840 reg0 = gen_rtx_REG (SImode, 0);
9841 emit_move_insn (reg0, operands[0]);
9842 emit_jump_insn (gen_thumb1_casesi_dispatch (operands[2]/*, operands[3]*/));
9843 DONE;
9844 }
9845 )
9846
9847 (define_insn "thumb1_casesi_dispatch"
9848 [(parallel [(set (pc) (unspec [(reg:SI 0)
9849 (label_ref (match_operand 0 "" ""))
9850 ;; (label_ref (match_operand 1 "" ""))
9851 ]
9852 UNSPEC_THUMB1_CASESI))
9853 (clobber (reg:SI IP_REGNUM))
9854 (clobber (reg:SI LR_REGNUM))])]
9855 "TARGET_THUMB1"
9856 "* return thumb1_output_casesi(operands);"
9857 [(set_attr "length" "4")
9858 (set_attr "type" "multiple")]
9859 )
9860
9861 (define_expand "indirect_jump"
9862 [(set (pc)
9863 (match_operand:SI 0 "s_register_operand" ""))]
9864 "TARGET_EITHER"
9865 "
9866 /* Thumb-2 doesn't have mov pc, reg. Explicitly set the low bit of the
9867 address and use bx. */
9868 if (TARGET_THUMB2)
9869 {
9870 rtx tmp;
9871 tmp = gen_reg_rtx (SImode);
9872 emit_insn (gen_iorsi3 (tmp, operands[0], GEN_INT(1)));
9873 operands[0] = tmp;
9874 }
9875 "
9876 )
9877
9878 ;; NB Never uses BX.
9879 (define_insn "*arm_indirect_jump"
9880 [(set (pc)
9881 (match_operand:SI 0 "s_register_operand" "r"))]
9882 "TARGET_ARM"
9883 "mov%?\\t%|pc, %0\\t%@ indirect register jump"
9884 [(set_attr "predicable" "yes")
9885 (set_attr "type" "branch")]
9886 )
9887
9888 (define_insn "*load_indirect_jump"
9889 [(set (pc)
9890 (match_operand:SI 0 "memory_operand" "m"))]
9891 "TARGET_ARM"
9892 "ldr%?\\t%|pc, %0\\t%@ indirect memory jump"
9893 [(set_attr "type" "load1")
9894 (set_attr "pool_range" "4096")
9895 (set_attr "neg_pool_range" "4084")
9896 (set_attr "predicable" "yes")]
9897 )
9898
9899 ;; NB Never uses BX.
9900 (define_insn "*thumb1_indirect_jump"
9901 [(set (pc)
9902 (match_operand:SI 0 "register_operand" "l*r"))]
9903 "TARGET_THUMB1"
9904 "mov\\tpc, %0"
9905 [(set_attr "conds" "clob")
9906 (set_attr "length" "2")
9907 (set_attr "type" "branch")]
9908 )
9909
9910 \f
9911 ;; Misc insns
9912
9913 (define_insn "nop"
9914 [(const_int 0)]
9915 "TARGET_EITHER"
9916 "*
9917 if (TARGET_UNIFIED_ASM)
9918 return \"nop\";
9919 if (TARGET_ARM)
9920 return \"mov%?\\t%|r0, %|r0\\t%@ nop\";
9921 return \"mov\\tr8, r8\";
9922 "
9923 [(set (attr "length")
9924 (if_then_else (eq_attr "is_thumb" "yes")
9925 (const_int 2)
9926 (const_int 4)))
9927 (set_attr "type" "mov_reg")]
9928 )
9929
9930 (define_insn "trap"
9931 [(trap_if (const_int 1) (const_int 0))]
9932 ""
9933 "*
9934 if (TARGET_ARM)
9935 return \".inst\\t0xe7f000f0\";
9936 else
9937 return \".inst\\t0xdeff\";
9938 "
9939 [(set (attr "length")
9940 (if_then_else (eq_attr "is_thumb" "yes")
9941 (const_int 2)
9942 (const_int 4)))
9943 (set_attr "type" "trap")
9944 (set_attr "conds" "unconditional")]
9945 )
9946
9947 \f
9948 ;; Patterns to allow combination of arithmetic, cond code and shifts
9949
9950 (define_insn "*arith_shiftsi"
9951 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r")
9952 (match_operator:SI 1 "shiftable_operator"
9953 [(match_operator:SI 3 "shift_operator"
9954 [(match_operand:SI 4 "s_register_operand" "r,r,r,r")
9955 (match_operand:SI 5 "shift_amount_operand" "M,M,M,r")])
9956 (match_operand:SI 2 "s_register_operand" "rk,rk,r,rk")]))]
9957 "TARGET_32BIT"
9958 "%i1%?\\t%0, %2, %4%S3"
9959 [(set_attr "predicable" "yes")
9960 (set_attr "shift" "4")
9961 (set_attr "arch" "a,t2,t2,a")
9962 ;; Thumb2 doesn't allow the stack pointer to be used for
9963 ;; operand1 for all operations other than add and sub. In this case
9964 ;; the minus operation is a candidate for an rsub and hence needs
9965 ;; to be disabled.
9966 ;; We have to make sure to disable the fourth alternative if
9967 ;; the shift_operator is MULT, since otherwise the insn will
9968 ;; also match a multiply_accumulate pattern and validate_change
9969 ;; will allow a replacement of the constant with a register
9970 ;; despite the checks done in shift_operator.
9971 (set_attr_alternative "insn_enabled"
9972 [(const_string "yes")
9973 (if_then_else
9974 (match_operand:SI 1 "add_operator" "")
9975 (const_string "yes") (const_string "no"))
9976 (const_string "yes")
9977 (if_then_else
9978 (match_operand:SI 3 "mult_operator" "")
9979 (const_string "no") (const_string "yes"))])
9980 (set_attr "type" "alu_shift_imm,alu_shift_imm,alu_shift_imm,alu_shift_reg")])
9981
9982 (define_split
9983 [(set (match_operand:SI 0 "s_register_operand" "")
9984 (match_operator:SI 1 "shiftable_operator"
9985 [(match_operator:SI 2 "shiftable_operator"
9986 [(match_operator:SI 3 "shift_operator"
9987 [(match_operand:SI 4 "s_register_operand" "")
9988 (match_operand:SI 5 "reg_or_int_operand" "")])
9989 (match_operand:SI 6 "s_register_operand" "")])
9990 (match_operand:SI 7 "arm_rhs_operand" "")]))
9991 (clobber (match_operand:SI 8 "s_register_operand" ""))]
9992 "TARGET_32BIT"
9993 [(set (match_dup 8)
9994 (match_op_dup 2 [(match_op_dup 3 [(match_dup 4) (match_dup 5)])
9995 (match_dup 6)]))
9996 (set (match_dup 0)
9997 (match_op_dup 1 [(match_dup 8) (match_dup 7)]))]
9998 "")
9999
10000 (define_insn "*arith_shiftsi_compare0"
10001 [(set (reg:CC_NOOV CC_REGNUM)
10002 (compare:CC_NOOV
10003 (match_operator:SI 1 "shiftable_operator"
10004 [(match_operator:SI 3 "shift_operator"
10005 [(match_operand:SI 4 "s_register_operand" "r,r")
10006 (match_operand:SI 5 "shift_amount_operand" "M,r")])
10007 (match_operand:SI 2 "s_register_operand" "r,r")])
10008 (const_int 0)))
10009 (set (match_operand:SI 0 "s_register_operand" "=r,r")
10010 (match_op_dup 1 [(match_op_dup 3 [(match_dup 4) (match_dup 5)])
10011 (match_dup 2)]))]
10012 "TARGET_32BIT"
10013 "%i1%.\\t%0, %2, %4%S3"
10014 [(set_attr "conds" "set")
10015 (set_attr "shift" "4")
10016 (set_attr "arch" "32,a")
10017 (set_attr "type" "alus_shift_imm,alus_shift_reg")])
10018
10019 (define_insn "*arith_shiftsi_compare0_scratch"
10020 [(set (reg:CC_NOOV CC_REGNUM)
10021 (compare:CC_NOOV
10022 (match_operator:SI 1 "shiftable_operator"
10023 [(match_operator:SI 3 "shift_operator"
10024 [(match_operand:SI 4 "s_register_operand" "r,r")
10025 (match_operand:SI 5 "shift_amount_operand" "M,r")])
10026 (match_operand:SI 2 "s_register_operand" "r,r")])
10027 (const_int 0)))
10028 (clobber (match_scratch:SI 0 "=r,r"))]
10029 "TARGET_32BIT"
10030 "%i1%.\\t%0, %2, %4%S3"
10031 [(set_attr "conds" "set")
10032 (set_attr "shift" "4")
10033 (set_attr "arch" "32,a")
10034 (set_attr "type" "alus_shift_imm,alus_shift_reg")])
10035
10036 (define_insn "*sub_shiftsi"
10037 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10038 (minus:SI (match_operand:SI 1 "s_register_operand" "r,r")
10039 (match_operator:SI 2 "shift_operator"
10040 [(match_operand:SI 3 "s_register_operand" "r,r")
10041 (match_operand:SI 4 "shift_amount_operand" "M,r")])))]
10042 "TARGET_32BIT"
10043 "sub%?\\t%0, %1, %3%S2"
10044 [(set_attr "predicable" "yes")
10045 (set_attr "shift" "3")
10046 (set_attr "arch" "32,a")
10047 (set_attr "type" "alus_shift_imm,alus_shift_reg")])
10048
10049 (define_insn "*sub_shiftsi_compare0"
10050 [(set (reg:CC_NOOV CC_REGNUM)
10051 (compare:CC_NOOV
10052 (minus:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
10053 (match_operator:SI 2 "shift_operator"
10054 [(match_operand:SI 3 "s_register_operand" "r,r,r")
10055 (match_operand:SI 4 "shift_amount_operand" "M,r,M")]))
10056 (const_int 0)))
10057 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
10058 (minus:SI (match_dup 1)
10059 (match_op_dup 2 [(match_dup 3) (match_dup 4)])))]
10060 "TARGET_32BIT"
10061 "sub%.\\t%0, %1, %3%S2"
10062 [(set_attr "conds" "set")
10063 (set_attr "shift" "3")
10064 (set_attr "arch" "32,a,a")
10065 (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")])
10066
10067 (define_insn "*sub_shiftsi_compare0_scratch"
10068 [(set (reg:CC_NOOV CC_REGNUM)
10069 (compare:CC_NOOV
10070 (minus:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
10071 (match_operator:SI 2 "shift_operator"
10072 [(match_operand:SI 3 "s_register_operand" "r,r,r")
10073 (match_operand:SI 4 "shift_amount_operand" "M,r,M")]))
10074 (const_int 0)))
10075 (clobber (match_scratch:SI 0 "=r,r,r"))]
10076 "TARGET_32BIT"
10077 "sub%.\\t%0, %1, %3%S2"
10078 [(set_attr "conds" "set")
10079 (set_attr "shift" "3")
10080 (set_attr "arch" "32,a,a")
10081 (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")])
10082 \f
10083
10084 (define_insn_and_split "*and_scc"
10085 [(set (match_operand:SI 0 "s_register_operand" "=r")
10086 (and:SI (match_operator:SI 1 "arm_comparison_operator"
10087 [(match_operand 2 "cc_register" "") (const_int 0)])
10088 (match_operand:SI 3 "s_register_operand" "r")))]
10089 "TARGET_ARM"
10090 "#" ; "mov%D1\\t%0, #0\;and%d1\\t%0, %3, #1"
10091 "&& reload_completed"
10092 [(cond_exec (match_dup 5) (set (match_dup 0) (const_int 0)))
10093 (cond_exec (match_dup 4) (set (match_dup 0)
10094 (and:SI (match_dup 3) (const_int 1))))]
10095 {
10096 enum machine_mode mode = GET_MODE (operands[2]);
10097 enum rtx_code rc = GET_CODE (operands[1]);
10098
10099 /* Note that operands[4] is the same as operands[1],
10100 but with VOIDmode as the result. */
10101 operands[4] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
10102 if (mode == CCFPmode || mode == CCFPEmode)
10103 rc = reverse_condition_maybe_unordered (rc);
10104 else
10105 rc = reverse_condition (rc);
10106 operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
10107 }
10108 [(set_attr "conds" "use")
10109 (set_attr "type" "multiple")
10110 (set_attr "length" "8")]
10111 )
10112
10113 (define_insn_and_split "*ior_scc"
10114 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10115 (ior:SI (match_operator:SI 1 "arm_comparison_operator"
10116 [(match_operand 2 "cc_register" "") (const_int 0)])
10117 (match_operand:SI 3 "s_register_operand" "0,?r")))]
10118 "TARGET_ARM"
10119 "@
10120 orr%d1\\t%0, %3, #1
10121 #"
10122 "&& reload_completed
10123 && REGNO (operands [0]) != REGNO (operands[3])"
10124 ;; && which_alternative == 1
10125 ; mov%D1\\t%0, %3\;orr%d1\\t%0, %3, #1
10126 [(cond_exec (match_dup 5) (set (match_dup 0) (match_dup 3)))
10127 (cond_exec (match_dup 4) (set (match_dup 0)
10128 (ior:SI (match_dup 3) (const_int 1))))]
10129 {
10130 enum machine_mode mode = GET_MODE (operands[2]);
10131 enum rtx_code rc = GET_CODE (operands[1]);
10132
10133 /* Note that operands[4] is the same as operands[1],
10134 but with VOIDmode as the result. */
10135 operands[4] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
10136 if (mode == CCFPmode || mode == CCFPEmode)
10137 rc = reverse_condition_maybe_unordered (rc);
10138 else
10139 rc = reverse_condition (rc);
10140 operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
10141 }
10142 [(set_attr "conds" "use")
10143 (set_attr "length" "4,8")
10144 (set_attr "type" "logic_imm,multiple")]
10145 )
10146
10147 ; A series of splitters for the compare_scc pattern below. Note that
10148 ; order is important.
10149 (define_split
10150 [(set (match_operand:SI 0 "s_register_operand" "")
10151 (lt:SI (match_operand:SI 1 "s_register_operand" "")
10152 (const_int 0)))
10153 (clobber (reg:CC CC_REGNUM))]
10154 "TARGET_32BIT && reload_completed"
10155 [(set (match_dup 0) (lshiftrt:SI (match_dup 1) (const_int 31)))])
10156
10157 (define_split
10158 [(set (match_operand:SI 0 "s_register_operand" "")
10159 (ge:SI (match_operand:SI 1 "s_register_operand" "")
10160 (const_int 0)))
10161 (clobber (reg:CC CC_REGNUM))]
10162 "TARGET_32BIT && reload_completed"
10163 [(set (match_dup 0) (not:SI (match_dup 1)))
10164 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 31)))])
10165
10166 (define_split
10167 [(set (match_operand:SI 0 "s_register_operand" "")
10168 (eq:SI (match_operand:SI 1 "s_register_operand" "")
10169 (const_int 0)))
10170 (clobber (reg:CC CC_REGNUM))]
10171 "arm_arch5 && TARGET_32BIT"
10172 [(set (match_dup 0) (clz:SI (match_dup 1)))
10173 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 5)))]
10174 )
10175
10176 (define_split
10177 [(set (match_operand:SI 0 "s_register_operand" "")
10178 (eq:SI (match_operand:SI 1 "s_register_operand" "")
10179 (const_int 0)))
10180 (clobber (reg:CC CC_REGNUM))]
10181 "TARGET_32BIT && reload_completed"
10182 [(parallel
10183 [(set (reg:CC CC_REGNUM)
10184 (compare:CC (const_int 1) (match_dup 1)))
10185 (set (match_dup 0)
10186 (minus:SI (const_int 1) (match_dup 1)))])
10187 (cond_exec (ltu:CC (reg:CC CC_REGNUM) (const_int 0))
10188 (set (match_dup 0) (const_int 0)))])
10189
10190 (define_split
10191 [(set (match_operand:SI 0 "s_register_operand" "")
10192 (ne:SI (match_operand:SI 1 "s_register_operand" "")
10193 (match_operand:SI 2 "const_int_operand" "")))
10194 (clobber (reg:CC CC_REGNUM))]
10195 "TARGET_32BIT && reload_completed"
10196 [(parallel
10197 [(set (reg:CC CC_REGNUM)
10198 (compare:CC (match_dup 1) (match_dup 2)))
10199 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 3)))])
10200 (cond_exec (ne:CC (reg:CC CC_REGNUM) (const_int 0))
10201 (set (match_dup 0) (const_int 1)))]
10202 {
10203 operands[3] = GEN_INT (-INTVAL (operands[2]));
10204 })
10205
10206 (define_split
10207 [(set (match_operand:SI 0 "s_register_operand" "")
10208 (ne:SI (match_operand:SI 1 "s_register_operand" "")
10209 (match_operand:SI 2 "arm_add_operand" "")))
10210 (clobber (reg:CC CC_REGNUM))]
10211 "TARGET_32BIT && reload_completed"
10212 [(parallel
10213 [(set (reg:CC_NOOV CC_REGNUM)
10214 (compare:CC_NOOV (minus:SI (match_dup 1) (match_dup 2))
10215 (const_int 0)))
10216 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
10217 (cond_exec (ne:CC_NOOV (reg:CC_NOOV CC_REGNUM) (const_int 0))
10218 (set (match_dup 0) (const_int 1)))])
10219
10220 (define_insn_and_split "*compare_scc"
10221 [(set (match_operand:SI 0 "s_register_operand" "=Ts,Ts")
10222 (match_operator:SI 1 "arm_comparison_operator"
10223 [(match_operand:SI 2 "s_register_operand" "r,r")
10224 (match_operand:SI 3 "arm_add_operand" "rI,L")]))
10225 (clobber (reg:CC CC_REGNUM))]
10226 "TARGET_32BIT"
10227 "#"
10228 "&& reload_completed"
10229 [(set (reg:CC CC_REGNUM) (compare:CC (match_dup 2) (match_dup 3)))
10230 (cond_exec (match_dup 4) (set (match_dup 0) (const_int 0)))
10231 (cond_exec (match_dup 5) (set (match_dup 0) (const_int 1)))]
10232 {
10233 rtx tmp1;
10234 enum machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
10235 operands[2], operands[3]);
10236 enum rtx_code rc = GET_CODE (operands[1]);
10237
10238 tmp1 = gen_rtx_REG (mode, CC_REGNUM);
10239
10240 operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, tmp1, const0_rtx);
10241 if (mode == CCFPmode || mode == CCFPEmode)
10242 rc = reverse_condition_maybe_unordered (rc);
10243 else
10244 rc = reverse_condition (rc);
10245 operands[4] = gen_rtx_fmt_ee (rc, VOIDmode, tmp1, const0_rtx);
10246 }
10247 [(set_attr "type" "multiple")]
10248 )
10249
10250 ;; Attempt to improve the sequence generated by the compare_scc splitters
10251 ;; not to use conditional execution.
10252
10253 ;; Rd = (eq (reg1) (const_int0)) // ARMv5
10254 ;; clz Rd, reg1
10255 ;; lsr Rd, Rd, #5
10256 (define_peephole2
10257 [(set (reg:CC CC_REGNUM)
10258 (compare:CC (match_operand:SI 1 "register_operand" "")
10259 (const_int 0)))
10260 (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
10261 (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
10262 (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
10263 (set (match_dup 0) (const_int 1)))]
10264 "arm_arch5 && TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)"
10265 [(set (match_dup 0) (clz:SI (match_dup 1)))
10266 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 5)))]
10267 )
10268
10269 ;; Rd = (eq (reg1) (const_int0)) // !ARMv5
10270 ;; negs Rd, reg1
10271 ;; adc Rd, Rd, reg1
10272 (define_peephole2
10273 [(set (reg:CC CC_REGNUM)
10274 (compare:CC (match_operand:SI 1 "register_operand" "")
10275 (const_int 0)))
10276 (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
10277 (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
10278 (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
10279 (set (match_dup 0) (const_int 1)))
10280 (match_scratch:SI 2 "r")]
10281 "TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)"
10282 [(parallel
10283 [(set (reg:CC CC_REGNUM)
10284 (compare:CC (const_int 0) (match_dup 1)))
10285 (set (match_dup 2) (minus:SI (const_int 0) (match_dup 1)))])
10286 (set (match_dup 0)
10287 (plus:SI (plus:SI (match_dup 1) (match_dup 2))
10288 (geu:SI (reg:CC CC_REGNUM) (const_int 0))))]
10289 )
10290
10291 ;; Rd = (eq (reg1) (reg2/imm)) // ARMv5 and optimising for speed.
10292 ;; sub Rd, Reg1, reg2
10293 ;; clz Rd, Rd
10294 ;; lsr Rd, Rd, #5
10295 (define_peephole2
10296 [(set (reg:CC CC_REGNUM)
10297 (compare:CC (match_operand:SI 1 "register_operand" "")
10298 (match_operand:SI 2 "arm_rhs_operand" "")))
10299 (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
10300 (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
10301 (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
10302 (set (match_dup 0) (const_int 1)))]
10303 "arm_arch5 && TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)
10304 && !(TARGET_THUMB2 && optimize_insn_for_size_p ())"
10305 [(set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))
10306 (set (match_dup 0) (clz:SI (match_dup 0)))
10307 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 5)))]
10308 )
10309
10310
10311 ;; Rd = (eq (reg1) (reg2)) // ! ARMv5 or optimising for size.
10312 ;; sub T1, Reg1, reg2
10313 ;; negs Rd, T1
10314 ;; adc Rd, Rd, T1
10315 (define_peephole2
10316 [(set (reg:CC CC_REGNUM)
10317 (compare:CC (match_operand:SI 1 "register_operand" "")
10318 (match_operand:SI 2 "arm_rhs_operand" "")))
10319 (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
10320 (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
10321 (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
10322 (set (match_dup 0) (const_int 1)))
10323 (match_scratch:SI 3 "r")]
10324 "TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)"
10325 [(set (match_dup 3) (match_dup 4))
10326 (parallel
10327 [(set (reg:CC CC_REGNUM)
10328 (compare:CC (const_int 0) (match_dup 3)))
10329 (set (match_dup 0) (minus:SI (const_int 0) (match_dup 3)))])
10330 (set (match_dup 0)
10331 (plus:SI (plus:SI (match_dup 0) (match_dup 3))
10332 (geu:SI (reg:CC CC_REGNUM) (const_int 0))))]
10333 "
10334 if (CONST_INT_P (operands[2]))
10335 operands[4] = plus_constant (SImode, operands[1], -INTVAL (operands[2]));
10336 else
10337 operands[4] = gen_rtx_MINUS (SImode, operands[1], operands[2]);
10338 ")
10339
10340 (define_insn "*cond_move"
10341 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
10342 (if_then_else:SI (match_operator 3 "equality_operator"
10343 [(match_operator 4 "arm_comparison_operator"
10344 [(match_operand 5 "cc_register" "") (const_int 0)])
10345 (const_int 0)])
10346 (match_operand:SI 1 "arm_rhs_operand" "0,rI,?rI")
10347 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))]
10348 "TARGET_ARM"
10349 "*
10350 if (GET_CODE (operands[3]) == NE)
10351 {
10352 if (which_alternative != 1)
10353 output_asm_insn (\"mov%D4\\t%0, %2\", operands);
10354 if (which_alternative != 0)
10355 output_asm_insn (\"mov%d4\\t%0, %1\", operands);
10356 return \"\";
10357 }
10358 if (which_alternative != 0)
10359 output_asm_insn (\"mov%D4\\t%0, %1\", operands);
10360 if (which_alternative != 1)
10361 output_asm_insn (\"mov%d4\\t%0, %2\", operands);
10362 return \"\";
10363 "
10364 [(set_attr "conds" "use")
10365 (set_attr "type" "mov_reg,mov_reg,multiple")
10366 (set_attr "length" "4,4,8")]
10367 )
10368
10369 (define_insn "*cond_arith"
10370 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10371 (match_operator:SI 5 "shiftable_operator"
10372 [(match_operator:SI 4 "arm_comparison_operator"
10373 [(match_operand:SI 2 "s_register_operand" "r,r")
10374 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
10375 (match_operand:SI 1 "s_register_operand" "0,?r")]))
10376 (clobber (reg:CC CC_REGNUM))]
10377 "TARGET_ARM"
10378 "*
10379 if (GET_CODE (operands[4]) == LT && operands[3] == const0_rtx)
10380 return \"%i5\\t%0, %1, %2, lsr #31\";
10381
10382 output_asm_insn (\"cmp\\t%2, %3\", operands);
10383 if (GET_CODE (operands[5]) == AND)
10384 output_asm_insn (\"mov%D4\\t%0, #0\", operands);
10385 else if (GET_CODE (operands[5]) == MINUS)
10386 output_asm_insn (\"rsb%D4\\t%0, %1, #0\", operands);
10387 else if (which_alternative != 0)
10388 output_asm_insn (\"mov%D4\\t%0, %1\", operands);
10389 return \"%i5%d4\\t%0, %1, #1\";
10390 "
10391 [(set_attr "conds" "clob")
10392 (set_attr "length" "12")
10393 (set_attr "type" "multiple")]
10394 )
10395
10396 (define_insn "*cond_sub"
10397 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10398 (minus:SI (match_operand:SI 1 "s_register_operand" "0,?r")
10399 (match_operator:SI 4 "arm_comparison_operator"
10400 [(match_operand:SI 2 "s_register_operand" "r,r")
10401 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))
10402 (clobber (reg:CC CC_REGNUM))]
10403 "TARGET_ARM"
10404 "*
10405 output_asm_insn (\"cmp\\t%2, %3\", operands);
10406 if (which_alternative != 0)
10407 output_asm_insn (\"mov%D4\\t%0, %1\", operands);
10408 return \"sub%d4\\t%0, %1, #1\";
10409 "
10410 [(set_attr "conds" "clob")
10411 (set_attr "length" "8,12")
10412 (set_attr "type" "multiple")]
10413 )
10414
10415 (define_insn "*cmp_ite0"
10416 [(set (match_operand 6 "dominant_cc_register" "")
10417 (compare
10418 (if_then_else:SI
10419 (match_operator 4 "arm_comparison_operator"
10420 [(match_operand:SI 0 "s_register_operand"
10421 "l,l,l,r,r,r,r,r,r")
10422 (match_operand:SI 1 "arm_add_operand"
10423 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
10424 (match_operator:SI 5 "arm_comparison_operator"
10425 [(match_operand:SI 2 "s_register_operand"
10426 "l,r,r,l,l,r,r,r,r")
10427 (match_operand:SI 3 "arm_add_operand"
10428 "lPy,rI,L,lPy,lPy,rI,rI,L,L")])
10429 (const_int 0))
10430 (const_int 0)))]
10431 "TARGET_32BIT"
10432 "*
10433 {
10434 static const char * const cmp1[NUM_OF_COND_CMP][2] =
10435 {
10436 {\"cmp%d5\\t%0, %1\",
10437 \"cmp%d4\\t%2, %3\"},
10438 {\"cmn%d5\\t%0, #%n1\",
10439 \"cmp%d4\\t%2, %3\"},
10440 {\"cmp%d5\\t%0, %1\",
10441 \"cmn%d4\\t%2, #%n3\"},
10442 {\"cmn%d5\\t%0, #%n1\",
10443 \"cmn%d4\\t%2, #%n3\"}
10444 };
10445 static const char * const cmp2[NUM_OF_COND_CMP][2] =
10446 {
10447 {\"cmp\\t%2, %3\",
10448 \"cmp\\t%0, %1\"},
10449 {\"cmp\\t%2, %3\",
10450 \"cmn\\t%0, #%n1\"},
10451 {\"cmn\\t%2, #%n3\",
10452 \"cmp\\t%0, %1\"},
10453 {\"cmn\\t%2, #%n3\",
10454 \"cmn\\t%0, #%n1\"}
10455 };
10456 static const char * const ite[2] =
10457 {
10458 \"it\\t%d5\",
10459 \"it\\t%d4\"
10460 };
10461 static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
10462 CMP_CMP, CMN_CMP, CMP_CMP,
10463 CMN_CMP, CMP_CMN, CMN_CMN};
10464 int swap =
10465 comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4]));
10466
10467 output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
10468 if (TARGET_THUMB2) {
10469 output_asm_insn (ite[swap], operands);
10470 }
10471 output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
10472 return \"\";
10473 }"
10474 [(set_attr "conds" "set")
10475 (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
10476 (set_attr "type" "multiple")
10477 (set_attr_alternative "length"
10478 [(const_int 6)
10479 (const_int 8)
10480 (const_int 8)
10481 (const_int 8)
10482 (const_int 8)
10483 (if_then_else (eq_attr "is_thumb" "no")
10484 (const_int 8)
10485 (const_int 10))
10486 (if_then_else (eq_attr "is_thumb" "no")
10487 (const_int 8)
10488 (const_int 10))
10489 (if_then_else (eq_attr "is_thumb" "no")
10490 (const_int 8)
10491 (const_int 10))
10492 (if_then_else (eq_attr "is_thumb" "no")
10493 (const_int 8)
10494 (const_int 10))])]
10495 )
10496
10497 (define_insn "*cmp_ite1"
10498 [(set (match_operand 6 "dominant_cc_register" "")
10499 (compare
10500 (if_then_else:SI
10501 (match_operator 4 "arm_comparison_operator"
10502 [(match_operand:SI 0 "s_register_operand"
10503 "l,l,l,r,r,r,r,r,r")
10504 (match_operand:SI 1 "arm_add_operand"
10505 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
10506 (match_operator:SI 5 "arm_comparison_operator"
10507 [(match_operand:SI 2 "s_register_operand"
10508 "l,r,r,l,l,r,r,r,r")
10509 (match_operand:SI 3 "arm_add_operand"
10510 "lPy,rI,L,lPy,lPy,rI,rI,L,L")])
10511 (const_int 1))
10512 (const_int 0)))]
10513 "TARGET_32BIT"
10514 "*
10515 {
10516 static const char * const cmp1[NUM_OF_COND_CMP][2] =
10517 {
10518 {\"cmp\\t%0, %1\",
10519 \"cmp\\t%2, %3\"},
10520 {\"cmn\\t%0, #%n1\",
10521 \"cmp\\t%2, %3\"},
10522 {\"cmp\\t%0, %1\",
10523 \"cmn\\t%2, #%n3\"},
10524 {\"cmn\\t%0, #%n1\",
10525 \"cmn\\t%2, #%n3\"}
10526 };
10527 static const char * const cmp2[NUM_OF_COND_CMP][2] =
10528 {
10529 {\"cmp%d4\\t%2, %3\",
10530 \"cmp%D5\\t%0, %1\"},
10531 {\"cmp%d4\\t%2, %3\",
10532 \"cmn%D5\\t%0, #%n1\"},
10533 {\"cmn%d4\\t%2, #%n3\",
10534 \"cmp%D5\\t%0, %1\"},
10535 {\"cmn%d4\\t%2, #%n3\",
10536 \"cmn%D5\\t%0, #%n1\"}
10537 };
10538 static const char * const ite[2] =
10539 {
10540 \"it\\t%d4\",
10541 \"it\\t%D5\"
10542 };
10543 static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
10544 CMP_CMP, CMN_CMP, CMP_CMP,
10545 CMN_CMP, CMP_CMN, CMN_CMN};
10546 int swap =
10547 comparison_dominates_p (GET_CODE (operands[5]),
10548 reverse_condition (GET_CODE (operands[4])));
10549
10550 output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
10551 if (TARGET_THUMB2) {
10552 output_asm_insn (ite[swap], operands);
10553 }
10554 output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
10555 return \"\";
10556 }"
10557 [(set_attr "conds" "set")
10558 (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
10559 (set_attr_alternative "length"
10560 [(const_int 6)
10561 (const_int 8)
10562 (const_int 8)
10563 (const_int 8)
10564 (const_int 8)
10565 (if_then_else (eq_attr "is_thumb" "no")
10566 (const_int 8)
10567 (const_int 10))
10568 (if_then_else (eq_attr "is_thumb" "no")
10569 (const_int 8)
10570 (const_int 10))
10571 (if_then_else (eq_attr "is_thumb" "no")
10572 (const_int 8)
10573 (const_int 10))
10574 (if_then_else (eq_attr "is_thumb" "no")
10575 (const_int 8)
10576 (const_int 10))])
10577 (set_attr "type" "multiple")]
10578 )
10579
10580 (define_insn "*cmp_and"
10581 [(set (match_operand 6 "dominant_cc_register" "")
10582 (compare
10583 (and:SI
10584 (match_operator 4 "arm_comparison_operator"
10585 [(match_operand:SI 0 "s_register_operand"
10586 "l,l,l,r,r,r,r,r,r")
10587 (match_operand:SI 1 "arm_add_operand"
10588 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
10589 (match_operator:SI 5 "arm_comparison_operator"
10590 [(match_operand:SI 2 "s_register_operand"
10591 "l,r,r,l,l,r,r,r,r")
10592 (match_operand:SI 3 "arm_add_operand"
10593 "lPy,rI,L,lPy,lPy,rI,rI,L,L")]))
10594 (const_int 0)))]
10595 "TARGET_32BIT"
10596 "*
10597 {
10598 static const char *const cmp1[NUM_OF_COND_CMP][2] =
10599 {
10600 {\"cmp%d5\\t%0, %1\",
10601 \"cmp%d4\\t%2, %3\"},
10602 {\"cmn%d5\\t%0, #%n1\",
10603 \"cmp%d4\\t%2, %3\"},
10604 {\"cmp%d5\\t%0, %1\",
10605 \"cmn%d4\\t%2, #%n3\"},
10606 {\"cmn%d5\\t%0, #%n1\",
10607 \"cmn%d4\\t%2, #%n3\"}
10608 };
10609 static const char *const cmp2[NUM_OF_COND_CMP][2] =
10610 {
10611 {\"cmp\\t%2, %3\",
10612 \"cmp\\t%0, %1\"},
10613 {\"cmp\\t%2, %3\",
10614 \"cmn\\t%0, #%n1\"},
10615 {\"cmn\\t%2, #%n3\",
10616 \"cmp\\t%0, %1\"},
10617 {\"cmn\\t%2, #%n3\",
10618 \"cmn\\t%0, #%n1\"}
10619 };
10620 static const char *const ite[2] =
10621 {
10622 \"it\\t%d5\",
10623 \"it\\t%d4\"
10624 };
10625 static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
10626 CMP_CMP, CMN_CMP, CMP_CMP,
10627 CMN_CMP, CMP_CMN, CMN_CMN};
10628 int swap =
10629 comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4]));
10630
10631 output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
10632 if (TARGET_THUMB2) {
10633 output_asm_insn (ite[swap], operands);
10634 }
10635 output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
10636 return \"\";
10637 }"
10638 [(set_attr "conds" "set")
10639 (set_attr "predicable" "no")
10640 (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
10641 (set_attr_alternative "length"
10642 [(const_int 6)
10643 (const_int 8)
10644 (const_int 8)
10645 (const_int 8)
10646 (const_int 8)
10647 (if_then_else (eq_attr "is_thumb" "no")
10648 (const_int 8)
10649 (const_int 10))
10650 (if_then_else (eq_attr "is_thumb" "no")
10651 (const_int 8)
10652 (const_int 10))
10653 (if_then_else (eq_attr "is_thumb" "no")
10654 (const_int 8)
10655 (const_int 10))
10656 (if_then_else (eq_attr "is_thumb" "no")
10657 (const_int 8)
10658 (const_int 10))])
10659 (set_attr "type" "multiple")]
10660 )
10661
10662 (define_insn "*cmp_ior"
10663 [(set (match_operand 6 "dominant_cc_register" "")
10664 (compare
10665 (ior:SI
10666 (match_operator 4 "arm_comparison_operator"
10667 [(match_operand:SI 0 "s_register_operand"
10668 "l,l,l,r,r,r,r,r,r")
10669 (match_operand:SI 1 "arm_add_operand"
10670 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
10671 (match_operator:SI 5 "arm_comparison_operator"
10672 [(match_operand:SI 2 "s_register_operand"
10673 "l,r,r,l,l,r,r,r,r")
10674 (match_operand:SI 3 "arm_add_operand"
10675 "lPy,rI,L,lPy,lPy,rI,rI,L,L")]))
10676 (const_int 0)))]
10677 "TARGET_32BIT"
10678 "*
10679 {
10680 static const char *const cmp1[NUM_OF_COND_CMP][2] =
10681 {
10682 {\"cmp\\t%0, %1\",
10683 \"cmp\\t%2, %3\"},
10684 {\"cmn\\t%0, #%n1\",
10685 \"cmp\\t%2, %3\"},
10686 {\"cmp\\t%0, %1\",
10687 \"cmn\\t%2, #%n3\"},
10688 {\"cmn\\t%0, #%n1\",
10689 \"cmn\\t%2, #%n3\"}
10690 };
10691 static const char *const cmp2[NUM_OF_COND_CMP][2] =
10692 {
10693 {\"cmp%D4\\t%2, %3\",
10694 \"cmp%D5\\t%0, %1\"},
10695 {\"cmp%D4\\t%2, %3\",
10696 \"cmn%D5\\t%0, #%n1\"},
10697 {\"cmn%D4\\t%2, #%n3\",
10698 \"cmp%D5\\t%0, %1\"},
10699 {\"cmn%D4\\t%2, #%n3\",
10700 \"cmn%D5\\t%0, #%n1\"}
10701 };
10702 static const char *const ite[2] =
10703 {
10704 \"it\\t%D4\",
10705 \"it\\t%D5\"
10706 };
10707 static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
10708 CMP_CMP, CMN_CMP, CMP_CMP,
10709 CMN_CMP, CMP_CMN, CMN_CMN};
10710 int swap =
10711 comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4]));
10712
10713 output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
10714 if (TARGET_THUMB2) {
10715 output_asm_insn (ite[swap], operands);
10716 }
10717 output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
10718 return \"\";
10719 }
10720 "
10721 [(set_attr "conds" "set")
10722 (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
10723 (set_attr_alternative "length"
10724 [(const_int 6)
10725 (const_int 8)
10726 (const_int 8)
10727 (const_int 8)
10728 (const_int 8)
10729 (if_then_else (eq_attr "is_thumb" "no")
10730 (const_int 8)
10731 (const_int 10))
10732 (if_then_else (eq_attr "is_thumb" "no")
10733 (const_int 8)
10734 (const_int 10))
10735 (if_then_else (eq_attr "is_thumb" "no")
10736 (const_int 8)
10737 (const_int 10))
10738 (if_then_else (eq_attr "is_thumb" "no")
10739 (const_int 8)
10740 (const_int 10))])
10741 (set_attr "type" "multiple")]
10742 )
10743
10744 (define_insn_and_split "*ior_scc_scc"
10745 [(set (match_operand:SI 0 "s_register_operand" "=Ts")
10746 (ior:SI (match_operator:SI 3 "arm_comparison_operator"
10747 [(match_operand:SI 1 "s_register_operand" "r")
10748 (match_operand:SI 2 "arm_add_operand" "rIL")])
10749 (match_operator:SI 6 "arm_comparison_operator"
10750 [(match_operand:SI 4 "s_register_operand" "r")
10751 (match_operand:SI 5 "arm_add_operand" "rIL")])))
10752 (clobber (reg:CC CC_REGNUM))]
10753 "TARGET_32BIT
10754 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_OR_Y)
10755 != CCmode)"
10756 "#"
10757 "TARGET_32BIT && reload_completed"
10758 [(set (match_dup 7)
10759 (compare
10760 (ior:SI
10761 (match_op_dup 3 [(match_dup 1) (match_dup 2)])
10762 (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
10763 (const_int 0)))
10764 (set (match_dup 0) (ne:SI (match_dup 7) (const_int 0)))]
10765 "operands[7]
10766 = gen_rtx_REG (arm_select_dominance_cc_mode (operands[3], operands[6],
10767 DOM_CC_X_OR_Y),
10768 CC_REGNUM);"
10769 [(set_attr "conds" "clob")
10770 (set_attr "length" "16")
10771 (set_attr "type" "multiple")]
10772 )
10773
10774 ; If the above pattern is followed by a CMP insn, then the compare is
10775 ; redundant, since we can rework the conditional instruction that follows.
10776 (define_insn_and_split "*ior_scc_scc_cmp"
10777 [(set (match_operand 0 "dominant_cc_register" "")
10778 (compare (ior:SI (match_operator:SI 3 "arm_comparison_operator"
10779 [(match_operand:SI 1 "s_register_operand" "r")
10780 (match_operand:SI 2 "arm_add_operand" "rIL")])
10781 (match_operator:SI 6 "arm_comparison_operator"
10782 [(match_operand:SI 4 "s_register_operand" "r")
10783 (match_operand:SI 5 "arm_add_operand" "rIL")]))
10784 (const_int 0)))
10785 (set (match_operand:SI 7 "s_register_operand" "=Ts")
10786 (ior:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)])
10787 (match_op_dup 6 [(match_dup 4) (match_dup 5)])))]
10788 "TARGET_32BIT"
10789 "#"
10790 "TARGET_32BIT && reload_completed"
10791 [(set (match_dup 0)
10792 (compare
10793 (ior:SI
10794 (match_op_dup 3 [(match_dup 1) (match_dup 2)])
10795 (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
10796 (const_int 0)))
10797 (set (match_dup 7) (ne:SI (match_dup 0) (const_int 0)))]
10798 ""
10799 [(set_attr "conds" "set")
10800 (set_attr "length" "16")
10801 (set_attr "type" "multiple")]
10802 )
10803
10804 (define_insn_and_split "*and_scc_scc"
10805 [(set (match_operand:SI 0 "s_register_operand" "=Ts")
10806 (and:SI (match_operator:SI 3 "arm_comparison_operator"
10807 [(match_operand:SI 1 "s_register_operand" "r")
10808 (match_operand:SI 2 "arm_add_operand" "rIL")])
10809 (match_operator:SI 6 "arm_comparison_operator"
10810 [(match_operand:SI 4 "s_register_operand" "r")
10811 (match_operand:SI 5 "arm_add_operand" "rIL")])))
10812 (clobber (reg:CC CC_REGNUM))]
10813 "TARGET_32BIT
10814 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y)
10815 != CCmode)"
10816 "#"
10817 "TARGET_32BIT && reload_completed
10818 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y)
10819 != CCmode)"
10820 [(set (match_dup 7)
10821 (compare
10822 (and:SI
10823 (match_op_dup 3 [(match_dup 1) (match_dup 2)])
10824 (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
10825 (const_int 0)))
10826 (set (match_dup 0) (ne:SI (match_dup 7) (const_int 0)))]
10827 "operands[7]
10828 = gen_rtx_REG (arm_select_dominance_cc_mode (operands[3], operands[6],
10829 DOM_CC_X_AND_Y),
10830 CC_REGNUM);"
10831 [(set_attr "conds" "clob")
10832 (set_attr "length" "16")
10833 (set_attr "type" "multiple")]
10834 )
10835
10836 ; If the above pattern is followed by a CMP insn, then the compare is
10837 ; redundant, since we can rework the conditional instruction that follows.
10838 (define_insn_and_split "*and_scc_scc_cmp"
10839 [(set (match_operand 0 "dominant_cc_register" "")
10840 (compare (and:SI (match_operator:SI 3 "arm_comparison_operator"
10841 [(match_operand:SI 1 "s_register_operand" "r")
10842 (match_operand:SI 2 "arm_add_operand" "rIL")])
10843 (match_operator:SI 6 "arm_comparison_operator"
10844 [(match_operand:SI 4 "s_register_operand" "r")
10845 (match_operand:SI 5 "arm_add_operand" "rIL")]))
10846 (const_int 0)))
10847 (set (match_operand:SI 7 "s_register_operand" "=Ts")
10848 (and:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)])
10849 (match_op_dup 6 [(match_dup 4) (match_dup 5)])))]
10850 "TARGET_32BIT"
10851 "#"
10852 "TARGET_32BIT && reload_completed"
10853 [(set (match_dup 0)
10854 (compare
10855 (and:SI
10856 (match_op_dup 3 [(match_dup 1) (match_dup 2)])
10857 (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
10858 (const_int 0)))
10859 (set (match_dup 7) (ne:SI (match_dup 0) (const_int 0)))]
10860 ""
10861 [(set_attr "conds" "set")
10862 (set_attr "length" "16")
10863 (set_attr "type" "multiple")]
10864 )
10865
10866 ;; If there is no dominance in the comparison, then we can still save an
10867 ;; instruction in the AND case, since we can know that the second compare
10868 ;; need only zero the value if false (if true, then the value is already
10869 ;; correct).
10870 (define_insn_and_split "*and_scc_scc_nodom"
10871 [(set (match_operand:SI 0 "s_register_operand" "=&Ts,&Ts,&Ts")
10872 (and:SI (match_operator:SI 3 "arm_comparison_operator"
10873 [(match_operand:SI 1 "s_register_operand" "r,r,0")
10874 (match_operand:SI 2 "arm_add_operand" "rIL,0,rIL")])
10875 (match_operator:SI 6 "arm_comparison_operator"
10876 [(match_operand:SI 4 "s_register_operand" "r,r,r")
10877 (match_operand:SI 5 "arm_add_operand" "rIL,rIL,rIL")])))
10878 (clobber (reg:CC CC_REGNUM))]
10879 "TARGET_32BIT
10880 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y)
10881 == CCmode)"
10882 "#"
10883 "TARGET_32BIT && reload_completed"
10884 [(parallel [(set (match_dup 0)
10885 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
10886 (clobber (reg:CC CC_REGNUM))])
10887 (set (match_dup 7) (match_op_dup 8 [(match_dup 4) (match_dup 5)]))
10888 (set (match_dup 0)
10889 (if_then_else:SI (match_op_dup 6 [(match_dup 7) (const_int 0)])
10890 (match_dup 0)
10891 (const_int 0)))]
10892 "operands[7] = gen_rtx_REG (SELECT_CC_MODE (GET_CODE (operands[6]),
10893 operands[4], operands[5]),
10894 CC_REGNUM);
10895 operands[8] = gen_rtx_COMPARE (GET_MODE (operands[7]), operands[4],
10896 operands[5]);"
10897 [(set_attr "conds" "clob")
10898 (set_attr "length" "20")
10899 (set_attr "type" "multiple")]
10900 )
10901
10902 (define_split
10903 [(set (reg:CC_NOOV CC_REGNUM)
10904 (compare:CC_NOOV (ior:SI
10905 (and:SI (match_operand:SI 0 "s_register_operand" "")
10906 (const_int 1))
10907 (match_operator:SI 1 "arm_comparison_operator"
10908 [(match_operand:SI 2 "s_register_operand" "")
10909 (match_operand:SI 3 "arm_add_operand" "")]))
10910 (const_int 0)))
10911 (clobber (match_operand:SI 4 "s_register_operand" ""))]
10912 "TARGET_ARM"
10913 [(set (match_dup 4)
10914 (ior:SI (match_op_dup 1 [(match_dup 2) (match_dup 3)])
10915 (match_dup 0)))
10916 (set (reg:CC_NOOV CC_REGNUM)
10917 (compare:CC_NOOV (and:SI (match_dup 4) (const_int 1))
10918 (const_int 0)))]
10919 "")
10920
10921 (define_split
10922 [(set (reg:CC_NOOV CC_REGNUM)
10923 (compare:CC_NOOV (ior:SI
10924 (match_operator:SI 1 "arm_comparison_operator"
10925 [(match_operand:SI 2 "s_register_operand" "")
10926 (match_operand:SI 3 "arm_add_operand" "")])
10927 (and:SI (match_operand:SI 0 "s_register_operand" "")
10928 (const_int 1)))
10929 (const_int 0)))
10930 (clobber (match_operand:SI 4 "s_register_operand" ""))]
10931 "TARGET_ARM"
10932 [(set (match_dup 4)
10933 (ior:SI (match_op_dup 1 [(match_dup 2) (match_dup 3)])
10934 (match_dup 0)))
10935 (set (reg:CC_NOOV CC_REGNUM)
10936 (compare:CC_NOOV (and:SI (match_dup 4) (const_int 1))
10937 (const_int 0)))]
10938 "")
10939 ;; ??? The conditional patterns above need checking for Thumb-2 usefulness
10940
10941 (define_insn_and_split "*negscc"
10942 [(set (match_operand:SI 0 "s_register_operand" "=r")
10943 (neg:SI (match_operator 3 "arm_comparison_operator"
10944 [(match_operand:SI 1 "s_register_operand" "r")
10945 (match_operand:SI 2 "arm_rhs_operand" "rI")])))
10946 (clobber (reg:CC CC_REGNUM))]
10947 "TARGET_ARM"
10948 "#"
10949 "&& reload_completed"
10950 [(const_int 0)]
10951 {
10952 rtx cc_reg = gen_rtx_REG (CCmode, CC_REGNUM);
10953
10954 if (GET_CODE (operands[3]) == LT && operands[2] == const0_rtx)
10955 {
10956 /* Emit mov\\t%0, %1, asr #31 */
10957 emit_insn (gen_rtx_SET (VOIDmode,
10958 operands[0],
10959 gen_rtx_ASHIFTRT (SImode,
10960 operands[1],
10961 GEN_INT (31))));
10962 DONE;
10963 }
10964 else if (GET_CODE (operands[3]) == NE)
10965 {
10966 /* Emit subs\\t%0, %1, %2\;mvnne\\t%0, #0 */
10967 if (CONST_INT_P (operands[2]))
10968 emit_insn (gen_cmpsi2_addneg (operands[0], operands[1], operands[2],
10969 GEN_INT (- INTVAL (operands[2]))));
10970 else
10971 emit_insn (gen_subsi3_compare (operands[0], operands[1], operands[2]));
10972
10973 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
10974 gen_rtx_NE (SImode,
10975 cc_reg,
10976 const0_rtx),
10977 gen_rtx_SET (SImode,
10978 operands[0],
10979 GEN_INT (~0))));
10980 DONE;
10981 }
10982 else
10983 {
10984 /* Emit: cmp\\t%1, %2\;mov%D3\\t%0, #0\;mvn%d3\\t%0, #0 */
10985 emit_insn (gen_rtx_SET (VOIDmode,
10986 cc_reg,
10987 gen_rtx_COMPARE (CCmode, operands[1], operands[2])));
10988 enum rtx_code rc = GET_CODE (operands[3]);
10989
10990 rc = reverse_condition (rc);
10991 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
10992 gen_rtx_fmt_ee (rc,
10993 VOIDmode,
10994 cc_reg,
10995 const0_rtx),
10996 gen_rtx_SET (VOIDmode, operands[0], const0_rtx)));
10997 rc = GET_CODE (operands[3]);
10998 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
10999 gen_rtx_fmt_ee (rc,
11000 VOIDmode,
11001 cc_reg,
11002 const0_rtx),
11003 gen_rtx_SET (VOIDmode,
11004 operands[0],
11005 GEN_INT (~0))));
11006 DONE;
11007 }
11008 FAIL;
11009 }
11010 [(set_attr "conds" "clob")
11011 (set_attr "length" "12")
11012 (set_attr "type" "multiple")]
11013 )
11014
11015 (define_insn_and_split "movcond_addsi"
11016 [(set (match_operand:SI 0 "s_register_operand" "=r,l,r")
11017 (if_then_else:SI
11018 (match_operator 5 "comparison_operator"
11019 [(plus:SI (match_operand:SI 3 "s_register_operand" "r,r,r")
11020 (match_operand:SI 4 "arm_add_operand" "rIL,rIL,rIL"))
11021 (const_int 0)])
11022 (match_operand:SI 1 "arm_rhs_operand" "rI,rPy,r")
11023 (match_operand:SI 2 "arm_rhs_operand" "rI,rPy,r")))
11024 (clobber (reg:CC CC_REGNUM))]
11025 "TARGET_32BIT"
11026 "#"
11027 "&& reload_completed"
11028 [(set (reg:CC_NOOV CC_REGNUM)
11029 (compare:CC_NOOV
11030 (plus:SI (match_dup 3)
11031 (match_dup 4))
11032 (const_int 0)))
11033 (set (match_dup 0) (match_dup 1))
11034 (cond_exec (match_dup 6)
11035 (set (match_dup 0) (match_dup 2)))]
11036 "
11037 {
11038 enum machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[5]),
11039 operands[3], operands[4]);
11040 enum rtx_code rc = GET_CODE (operands[5]);
11041
11042 operands[6] = gen_rtx_REG (mode, CC_REGNUM);
11043 gcc_assert (!(mode == CCFPmode || mode == CCFPEmode));
11044 rc = reverse_condition (rc);
11045
11046 operands[6] = gen_rtx_fmt_ee (rc, VOIDmode, operands[6], const0_rtx);
11047 }
11048 "
11049 [(set_attr "conds" "clob")
11050 (set_attr "enabled_for_depr_it" "no,yes,yes")
11051 (set_attr "type" "multiple")]
11052 )
11053
11054 (define_insn "movcond"
11055 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
11056 (if_then_else:SI
11057 (match_operator 5 "arm_comparison_operator"
11058 [(match_operand:SI 3 "s_register_operand" "r,r,r")
11059 (match_operand:SI 4 "arm_add_operand" "rIL,rIL,rIL")])
11060 (match_operand:SI 1 "arm_rhs_operand" "0,rI,?rI")
11061 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
11062 (clobber (reg:CC CC_REGNUM))]
11063 "TARGET_ARM"
11064 "*
11065 if (GET_CODE (operands[5]) == LT
11066 && (operands[4] == const0_rtx))
11067 {
11068 if (which_alternative != 1 && REG_P (operands[1]))
11069 {
11070 if (operands[2] == const0_rtx)
11071 return \"and\\t%0, %1, %3, asr #31\";
11072 return \"ands\\t%0, %1, %3, asr #32\;movcc\\t%0, %2\";
11073 }
11074 else if (which_alternative != 0 && REG_P (operands[2]))
11075 {
11076 if (operands[1] == const0_rtx)
11077 return \"bic\\t%0, %2, %3, asr #31\";
11078 return \"bics\\t%0, %2, %3, asr #32\;movcs\\t%0, %1\";
11079 }
11080 /* The only case that falls through to here is when both ops 1 & 2
11081 are constants. */
11082 }
11083
11084 if (GET_CODE (operands[5]) == GE
11085 && (operands[4] == const0_rtx))
11086 {
11087 if (which_alternative != 1 && REG_P (operands[1]))
11088 {
11089 if (operands[2] == const0_rtx)
11090 return \"bic\\t%0, %1, %3, asr #31\";
11091 return \"bics\\t%0, %1, %3, asr #32\;movcs\\t%0, %2\";
11092 }
11093 else if (which_alternative != 0 && REG_P (operands[2]))
11094 {
11095 if (operands[1] == const0_rtx)
11096 return \"and\\t%0, %2, %3, asr #31\";
11097 return \"ands\\t%0, %2, %3, asr #32\;movcc\\t%0, %1\";
11098 }
11099 /* The only case that falls through to here is when both ops 1 & 2
11100 are constants. */
11101 }
11102 if (CONST_INT_P (operands[4])
11103 && !const_ok_for_arm (INTVAL (operands[4])))
11104 output_asm_insn (\"cmn\\t%3, #%n4\", operands);
11105 else
11106 output_asm_insn (\"cmp\\t%3, %4\", operands);
11107 if (which_alternative != 0)
11108 output_asm_insn (\"mov%d5\\t%0, %1\", operands);
11109 if (which_alternative != 1)
11110 output_asm_insn (\"mov%D5\\t%0, %2\", operands);
11111 return \"\";
11112 "
11113 [(set_attr "conds" "clob")
11114 (set_attr "length" "8,8,12")
11115 (set_attr "type" "multiple")]
11116 )
11117
11118 ;; ??? The patterns below need checking for Thumb-2 usefulness.
11119
11120 (define_insn "*ifcompare_plus_move"
11121 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
11122 (if_then_else:SI (match_operator 6 "arm_comparison_operator"
11123 [(match_operand:SI 4 "s_register_operand" "r,r")
11124 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
11125 (plus:SI
11126 (match_operand:SI 2 "s_register_operand" "r,r")
11127 (match_operand:SI 3 "arm_add_operand" "rIL,rIL"))
11128 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))
11129 (clobber (reg:CC CC_REGNUM))]
11130 "TARGET_ARM"
11131 "#"
11132 [(set_attr "conds" "clob")
11133 (set_attr "length" "8,12")
11134 (set_attr "type" "multiple")]
11135 )
11136
11137 (define_insn "*if_plus_move"
11138 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r")
11139 (if_then_else:SI
11140 (match_operator 4 "arm_comparison_operator"
11141 [(match_operand 5 "cc_register" "") (const_int 0)])
11142 (plus:SI
11143 (match_operand:SI 2 "s_register_operand" "r,r,r,r")
11144 (match_operand:SI 3 "arm_add_operand" "rI,L,rI,L"))
11145 (match_operand:SI 1 "arm_rhs_operand" "0,0,?rI,?rI")))]
11146 "TARGET_ARM"
11147 "@
11148 add%d4\\t%0, %2, %3
11149 sub%d4\\t%0, %2, #%n3
11150 add%d4\\t%0, %2, %3\;mov%D4\\t%0, %1
11151 sub%d4\\t%0, %2, #%n3\;mov%D4\\t%0, %1"
11152 [(set_attr "conds" "use")
11153 (set_attr "length" "4,4,8,8")
11154 (set_attr_alternative "type"
11155 [(if_then_else (match_operand 3 "const_int_operand" "")
11156 (const_string "alu_imm" )
11157 (const_string "alu_reg"))
11158 (const_string "alu_imm")
11159 (const_string "alu_reg")
11160 (const_string "alu_reg")])]
11161 )
11162
11163 (define_insn "*ifcompare_move_plus"
11164 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
11165 (if_then_else:SI (match_operator 6 "arm_comparison_operator"
11166 [(match_operand:SI 4 "s_register_operand" "r,r")
11167 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
11168 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
11169 (plus:SI
11170 (match_operand:SI 2 "s_register_operand" "r,r")
11171 (match_operand:SI 3 "arm_add_operand" "rIL,rIL"))))
11172 (clobber (reg:CC CC_REGNUM))]
11173 "TARGET_ARM"
11174 "#"
11175 [(set_attr "conds" "clob")
11176 (set_attr "length" "8,12")
11177 (set_attr "type" "multiple")]
11178 )
11179
11180 (define_insn "*if_move_plus"
11181 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r")
11182 (if_then_else:SI
11183 (match_operator 4 "arm_comparison_operator"
11184 [(match_operand 5 "cc_register" "") (const_int 0)])
11185 (match_operand:SI 1 "arm_rhs_operand" "0,0,?rI,?rI")
11186 (plus:SI
11187 (match_operand:SI 2 "s_register_operand" "r,r,r,r")
11188 (match_operand:SI 3 "arm_add_operand" "rI,L,rI,L"))))]
11189 "TARGET_ARM"
11190 "@
11191 add%D4\\t%0, %2, %3
11192 sub%D4\\t%0, %2, #%n3
11193 add%D4\\t%0, %2, %3\;mov%d4\\t%0, %1
11194 sub%D4\\t%0, %2, #%n3\;mov%d4\\t%0, %1"
11195 [(set_attr "conds" "use")
11196 (set_attr "length" "4,4,8,8")
11197 (set_attr "type" "alu_reg,alu_imm,multiple,multiple")]
11198 )
11199
11200 (define_insn "*ifcompare_arith_arith"
11201 [(set (match_operand:SI 0 "s_register_operand" "=r")
11202 (if_then_else:SI (match_operator 9 "arm_comparison_operator"
11203 [(match_operand:SI 5 "s_register_operand" "r")
11204 (match_operand:SI 6 "arm_add_operand" "rIL")])
11205 (match_operator:SI 8 "shiftable_operator"
11206 [(match_operand:SI 1 "s_register_operand" "r")
11207 (match_operand:SI 2 "arm_rhs_operand" "rI")])
11208 (match_operator:SI 7 "shiftable_operator"
11209 [(match_operand:SI 3 "s_register_operand" "r")
11210 (match_operand:SI 4 "arm_rhs_operand" "rI")])))
11211 (clobber (reg:CC CC_REGNUM))]
11212 "TARGET_ARM"
11213 "#"
11214 [(set_attr "conds" "clob")
11215 (set_attr "length" "12")
11216 (set_attr "type" "multiple")]
11217 )
11218
11219 (define_insn "*if_arith_arith"
11220 [(set (match_operand:SI 0 "s_register_operand" "=r")
11221 (if_then_else:SI (match_operator 5 "arm_comparison_operator"
11222 [(match_operand 8 "cc_register" "") (const_int 0)])
11223 (match_operator:SI 6 "shiftable_operator"
11224 [(match_operand:SI 1 "s_register_operand" "r")
11225 (match_operand:SI 2 "arm_rhs_operand" "rI")])
11226 (match_operator:SI 7 "shiftable_operator"
11227 [(match_operand:SI 3 "s_register_operand" "r")
11228 (match_operand:SI 4 "arm_rhs_operand" "rI")])))]
11229 "TARGET_ARM"
11230 "%I6%d5\\t%0, %1, %2\;%I7%D5\\t%0, %3, %4"
11231 [(set_attr "conds" "use")
11232 (set_attr "length" "8")
11233 (set_attr "type" "multiple")]
11234 )
11235
11236 (define_insn "*ifcompare_arith_move"
11237 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
11238 (if_then_else:SI (match_operator 6 "arm_comparison_operator"
11239 [(match_operand:SI 2 "s_register_operand" "r,r")
11240 (match_operand:SI 3 "arm_add_operand" "rIL,rIL")])
11241 (match_operator:SI 7 "shiftable_operator"
11242 [(match_operand:SI 4 "s_register_operand" "r,r")
11243 (match_operand:SI 5 "arm_rhs_operand" "rI,rI")])
11244 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))
11245 (clobber (reg:CC CC_REGNUM))]
11246 "TARGET_ARM"
11247 "*
11248 /* If we have an operation where (op x 0) is the identity operation and
11249 the conditional operator is LT or GE and we are comparing against zero and
11250 everything is in registers then we can do this in two instructions. */
11251 if (operands[3] == const0_rtx
11252 && GET_CODE (operands[7]) != AND
11253 && REG_P (operands[5])
11254 && REG_P (operands[1])
11255 && REGNO (operands[1]) == REGNO (operands[4])
11256 && REGNO (operands[4]) != REGNO (operands[0]))
11257 {
11258 if (GET_CODE (operands[6]) == LT)
11259 return \"and\\t%0, %5, %2, asr #31\;%I7\\t%0, %4, %0\";
11260 else if (GET_CODE (operands[6]) == GE)
11261 return \"bic\\t%0, %5, %2, asr #31\;%I7\\t%0, %4, %0\";
11262 }
11263 if (CONST_INT_P (operands[3])
11264 && !const_ok_for_arm (INTVAL (operands[3])))
11265 output_asm_insn (\"cmn\\t%2, #%n3\", operands);
11266 else
11267 output_asm_insn (\"cmp\\t%2, %3\", operands);
11268 output_asm_insn (\"%I7%d6\\t%0, %4, %5\", operands);
11269 if (which_alternative != 0)
11270 return \"mov%D6\\t%0, %1\";
11271 return \"\";
11272 "
11273 [(set_attr "conds" "clob")
11274 (set_attr "length" "8,12")
11275 (set_attr "type" "multiple")]
11276 )
11277
11278 (define_insn "*if_arith_move"
11279 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
11280 (if_then_else:SI (match_operator 4 "arm_comparison_operator"
11281 [(match_operand 6 "cc_register" "") (const_int 0)])
11282 (match_operator:SI 5 "shiftable_operator"
11283 [(match_operand:SI 2 "s_register_operand" "r,r")
11284 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
11285 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))]
11286 "TARGET_ARM"
11287 "@
11288 %I5%d4\\t%0, %2, %3
11289 %I5%d4\\t%0, %2, %3\;mov%D4\\t%0, %1"
11290 [(set_attr "conds" "use")
11291 (set_attr "length" "4,8")
11292 (set_attr "type" "alu_shift_reg,multiple")]
11293 )
11294
11295 (define_insn "*ifcompare_move_arith"
11296 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
11297 (if_then_else:SI (match_operator 6 "arm_comparison_operator"
11298 [(match_operand:SI 4 "s_register_operand" "r,r")
11299 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
11300 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
11301 (match_operator:SI 7 "shiftable_operator"
11302 [(match_operand:SI 2 "s_register_operand" "r,r")
11303 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))
11304 (clobber (reg:CC CC_REGNUM))]
11305 "TARGET_ARM"
11306 "*
11307 /* If we have an operation where (op x 0) is the identity operation and
11308 the conditional operator is LT or GE and we are comparing against zero and
11309 everything is in registers then we can do this in two instructions */
11310 if (operands[5] == const0_rtx
11311 && GET_CODE (operands[7]) != AND
11312 && REG_P (operands[3])
11313 && REG_P (operands[1])
11314 && REGNO (operands[1]) == REGNO (operands[2])
11315 && REGNO (operands[2]) != REGNO (operands[0]))
11316 {
11317 if (GET_CODE (operands[6]) == GE)
11318 return \"and\\t%0, %3, %4, asr #31\;%I7\\t%0, %2, %0\";
11319 else if (GET_CODE (operands[6]) == LT)
11320 return \"bic\\t%0, %3, %4, asr #31\;%I7\\t%0, %2, %0\";
11321 }
11322
11323 if (CONST_INT_P (operands[5])
11324 && !const_ok_for_arm (INTVAL (operands[5])))
11325 output_asm_insn (\"cmn\\t%4, #%n5\", operands);
11326 else
11327 output_asm_insn (\"cmp\\t%4, %5\", operands);
11328
11329 if (which_alternative != 0)
11330 output_asm_insn (\"mov%d6\\t%0, %1\", operands);
11331 return \"%I7%D6\\t%0, %2, %3\";
11332 "
11333 [(set_attr "conds" "clob")
11334 (set_attr "length" "8,12")
11335 (set_attr "type" "multiple")]
11336 )
11337
11338 (define_insn "*if_move_arith"
11339 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
11340 (if_then_else:SI
11341 (match_operator 4 "arm_comparison_operator"
11342 [(match_operand 6 "cc_register" "") (const_int 0)])
11343 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
11344 (match_operator:SI 5 "shiftable_operator"
11345 [(match_operand:SI 2 "s_register_operand" "r,r")
11346 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))]
11347 "TARGET_ARM"
11348 "@
11349 %I5%D4\\t%0, %2, %3
11350 %I5%D4\\t%0, %2, %3\;mov%d4\\t%0, %1"
11351 [(set_attr "conds" "use")
11352 (set_attr "length" "4,8")
11353 (set_attr "type" "alu_shift_reg,multiple")]
11354 )
11355
11356 (define_insn "*ifcompare_move_not"
11357 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
11358 (if_then_else:SI
11359 (match_operator 5 "arm_comparison_operator"
11360 [(match_operand:SI 3 "s_register_operand" "r,r")
11361 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
11362 (match_operand:SI 1 "arm_not_operand" "0,?rIK")
11363 (not:SI
11364 (match_operand:SI 2 "s_register_operand" "r,r"))))
11365 (clobber (reg:CC CC_REGNUM))]
11366 "TARGET_ARM"
11367 "#"
11368 [(set_attr "conds" "clob")
11369 (set_attr "length" "8,12")
11370 (set_attr "type" "multiple")]
11371 )
11372
11373 (define_insn "*if_move_not"
11374 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
11375 (if_then_else:SI
11376 (match_operator 4 "arm_comparison_operator"
11377 [(match_operand 3 "cc_register" "") (const_int 0)])
11378 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")
11379 (not:SI (match_operand:SI 2 "s_register_operand" "r,r,r"))))]
11380 "TARGET_ARM"
11381 "@
11382 mvn%D4\\t%0, %2
11383 mov%d4\\t%0, %1\;mvn%D4\\t%0, %2
11384 mvn%d4\\t%0, #%B1\;mvn%D4\\t%0, %2"
11385 [(set_attr "conds" "use")
11386 (set_attr "type" "mvn_reg")
11387 (set_attr "length" "4,8,8")
11388 (set_attr "type" "mvn_reg,multiple,multiple")]
11389 )
11390
11391 (define_insn "*ifcompare_not_move"
11392 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
11393 (if_then_else:SI
11394 (match_operator 5 "arm_comparison_operator"
11395 [(match_operand:SI 3 "s_register_operand" "r,r")
11396 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
11397 (not:SI
11398 (match_operand:SI 2 "s_register_operand" "r,r"))
11399 (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
11400 (clobber (reg:CC CC_REGNUM))]
11401 "TARGET_ARM"
11402 "#"
11403 [(set_attr "conds" "clob")
11404 (set_attr "length" "8,12")
11405 (set_attr "type" "multiple")]
11406 )
11407
11408 (define_insn "*if_not_move"
11409 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
11410 (if_then_else:SI
11411 (match_operator 4 "arm_comparison_operator"
11412 [(match_operand 3 "cc_register" "") (const_int 0)])
11413 (not:SI (match_operand:SI 2 "s_register_operand" "r,r,r"))
11414 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")))]
11415 "TARGET_ARM"
11416 "@
11417 mvn%d4\\t%0, %2
11418 mov%D4\\t%0, %1\;mvn%d4\\t%0, %2
11419 mvn%D4\\t%0, #%B1\;mvn%d4\\t%0, %2"
11420 [(set_attr "conds" "use")
11421 (set_attr "type" "mvn_reg,multiple,multiple")
11422 (set_attr "length" "4,8,8")]
11423 )
11424
11425 (define_insn "*ifcompare_shift_move"
11426 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
11427 (if_then_else:SI
11428 (match_operator 6 "arm_comparison_operator"
11429 [(match_operand:SI 4 "s_register_operand" "r,r")
11430 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
11431 (match_operator:SI 7 "shift_operator"
11432 [(match_operand:SI 2 "s_register_operand" "r,r")
11433 (match_operand:SI 3 "arm_rhs_operand" "rM,rM")])
11434 (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
11435 (clobber (reg:CC CC_REGNUM))]
11436 "TARGET_ARM"
11437 "#"
11438 [(set_attr "conds" "clob")
11439 (set_attr "length" "8,12")
11440 (set_attr "type" "multiple")]
11441 )
11442
11443 (define_insn "*if_shift_move"
11444 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
11445 (if_then_else:SI
11446 (match_operator 5 "arm_comparison_operator"
11447 [(match_operand 6 "cc_register" "") (const_int 0)])
11448 (match_operator:SI 4 "shift_operator"
11449 [(match_operand:SI 2 "s_register_operand" "r,r,r")
11450 (match_operand:SI 3 "arm_rhs_operand" "rM,rM,rM")])
11451 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")))]
11452 "TARGET_ARM"
11453 "@
11454 mov%d5\\t%0, %2%S4
11455 mov%D5\\t%0, %1\;mov%d5\\t%0, %2%S4
11456 mvn%D5\\t%0, #%B1\;mov%d5\\t%0, %2%S4"
11457 [(set_attr "conds" "use")
11458 (set_attr "shift" "2")
11459 (set_attr "length" "4,8,8")
11460 (set_attr "type" "mov_shift_reg,multiple,multiple")]
11461 )
11462
11463 (define_insn "*ifcompare_move_shift"
11464 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
11465 (if_then_else:SI
11466 (match_operator 6 "arm_comparison_operator"
11467 [(match_operand:SI 4 "s_register_operand" "r,r")
11468 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
11469 (match_operand:SI 1 "arm_not_operand" "0,?rIK")
11470 (match_operator:SI 7 "shift_operator"
11471 [(match_operand:SI 2 "s_register_operand" "r,r")
11472 (match_operand:SI 3 "arm_rhs_operand" "rM,rM")])))
11473 (clobber (reg:CC CC_REGNUM))]
11474 "TARGET_ARM"
11475 "#"
11476 [(set_attr "conds" "clob")
11477 (set_attr "length" "8,12")
11478 (set_attr "type" "multiple")]
11479 )
11480
11481 (define_insn "*if_move_shift"
11482 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
11483 (if_then_else:SI
11484 (match_operator 5 "arm_comparison_operator"
11485 [(match_operand 6 "cc_register" "") (const_int 0)])
11486 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")
11487 (match_operator:SI 4 "shift_operator"
11488 [(match_operand:SI 2 "s_register_operand" "r,r,r")
11489 (match_operand:SI 3 "arm_rhs_operand" "rM,rM,rM")])))]
11490 "TARGET_ARM"
11491 "@
11492 mov%D5\\t%0, %2%S4
11493 mov%d5\\t%0, %1\;mov%D5\\t%0, %2%S4
11494 mvn%d5\\t%0, #%B1\;mov%D5\\t%0, %2%S4"
11495 [(set_attr "conds" "use")
11496 (set_attr "shift" "2")
11497 (set_attr "length" "4,8,8")
11498 (set_attr "type" "mov_shift_reg,multiple,multiple")]
11499 )
11500
11501 (define_insn "*ifcompare_shift_shift"
11502 [(set (match_operand:SI 0 "s_register_operand" "=r")
11503 (if_then_else:SI
11504 (match_operator 7 "arm_comparison_operator"
11505 [(match_operand:SI 5 "s_register_operand" "r")
11506 (match_operand:SI 6 "arm_add_operand" "rIL")])
11507 (match_operator:SI 8 "shift_operator"
11508 [(match_operand:SI 1 "s_register_operand" "r")
11509 (match_operand:SI 2 "arm_rhs_operand" "rM")])
11510 (match_operator:SI 9 "shift_operator"
11511 [(match_operand:SI 3 "s_register_operand" "r")
11512 (match_operand:SI 4 "arm_rhs_operand" "rM")])))
11513 (clobber (reg:CC CC_REGNUM))]
11514 "TARGET_ARM"
11515 "#"
11516 [(set_attr "conds" "clob")
11517 (set_attr "length" "12")
11518 (set_attr "type" "multiple")]
11519 )
11520
11521 (define_insn "*if_shift_shift"
11522 [(set (match_operand:SI 0 "s_register_operand" "=r")
11523 (if_then_else:SI
11524 (match_operator 5 "arm_comparison_operator"
11525 [(match_operand 8 "cc_register" "") (const_int 0)])
11526 (match_operator:SI 6 "shift_operator"
11527 [(match_operand:SI 1 "s_register_operand" "r")
11528 (match_operand:SI 2 "arm_rhs_operand" "rM")])
11529 (match_operator:SI 7 "shift_operator"
11530 [(match_operand:SI 3 "s_register_operand" "r")
11531 (match_operand:SI 4 "arm_rhs_operand" "rM")])))]
11532 "TARGET_ARM"
11533 "mov%d5\\t%0, %1%S6\;mov%D5\\t%0, %3%S7"
11534 [(set_attr "conds" "use")
11535 (set_attr "shift" "1")
11536 (set_attr "length" "8")
11537 (set (attr "type") (if_then_else
11538 (and (match_operand 2 "const_int_operand" "")
11539 (match_operand 4 "const_int_operand" ""))
11540 (const_string "mov_shift")
11541 (const_string "mov_shift_reg")))]
11542 )
11543
11544 (define_insn "*ifcompare_not_arith"
11545 [(set (match_operand:SI 0 "s_register_operand" "=r")
11546 (if_then_else:SI
11547 (match_operator 6 "arm_comparison_operator"
11548 [(match_operand:SI 4 "s_register_operand" "r")
11549 (match_operand:SI 5 "arm_add_operand" "rIL")])
11550 (not:SI (match_operand:SI 1 "s_register_operand" "r"))
11551 (match_operator:SI 7 "shiftable_operator"
11552 [(match_operand:SI 2 "s_register_operand" "r")
11553 (match_operand:SI 3 "arm_rhs_operand" "rI")])))
11554 (clobber (reg:CC CC_REGNUM))]
11555 "TARGET_ARM"
11556 "#"
11557 [(set_attr "conds" "clob")
11558 (set_attr "length" "12")
11559 (set_attr "type" "multiple")]
11560 )
11561
11562 (define_insn "*if_not_arith"
11563 [(set (match_operand:SI 0 "s_register_operand" "=r")
11564 (if_then_else:SI
11565 (match_operator 5 "arm_comparison_operator"
11566 [(match_operand 4 "cc_register" "") (const_int 0)])
11567 (not:SI (match_operand:SI 1 "s_register_operand" "r"))
11568 (match_operator:SI 6 "shiftable_operator"
11569 [(match_operand:SI 2 "s_register_operand" "r")
11570 (match_operand:SI 3 "arm_rhs_operand" "rI")])))]
11571 "TARGET_ARM"
11572 "mvn%d5\\t%0, %1\;%I6%D5\\t%0, %2, %3"
11573 [(set_attr "conds" "use")
11574 (set_attr "type" "mvn_reg")
11575 (set_attr "length" "8")]
11576 )
11577
11578 (define_insn "*ifcompare_arith_not"
11579 [(set (match_operand:SI 0 "s_register_operand" "=r")
11580 (if_then_else:SI
11581 (match_operator 6 "arm_comparison_operator"
11582 [(match_operand:SI 4 "s_register_operand" "r")
11583 (match_operand:SI 5 "arm_add_operand" "rIL")])
11584 (match_operator:SI 7 "shiftable_operator"
11585 [(match_operand:SI 2 "s_register_operand" "r")
11586 (match_operand:SI 3 "arm_rhs_operand" "rI")])
11587 (not:SI (match_operand:SI 1 "s_register_operand" "r"))))
11588 (clobber (reg:CC CC_REGNUM))]
11589 "TARGET_ARM"
11590 "#"
11591 [(set_attr "conds" "clob")
11592 (set_attr "length" "12")
11593 (set_attr "type" "multiple")]
11594 )
11595
11596 (define_insn "*if_arith_not"
11597 [(set (match_operand:SI 0 "s_register_operand" "=r")
11598 (if_then_else:SI
11599 (match_operator 5 "arm_comparison_operator"
11600 [(match_operand 4 "cc_register" "") (const_int 0)])
11601 (match_operator:SI 6 "shiftable_operator"
11602 [(match_operand:SI 2 "s_register_operand" "r")
11603 (match_operand:SI 3 "arm_rhs_operand" "rI")])
11604 (not:SI (match_operand:SI 1 "s_register_operand" "r"))))]
11605 "TARGET_ARM"
11606 "mvn%D5\\t%0, %1\;%I6%d5\\t%0, %2, %3"
11607 [(set_attr "conds" "use")
11608 (set_attr "type" "multiple")
11609 (set_attr "length" "8")]
11610 )
11611
11612 (define_insn "*ifcompare_neg_move"
11613 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
11614 (if_then_else:SI
11615 (match_operator 5 "arm_comparison_operator"
11616 [(match_operand:SI 3 "s_register_operand" "r,r")
11617 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
11618 (neg:SI (match_operand:SI 2 "s_register_operand" "r,r"))
11619 (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
11620 (clobber (reg:CC CC_REGNUM))]
11621 "TARGET_ARM"
11622 "#"
11623 [(set_attr "conds" "clob")
11624 (set_attr "length" "8,12")
11625 (set_attr "type" "multiple")]
11626 )
11627
11628 (define_insn "*if_neg_move"
11629 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
11630 (if_then_else:SI
11631 (match_operator 4 "arm_comparison_operator"
11632 [(match_operand 3 "cc_register" "") (const_int 0)])
11633 (neg:SI (match_operand:SI 2 "s_register_operand" "r,r,r"))
11634 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")))]
11635 "TARGET_ARM"
11636 "@
11637 rsb%d4\\t%0, %2, #0
11638 mov%D4\\t%0, %1\;rsb%d4\\t%0, %2, #0
11639 mvn%D4\\t%0, #%B1\;rsb%d4\\t%0, %2, #0"
11640 [(set_attr "conds" "use")
11641 (set_attr "length" "4,8,8")
11642 (set_attr "type" "logic_shift_imm,multiple,multiple")]
11643 )
11644
11645 (define_insn "*ifcompare_move_neg"
11646 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
11647 (if_then_else:SI
11648 (match_operator 5 "arm_comparison_operator"
11649 [(match_operand:SI 3 "s_register_operand" "r,r")
11650 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
11651 (match_operand:SI 1 "arm_not_operand" "0,?rIK")
11652 (neg:SI (match_operand:SI 2 "s_register_operand" "r,r"))))
11653 (clobber (reg:CC CC_REGNUM))]
11654 "TARGET_ARM"
11655 "#"
11656 [(set_attr "conds" "clob")
11657 (set_attr "length" "8,12")
11658 (set_attr "type" "multiple")]
11659 )
11660
11661 (define_insn "*if_move_neg"
11662 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
11663 (if_then_else:SI
11664 (match_operator 4 "arm_comparison_operator"
11665 [(match_operand 3 "cc_register" "") (const_int 0)])
11666 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")
11667 (neg:SI (match_operand:SI 2 "s_register_operand" "r,r,r"))))]
11668 "TARGET_ARM"
11669 "@
11670 rsb%D4\\t%0, %2, #0
11671 mov%d4\\t%0, %1\;rsb%D4\\t%0, %2, #0
11672 mvn%d4\\t%0, #%B1\;rsb%D4\\t%0, %2, #0"
11673 [(set_attr "conds" "use")
11674 (set_attr "length" "4,8,8")
11675 (set_attr "type" "logic_shift_imm,multiple,multiple")]
11676 )
11677
11678 (define_insn "*arith_adjacentmem"
11679 [(set (match_operand:SI 0 "s_register_operand" "=r")
11680 (match_operator:SI 1 "shiftable_operator"
11681 [(match_operand:SI 2 "memory_operand" "m")
11682 (match_operand:SI 3 "memory_operand" "m")]))
11683 (clobber (match_scratch:SI 4 "=r"))]
11684 "TARGET_ARM && adjacent_mem_locations (operands[2], operands[3])"
11685 "*
11686 {
11687 rtx ldm[3];
11688 rtx arith[4];
11689 rtx base_reg;
11690 HOST_WIDE_INT val1 = 0, val2 = 0;
11691
11692 if (REGNO (operands[0]) > REGNO (operands[4]))
11693 {
11694 ldm[1] = operands[4];
11695 ldm[2] = operands[0];
11696 }
11697 else
11698 {
11699 ldm[1] = operands[0];
11700 ldm[2] = operands[4];
11701 }
11702
11703 base_reg = XEXP (operands[2], 0);
11704
11705 if (!REG_P (base_reg))
11706 {
11707 val1 = INTVAL (XEXP (base_reg, 1));
11708 base_reg = XEXP (base_reg, 0);
11709 }
11710
11711 if (!REG_P (XEXP (operands[3], 0)))
11712 val2 = INTVAL (XEXP (XEXP (operands[3], 0), 1));
11713
11714 arith[0] = operands[0];
11715 arith[3] = operands[1];
11716
11717 if (val1 < val2)
11718 {
11719 arith[1] = ldm[1];
11720 arith[2] = ldm[2];
11721 }
11722 else
11723 {
11724 arith[1] = ldm[2];
11725 arith[2] = ldm[1];
11726 }
11727
11728 ldm[0] = base_reg;
11729 if (val1 !=0 && val2 != 0)
11730 {
11731 rtx ops[3];
11732
11733 if (val1 == 4 || val2 == 4)
11734 /* Other val must be 8, since we know they are adjacent and neither
11735 is zero. */
11736 output_asm_insn (\"ldm%(ib%)\\t%0, {%1, %2}\", ldm);
11737 else if (const_ok_for_arm (val1) || const_ok_for_arm (-val1))
11738 {
11739 ldm[0] = ops[0] = operands[4];
11740 ops[1] = base_reg;
11741 ops[2] = GEN_INT (val1);
11742 output_add_immediate (ops);
11743 if (val1 < val2)
11744 output_asm_insn (\"ldm%(ia%)\\t%0, {%1, %2}\", ldm);
11745 else
11746 output_asm_insn (\"ldm%(da%)\\t%0, {%1, %2}\", ldm);
11747 }
11748 else
11749 {
11750 /* Offset is out of range for a single add, so use two ldr. */
11751 ops[0] = ldm[1];
11752 ops[1] = base_reg;
11753 ops[2] = GEN_INT (val1);
11754 output_asm_insn (\"ldr%?\\t%0, [%1, %2]\", ops);
11755 ops[0] = ldm[2];
11756 ops[2] = GEN_INT (val2);
11757 output_asm_insn (\"ldr%?\\t%0, [%1, %2]\", ops);
11758 }
11759 }
11760 else if (val1 != 0)
11761 {
11762 if (val1 < val2)
11763 output_asm_insn (\"ldm%(da%)\\t%0, {%1, %2}\", ldm);
11764 else
11765 output_asm_insn (\"ldm%(ia%)\\t%0, {%1, %2}\", ldm);
11766 }
11767 else
11768 {
11769 if (val1 < val2)
11770 output_asm_insn (\"ldm%(ia%)\\t%0, {%1, %2}\", ldm);
11771 else
11772 output_asm_insn (\"ldm%(da%)\\t%0, {%1, %2}\", ldm);
11773 }
11774 output_asm_insn (\"%I3%?\\t%0, %1, %2\", arith);
11775 return \"\";
11776 }"
11777 [(set_attr "length" "12")
11778 (set_attr "predicable" "yes")
11779 (set_attr "type" "load1")]
11780 )
11781
11782 ; This pattern is never tried by combine, so do it as a peephole
11783
11784 (define_peephole2
11785 [(set (match_operand:SI 0 "arm_general_register_operand" "")
11786 (match_operand:SI 1 "arm_general_register_operand" ""))
11787 (set (reg:CC CC_REGNUM)
11788 (compare:CC (match_dup 1) (const_int 0)))]
11789 "TARGET_ARM"
11790 [(parallel [(set (reg:CC CC_REGNUM) (compare:CC (match_dup 1) (const_int 0)))
11791 (set (match_dup 0) (match_dup 1))])]
11792 ""
11793 )
11794
11795 (define_split
11796 [(set (match_operand:SI 0 "s_register_operand" "")
11797 (and:SI (ge:SI (match_operand:SI 1 "s_register_operand" "")
11798 (const_int 0))
11799 (neg:SI (match_operator:SI 2 "arm_comparison_operator"
11800 [(match_operand:SI 3 "s_register_operand" "")
11801 (match_operand:SI 4 "arm_rhs_operand" "")]))))
11802 (clobber (match_operand:SI 5 "s_register_operand" ""))]
11803 "TARGET_ARM"
11804 [(set (match_dup 5) (not:SI (ashiftrt:SI (match_dup 1) (const_int 31))))
11805 (set (match_dup 0) (and:SI (match_op_dup 2 [(match_dup 3) (match_dup 4)])
11806 (match_dup 5)))]
11807 ""
11808 )
11809
11810 ;; This split can be used because CC_Z mode implies that the following
11811 ;; branch will be an equality, or an unsigned inequality, so the sign
11812 ;; extension is not needed.
11813
11814 (define_split
11815 [(set (reg:CC_Z CC_REGNUM)
11816 (compare:CC_Z
11817 (ashift:SI (subreg:SI (match_operand:QI 0 "memory_operand" "") 0)
11818 (const_int 24))
11819 (match_operand 1 "const_int_operand" "")))
11820 (clobber (match_scratch:SI 2 ""))]
11821 "TARGET_ARM
11822 && (((unsigned HOST_WIDE_INT) INTVAL (operands[1]))
11823 == (((unsigned HOST_WIDE_INT) INTVAL (operands[1])) >> 24) << 24)"
11824 [(set (match_dup 2) (zero_extend:SI (match_dup 0)))
11825 (set (reg:CC CC_REGNUM) (compare:CC (match_dup 2) (match_dup 1)))]
11826 "
11827 operands[1] = GEN_INT (((unsigned long) INTVAL (operands[1])) >> 24);
11828 "
11829 )
11830 ;; ??? Check the patterns above for Thumb-2 usefulness
11831
11832 (define_expand "prologue"
11833 [(clobber (const_int 0))]
11834 "TARGET_EITHER"
11835 "if (TARGET_32BIT)
11836 arm_expand_prologue ();
11837 else
11838 thumb1_expand_prologue ();
11839 DONE;
11840 "
11841 )
11842
11843 (define_expand "epilogue"
11844 [(clobber (const_int 0))]
11845 "TARGET_EITHER"
11846 "
11847 if (crtl->calls_eh_return)
11848 emit_insn (gen_force_register_use (gen_rtx_REG (Pmode, 2)));
11849 if (TARGET_THUMB1)
11850 {
11851 thumb1_expand_epilogue ();
11852 emit_jump_insn (gen_rtx_UNSPEC_VOLATILE (VOIDmode,
11853 gen_rtvec (1, ret_rtx), VUNSPEC_EPILOGUE));
11854 }
11855 else if (HAVE_return)
11856 {
11857 /* HAVE_return is testing for USE_RETURN_INSN (FALSE). Hence,
11858 no need for explicit testing again. */
11859 emit_jump_insn (gen_return ());
11860 }
11861 else if (TARGET_32BIT)
11862 {
11863 arm_expand_epilogue (true);
11864 }
11865 DONE;
11866 "
11867 )
11868
11869 (define_insn "prologue_thumb1_interwork"
11870 [(unspec_volatile [(const_int 0)] VUNSPEC_THUMB1_INTERWORK)]
11871 "TARGET_THUMB1"
11872 "* return thumb1_output_interwork ();"
11873 [(set_attr "length" "8")
11874 (set_attr "type" "multiple")]
11875 )
11876
11877 ;; Note - although unspec_volatile's USE all hard registers,
11878 ;; USEs are ignored after relaod has completed. Thus we need
11879 ;; to add an unspec of the link register to ensure that flow
11880 ;; does not think that it is unused by the sibcall branch that
11881 ;; will replace the standard function epilogue.
11882 (define_expand "sibcall_epilogue"
11883 [(parallel [(unspec:SI [(reg:SI LR_REGNUM)] UNSPEC_REGISTER_USE)
11884 (unspec_volatile [(return)] VUNSPEC_EPILOGUE)])]
11885 "TARGET_32BIT"
11886 "
11887 arm_expand_epilogue (false);
11888 DONE;
11889 "
11890 )
11891
11892 (define_insn "*epilogue_insns"
11893 [(unspec_volatile [(return)] VUNSPEC_EPILOGUE)]
11894 "TARGET_THUMB1"
11895 "*
11896 return thumb1_unexpanded_epilogue ();
11897 "
11898 ; Length is absolute worst case
11899 [(set_attr "length" "44")
11900 (set_attr "type" "block")
11901 ;; We don't clobber the conditions, but the potential length of this
11902 ;; operation is sufficient to make conditionalizing the sequence
11903 ;; unlikely to be profitable.
11904 (set_attr "conds" "clob")]
11905 )
11906
11907 (define_expand "eh_epilogue"
11908 [(use (match_operand:SI 0 "register_operand" ""))
11909 (use (match_operand:SI 1 "register_operand" ""))
11910 (use (match_operand:SI 2 "register_operand" ""))]
11911 "TARGET_EITHER"
11912 "
11913 {
11914 cfun->machine->eh_epilogue_sp_ofs = operands[1];
11915 if (!REG_P (operands[2]) || REGNO (operands[2]) != 2)
11916 {
11917 rtx ra = gen_rtx_REG (Pmode, 2);
11918
11919 emit_move_insn (ra, operands[2]);
11920 operands[2] = ra;
11921 }
11922 /* This is a hack -- we may have crystalized the function type too
11923 early. */
11924 cfun->machine->func_type = 0;
11925 }"
11926 )
11927
11928 ;; This split is only used during output to reduce the number of patterns
11929 ;; that need assembler instructions adding to them. We allowed the setting
11930 ;; of the conditions to be implicit during rtl generation so that
11931 ;; the conditional compare patterns would work. However this conflicts to
11932 ;; some extent with the conditional data operations, so we have to split them
11933 ;; up again here.
11934
11935 ;; ??? Need to audit these splitters for Thumb-2. Why isn't normal
11936 ;; conditional execution sufficient?
11937
11938 (define_split
11939 [(set (match_operand:SI 0 "s_register_operand" "")
11940 (if_then_else:SI (match_operator 1 "arm_comparison_operator"
11941 [(match_operand 2 "" "") (match_operand 3 "" "")])
11942 (match_dup 0)
11943 (match_operand 4 "" "")))
11944 (clobber (reg:CC CC_REGNUM))]
11945 "TARGET_ARM && reload_completed"
11946 [(set (match_dup 5) (match_dup 6))
11947 (cond_exec (match_dup 7)
11948 (set (match_dup 0) (match_dup 4)))]
11949 "
11950 {
11951 enum machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
11952 operands[2], operands[3]);
11953 enum rtx_code rc = GET_CODE (operands[1]);
11954
11955 operands[5] = gen_rtx_REG (mode, CC_REGNUM);
11956 operands[6] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
11957 if (mode == CCFPmode || mode == CCFPEmode)
11958 rc = reverse_condition_maybe_unordered (rc);
11959 else
11960 rc = reverse_condition (rc);
11961
11962 operands[7] = gen_rtx_fmt_ee (rc, VOIDmode, operands[5], const0_rtx);
11963 }"
11964 )
11965
11966 (define_split
11967 [(set (match_operand:SI 0 "s_register_operand" "")
11968 (if_then_else:SI (match_operator 1 "arm_comparison_operator"
11969 [(match_operand 2 "" "") (match_operand 3 "" "")])
11970 (match_operand 4 "" "")
11971 (match_dup 0)))
11972 (clobber (reg:CC CC_REGNUM))]
11973 "TARGET_ARM && reload_completed"
11974 [(set (match_dup 5) (match_dup 6))
11975 (cond_exec (match_op_dup 1 [(match_dup 5) (const_int 0)])
11976 (set (match_dup 0) (match_dup 4)))]
11977 "
11978 {
11979 enum machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
11980 operands[2], operands[3]);
11981
11982 operands[5] = gen_rtx_REG (mode, CC_REGNUM);
11983 operands[6] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
11984 }"
11985 )
11986
11987 (define_split
11988 [(set (match_operand:SI 0 "s_register_operand" "")
11989 (if_then_else:SI (match_operator 1 "arm_comparison_operator"
11990 [(match_operand 2 "" "") (match_operand 3 "" "")])
11991 (match_operand 4 "" "")
11992 (match_operand 5 "" "")))
11993 (clobber (reg:CC CC_REGNUM))]
11994 "TARGET_ARM && reload_completed"
11995 [(set (match_dup 6) (match_dup 7))
11996 (cond_exec (match_op_dup 1 [(match_dup 6) (const_int 0)])
11997 (set (match_dup 0) (match_dup 4)))
11998 (cond_exec (match_dup 8)
11999 (set (match_dup 0) (match_dup 5)))]
12000 "
12001 {
12002 enum machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
12003 operands[2], operands[3]);
12004 enum rtx_code rc = GET_CODE (operands[1]);
12005
12006 operands[6] = gen_rtx_REG (mode, CC_REGNUM);
12007 operands[7] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
12008 if (mode == CCFPmode || mode == CCFPEmode)
12009 rc = reverse_condition_maybe_unordered (rc);
12010 else
12011 rc = reverse_condition (rc);
12012
12013 operands[8] = gen_rtx_fmt_ee (rc, VOIDmode, operands[6], const0_rtx);
12014 }"
12015 )
12016
12017 (define_split
12018 [(set (match_operand:SI 0 "s_register_operand" "")
12019 (if_then_else:SI (match_operator 1 "arm_comparison_operator"
12020 [(match_operand:SI 2 "s_register_operand" "")
12021 (match_operand:SI 3 "arm_add_operand" "")])
12022 (match_operand:SI 4 "arm_rhs_operand" "")
12023 (not:SI
12024 (match_operand:SI 5 "s_register_operand" ""))))
12025 (clobber (reg:CC CC_REGNUM))]
12026 "TARGET_ARM && reload_completed"
12027 [(set (match_dup 6) (match_dup 7))
12028 (cond_exec (match_op_dup 1 [(match_dup 6) (const_int 0)])
12029 (set (match_dup 0) (match_dup 4)))
12030 (cond_exec (match_dup 8)
12031 (set (match_dup 0) (not:SI (match_dup 5))))]
12032 "
12033 {
12034 enum machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
12035 operands[2], operands[3]);
12036 enum rtx_code rc = GET_CODE (operands[1]);
12037
12038 operands[6] = gen_rtx_REG (mode, CC_REGNUM);
12039 operands[7] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
12040 if (mode == CCFPmode || mode == CCFPEmode)
12041 rc = reverse_condition_maybe_unordered (rc);
12042 else
12043 rc = reverse_condition (rc);
12044
12045 operands[8] = gen_rtx_fmt_ee (rc, VOIDmode, operands[6], const0_rtx);
12046 }"
12047 )
12048
12049 (define_insn "*cond_move_not"
12050 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
12051 (if_then_else:SI (match_operator 4 "arm_comparison_operator"
12052 [(match_operand 3 "cc_register" "") (const_int 0)])
12053 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
12054 (not:SI
12055 (match_operand:SI 2 "s_register_operand" "r,r"))))]
12056 "TARGET_ARM"
12057 "@
12058 mvn%D4\\t%0, %2
12059 mov%d4\\t%0, %1\;mvn%D4\\t%0, %2"
12060 [(set_attr "conds" "use")
12061 (set_attr "type" "mvn_reg,multiple")
12062 (set_attr "length" "4,8")]
12063 )
12064
12065 ;; The next two patterns occur when an AND operation is followed by a
12066 ;; scc insn sequence
12067
12068 (define_insn "*sign_extract_onebit"
12069 [(set (match_operand:SI 0 "s_register_operand" "=r")
12070 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
12071 (const_int 1)
12072 (match_operand:SI 2 "const_int_operand" "n")))
12073 (clobber (reg:CC CC_REGNUM))]
12074 "TARGET_ARM"
12075 "*
12076 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
12077 output_asm_insn (\"ands\\t%0, %1, %2\", operands);
12078 return \"mvnne\\t%0, #0\";
12079 "
12080 [(set_attr "conds" "clob")
12081 (set_attr "length" "8")
12082 (set_attr "type" "multiple")]
12083 )
12084
12085 (define_insn "*not_signextract_onebit"
12086 [(set (match_operand:SI 0 "s_register_operand" "=r")
12087 (not:SI
12088 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
12089 (const_int 1)
12090 (match_operand:SI 2 "const_int_operand" "n"))))
12091 (clobber (reg:CC CC_REGNUM))]
12092 "TARGET_ARM"
12093 "*
12094 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
12095 output_asm_insn (\"tst\\t%1, %2\", operands);
12096 output_asm_insn (\"mvneq\\t%0, #0\", operands);
12097 return \"movne\\t%0, #0\";
12098 "
12099 [(set_attr "conds" "clob")
12100 (set_attr "length" "12")
12101 (set_attr "type" "multiple")]
12102 )
12103 ;; ??? The above patterns need auditing for Thumb-2
12104
12105 ;; Push multiple registers to the stack. Registers are in parallel (use ...)
12106 ;; expressions. For simplicity, the first register is also in the unspec
12107 ;; part.
12108 ;; To avoid the usage of GNU extension, the length attribute is computed
12109 ;; in a C function arm_attr_length_push_multi.
12110 (define_insn "*push_multi"
12111 [(match_parallel 2 "multi_register_push"
12112 [(set (match_operand:BLK 0 "push_mult_memory_operand" "")
12113 (unspec:BLK [(match_operand:SI 1 "s_register_operand" "")]
12114 UNSPEC_PUSH_MULT))])]
12115 ""
12116 "*
12117 {
12118 int num_saves = XVECLEN (operands[2], 0);
12119
12120 /* For the StrongARM at least it is faster to
12121 use STR to store only a single register.
12122 In Thumb mode always use push, and the assembler will pick
12123 something appropriate. */
12124 if (num_saves == 1 && TARGET_ARM)
12125 output_asm_insn (\"str%?\\t%1, [%m0, #-4]!\", operands);
12126 else
12127 {
12128 int i;
12129 char pattern[100];
12130
12131 if (TARGET_ARM)
12132 strcpy (pattern, \"stm%(fd%)\\t%m0!, {%1\");
12133 else if (TARGET_THUMB2)
12134 strcpy (pattern, \"push%?\\t{%1\");
12135 else
12136 strcpy (pattern, \"push\\t{%1\");
12137
12138 for (i = 1; i < num_saves; i++)
12139 {
12140 strcat (pattern, \", %|\");
12141 strcat (pattern,
12142 reg_names[REGNO (XEXP (XVECEXP (operands[2], 0, i), 0))]);
12143 }
12144
12145 strcat (pattern, \"}\");
12146 output_asm_insn (pattern, operands);
12147 }
12148
12149 return \"\";
12150 }"
12151 [(set_attr "type" "store4")
12152 (set (attr "length")
12153 (symbol_ref "arm_attr_length_push_multi (operands[2], operands[1])"))]
12154 )
12155
12156 (define_insn "stack_tie"
12157 [(set (mem:BLK (scratch))
12158 (unspec:BLK [(match_operand:SI 0 "s_register_operand" "rk")
12159 (match_operand:SI 1 "s_register_operand" "rk")]
12160 UNSPEC_PRLG_STK))]
12161 ""
12162 ""
12163 [(set_attr "length" "0")
12164 (set_attr "type" "block")]
12165 )
12166
12167 ;; Pop (as used in epilogue RTL)
12168 ;;
12169 (define_insn "*load_multiple_with_writeback"
12170 [(match_parallel 0 "load_multiple_operation"
12171 [(set (match_operand:SI 1 "s_register_operand" "+rk")
12172 (plus:SI (match_dup 1)
12173 (match_operand:SI 2 "const_int_operand" "I")))
12174 (set (match_operand:SI 3 "s_register_operand" "=rk")
12175 (mem:SI (match_dup 1)))
12176 ])]
12177 "TARGET_32BIT && (reload_in_progress || reload_completed)"
12178 "*
12179 {
12180 arm_output_multireg_pop (operands, /*return_pc=*/false,
12181 /*cond=*/const_true_rtx,
12182 /*reverse=*/false,
12183 /*update=*/true);
12184 return \"\";
12185 }
12186 "
12187 [(set_attr "type" "load4")
12188 (set_attr "predicable" "yes")]
12189 )
12190
12191 ;; Pop with return (as used in epilogue RTL)
12192 ;;
12193 ;; This instruction is generated when the registers are popped at the end of
12194 ;; epilogue. Here, instead of popping the value into LR and then generating
12195 ;; jump to LR, value is popped into PC directly. Hence, the pattern is combined
12196 ;; with (return).
12197 (define_insn "*pop_multiple_with_writeback_and_return"
12198 [(match_parallel 0 "pop_multiple_return"
12199 [(return)
12200 (set (match_operand:SI 1 "s_register_operand" "+rk")
12201 (plus:SI (match_dup 1)
12202 (match_operand:SI 2 "const_int_operand" "I")))
12203 (set (match_operand:SI 3 "s_register_operand" "=rk")
12204 (mem:SI (match_dup 1)))
12205 ])]
12206 "TARGET_32BIT && (reload_in_progress || reload_completed)"
12207 "*
12208 {
12209 arm_output_multireg_pop (operands, /*return_pc=*/true,
12210 /*cond=*/const_true_rtx,
12211 /*reverse=*/false,
12212 /*update=*/true);
12213 return \"\";
12214 }
12215 "
12216 [(set_attr "type" "load4")
12217 (set_attr "predicable" "yes")]
12218 )
12219
12220 (define_insn "*pop_multiple_with_return"
12221 [(match_parallel 0 "pop_multiple_return"
12222 [(return)
12223 (set (match_operand:SI 2 "s_register_operand" "=rk")
12224 (mem:SI (match_operand:SI 1 "s_register_operand" "rk")))
12225 ])]
12226 "TARGET_32BIT && (reload_in_progress || reload_completed)"
12227 "*
12228 {
12229 arm_output_multireg_pop (operands, /*return_pc=*/true,
12230 /*cond=*/const_true_rtx,
12231 /*reverse=*/false,
12232 /*update=*/false);
12233 return \"\";
12234 }
12235 "
12236 [(set_attr "type" "load4")
12237 (set_attr "predicable" "yes")]
12238 )
12239
12240 ;; Load into PC and return
12241 (define_insn "*ldr_with_return"
12242 [(return)
12243 (set (reg:SI PC_REGNUM)
12244 (mem:SI (post_inc:SI (match_operand:SI 0 "s_register_operand" "+rk"))))]
12245 "TARGET_32BIT && (reload_in_progress || reload_completed)"
12246 "ldr%?\t%|pc, [%0], #4"
12247 [(set_attr "type" "load1")
12248 (set_attr "predicable" "yes")]
12249 )
12250 ;; Pop for floating point registers (as used in epilogue RTL)
12251 (define_insn "*vfp_pop_multiple_with_writeback"
12252 [(match_parallel 0 "pop_multiple_fp"
12253 [(set (match_operand:SI 1 "s_register_operand" "+rk")
12254 (plus:SI (match_dup 1)
12255 (match_operand:SI 2 "const_int_operand" "I")))
12256 (set (match_operand:DF 3 "arm_hard_register_operand" "")
12257 (mem:DF (match_dup 1)))])]
12258 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
12259 "*
12260 {
12261 int num_regs = XVECLEN (operands[0], 0);
12262 char pattern[100];
12263 rtx op_list[2];
12264 strcpy (pattern, \"fldmfdd\\t\");
12265 strcat (pattern, reg_names[REGNO (SET_DEST (XVECEXP (operands[0], 0, 0)))]);
12266 strcat (pattern, \"!, {\");
12267 op_list[0] = XEXP (XVECEXP (operands[0], 0, 1), 0);
12268 strcat (pattern, \"%P0\");
12269 if ((num_regs - 1) > 1)
12270 {
12271 strcat (pattern, \"-%P1\");
12272 op_list [1] = XEXP (XVECEXP (operands[0], 0, num_regs - 1), 0);
12273 }
12274
12275 strcat (pattern, \"}\");
12276 output_asm_insn (pattern, op_list);
12277 return \"\";
12278 }
12279 "
12280 [(set_attr "type" "load4")
12281 (set_attr "conds" "unconditional")
12282 (set_attr "predicable" "no")]
12283 )
12284
12285 ;; Special patterns for dealing with the constant pool
12286
12287 (define_insn "align_4"
12288 [(unspec_volatile [(const_int 0)] VUNSPEC_ALIGN)]
12289 "TARGET_EITHER"
12290 "*
12291 assemble_align (32);
12292 return \"\";
12293 "
12294 [(set_attr "type" "no_insn")]
12295 )
12296
12297 (define_insn "align_8"
12298 [(unspec_volatile [(const_int 0)] VUNSPEC_ALIGN8)]
12299 "TARGET_EITHER"
12300 "*
12301 assemble_align (64);
12302 return \"\";
12303 "
12304 [(set_attr "type" "no_insn")]
12305 )
12306
12307 (define_insn "consttable_end"
12308 [(unspec_volatile [(const_int 0)] VUNSPEC_POOL_END)]
12309 "TARGET_EITHER"
12310 "*
12311 making_const_table = FALSE;
12312 return \"\";
12313 "
12314 [(set_attr "type" "no_insn")]
12315 )
12316
12317 (define_insn "consttable_1"
12318 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_1)]
12319 "TARGET_THUMB1"
12320 "*
12321 making_const_table = TRUE;
12322 assemble_integer (operands[0], 1, BITS_PER_WORD, 1);
12323 assemble_zeros (3);
12324 return \"\";
12325 "
12326 [(set_attr "length" "4")
12327 (set_attr "type" "no_insn")]
12328 )
12329
12330 (define_insn "consttable_2"
12331 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_2)]
12332 "TARGET_THUMB1"
12333 "*
12334 making_const_table = TRUE;
12335 gcc_assert (GET_MODE_CLASS (GET_MODE (operands[0])) != MODE_FLOAT);
12336 assemble_integer (operands[0], 2, BITS_PER_WORD, 1);
12337 assemble_zeros (2);
12338 return \"\";
12339 "
12340 [(set_attr "length" "4")
12341 (set_attr "type" "no_insn")]
12342 )
12343
12344 (define_insn "consttable_4"
12345 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_4)]
12346 "TARGET_EITHER"
12347 "*
12348 {
12349 rtx x = operands[0];
12350 making_const_table = TRUE;
12351 switch (GET_MODE_CLASS (GET_MODE (x)))
12352 {
12353 case MODE_FLOAT:
12354 if (GET_MODE (x) == HFmode)
12355 arm_emit_fp16_const (x);
12356 else
12357 {
12358 REAL_VALUE_TYPE r;
12359 REAL_VALUE_FROM_CONST_DOUBLE (r, x);
12360 assemble_real (r, GET_MODE (x), BITS_PER_WORD);
12361 }
12362 break;
12363 default:
12364 /* XXX: Sometimes gcc does something really dumb and ends up with
12365 a HIGH in a constant pool entry, usually because it's trying to
12366 load into a VFP register. We know this will always be used in
12367 combination with a LO_SUM which ignores the high bits, so just
12368 strip off the HIGH. */
12369 if (GET_CODE (x) == HIGH)
12370 x = XEXP (x, 0);
12371 assemble_integer (x, 4, BITS_PER_WORD, 1);
12372 mark_symbol_refs_as_used (x);
12373 break;
12374 }
12375 return \"\";
12376 }"
12377 [(set_attr "length" "4")
12378 (set_attr "type" "no_insn")]
12379 )
12380
12381 (define_insn "consttable_8"
12382 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_8)]
12383 "TARGET_EITHER"
12384 "*
12385 {
12386 making_const_table = TRUE;
12387 switch (GET_MODE_CLASS (GET_MODE (operands[0])))
12388 {
12389 case MODE_FLOAT:
12390 {
12391 REAL_VALUE_TYPE r;
12392 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[0]);
12393 assemble_real (r, GET_MODE (operands[0]), BITS_PER_WORD);
12394 break;
12395 }
12396 default:
12397 assemble_integer (operands[0], 8, BITS_PER_WORD, 1);
12398 break;
12399 }
12400 return \"\";
12401 }"
12402 [(set_attr "length" "8")
12403 (set_attr "type" "no_insn")]
12404 )
12405
12406 (define_insn "consttable_16"
12407 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_16)]
12408 "TARGET_EITHER"
12409 "*
12410 {
12411 making_const_table = TRUE;
12412 switch (GET_MODE_CLASS (GET_MODE (operands[0])))
12413 {
12414 case MODE_FLOAT:
12415 {
12416 REAL_VALUE_TYPE r;
12417 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[0]);
12418 assemble_real (r, GET_MODE (operands[0]), BITS_PER_WORD);
12419 break;
12420 }
12421 default:
12422 assemble_integer (operands[0], 16, BITS_PER_WORD, 1);
12423 break;
12424 }
12425 return \"\";
12426 }"
12427 [(set_attr "length" "16")
12428 (set_attr "type" "no_insn")]
12429 )
12430
12431 ;; Miscellaneous Thumb patterns
12432
12433 (define_expand "tablejump"
12434 [(parallel [(set (pc) (match_operand:SI 0 "register_operand" ""))
12435 (use (label_ref (match_operand 1 "" "")))])]
12436 "TARGET_THUMB1"
12437 "
12438 if (flag_pic)
12439 {
12440 /* Hopefully, CSE will eliminate this copy. */
12441 rtx reg1 = copy_addr_to_reg (gen_rtx_LABEL_REF (Pmode, operands[1]));
12442 rtx reg2 = gen_reg_rtx (SImode);
12443
12444 emit_insn (gen_addsi3 (reg2, operands[0], reg1));
12445 operands[0] = reg2;
12446 }
12447 "
12448 )
12449
12450 ;; NB never uses BX.
12451 (define_insn "*thumb1_tablejump"
12452 [(set (pc) (match_operand:SI 0 "register_operand" "l*r"))
12453 (use (label_ref (match_operand 1 "" "")))]
12454 "TARGET_THUMB1"
12455 "mov\\t%|pc, %0"
12456 [(set_attr "length" "2")
12457 (set_attr "type" "no_insn")]
12458 )
12459
12460 ;; V5 Instructions,
12461
12462 (define_insn "clzsi2"
12463 [(set (match_operand:SI 0 "s_register_operand" "=r")
12464 (clz:SI (match_operand:SI 1 "s_register_operand" "r")))]
12465 "TARGET_32BIT && arm_arch5"
12466 "clz%?\\t%0, %1"
12467 [(set_attr "predicable" "yes")
12468 (set_attr "type" "clz")])
12469
12470 (define_insn "rbitsi2"
12471 [(set (match_operand:SI 0 "s_register_operand" "=r")
12472 (unspec:SI [(match_operand:SI 1 "s_register_operand" "r")] UNSPEC_RBIT))]
12473 "TARGET_32BIT && arm_arch_thumb2"
12474 "rbit%?\\t%0, %1"
12475 [(set_attr "predicable" "yes")
12476 (set_attr "type" "clz")])
12477
12478 (define_expand "ctzsi2"
12479 [(set (match_operand:SI 0 "s_register_operand" "")
12480 (ctz:SI (match_operand:SI 1 "s_register_operand" "")))]
12481 "TARGET_32BIT && arm_arch_thumb2"
12482 "
12483 {
12484 rtx tmp = gen_reg_rtx (SImode);
12485 emit_insn (gen_rbitsi2 (tmp, operands[1]));
12486 emit_insn (gen_clzsi2 (operands[0], tmp));
12487 }
12488 DONE;
12489 "
12490 )
12491
12492 ;; V5E instructions.
12493
12494 (define_insn "prefetch"
12495 [(prefetch (match_operand:SI 0 "address_operand" "p")
12496 (match_operand:SI 1 "" "")
12497 (match_operand:SI 2 "" ""))]
12498 "TARGET_32BIT && arm_arch5e"
12499 "pld\\t%a0"
12500 [(set_attr "type" "load1")]
12501 )
12502
12503 ;; General predication pattern
12504
12505 (define_cond_exec
12506 [(match_operator 0 "arm_comparison_operator"
12507 [(match_operand 1 "cc_register" "")
12508 (const_int 0)])]
12509 "TARGET_32BIT"
12510 ""
12511 [(set_attr "predicated" "yes")]
12512 )
12513
12514 (define_insn "force_register_use"
12515 [(unspec:SI [(match_operand:SI 0 "register_operand" "")] UNSPEC_REGISTER_USE)]
12516 ""
12517 "%@ %0 needed"
12518 [(set_attr "length" "0")
12519 (set_attr "type" "no_insn")]
12520 )
12521
12522
12523 ;; Patterns for exception handling
12524
12525 (define_expand "eh_return"
12526 [(use (match_operand 0 "general_operand" ""))]
12527 "TARGET_EITHER"
12528 "
12529 {
12530 if (TARGET_32BIT)
12531 emit_insn (gen_arm_eh_return (operands[0]));
12532 else
12533 emit_insn (gen_thumb_eh_return (operands[0]));
12534 DONE;
12535 }"
12536 )
12537
12538 ;; We can't expand this before we know where the link register is stored.
12539 (define_insn_and_split "arm_eh_return"
12540 [(unspec_volatile [(match_operand:SI 0 "s_register_operand" "r")]
12541 VUNSPEC_EH_RETURN)
12542 (clobber (match_scratch:SI 1 "=&r"))]
12543 "TARGET_ARM"
12544 "#"
12545 "&& reload_completed"
12546 [(const_int 0)]
12547 "
12548 {
12549 arm_set_return_address (operands[0], operands[1]);
12550 DONE;
12551 }"
12552 )
12553
12554 (define_insn_and_split "thumb_eh_return"
12555 [(unspec_volatile [(match_operand:SI 0 "s_register_operand" "l")]
12556 VUNSPEC_EH_RETURN)
12557 (clobber (match_scratch:SI 1 "=&l"))]
12558 "TARGET_THUMB1"
12559 "#"
12560 "&& reload_completed"
12561 [(const_int 0)]
12562 "
12563 {
12564 thumb_set_return_address (operands[0], operands[1]);
12565 DONE;
12566 }"
12567 [(set_attr "type" "mov_reg")]
12568 )
12569
12570 \f
12571 ;; TLS support
12572
12573 (define_insn "load_tp_hard"
12574 [(set (match_operand:SI 0 "register_operand" "=r")
12575 (unspec:SI [(const_int 0)] UNSPEC_TLS))]
12576 "TARGET_HARD_TP"
12577 "mrc%?\\tp15, 0, %0, c13, c0, 3\\t@ load_tp_hard"
12578 [(set_attr "predicable" "yes")
12579 (set_attr "type" "mrs")]
12580 )
12581
12582 ;; Doesn't clobber R1-R3. Must use r0 for the first operand.
12583 (define_insn "load_tp_soft"
12584 [(set (reg:SI 0) (unspec:SI [(const_int 0)] UNSPEC_TLS))
12585 (clobber (reg:SI LR_REGNUM))
12586 (clobber (reg:SI IP_REGNUM))
12587 (clobber (reg:CC CC_REGNUM))]
12588 "TARGET_SOFT_TP"
12589 "bl\\t__aeabi_read_tp\\t@ load_tp_soft"
12590 [(set_attr "conds" "clob")
12591 (set_attr "type" "branch")]
12592 )
12593
12594 ;; tls descriptor call
12595 (define_insn "tlscall"
12596 [(set (reg:SI R0_REGNUM)
12597 (unspec:SI [(reg:SI R0_REGNUM)
12598 (match_operand:SI 0 "" "X")
12599 (match_operand 1 "" "")] UNSPEC_TLS))
12600 (clobber (reg:SI R1_REGNUM))
12601 (clobber (reg:SI LR_REGNUM))
12602 (clobber (reg:SI CC_REGNUM))]
12603 "TARGET_GNU2_TLS"
12604 {
12605 targetm.asm_out.internal_label (asm_out_file, "LPIC",
12606 INTVAL (operands[1]));
12607 return "bl\\t%c0(tlscall)";
12608 }
12609 [(set_attr "conds" "clob")
12610 (set_attr "length" "4")
12611 (set_attr "type" "branch")]
12612 )
12613
12614 ;; For thread pointer builtin
12615 (define_expand "get_thread_pointersi"
12616 [(match_operand:SI 0 "s_register_operand" "=r")]
12617 ""
12618 "
12619 {
12620 arm_load_tp (operands[0]);
12621 DONE;
12622 }")
12623
12624 ;;
12625
12626 ;; We only care about the lower 16 bits of the constant
12627 ;; being inserted into the upper 16 bits of the register.
12628 (define_insn "*arm_movtas_ze"
12629 [(set (zero_extract:SI (match_operand:SI 0 "s_register_operand" "+r")
12630 (const_int 16)
12631 (const_int 16))
12632 (match_operand:SI 1 "const_int_operand" ""))]
12633 "arm_arch_thumb2"
12634 "movt%?\t%0, %L1"
12635 [(set_attr "predicable" "yes")
12636 (set_attr "predicable_short_it" "no")
12637 (set_attr "length" "4")
12638 (set_attr "type" "mov_imm")]
12639 )
12640
12641 (define_insn "*arm_rev"
12642 [(set (match_operand:SI 0 "s_register_operand" "=l,l,r")
12643 (bswap:SI (match_operand:SI 1 "s_register_operand" "l,l,r")))]
12644 "arm_arch6"
12645 "@
12646 rev\t%0, %1
12647 rev%?\t%0, %1
12648 rev%?\t%0, %1"
12649 [(set_attr "arch" "t1,t2,32")
12650 (set_attr "length" "2,2,4")
12651 (set_attr "type" "rev")]
12652 )
12653
12654 (define_expand "arm_legacy_rev"
12655 [(set (match_operand:SI 2 "s_register_operand" "")
12656 (xor:SI (rotatert:SI (match_operand:SI 1 "s_register_operand" "")
12657 (const_int 16))
12658 (match_dup 1)))
12659 (set (match_dup 2)
12660 (lshiftrt:SI (match_dup 2)
12661 (const_int 8)))
12662 (set (match_operand:SI 3 "s_register_operand" "")
12663 (rotatert:SI (match_dup 1)
12664 (const_int 8)))
12665 (set (match_dup 2)
12666 (and:SI (match_dup 2)
12667 (const_int -65281)))
12668 (set (match_operand:SI 0 "s_register_operand" "")
12669 (xor:SI (match_dup 3)
12670 (match_dup 2)))]
12671 "TARGET_32BIT"
12672 ""
12673 )
12674
12675 ;; Reuse temporaries to keep register pressure down.
12676 (define_expand "thumb_legacy_rev"
12677 [(set (match_operand:SI 2 "s_register_operand" "")
12678 (ashift:SI (match_operand:SI 1 "s_register_operand" "")
12679 (const_int 24)))
12680 (set (match_operand:SI 3 "s_register_operand" "")
12681 (lshiftrt:SI (match_dup 1)
12682 (const_int 24)))
12683 (set (match_dup 3)
12684 (ior:SI (match_dup 3)
12685 (match_dup 2)))
12686 (set (match_operand:SI 4 "s_register_operand" "")
12687 (const_int 16))
12688 (set (match_operand:SI 5 "s_register_operand" "")
12689 (rotatert:SI (match_dup 1)
12690 (match_dup 4)))
12691 (set (match_dup 2)
12692 (ashift:SI (match_dup 5)
12693 (const_int 24)))
12694 (set (match_dup 5)
12695 (lshiftrt:SI (match_dup 5)
12696 (const_int 24)))
12697 (set (match_dup 5)
12698 (ior:SI (match_dup 5)
12699 (match_dup 2)))
12700 (set (match_dup 5)
12701 (rotatert:SI (match_dup 5)
12702 (match_dup 4)))
12703 (set (match_operand:SI 0 "s_register_operand" "")
12704 (ior:SI (match_dup 5)
12705 (match_dup 3)))]
12706 "TARGET_THUMB"
12707 ""
12708 )
12709
12710 (define_expand "bswapsi2"
12711 [(set (match_operand:SI 0 "s_register_operand" "=r")
12712 (bswap:SI (match_operand:SI 1 "s_register_operand" "r")))]
12713 "TARGET_EITHER && (arm_arch6 || !optimize_size)"
12714 "
12715 if (!arm_arch6)
12716 {
12717 rtx op2 = gen_reg_rtx (SImode);
12718 rtx op3 = gen_reg_rtx (SImode);
12719
12720 if (TARGET_THUMB)
12721 {
12722 rtx op4 = gen_reg_rtx (SImode);
12723 rtx op5 = gen_reg_rtx (SImode);
12724
12725 emit_insn (gen_thumb_legacy_rev (operands[0], operands[1],
12726 op2, op3, op4, op5));
12727 }
12728 else
12729 {
12730 emit_insn (gen_arm_legacy_rev (operands[0], operands[1],
12731 op2, op3));
12732 }
12733
12734 DONE;
12735 }
12736 "
12737 )
12738
12739 ;; bswap16 patterns: use revsh and rev16 instructions for the signed
12740 ;; and unsigned variants, respectively. For rev16, expose
12741 ;; byte-swapping in the lower 16 bits only.
12742 (define_insn "*arm_revsh"
12743 [(set (match_operand:SI 0 "s_register_operand" "=l,l,r")
12744 (sign_extend:SI (bswap:HI (match_operand:HI 1 "s_register_operand" "l,l,r"))))]
12745 "arm_arch6"
12746 "@
12747 revsh\t%0, %1
12748 revsh%?\t%0, %1
12749 revsh%?\t%0, %1"
12750 [(set_attr "arch" "t1,t2,32")
12751 (set_attr "length" "2,2,4")
12752 (set_attr "type" "rev")]
12753 )
12754
12755 (define_insn "*arm_rev16"
12756 [(set (match_operand:HI 0 "s_register_operand" "=l,l,r")
12757 (bswap:HI (match_operand:HI 1 "s_register_operand" "l,l,r")))]
12758 "arm_arch6"
12759 "@
12760 rev16\t%0, %1
12761 rev16%?\t%0, %1
12762 rev16%?\t%0, %1"
12763 [(set_attr "arch" "t1,t2,32")
12764 (set_attr "length" "2,2,4")
12765 (set_attr "type" "rev")]
12766 )
12767
12768 (define_expand "bswaphi2"
12769 [(set (match_operand:HI 0 "s_register_operand" "=r")
12770 (bswap:HI (match_operand:HI 1 "s_register_operand" "r")))]
12771 "arm_arch6"
12772 ""
12773 )
12774
12775 ;; Patterns for LDRD/STRD in Thumb2 mode
12776
12777 (define_insn "*thumb2_ldrd"
12778 [(set (match_operand:SI 0 "s_register_operand" "=r")
12779 (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "rk")
12780 (match_operand:SI 2 "ldrd_strd_offset_operand" "Do"))))
12781 (set (match_operand:SI 3 "s_register_operand" "=r")
12782 (mem:SI (plus:SI (match_dup 1)
12783 (match_operand:SI 4 "const_int_operand" ""))))]
12784 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
12785 && current_tune->prefer_ldrd_strd
12786 && ((INTVAL (operands[2]) + 4) == INTVAL (operands[4]))
12787 && (operands_ok_ldrd_strd (operands[0], operands[3],
12788 operands[1], INTVAL (operands[2]),
12789 false, true))"
12790 "ldrd%?\t%0, %3, [%1, %2]"
12791 [(set_attr "type" "load2")
12792 (set_attr "predicable" "yes")
12793 (set_attr "predicable_short_it" "no")])
12794
12795 (define_insn "*thumb2_ldrd_base"
12796 [(set (match_operand:SI 0 "s_register_operand" "=r")
12797 (mem:SI (match_operand:SI 1 "s_register_operand" "rk")))
12798 (set (match_operand:SI 2 "s_register_operand" "=r")
12799 (mem:SI (plus:SI (match_dup 1)
12800 (const_int 4))))]
12801 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
12802 && current_tune->prefer_ldrd_strd
12803 && (operands_ok_ldrd_strd (operands[0], operands[2],
12804 operands[1], 0, false, true))"
12805 "ldrd%?\t%0, %2, [%1]"
12806 [(set_attr "type" "load2")
12807 (set_attr "predicable" "yes")
12808 (set_attr "predicable_short_it" "no")])
12809
12810 (define_insn "*thumb2_ldrd_base_neg"
12811 [(set (match_operand:SI 0 "s_register_operand" "=r")
12812 (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "rk")
12813 (const_int -4))))
12814 (set (match_operand:SI 2 "s_register_operand" "=r")
12815 (mem:SI (match_dup 1)))]
12816 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
12817 && current_tune->prefer_ldrd_strd
12818 && (operands_ok_ldrd_strd (operands[0], operands[2],
12819 operands[1], -4, false, true))"
12820 "ldrd%?\t%0, %2, [%1, #-4]"
12821 [(set_attr "type" "load2")
12822 (set_attr "predicable" "yes")
12823 (set_attr "predicable_short_it" "no")])
12824
12825 (define_insn "*thumb2_strd"
12826 [(set (mem:SI (plus:SI (match_operand:SI 0 "s_register_operand" "rk")
12827 (match_operand:SI 1 "ldrd_strd_offset_operand" "Do")))
12828 (match_operand:SI 2 "s_register_operand" "r"))
12829 (set (mem:SI (plus:SI (match_dup 0)
12830 (match_operand:SI 3 "const_int_operand" "")))
12831 (match_operand:SI 4 "s_register_operand" "r"))]
12832 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
12833 && current_tune->prefer_ldrd_strd
12834 && ((INTVAL (operands[1]) + 4) == INTVAL (operands[3]))
12835 && (operands_ok_ldrd_strd (operands[2], operands[4],
12836 operands[0], INTVAL (operands[1]),
12837 false, false))"
12838 "strd%?\t%2, %4, [%0, %1]"
12839 [(set_attr "type" "store2")
12840 (set_attr "predicable" "yes")
12841 (set_attr "predicable_short_it" "no")])
12842
12843 (define_insn "*thumb2_strd_base"
12844 [(set (mem:SI (match_operand:SI 0 "s_register_operand" "rk"))
12845 (match_operand:SI 1 "s_register_operand" "r"))
12846 (set (mem:SI (plus:SI (match_dup 0)
12847 (const_int 4)))
12848 (match_operand:SI 2 "s_register_operand" "r"))]
12849 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
12850 && current_tune->prefer_ldrd_strd
12851 && (operands_ok_ldrd_strd (operands[1], operands[2],
12852 operands[0], 0, false, false))"
12853 "strd%?\t%1, %2, [%0]"
12854 [(set_attr "type" "store2")
12855 (set_attr "predicable" "yes")
12856 (set_attr "predicable_short_it" "no")])
12857
12858 (define_insn "*thumb2_strd_base_neg"
12859 [(set (mem:SI (plus:SI (match_operand:SI 0 "s_register_operand" "rk")
12860 (const_int -4)))
12861 (match_operand:SI 1 "s_register_operand" "r"))
12862 (set (mem:SI (match_dup 0))
12863 (match_operand:SI 2 "s_register_operand" "r"))]
12864 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
12865 && current_tune->prefer_ldrd_strd
12866 && (operands_ok_ldrd_strd (operands[1], operands[2],
12867 operands[0], -4, false, false))"
12868 "strd%?\t%1, %2, [%0, #-4]"
12869 [(set_attr "type" "store2")
12870 (set_attr "predicable" "yes")
12871 (set_attr "predicable_short_it" "no")])
12872
12873
12874 ;; Load the load/store double peephole optimizations.
12875 (include "ldrdstrd.md")
12876
12877 ;; Load the load/store multiple patterns
12878 (include "ldmstm.md")
12879
12880 ;; Patterns in ldmstm.md don't cover more than 4 registers. This pattern covers
12881 ;; large lists without explicit writeback generated for APCS_FRAME epilogue.
12882 (define_insn "*load_multiple"
12883 [(match_parallel 0 "load_multiple_operation"
12884 [(set (match_operand:SI 2 "s_register_operand" "=rk")
12885 (mem:SI (match_operand:SI 1 "s_register_operand" "rk")))
12886 ])]
12887 "TARGET_32BIT"
12888 "*
12889 {
12890 arm_output_multireg_pop (operands, /*return_pc=*/false,
12891 /*cond=*/const_true_rtx,
12892 /*reverse=*/false,
12893 /*update=*/false);
12894 return \"\";
12895 }
12896 "
12897 [(set_attr "predicable" "yes")]
12898 )
12899
12900 ;; Vector bits common to IWMMXT and Neon
12901 (include "vec-common.md")
12902 ;; Load the Intel Wireless Multimedia Extension patterns
12903 (include "iwmmxt.md")
12904 ;; Load the VFP co-processor patterns
12905 (include "vfp.md")
12906 ;; Thumb-2 patterns
12907 (include "thumb2.md")
12908 ;; Neon patterns
12909 (include "neon.md")
12910 ;; Synchronization Primitives
12911 (include "sync.md")
12912 ;; Fixed-point patterns
12913 (include "arm-fixed.md")